The Quartz port now supports arbitrary multiple monitor layouts instead
of only monitors are were laid out horizontally. This builds on the
reworked coordinate translation done in a previous commit.
The root window contains all the monitors attached to a Mac. The
coordinate transformation now both translates the x and y coordinate,
translating it from the Cocoa monitor coordinate space to the GDK
coordinate space. How monitors are laid out in the root window differs
between Cocoa and GDK, which is why it is important to translate based
on the root window to get multi monitor setups to work properly.
We have replaced the old y coordinate transformation function with
new functions that translate both the x and y coordinate.
When creating new toplevels, we have to determine the Cocoa screen on
which the toplevel should appear and translate the coordinates according
to that screen.
This change also fixes event handling in case there is a monitor left
of the screen containing the menu bar. In such a case all coordinates
on the left monitor are negative. Event handling broke, because of
_gdk_quartz_window_find_child() checking bounds. Now that coordinates
are always properly translated to GDK coordinate space, in which negative
coordinates do never occur, the checks here will work properly.
Using this we can update our internal monitor/screen layout state
and emit the GdkScreen::size-changed signal. Work has not
completely finished on this yet, see bug 596238.
Add dummy for _gdk_input_window_crossing (). Set both input_window_destroy
and input_window_crossing pointers in the Impl struct.
Reported by John Ralls.
The root window width and height have already been correctly
initialised in _gdk_root_window_size_init() to cover all monitors, so
don't incorrectly re-initialise using GetSystemMetrics(SM_C[XY]SCREEN)
which only gives the size of the primary monitor anyway. (See MSDN.)
This fixes at least gdk_screen_get_{width,height}() which indirectly
affects at least the positioning of combo box pop-up menus on multiple
monitors.
We need to do a final XQueryWindow to get the coordinates inside the
windows rather than in the parent window.
This fixes bug #597386, "Cannot click buttons more than once...", which
failed due to the grab tracking stuff getting the wrong coordinates as
per the above.
Thanks gcc :
gdkwindow-x11.c:1731: warning: passing argument 3 of
'XReconfigureWMWindow' makes integer from pointer without a cast
/usr/include/X11/Xlib.h:1871: note: expected 'int' but argument is of
type 'struct GdkScreen *'
Signed-off-by: Pascal Terjan <pterjan@mandriva.com>
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.
This detection code is not 100% reliable, but it should fare much better
than the current code, which just compares the device name to a fixed
set of strings. Many applications depend on erasers being recognized
reliably, so we start by checking for a device name containing the
substring 'eraser'.
Signed-off-by: Thomas Jaeger <ThJaeger@gmail.com>
This has two advantages:
1) In many backends, this is faster as we can terminate the window
hierarchy traversal earlier
2) When used in gdkdisplay.c::get_current_toplevel() to get the
current toplevel that has the pointer we now correctly return
a toplevel with the pointer in it where the pointer is inside
some foreign subwindow of a toplevel window.
The second advantage fixes some bugs in client side event generation
when the pointer is inside such a foreign child window.
Based on first patches by Christian Hergert. Change
screen_get_monitor_geometry() so that it translates the layout of the screens
from Cocoa layout to GDK layout. In Cocoa, the screen locations
are specified in Cocoa geometry, as well as that GDK uses a different way
to place individual monitors in the root window. For now only monitors
that are laid out horizontally are supported (see the FIXMEs in the source),
in bug 596238 we will track future work to get things fully right.
Modify _gdk_quartz_window_get_inverted_screen_y() to take the differences
in screen layout between Cocoa and GDK into account. Also this function
is subject to future work.
Explicitly handle resizing by leaving all events in the lower right 15x15
corner to Cocoa, if the window shows a resizing indicator. Some
applications may have widgets allocated in this area. Generally, these
widgets are likely larger than 15x15 so they can still be hit. Often
scroll bars are found in this area and these can also be manipulated by
other means. Since this is the only way of resizing windows on Mac OS X,
it is too important to keep it broken.
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.
Make the quartz backend support the new queued translations. We do this
by keeping our own copy of the region that has been set to need display.
Using this region we can intersect by the given area, translate this and also
set needs display for the resulting area.
When filtering out the events for "window" from the events we got for
our "impl_window", don't forget to adjust the returned number of
events because it might be smaller than what XGetMotionEvents has
returned, and free coords we allocated too much. Also if we filtered
away *all* events, return FALSE and get rid of the allocated history
entirely. Together fixes all sorts of mishehavior when painting in
GIMP, from coords going wild to plain crashes and infinite loops.
On startup, the root window got assigned the size of the main screen.
But, the GdkScreen has the width of all screens/monitors connected to the
machine. Change this so that in _gdk_windowing_window_init, we assign
the width/height of all monitors to the root window width, height.
Should fix bug 594738.
The quartz backend simulates the semantics of XGrabPointer, as a part of
this it checks the event mask of the grab. However, implicit grabs on X
do not go through XGrabPointer and thus the quartz backend should not check
the event mask for these. This fixes various "the UI got stuck" cases.
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.