GNOME Bugzilla – Bug 682854
Scrolled window draws often the wrong background
Last modified: 2012-08-28 15:57:25 UTC
Created attachment 222613 [details] test case I haven't figured out yet why, but this is easy to reproduce if you place an iconview with centered alignment inside a scrolledwindow with fill-alignment and take the focus away from it (so that it renders with backdrop background color). The background color of the area not filled by the iconview is rendered without the backdrop color. I suppose that this is a combination of issues, but at least here's a test case for starters.
When the icon view gets a state_flags_changed signal it updates the background on the GdkWindows which will cause a re-expose of the icon view window. The expose handling of this will include redrawing the parent window (i.e. the scrolledwindow), but only clipped to the area of the icon view. The scrolled window itself does not do anything to cause it to repaint when the state flags changes on itself, and even less when the state changes on its child. So, it will never be re-exposed in its entirety when going to the :background state. This means that it will only repaint itself on a :background transition in the areas covered by the child.
Isn't this a general problem? All widgets that draw a background/frame needs to queue a redraw in state_flags_changed if the state flags change would cause the current css rulest to change the background/frame css properties. How is this generally handled?
GTK currently always queues a redraw (in fact, it queues a resize) whenever any CSS property changes. Note that it does that during style validation, which happens before the actual resize. So it will not have happened yet during state_flags_changed emission.
<alex> Company: ok, so it queues a redraw on the widget where the state flag change causes a css property change, right? <Company> yes <alex> So, thats the problem here <Company> it triggers a restyle, which may or may not trigger a resize <alex> Basically, we have a widget inside a scrolledwindow <alex> Which is smaller than the scrolledwindow <alex> Now, a :backdrop change causes the background properties to change on the sw child so its repainted <alex> However, there are no rules to change the sw background based on :backdrop <alex> Instead the scrolled window draw code does: <alex> /* Use child's background if possible */ <alex> child = gtk_bin_get_child (GTK_BIN (widget)); <alex> if (child && gtk_widget_get_has_window (child)) <alex> pattern = gdk_window_get_background_pattern (gtk_widget_get_window (child)); <alex> if (pattern && <alex> cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID) <alex> ... draw the patten over the whole sw <Company> oh, i remember that <alex> Obviously, the css machinery has no idea of this connection, so the whole sw widget is not repainted <Company> cosimoc, garnacho and me talked about it <alex> only the area under the child <Company> and i thought cosimoc was gonna remove that - or am I misremembering that? * alex & no idea <Company> it had to do with overdraw on kinetic scrolling
Pushed a fix for this to git master now, thanks for the report!