If we move, resize or otherwise change a window from inside a (double
buffered) expose handler we can run into issues with double buffered
paints that have already been ended but have not yet been commited
to the window from the implicit paint pixmap.
For instance, any copies of source regions due to a window scroll need
to take these into account, and any operation that causes some drawing at
a destination covered by the implicit paint region would be overdrawn
when the implicit paint is ended.
So, before we do any window-hierarchy changing operation while an implicit
paint is in effect we flush all moves and already commited paints.
When a window is moved or resized from a double-buffered expose handler
we can't really just copy the window region around, as the window
will be overdrawn with the double buffered region when the expose returns.
Instead we remove all regions with outstanding implicit paints from the
region to be copied and just mark this area as invalid to be redrawn
later.
This fixes bug 594880.
Its not correct for recurse gdk_window_process_updates_internal, as
the outer instance will overdraw the inner. So, protect against
gdk_window_process_updates() being called while in an expose
handler.
This shouldn't be a repaint problem, as eventually the idle handler
will cause the updates to be processed.
We used to handle zero height/width specially in the non-double buffered
case due to the weird behaviour of XClearArea in this case. However
this is undocumented, incompatible with what happens on double-buffered
drawing, and just not a good API. So, we drop this behaviour, having
fixed gtkclist.c which used this.
There are two issues here. First of all an ignored update didn't
use to unset update_idle which could cause all further idle repaints
to be ignored. (Bug #591583)
Secondly, if we ignore the process_all_updates we may end up not updating
the windows in update_windows unless something else triggers an update.
So, we handle this by checking for recursions and scheduling a new update
at the end of the outermost process_all_updates.
The check for a possible implicit paint flush before queueing an
antiexposure was wrong. An implicit flush doesn't actually NULL
the implicit paint, se we have add a flag to explicitly track if
it is flushed.
Passing region into _gdk_gc_set_clip_region_internal takes ownership,
so don't use it after that. We can just as well just move the usage
above the call.
For toplevels, never apply clip as shape, instead apply shape.
This way we don't have to re-set it all the time as the window size
changes. Furthermore, this change fixes unsetting a shape on a
toplevel window which didn't actually unset the shape before.
Additionally we never apply clips as shape if the shape would just
be the same as the regular window size. This means we won't unnecessarily
add a useless shape to most native child windows (and additionally this
helps apps that do weird X stuff that don't expect these shaped windows).
I.e. we use:
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
And then use impl_iface instead of the full macro when calling vfuncs.
Also, in some places we avoid getting the iface multiple times.
For instance, two clients selecting for button events can cause BadAccess.
This fixes bug 592624, where a gdk_window_reparent caused us to re-set
the event mask, breaking the workaround for the mozilla BadAccess bug.
When updating the clip region on cairo context (due to window changes or
paints of different sizes) we reset the old clip region, but this was
erronously done inside a cairo_save/cairo_restore pair, which made the
reset not take effect.
This fixes bug #592263.
Instead of doing some magic in gdk_draw_drawable() to avoid double
offsetting when calling gdk_draw_drawable on the impl we call
the vfunc directly on the impl. Thus removing the weird magic from
gdk_draw_drawable().
I tested this with the testgtk test "text", where if the original magic
code is disabled typing a newline in the middle of a text line causes
the double offset issue to appear.
Some applications make weird assumtions on Gtk+ that do not work anymore
with the new client-side windows support. For instance SWT/Eclipse reorders
the stacking order of the X windows directly without telling gdk this,
which breaks gdk drawing as gdk now relies on knowing the stacking order
for window clipping.
This introduces a GDK_NATIVE_WINDOWS environment variable, which if set
causes Gtk+ to always use native windows. Its more compatible with
pre-csw Gtk+ behaviour if you do weird X-specific hacks, although it does
limit the size of GdkWindows to 65535x65535.
gdk_window_get_geometry calls the native function for all non-native
windows. This returns coords relative to the native parent. We need
to convert this to be relative to the client side parent.
This fixes DnD coordinates in firefox (bug 588437).
If antiexposures are queued and then we do the outstanding moves
we will queue translations that will affect incomming exposes
wrongly wrt the antiexposure. So, make sure we process the outstanding
moves before doing the antiexposure.
Additionally this commit adds a bunch of comments about how the
expose handling works and fixes a small bug that made us always
flush outstanding moves a little to early than necessary.
Apps may change the window hierarchy while recursing over it by
destroying windows from the expose event handler. We need to copy
the children list and ref all the children while recursing.
This fixes some crashers in gedit (bug #589367, bug #591434)
The X11 queue_translation operation uses NextRequest to get the serial
of the XCopyArea operation where the translation should end. However,
if the gc passed to gdk_draw_drawable has a non-flushed clip region
(which it commonly has now for the window clipping) then the next
operation will be the GC flush, not the XCopyArea.
To handle this right we now pass in the GC to be used to
queue_translation and ensure that it is flushed before calling
NextRequest().
When we copy the region we need to also re-expose the areas of
the copied region that was not also in the destination.
And, we need to do this invalidation after the move, as the
move also moves any invalid area.
If there are outstanding moves in an area that intersects
the source of an outstanding move we need to move the invalid
area correspondingly, otherwise we will expose the wrong area
as the outstanding move copy will happen before we expose
the invalid area.
When moving an area we move any invalid region in this area to the
new place, but there really is no need to remove the old invalid
area as it would just be invalidated again (being newly exposed).
This extends the usage of the native clear region call such that its
called also for windows that have parent relative background all the
way up to a native window. That way we get true background relative
background clearing even to a foreign parent, which means that some
transparent notification icons look right again.
This moves the native show/hide calls to the generic code
for calculating viewable rather than in its own separate code
called from gdk_window_show/hide. This simplifies the code a bit,
but most significantly it means things are correctly shown when
they become viewable for other reasons than a show/hide call.
For instance, this fixes bug 590442 (gvim embedding) where the
toplevel GtkPlug is mapped by the embedder and we didn't previously
pick up that the native children became viewable and should be shown.
We used to invalidate the whole window when raised, but this is
unnecessary much, we now just invalidate the visible area minus the
previously visible area.
This also fixes a problem where expose calling raise caused a loop (#588438)
This never worked before csw since the root window is never
set as IS_MAPPED, but with the new viewable check (which is
true for the root window) we could erronously queue exposes
on the root window.
This happened unexpectedly in bug 589369, where metacity
got a GraphicsExpose event on the root window due to some
graphics operation, queueing an expose which would be handled
by clearing that area. That is fixed with this commit.
We get the real pixmap size and use as cairo surface size rather
than doing some magic to try to get clipping on the right hand size
(and the magic looks wrong anyway).
The previous code could result in the width/height being to big for
the cairo 28.4 fix point size and thus not drawing anything.
This fixes bug #588076.
gdk_window_input_shape_combine_mask() can accept NULL for the mask
parameter, but it wasn't checking for NULL before passing the
resulting GdkRegion to gdk_region_destroy(). Fixes#589275
When the region is empty we can return early, because there
is no more area to remove. This happens often for children
of scrolled windows (i.e. things that are clipped out.
The scrolling and region moving code needs to avoid drawing when the
window is mapped, which it did. However, it also needs to avoid
drawing when any of its parents are not mapped, which it didn't so
switch to using gdk_window_is_viewable().
This fixes the index rendering in evolution (#588169)
If we get a nonlinear enter/leave notify on the toplevel we need
to set nonlinear in all the events we send, even if the in-toplevel
tree is linear.
This fixes combobox menus popping down immediately when you click
(not hold). (bug #587559)
We really need to wait for the MapNotify from the xserver to ensure
that the window has been mapped, as it may be delayed by the WM, network
or similar things.
This fixes a problem in the /ui-tests/keys-events gtk test
Turns out pygtk build broke due to the argument addition to draw_drawable.
So, we now add a new vfunc for the new draw_drawable and are thus
backwards compat.
we now use gdk_offscreen_window_set_embedder() instead of a signal
to get the parent. This also replaces set_has_offscreen_changes.
Rename "parent" in all embedding related names to "embedder" to make it
more obviously different than the normal parent.
Rename gdk_window_get_offscreen_pixmap to gdk_offscreen_window_get_pixmap
to match the other offscreen calls.
Rename gdk_window_offscreen_children_changed to gdk_window_geometry_changed
as this is more descriptive.
We emulate visibility by unmapping (in X) all mapped (according to
gdk) windows that are not visible (all parents mapped). This is because
there may be client side windows inbetween the native windows in the
hierarchy, so you can't know a native window is visible just because
all the parent native windows are mapped.
However, we don't want to unmap foreign windows, as that may cause all
sort of unexpected issues. This should be safe, because generally the
parent of a foreign window is a native window (e.g. a socket), so its
gdk visibility state is the same as the Xserver one.
This fixes an issue with the GDM notification area where the unmap of
the plug caused spurious UnmapNotify events that confused GtkSocket and
caused icons to become one pixel wide.
Last commit was bad, as it didn't clip against client side
children. This implements such clipping first and then
only clears the rectangles that need to be cleared.
This is how cairo works with native children.
This fixes an issue where the drag target outline is visible on the
evolution folder treeview when it isn't with native windows.
Without this we can't draw to them, which caused problems for e.g.
gnome-settings-daemon clearing the background when the desktop
background changed.
Note: We don't actually clip away child windows from the root window,
the clip is just based on the size of the root window.