Apps that set no exposure mask rely on the system clearing things
to the window background, so we need to do this ourselves.
Also, don't do this on foreign windows, as they are not controlled
by us. In fact don't do exposes on foreign windows either.
This is required for the GtkSocket code, as it shows the plug child
even though the current cached state is (wrongly) that its already
mapped.
This makes blink work for non-local case in testsocket.
Native descendants of a virtual children are not automatically destroyed
with the parent as if it was a native window, so we need to handle
the native recursion tracking manually in _gdk_window_destroy_hierarchy()
It turns out that XCopyArea handling of obscured source regions is
buggy. It clears the destination area even outside the GC clip
region. We work around this for the pixmap->window case as that
can happen in gtk+ and is easy to work around.
X Bug report at:
http://lists.freedesktop.org/archives/xorg/2009-February/043318.html
Some apps really need to set custom event masks on native child windows,
for example emacs sets the event masks with gdk, but then reads out
the raw X events via a filter, so gdk event emulation doesn't work for that.
When we get motion or button events we map back from the event position and
window to the toplevel before doing anything, because a toplevel native window
could e.g. overlap a child window or whatever.
These are generated when we get an implicit grab on a native
child window, and we can't filter them with _has_grab() because
they are sent before the button press event where we detect
the implicit grab.
This makes clicks work in the flash plugin again
It turns out we really have to ignore grab/ungrab events or we'll
report double crossing events when we grab or ungrab.
However, we also can't ignore crossing events from grabs from other clients
as that leads to missed enter/leave events on e.g. alt-tab in metacity.
Fortunately we now track grabs very precisely, so we know with certainty
whether we have a grab at the time (serial) of the native crossing events,
and only if we do we ignore them.
If we get crossing events with subwindow unexpectedly being NULL
that means there is a native subwindow that gdk doesn't know about.
We track these and forward them, with the correct virtual window
events inbetween.
This is important to get right, as metacity uses gdk for the frame
windows, but gdk doesn't know about the client windows reparented
into the frame.
For instance if we grab the pointer and then check if its grabbed
so that we know to ungrab we don't care that the grab is not
yet active, so report the steady state (i.e. the last grab)
Having GDK_WINDOW_CHILD windows with root as the parent apparently works,
and metacity uses it. The current gdk_window_get_toplevel() returns the
root window for that, which is wrong, so we check that explicitly.
This causes all sorts of weirdness with pointer_over_window
being the rootwindow and then crashing gdk_window_get_toplevel() later.
With this metacity stops crashing madly.
To avoid drawing the window background of other windows in the area
where the window was we set the bg to none recursively. However, this
is quite costly it the moved window has many siblings. Furthermore, it
is uncommon that siblings overlap, so this cost has little gain.
So, we only set bg None on the parent, which means that there will
be some more flicker in the uncommon case of overlapping siblings.
These are sent when someone else grabs the pointer, and we don't
want to miss these expose events. For instance, we missed enter
and leave events on alt-tab.
There were some issues with these wrt out-of-sync grab information
in the client, but that should now be handled. So, it should work
or at least be fixable if we find some bug.
After a successful grab/ungrab we wait for an xserver
roundtrip until we change the tracked grab in GdkDisplay.
This way that data is always up-to-date wrt events comming in.
Get rid of invalidate_maybe_recurse and process_updates. Implement
_gdk_windowing_{before,after}_process_all_updates(), and keep track of
when we're inside process_all_updates in the common code so we know
when to flush windows. Implement
_gdk_windowing_window_process_updates_recurse by means of
setNeedsDisplayInRect: displayIfNeeded. Use the added window argument
in begin_paint_region to get the right window (the paintable is always
the impl window now).
Replace them with two new functions
_gdk_windowing_{before,after}_process_all_updates() that are called
around the guts of gdk_window_process_all_updates(). Add empty ones
for X11 (nothing more needed), quartz ones will be implemented next.
We use this in the added windowing function
_gdk_windowing_window_process_updates_recurse. The X11 implementation
just calls _gdk_window_process_updates_recurse directly, but at least
quartz will need to do some more work.
This fixes a problem where we used to set them on a native window, but we
never unset it becase when the pointer moved to another native window
we just set the cursor on that window. Always setting on the toplevel
fixes this.
This reverts commit 7cc15ec6ea1504133dfe6febbdb12615550bb966.
Its risky to convert all the events in a go like this, as it
increases the out-of-order issues. It also isn't a full solution
to the motion hint issue as it will only work for the events
we happen to convert. It would be better to use serials to
handle motion hinting.
This is the first stage in tracking keyboard grabs in the common code.
This lets us handle destroying or unmapping virtual window with a
keyboard grab.
If we only convert the first then motion hint emulation won't
work since we don't see the next motion even until we've
fully handled this one.
However, this changes a behaviour that has been like this since
the mists of time. I don't know if it could cause other issues.
I haven't seen any yet though.
There was a performance problem with the old flicker fixing
approach. For moved windows we copied the window data to the double
buffer pixmap and then back to the window with the rest of the
expose data. In some cases the copy from window data to pixmap was
very slow because the pixmap was allocated in system memory and
the window in video memory.
The new approach is to delay all window moves and then replay them
after the expose has drawn to the double buffer pixmap but before
drawing it to the window. Furthermore, we remove all exposed areas
from the destination of the delayed moves so we won't copy something
just to then immediately draw over it.
This makes scrolling in firefox fast, and it makes tests/flicker not
show any (detectable) flicker.
We return the raw window drawable, so its likely the app will do some
weird stuff to it, like draw using non-gdk operations. We don't want
the app to see any half-drawn state, so flush everything.
This fixes a scroll issue in firefox at least.
This fixes a mismatch in save/release gstate for the CGContext. If
this function is ever used for pixmaps, we need to add support for
that, probably will have to do so soon.
The one that puts windows outside the screen and moves them in when
showing. It might not be needed anymore and the workaround doesn't
work with the client-side window branch anyway because the window is
already mapped when we get showed for some reason.
If we do this there is a short window where we think there is a grab, and
if we generate a client side pointer motion event in this time (e.g. from
a window move) we could be delivering that according to the grab. But in
the Xserver that grab is infinitely short as it sends Press and then
Release immediately.
To see a problem from this, try using the scrollwheel to quickly scroll
in the testgtk list of buttons.
This is basically the same fix as was done for
gdk_window_move_resize_internal. We make sure not to move the native
child window contents twice and we don't copy data that was overwritten
by the moving of the native child windows.
Whenever a native window is moved this causes an immediate change in
the window (the window content is copied). This change conflicts can
conflict with outstanding moves or other cached changed, so we need
to flush all outstanding moves in the related windows.
To simplify the code for window move/resize the toplevel version was
split out to its own function.
Move native windows after recomputing so that we get the right new
shape before moving (and the implied copy). This means we're not
copying too much data.
Take into account the area of a moved window that contains native
subwindows, as these affect things in two ways:
First of all we shouldn't copy the original window location, as that
is copied by the native window move.
Secondly, we can't copy things that would end up copying from the
native window move destination, as the data that used to be there is
now destroyed by the native window move.
It can happen that another native window is re-shaped over the region to
be moved, this will not destroy the data (since we're unsetting the background
when we reshape), but it will mean we need to read from this window.
We already used INCLUDE_INFERIORS, but that only handle subwindows. We fix
this by doing the copy on the toplevel, offsetting the copy to compensate for
this.
All the calls that unset private->parent failed if that was
not a native window (impl), instead we need to find the impl window
for the parent. Add some helper functions for this and use them.
For move/resize of child windows, we really need to recursively unset
on the parent, because moving the window could expose other native
children of the parent.
In do_shape_combine_region, only unset background if we're changing
the bounding shape (i.e. not the input shape)
There is no need to do all these computations when moving toplevels
as that can't really change any visible regions. Nor will it cause
any exposes we need to handle.
move_region_on_impl() - doesn't need to copy anything if dx/dy == 0
Ensure that we queue an update when invalidating an empty area but we have outstanding moves
Temporarily unset background when moving native child windows