In the case where the layout phase queued a layout we don't
want to progress to the paint phase with invalid allocations, so
we loop the layout. This shouldn't normally happen, but it may
happen in some edge cases like if user/wm resizes clash with
natural window size changes from a gtk widget. This should not
generally loop though, so we detect this after 4 cycles and
print a warning.
This was detected because of an issue in GtkWindow where it
seems to incorrectly handle the case of a user interactive resize.
It seems gtk_window_move_resize() believes that configure_request_size_changed
changed due to hitting some corner case so it calls
gtk_widget_queue_resize_no_redraw(), marking the window as need_alloc
after the layout phase. This commit fixes the issue, but we should
also look into if we can fix that.
We can't really just draw by walking down the widget hierarchy, as
this doesn't get the right clipping (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 expose event
although we still do it at the same base cairo_t that we get for the
toplevel native window.
We also collect all the windows of a widget so we can expose them inside
the same opacity group if needed.
Rather than scroll via XCopyArea (which we no longer do) we keep an
offscreen buffer of the scrolled area with some extra space outside
the visible area and when we expose the viewport we just blit the
offscreen to the right place.
This lets you register callbacks for when child widgets invalidate
areas of the window read it and/or change it.
For instance, this lets you do rendering effects and keeping offscreen
caches uptodate.
Now that all windows are non-opaque we can simplify the invalidation
a lot. There is no need to clip the invalidate area to child regions,
because we will always redraw everything under all the children.
We only have to handle native childen specially.
We now only do one expose event per native window, so there will
only be one begin/end_paint() call. This means all the work with
implicit paints to combine the paints on a single double buffer
surface is unnecessary, so we can just delete it.
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.
NOTE: This change neuters gtk_widget_set_double_buffered for
widgets without native windows
Since we dropped the move region optimization there is really no need
to try carefully keep track of opaque non-overlapped regions, as we
don't use this information to trigger the optimization anymore.
So, by assuming that all windows are non-opaque we can vastly simplify
the clip region stuff. First of all, we don't need clip_region_with_children,
as each window will need to draw under all children anyway. Secondly, we
don't remove overlapping sibling areas from clip_region, as these are
all non-opaque anyway and we need to draw under them
Finally, we don't need to track the layered region anymore as its
essentially unused. The few times something like it is needed we can
compute it explicitly.
For the case of native children of widgets we may cause a repaint
under native windows that are guaranteed to be opaque, but these
will be clipped by the native child anyway.
This basically neuters gdk_window_move_region, gdk_window_scroll
and gdk_window_move_resize, in that they now never copy any bits but
just invalidate the source and destination regions. This is a performance
loss, but the hope is that the simplifications it later allows will let
us recover this performance loss (which mainly affects scrolling).
Newer versions of GCC/binutils must have the source file come before the
preprocessor and linker flags on the compiler command line, and this is
also compatible with previous versions.
https://bugzilla.gnome.org/show_bug.cgi?id=680241
Pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=699016
The fix here is slightly different. We make
_gtk_builder_parser_translate return a const char * instead of
a dup'ed string, and fix up the callers.
These tests may have some assumptions on reasonable window manager
behaviour. For now, we just test that the default size of the
window ends up as the allocated size of the content. This test
currently fails with client-side decorations, because we are
not properly discriminating between overall window size and
content size.
There is currently no Wayland protocol for providing presentation
timestamps or hints about when drawing will be presented onscreen.
However, by assuming the straightforward algorithm used by the
DRM backend to Weston, we can reverse engineer the right values.
https://bugzilla.gnome.org/show_bug.cgi?id=698864
Combine duplicate code for creating and destroying surfaces.
To make the operation of the destroy() operation more obvious, the
destruction of the (fake) root window at display dispose time is
changed to not be a "foreign" destroy.
https://bugzilla.gnome.org/show_bug.cgi?id=698864
Use wl_surface_frame() to get notification when the compositor paints
a frame, and use this to throttle drawing to the compositor's refresh
cycle.
https://bugzilla.gnome.org/show_bug.cgi?id=698864
Lazily creating the cairo surface that backs a window when we
first paint to it means that the call to
gdk_wayland_window_attach_image() in
gdk_wayland_window_process_updates_recurse() wasn't working the
first time a window was painted.
https://bugzilla.gnome.org/show_bug.cgi?id=698864
When exposing an area, we were individually damaging and committing
each rectangle, *before* drawing. Surprisingly, this almost worked.
Order things right and only commit once.
https://bugzilla.gnome.org/show_bug.cgi?id=698864
Cache the style contexts for the up and down panels, instead of recreating
them each time they are drawn or size requested. GtkSpinButtons were
many times slower to draw than other widgets because of the constant
style matching.
https://bugzilla.gnome.org/show_bug.cgi?id=698682