mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Break out code that was repeated into separate functions and call them
2007-05-28 Richard Hult <richard@imendio.com> * gdk/quartz/gdkevents-quartz.c (get_child_coordinates_from_ancestor) (get_ancestor_coordinates_from_child): Break out code that was repeated into separate functions and call them instead. (find_window_for_mouse_nsevent): Break out this from find_window_for_nsevent to make the code clearer. (find_window_for_nsevent): Use the above and fix the returned coordinates in the process so that they are always relative the found window, both for the normal case and during grabs. Still needs fixing for the case where we get nsevents for a window other than than grab window during grabs. svn path=/trunk/; revision=17971
This commit is contained in:
parent
d36c24a8b9
commit
f2f1be4e4f
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
2007-05-28 Richard Hult <richard@imendio.com>
|
||||
|
||||
* gdk/quartz/gdkevents-quartz.c (get_child_coordinates_from_ancestor)
|
||||
(get_ancestor_coordinates_from_child): Break out code that was
|
||||
repeated into separate functions and call them instead.
|
||||
(find_window_for_mouse_nsevent): Break out this from
|
||||
find_window_for_nsevent to make the code clearer.
|
||||
(find_window_for_nsevent): Use the above and fix the returned
|
||||
coordinates in the process so that they are always relative the
|
||||
found window, both for the normal case and during grabs. Still
|
||||
needs fixing for the case where we get nsevents for a window other
|
||||
than than grab window during grabs.
|
||||
|
||||
2007-05-28 Richard Hult <richard@imendio.com>
|
||||
|
||||
* gdk/quartz/gdkevents-quartz.c (gdk_event_translate): Fix typo,
|
||||
|
@ -785,33 +785,136 @@ _gdk_quartz_events_update_cursor (GdkWindow *window)
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
/* This function finds the correct window to send an event to,
|
||||
* taking into account grabs (FIXME: not done yet), event propagation,
|
||||
* and event masks.
|
||||
/* Translates coordinates from an ancestor window + coords, to
|
||||
* coordinates that are relative the child window.
|
||||
*/
|
||||
static void
|
||||
get_child_coordinates_from_ancestor (GdkWindow *ancestor_window,
|
||||
gint ancestor_x,
|
||||
gint ancestor_y,
|
||||
GdkWindow *child_window,
|
||||
gint *child_x,
|
||||
gint *child_y)
|
||||
{
|
||||
GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
|
||||
GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
|
||||
|
||||
while (child_private != ancestor_private)
|
||||
{
|
||||
ancestor_x -= child_private->x;
|
||||
ancestor_y -= child_private->y;
|
||||
|
||||
child_private = child_private->parent;
|
||||
}
|
||||
|
||||
*child_x = ancestor_x;
|
||||
*child_y = ancestor_y;
|
||||
}
|
||||
|
||||
/* Translates coordinates from a child window + coords, to
|
||||
* coordinates that are relative the ancestor window.
|
||||
*/
|
||||
static void
|
||||
get_ancestor_coordinates_from_child (GdkWindow *child_window,
|
||||
gint child_x,
|
||||
gint child_y,
|
||||
GdkWindow *ancestor_window,
|
||||
gint *ancestor_x,
|
||||
gint *ancestor_y)
|
||||
{
|
||||
GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
|
||||
GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
|
||||
|
||||
while (child_private != ancestor_private)
|
||||
{
|
||||
child_x += child_private->x;
|
||||
child_y += child_private->y;
|
||||
|
||||
child_private = child_private->parent;
|
||||
}
|
||||
|
||||
*ancestor_x = child_x;
|
||||
*ancestor_y = child_y;
|
||||
}
|
||||
|
||||
/* Given a mouse NSEvent, returns the window in which the pointer
|
||||
* position from the event is. The returned coordinates are relative
|
||||
* to the found window, and normal GDK coordinates, not Quartz.
|
||||
*/
|
||||
static GdkWindow *
|
||||
find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
|
||||
find_window_for_mouse_nsevent (NSEvent *nsevent,
|
||||
gint *x_ret,
|
||||
gint *y_ret)
|
||||
{
|
||||
NSWindow *nswindow;
|
||||
GdkWindow *toplevel;
|
||||
NSPoint point;
|
||||
gint x_tmp, y_tmp;
|
||||
GdkWindow *found_window;
|
||||
|
||||
nswindow = [nsevent window];
|
||||
toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
|
||||
|
||||
point = [nsevent locationInWindow];
|
||||
|
||||
x_tmp = point.x;
|
||||
|
||||
/* Flip the y coordinate. */
|
||||
if (toplevel == _gdk_root)
|
||||
y_tmp = _gdk_quartz_window_get_inverted_screen_y (point.y);
|
||||
else
|
||||
{
|
||||
GdkWindowImplQuartz *impl;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
|
||||
y_tmp = impl->height - point.y;
|
||||
}
|
||||
|
||||
found_window = _gdk_quartz_window_find_child (toplevel, x_tmp, y_tmp);
|
||||
|
||||
/* Translate the coordinates so they are relative to the found
|
||||
* window.
|
||||
*/
|
||||
if (found_window)
|
||||
get_child_coordinates_from_ancestor (toplevel,
|
||||
x_tmp, y_tmp,
|
||||
found_window,
|
||||
&x_tmp, &y_tmp);
|
||||
|
||||
*x_ret = x_tmp;
|
||||
*y_ret = y_tmp;
|
||||
|
||||
return found_window;
|
||||
}
|
||||
|
||||
/* This function finds the correct window to send an event to, taking
|
||||
* into account grabs, event propagation, and event masks.
|
||||
*/
|
||||
static GdkWindow *
|
||||
find_window_for_nsevent (NSEvent *nsevent, gint *x, gint *y)
|
||||
{
|
||||
NSWindow *nswindow = [nsevent window];
|
||||
NSEventType event_type = [nsevent type];
|
||||
|
||||
if (!nswindow)
|
||||
return NULL;
|
||||
|
||||
/* Window where not created by GDK so the event should be handled by Quartz */
|
||||
|
||||
/* Window was not created by GDK so the event should be handled by Quartz. */
|
||||
if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
|
||||
return NULL;
|
||||
|
||||
|
||||
/* Synthesize crossing events when moving between child
|
||||
* windows. Toplevels are handled with NSMouseEntered and
|
||||
* NSMouseExited in the switch below.
|
||||
*/
|
||||
if (event_type == NSMouseMoved ||
|
||||
event_type == NSLeftMouseDragged ||
|
||||
event_type == NSRightMouseDragged ||
|
||||
event_type == NSOtherMouseDragged)
|
||||
{
|
||||
GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
|
||||
NSPoint point = [nsevent locationInWindow];
|
||||
GdkWindow *mouse_window;
|
||||
|
||||
mouse_window = _gdk_quartz_window_find_child_by_point (toplevel, point.x, point.y, x, y);
|
||||
mouse_window = find_window_for_mouse_nsevent (nsevent, x, y);
|
||||
|
||||
if (!mouse_window)
|
||||
mouse_window = _gdk_root;
|
||||
@ -826,7 +929,6 @@ find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
|
||||
if (current_mouse_window != mouse_window)
|
||||
{
|
||||
synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
|
||||
|
||||
_gdk_quartz_events_update_cursor (mouse_window);
|
||||
}
|
||||
}
|
||||
@ -846,73 +948,92 @@ find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
{
|
||||
GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
|
||||
NSPoint point = [nsevent locationInWindow];
|
||||
GdkWindow *mouse_window;
|
||||
GdkEventMask event_mask;
|
||||
GdkWindow *real_window;
|
||||
|
||||
if (_gdk_quartz_pointer_grab_window && !pointer_grab_owner_events)
|
||||
/* From the docs for XGrabPointer:
|
||||
*
|
||||
* If owner_events is True and if a generated pointer event
|
||||
* would normally be reported to this client, it is reported
|
||||
* as usual. Otherwise, the event is reported with respect to
|
||||
* the grab_window and is reported only if selected by
|
||||
* event_mask. For either value of owner_events, unreported
|
||||
* events are discarded.
|
||||
*
|
||||
* This means we first try the owner, then the grab window,
|
||||
* then give up.
|
||||
*/
|
||||
if (_gdk_quartz_pointer_grab_window)
|
||||
{
|
||||
if (pointer_grab_owner_events)
|
||||
{
|
||||
mouse_window = find_window_for_mouse_nsevent (nsevent, x, y);
|
||||
event_mask = get_event_mask_from_ns_event (nsevent);
|
||||
real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
|
||||
|
||||
if (mouse_window && real_window && mouse_window != real_window)
|
||||
get_ancestor_coordinates_from_child (mouse_window,
|
||||
*x, *y,
|
||||
real_window,
|
||||
x, y);
|
||||
|
||||
if (real_window)
|
||||
return real_window;
|
||||
}
|
||||
|
||||
/* FIXME: This part needs some fixing, it doesn't return
|
||||
* the right coordinates if the nsevent happens for a
|
||||
* different window than the grab window.
|
||||
*/
|
||||
if (pointer_grab_event_mask & get_event_mask_from_ns_event (nsevent))
|
||||
{
|
||||
int tempx, tempy;
|
||||
GdkWindowObject *w;
|
||||
GdkWindowObject *grab_toplevel;
|
||||
GdkWindow *grab_toplevel;
|
||||
NSPoint point;
|
||||
int x_tmp, y_tmp;
|
||||
|
||||
w = GDK_WINDOW_OBJECT (_gdk_quartz_pointer_grab_window);
|
||||
grab_toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window));
|
||||
grab_toplevel = gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window);
|
||||
point = [nsevent locationInWindow];
|
||||
|
||||
tempx = point.x;
|
||||
tempy = GDK_WINDOW_IMPL_QUARTZ (grab_toplevel->impl)->height -
|
||||
point.y;
|
||||
x_tmp = point.x;
|
||||
y_tmp = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (grab_toplevel)->impl)->height - point.y;
|
||||
|
||||
while (w != grab_toplevel)
|
||||
{
|
||||
tempx -= w->x;
|
||||
tempy -= w->y;
|
||||
|
||||
w = w->parent;
|
||||
}
|
||||
|
||||
*x = tempx;
|
||||
*y = tempy;
|
||||
get_child_coordinates_from_ancestor (grab_toplevel,
|
||||
x_tmp, y_tmp,
|
||||
_gdk_quartz_pointer_grab_window,
|
||||
x, y);
|
||||
|
||||
return _gdk_quartz_pointer_grab_window;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nswindow)
|
||||
{
|
||||
mouse_window = _gdk_root;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
mouse_window = _gdk_quartz_window_find_child_by_point (toplevel, point.x, point.y, x, y);
|
||||
}
|
||||
/* The non-grabbed case. */
|
||||
mouse_window = find_window_for_mouse_nsevent (nsevent, x, y);
|
||||
event_mask = get_event_mask_from_ns_event (nsevent);
|
||||
real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
|
||||
|
||||
/* We have to translate the coordinates if the actual
|
||||
* window is different from the mouse window.
|
||||
*/
|
||||
if (mouse_window && real_window && mouse_window != real_window)
|
||||
get_ancestor_coordinates_from_child (mouse_window,
|
||||
*x, *y,
|
||||
real_window,
|
||||
x, y);
|
||||
|
||||
event_mask = get_event_mask_from_ns_event (nsevent);
|
||||
real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
|
||||
|
||||
return real_window;
|
||||
return real_window;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSMouseEntered:
|
||||
{
|
||||
NSPoint point;
|
||||
GdkWindow *toplevel;
|
||||
GdkWindow *mouse_window;
|
||||
|
||||
point = [nsevent locationInWindow];
|
||||
toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
|
||||
|
||||
mouse_window = _gdk_quartz_window_find_child_by_point (toplevel, point.x, point.y, x, y);
|
||||
|
||||
mouse_window = find_window_for_mouse_nsevent (nsevent, x, y);
|
||||
synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
|
||||
}
|
||||
break;
|
||||
@ -1179,7 +1300,7 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
}
|
||||
}
|
||||
|
||||
window = find_window_for_event (nsevent, &x, &y);
|
||||
window = find_window_for_nsevent (nsevent, &x, &y);
|
||||
|
||||
/* FIXME: During owner_event grabs, we don't find a window when there is a
|
||||
* click on a no-window widget, which makes popups etc still stay up. Need
|
||||
|
Loading…
Reference in New Issue
Block a user