After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 679144 - Gdk doesn't properly find the child area with alpha
Gdk doesn't properly find the child area with alpha
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: X11
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2012-06-29 14:19 UTC by Alexander Larsson
Modified: 2012-08-23 14:45 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Fix nasty flashing when clicking on toolbar (1.70 KB, patch)
2012-06-29 14:25 UTC, Alexander Larsson
committed Details | Review
Fix flashing in non-double-buffered widgets (4.29 KB, patch)
2012-08-23 14:00 UTC, Alexander Larsson
committed Details | Review
Remove gdk_window_flush_if_exposing as its not needed anymore (2.87 KB, patch)
2012-08-23 14:00 UTC, Alexander Larsson
committed Details | Review

Description Alexander Larsson 2012-06-29 14:19:43 UTC
With latest gnome-themes-standard there is a very nasty flash whenever you
click on the toolbar.
Comment 1 Alexander Larsson 2012-06-29 14:25:48 UTC
Created attachment 217627 [details] [review]
Fix nasty flashing when clicking on toolbar

The spice widget is non-double-buffered, which interacts poorly with
transparent windows. What happens in this case is that the EvenBox
that the spice widet is inside is transparent, but its parent (the window
is not). When drawing the window gdk believes the area under the EventBox
is transparent, so its drawn by the window, and then not drawn as transparent
by the EventBox. When we get to the non-double buffered spice widget
we need to flush the current double buffer pixmap which temporarily shows
the window background before drawing the spice contents.

The fix here is to make the EventBox get a solid background. However, I don't
believe this should be necessary. Gdk should know that the spice widgets
window is opaque and fully covers the evenbox, so it should not have
to paint the window background under the eventbox. I believe this should
be fixable in Gtk+.
Comment 2 Alexander Larsson 2012-06-29 14:36:44 UTC
Comment on attachment 217627 [details] [review]
Fix nasty flashing when clicking on toolbar

Attachment 217627 [details] pushed as 493b670 - Fix nasty flashing when clicking on toolbar
Comment 3 Alexander Larsson 2012-06-29 14:39:54 UTC
Refiling against Gtk+. We should really fix this in Gdk, so that when a child window has_alpha_background we should not always make all that area layered, if it has opaque children.
Comment 4 Alexander Larsson 2012-08-23 13:46:47 UTC
This is still causing some pretty nasty flashing in gnome-boxes (due to the
Spice Widget disabling double buffering). We have a (simplified) hierarchy
something like this:.

 A - GtkWindow window
 |
 +-> B - Transparent GdkWindow
     |
     +>  C - Solid GdkWindow with double buffering disabled 
     

When drawing A we fill in (into the double-buffer) the background color. 
Historically this would have not cleared any area that had a child
window in it, but with the new alpha bg support we only clip out children
that are fully opaque. So, in this case we will clear the bg under B. This
will also cover the area where C will later overdraw, which is not typically
a problem apart from some unnecessary drawing.

However, In this case C is drawn without double buffering, which means we
have to "flush" the current double-buffer data before drawing it. We then
copy the currently rendered data there (the bg from A) to the window (so
that the window has the correct data so far), and then the non-double-buffered
rendering in C happens.

This guarantees the correct rendering even in cases where the expose handler
in C draws things with alpha, or if it somehow mixes double buffered drawing with
direct rendering. But it also creates a flash, as the A background is temporarily
visible on the screen.

The "correct" solution for this would be to fully track the child region such that
in a case like the above the region for C would be clipped out when you render to C.
However, calculating clip regions like that is extremely expensive as it means any
change in window positions/size/order can propagate to changes in the whole window
hierarchy.

A more reasonable fix is to avoid the flush operation on C copying the partially
drawn background to the window, thus avoiding the flash. This would make it
buggy to have a non-double-buffered expose handler draw with opacity, which isn't
really a big deal imho. It would also mean that you can't mix double buffering with
direct drawing. Today this means calling any of:
 gdk_window_flush, _raise, _lower, _move, _resize, _scroll
inside the expose handler of a double buffered widget.

We do have some code that handles this currently, by automatically flushing as
per above if you call any of these. But that would break if we disable the 
copy-partial-double-buffer-contents-to-window operation. However, it seems
to me that moving windows etc in an expose handler is pretty fringe and we
should be able to ignore that in order to get the "typical" non-db case (widgets
that already have a double buffered pixbuf and just draws it in expose) without
flickering.
Comment 5 Alexander Larsson 2012-08-23 14:00:00 UTC
Created attachment 222228 [details] [review]
Fix flashing in non-double-buffered widgets

Avoid copying back partially drawn double-buffer data
when flushing to avoid flicker. This means non double
buffered widgets must draw opaque pixels in its expose
handlers, and that you are not allowed to use direct
rendering (or modify GdkWindow pos/size/order) from
inside the expose handler of a double buffered widget.

See https://bugzilla.gnome.org/show_bug.cgi?id=679144 for more
details
Comment 6 Alexander Larsson 2012-08-23 14:00:11 UTC
Created attachment 222229 [details] [review]
Remove gdk_window_flush_if_exposing as its not needed anymore

We no longer support modifying GdkWindow hierarchies during
expose events. This is not working anymore anyway as the
flush operation now does not push already rendered pixels
in the flushed window from the double buffer to the window.
Comment 7 Alexander Larsson 2012-08-23 14:44:55 UTC
Attachment 222229 [details] pushed as 29a4208 - Remove gdk_window_flush_if_exposing as its not needed anymore