The window move code needs special attention for multiple reasons:
- invalid areas for expose events need to be modified
- self-copy is not supported by Cairo
- in X11, copying from an overlapped Window might cause unexposed areas
to be copied in, spo expose events for those need to be generated.
This was all special cased in various parts of the code. By making it an
explicit vfunc, we can work around it.
Includes fixing all callers to use the cairo region API instead. This is
usually just replacing the function names, the only difference is
gdk_region_get_rectangles() being replaced by
cairo_region_num_rectangles() and cairo_region_get_rectangle() which
required a bit more work.
https://bugzilla.gnome.org/show_bug.cgi?id=613284
which also works for offscreen windows and their embedder.
Also add gdk_window_get_effective_parent() and
gdk_window_get_effective_toplevel() which are offscreen aware.
This commit was created using a script that searched for all docstrings
containing a parameter and the string 'or %NULL'.
Gdk backends and demos excluded as they are not part of a public API
https://bugzilla.gnome.org/show_bug.cgi?id=610474
We need to do this because otherwise the implicit button grab for this
(native) window will not deliver the button events not selected for
by this window. This is a problem because non-native child windows may
select using a wider event mask, and we can't emulate these events if we
don't get the native events.
Fixes bug #607508
When a cairo surface is requested for direct window access (i.e. not
when double-buffering) we can't really track when the actual drawing happens
as cairo drawing is not virtualized. This means we can't properly flush
any outstanding window moves or implicit paints.
This actually causes problems with e.g. abiword (bug #606009) where they
draw without double-buffering. If you press down it scrolls the window
and then draws the caret, but the caret drawing does not flush the
outstanding move from the scroll, so the caret gets drawn on the wrong
screen.
We fix this by never allowing either implicit paints or outstanding window
moves on impl-windows where any windows related to it has an outstanding
direct cairo surface. Luckily this is not very common so in practice this
doesn't matter much.
It may happen that a window gets destroyed during painting, if so
we should not draw the implicit paint double-buffered pixmap to it
as that will cause a BadDrawable X error.
This fixes bug 600865
The Gdk-custom.c file in gir-repository contained a number of
introspection annotations. Merge those into the GDK source files.
Some documentation was moved from the tmpl/ files to accomodate
the addition of annotations.
https://bugzilla.gnome.org/show_bug.cgi?id=592279
They don't need double buffer combination since they have no
client-side children, and creating pixmaps for them is risky
since they could disappear at any time.
May fix bug 598476 and 603652.
It may happen when turning a client side window into a native window
that the window, or some of its children with the same native parent
have extension events enabled, and thus have an input window enabled
for the native parent which needs to change as the window is made
native.
We fix this by temporarily disabling extension events on all the affected
windows while we create the native window, and then reenable them afterwards.
This fixes: https://bugzilla.redhat.com/show_bug.cgi?id=544624
We don't really need to filter these out, it was just a leftover
safety check to not override the GDK_POINTER_MOTION_MASK.
Furthermore when we changed behaviour to not always select for native
pointer motion it is actually wrong. We'll still get normal motion
events for the toplevel which we will emulate as button motion on the
child, but the button motion mask will not be inherited by implicit
grabs which makes us not get any motion events during grabs.
This fixes bug 601473
When we just invalidate some area from the app we don't need to clear
windows with no exposure mask, because that wouldn't have happened pre-csw
anyway. Additionally we can avoid such clearing for native windows in cases
where the xserver already did the clearing like on exposes or when resizing
toplevels.
This means we don't fully redraw a GtkSocket when it resizes, thus
avoiding flicker in gnome-mplayer as reported in this bug:
https://bugzilla.gnome.org/show_bug.cgi?id=598050
When moving or scrolling a window with native children, there is no
need to expose the areas that are copied by the windowing system
as part of moving/resizing the native windows anyway.
These event types propagate up the hierarchy anyway, so this means
we avoid setting it unnecessarily. This is especially important
for button press event, since only one client can select for this
on each window, causing X errors if two clients do it.
When we grab the pointer we need to request more events than what is
specified, otherwise our event emulation stop working and you won't
e.g. get crossing event unless you specified motion event mask.
F-Spot needs this as it draws on a foreign (screensaver) window, which
used to work.
I believe this is safe, because in all typical cases the expose
mask will not be set, so we won't do anything, and its what we used to
do.
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.
In the destroyed window case in do_synthesize_crossing_event we didn't
return a value which can cause infinite "loops". Always return FALSE
to make sure the idle doesn't run again.
Doing this directly had some issues with picking going recursive in
clutter-gtk. Furthermore, doing it in an idle means we can coalesce
multiple calls (which is common due to widget changes) in the same
toplevel to just one call.
You can call this if you have offscreen children and the geometry of
them changed. This will cause re-picking of the active window sending
enter and leave events as needed.
We want to be able to map any window coordinate to a root coordinate, not
just the origin, because you can't rely anymore on a simple translation
from window coordinates to parent with offscreen windows. This lets
us e.g. pop up menus in the right place even if they are popped up from
a no-window widget.
We use the offscreen signals for getting parent, picking
children at a point and mapping coordinates between windows
embedding offscreens and offscreens.
This means we have two hierarchies more or less, one visible to apps via
the standard APIs and for drawing where the offscreens are their own
separate toplevels, and another one for event handling where embedded
offscreens appear as if they were children of the embedding window.
3 signals are for offscreen windows
get-offscreen-parent: Get the parent window an offscreen is embedded in
to-parent: Convert coordinates from offscreen to parent
from-parent: Convert coordinates from parent to offscreen
1 signal is for the window embedding offscreens:
pick-offscreen-child: This picks what (if any) offscreen is at a specific position
The last signal is only used if you call gdk_window_set_has_offscreen_children
to tell gdk that the window has embedded offscreen children.
Add get-pointer signal for offscreen window pointer getting
Apps using offscreen windows can connect to get-pointer on offscreen
windows in order to make gdk_window_get_pointer() return correct
values.
Add get-offscreen-parent signal
Add signals for from-parent and to-parent coordinate mapping
Add pick-offscreen-child signal
We returned the innermost child that has the pointer, which is not right.
Only the direct child that has the pointer in it should be reported (if any).
This also removes the (unimplemented) possibility to change a window to
non-native. This seems generally not very useful, and there are some problems
with it, for instance if two "users" need a window to be native and then
one of the "users" doesn't need it anymore it can't change it back, because
it is unaware of the other reason the window is native.
If a native window or a window with a native subwindow is moved or resized
then the client window moves and implicit paints need to be flushed since
the native window move will copy/overwrite data. This may happen while there
is an outstanding paint if the move is inside an expose event (weird, but
flash embedded in webkit hit this).
Right now we're asserting here, but the right fix is to allow this but
to not flush the parts that are currently in a (non-implicit) paint. This
means we flush all results from previous not-yet-flushed exposes, but not
the ones being drawn.
In the new world offscreen windows are not put in the hierarchy, but are
rather toplevels for themselves. Offscreen hooks don't make any sense
in this model.
It often happens that we move region A to B and then we move a subset
of B to C. When possible we'd like to replace this with a move from
A directly to C, and a suplimentary move from A to the areas of B not
overwritten by C.
Getting an optimal move combiner seems quite complicated, but this
simple approach gets most of the interesting cases right and isn't
all to complicated.