GtkMenu calls gtk_widget_size_allocate on its GtkWindow during
gtk_menu_popup_for_device if the menu has not been realised. This can cause the
allocation of the GtkWindow and the size of the GdkWindow to become out of sync
because a top level GtkWindow does not attempt to re-size the GdkWindow when
its allocation is set.
https://bugzilla.gnome.org/show_bug.cgi?id=695120
We should only draw the cross-fade on the bin window, not doing this
was causing us to draw it multiple times using ADD which resulted
in weird colors.
This makes iterating over the children a lot faster, as we're
not doing lots of intra-library calls and type checks. We're still
in some sence O(n^2) since we iterate over each child window for each
widget, but the profiles look much better.
We register an invalidate handler on the bin window to get told
of child widget invalidations, although we manually need to discard
invalidates from the scroll operation.
Additionally we invalidate all of the pixel cache whenever
the TreeView itself is queue_draw()n to handle e.g. style (bg)
changes, or changes due to model changes causing queue_draw() in
the tree view.
Since gdk_window_move() no longer uses XCopyArea all scrolling
now re-renders everything in the window. To get performance
back we use a GtkPixelCache to store already drawn children,
and we when we expose the viewport we just blit the
offscreen to the right place.
GtkPixelCache is a helper utility that lets you implement
faster scrolling of a viewport of a canvas by using an
offscreen pixmap cache.
You call _gtk_pixel_cache_draw with a callback function that
does the drawing, and additionally you specify the size and the
position of the viewport in the widget, and the position and size
of the canvas wrt the viewport. The callback will be called to
draw on an offscreen surface, and the surface will be drawn
on the window. The next time you do the same, any already drawn
pieces of the surface are re-used from the offscreen and need
not be rendered again.
If things inside the canvas change you need to call
_gtk_pixel_cache_invalidate to tell the cache about this.
Some other details:
* The offscreen surface is generally a bit larger than
the viewport, so scrolling a small amount can often
be done without redrawing children.
* If the canvas is not larger than the viewport no
offscreen surface is used.
GtkPixelCache: Make sure we always copy using SOURCE
We were using OVER for the first copy (from source to group surface.
GtkPixelCache: Fix x/y typos
GtkPixelCache: Allow NULL for invalidate region
gtkpixelcache: Use CONTENT_COLOR for solid bg windows
Since widgets now cache drawn state we allow them to override
queue_draw_region to detect when some region of the widget
should be redrawn. For instance, if a widget draws the
background color in a pixel cache we will need to invalidate
that when the style context changes which queues a repaint.
We do the save/restore when emitting ::draw rather than in a custom
marshaller, as this saves an extra stack frame, which is helpfull now
that we do painting fully recursive. This is also likely to save a few
cycles.
We now consider non-native windows non-opaque, which means any invalid
area in a subwindow will also be invalid all the way up to the nearest
native windows. We take advantage of this by ignoring all expose events
on non-native windows (which typically means just the toplevel) and instead
propagating down the draw() calls to children directly via
gtk_container_propagate_draw.
This is nice as it means we always draw widgets the same way, and it
will let us do some interesting ways in the future.
We also clean up the GtkWidget opacity handling as we can now always
rely on the draing happening via cairo.
We can't really just draw by walking down the widget hierarchy, as
this doesn't get the clipping right (so e.g. widgets doing cairo_paint
may draw outside the expected gdkwindow subarea) nor does it let
us paint window backgrounds.
So, we now do multiple draws for each widget, once for each GdkWindow,
although we still do it on the same base cairo_t that we get for the
toplevel native window. The difference is only the clipping, the rendering
order, and which other widgets we propagate into.
We also collect all the windows of a widget so we can expose them inside
the same opacity group if needed.
NOTE: This change neuters gtk_widget_set_double_buffered for
widgets without native windows. Its impossible to disable
the double buffering in this model.
Turns out our blurring function isn't very nice, it has a lot
of energy past the blur radius, so clipping at exactly the
blur radius causes ugly gradient stops. This just adds 4
extra pixels of slop, which makes this better in most cases.
We split up the rendering of blurred shadows into 9 parts, the
corners, the sides and the rest. This lets us only blur the "blurry"
part, and it lets us completely skip blurry parts that are fully
clipped.
As per css3-background 7.2. Drop Shadows: the ‘box-shadow’ property:
An outer box-shadow casts a shadow as if the border-box of the element
were opaque. The shadow is drawn outside the border edge only: it
is clipped inside the border-box of the element.
Also verified vs firefox behaviour.
glib-mkenums is not currently clever enough to know which version an
enum type was added in, so just mark all the _get_type() functions as
available in all versions.
This avoids an evil trap when doing MAX (..., ... - 2 * border_width)
and the expression on the right gets promoted to unsigned, instead
of going negative as you would expect.
https://bugzilla.gnome.org/show_bug.cgi?id=699633
These tests check that a toplevel window ends up with the expected
size after setting default sizes or resizing. It currently passes
on X, but fails with client-side decorations under X and Wayland.