mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-11 03:10:09 +00:00
Rework the event translation to look more like X11
Put the event in the queue with a pending flag, remove again if not handled.
This commit is contained in:
parent
036e045d53
commit
4c01ca7ddd
@ -317,50 +317,27 @@ append_event (GdkEvent *event)
|
||||
_gdk_event_queue_append (_gdk_display, event);
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
apply_filters (GdkWindow *window,
|
||||
NSEvent *nsevent,
|
||||
GList *filters)
|
||||
static gint
|
||||
gdk_event_apply_filters (NSEvent *nsevent,
|
||||
GdkEvent *event,
|
||||
GList *filters)
|
||||
{
|
||||
GdkFilterReturn result = GDK_FILTER_CONTINUE;
|
||||
GdkEvent *event;
|
||||
GList *node;
|
||||
GList *tmp_list;
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
if (window != NULL)
|
||||
event->any.window = g_object_ref (window);
|
||||
((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
|
||||
|
||||
/* I think GdkFilterFunc semantics require the passed-in event
|
||||
* to already be in the queue. The filter func can generate
|
||||
* more events and append them after it if it likes.
|
||||
*/
|
||||
node = _gdk_event_queue_append (_gdk_display, event);
|
||||
GdkFilterReturn result;
|
||||
|
||||
tmp_list = filters;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
|
||||
GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
result = filter->function (nsevent, event, filter->data);
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
break;
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
|
||||
{
|
||||
_gdk_event_queue_remove_link (_gdk_display, node);
|
||||
g_list_free_1 (node);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
else /* GDK_FILTER_TRANSLATE */
|
||||
{
|
||||
((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
|
||||
fixup_event (event);
|
||||
}
|
||||
return result;
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
/* Checks if the passed in window is interested in the event mask, and
|
||||
@ -1412,13 +1389,13 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
create_button_event (GdkWindow *window,
|
||||
NSEvent *nsevent,
|
||||
gint x,
|
||||
gint y)
|
||||
static void
|
||||
fill_button_event (GdkWindow *window,
|
||||
GdkEvent *event,
|
||||
NSEvent *nsevent,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkEventType type;
|
||||
gint state;
|
||||
gint button;
|
||||
@ -1444,7 +1421,7 @@ create_button_event (GdkWindow *window,
|
||||
|
||||
button = get_mouse_button_from_ns_event (nsevent);
|
||||
|
||||
event = gdk_event_new (type);
|
||||
event->any.type = type;
|
||||
event->button.window = window;
|
||||
event->button.time = get_time_from_ns_event (nsevent);
|
||||
event->button.x = x;
|
||||
@ -1456,17 +1433,15 @@ create_button_event (GdkWindow *window,
|
||||
convert_window_coordinates_to_root (window, x, y,
|
||||
&event->button.x_root,
|
||||
&event->button.y_root);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
create_motion_event (GdkWindow *window,
|
||||
NSEvent *nsevent,
|
||||
gint x,
|
||||
gint y)
|
||||
static void
|
||||
fill_motion_event (GdkWindow *window,
|
||||
GdkEvent *event,
|
||||
NSEvent *nsevent,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkEventType type;
|
||||
GdkModifierType state = 0;
|
||||
|
||||
@ -1486,7 +1461,7 @@ create_motion_event (GdkWindow *window,
|
||||
|
||||
state |= get_keyboard_modifiers_from_ns_event (nsevent);
|
||||
|
||||
event = gdk_event_new (type);
|
||||
event->any.type = type;
|
||||
event->motion.window = window;
|
||||
event->motion.time = get_time_from_ns_event (nsevent);
|
||||
event->motion.x = x;
|
||||
@ -1497,19 +1472,17 @@ create_motion_event (GdkWindow *window,
|
||||
event->motion.device = _gdk_display->core_pointer;
|
||||
convert_window_coordinates_to_root (window, x, y,
|
||||
&event->motion.x_root, &event->motion.y_root);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
create_scroll_event (GdkWindow *window,
|
||||
NSEvent *nsevent,
|
||||
GdkScrollDirection direction)
|
||||
static void
|
||||
fill_scroll_event (GdkWindow *window,
|
||||
GdkEvent *event,
|
||||
NSEvent *nsevent,
|
||||
GdkScrollDirection direction)
|
||||
{
|
||||
GdkEvent *event;
|
||||
NSPoint point;
|
||||
|
||||
event = gdk_event_new (GDK_SCROLL);
|
||||
event->any.type = GDK_SCROLL;
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = get_time_from_ns_event (nsevent);
|
||||
|
||||
@ -1523,21 +1496,19 @@ create_scroll_event (GdkWindow *window,
|
||||
|
||||
event->scroll.direction = direction;
|
||||
event->scroll.device = _gdk_display->core_pointer;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
create_key_event (GdkWindow *window,
|
||||
NSEvent *nsevent,
|
||||
GdkEventType type)
|
||||
static void
|
||||
fill_key_event (GdkWindow *window,
|
||||
GdkEvent *event,
|
||||
NSEvent *nsevent,
|
||||
GdkEventType type)
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkEventPrivate *priv;
|
||||
gchar buf[7];
|
||||
gunichar c = 0;
|
||||
|
||||
event = gdk_event_new (type);
|
||||
event->any.type = type;
|
||||
|
||||
priv = (GdkEventPrivate *) event;
|
||||
priv->windowing_data = [nsevent retain];
|
||||
@ -1644,7 +1615,6 @@ create_key_event (GdkWindow *window,
|
||||
event->key.window,
|
||||
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
|
||||
event->key.keyval));
|
||||
return event;
|
||||
}
|
||||
|
||||
GdkEventMask
|
||||
@ -1654,13 +1624,13 @@ _gdk_quartz_events_get_current_event_mask (void)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_translate (NSEvent *nsevent)
|
||||
gdk_event_translate (GdkEvent *event,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
NSWindow *nswindow;
|
||||
GdkWindow *window;
|
||||
GdkFilterReturn result;
|
||||
GdkEvent *event;
|
||||
int x, y;
|
||||
gboolean return_val;
|
||||
|
||||
/* There is no support for real desktop wide grabs, so we break
|
||||
* grabs when the application loses focus (gets deactivated).
|
||||
@ -1705,17 +1675,17 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
|
||||
nswindow = [nsevent window];
|
||||
|
||||
/* Apply any global filters. */
|
||||
if (_gdk_default_filters)
|
||||
{
|
||||
result = apply_filters (NULL, nsevent, _gdk_default_filters);
|
||||
/* Apply global filters */
|
||||
GdkFilterReturn result;
|
||||
|
||||
/* If result is GDK_FILTER_CONTINUE, we continue as if nothing
|
||||
* happened. If it is GDK_FILTER_REMOVE,
|
||||
* we return TRUE and won't send the message to Quartz.
|
||||
*/
|
||||
if (result == GDK_FILTER_REMOVE)
|
||||
return TRUE;
|
||||
result = gdk_event_apply_filters (nsevent, event, _gdk_default_filters);
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
{
|
||||
return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore events for no window or ones not created by GDK. */
|
||||
@ -1745,9 +1715,26 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
return FALSE;
|
||||
|
||||
/* Apply any window filters. */
|
||||
result = apply_filters (window, nsevent, ((GdkWindowObject *) window)->filters);
|
||||
if (result == GDK_FILTER_REMOVE)
|
||||
return TRUE;
|
||||
if (GDK_IS_WINDOW (window))
|
||||
{
|
||||
GdkWindowObject *filter_private = (GdkWindowObject *) window;
|
||||
GdkFilterReturn result;
|
||||
|
||||
if (filter_private->filters)
|
||||
{
|
||||
g_object_ref (window);
|
||||
|
||||
result = gdk_event_apply_filters (nsevent, event, filter_private->filters);
|
||||
|
||||
g_object_unref (window);
|
||||
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
{
|
||||
return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We need the appliction to be activated on clicks so that popups
|
||||
* like context menus get events routed properly. This is handled
|
||||
@ -1762,6 +1749,8 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
|
||||
current_event_mask = get_event_mask_from_ns_event (nsevent);
|
||||
|
||||
return_val = TRUE;
|
||||
|
||||
switch ([nsevent type])
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
@ -1783,17 +1772,13 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
}
|
||||
}
|
||||
|
||||
event = create_button_event (window, nsevent, x, y);
|
||||
append_event (event);
|
||||
|
||||
_gdk_event_button_generate (_gdk_display, event);
|
||||
fill_button_event (window, event, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSLeftMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
event = create_button_event (window, nsevent, x, y);
|
||||
append_event (event);
|
||||
fill_button_event (window, event, nsevent, x, y);
|
||||
|
||||
/* Ungrab implicit grab */
|
||||
if (_gdk_quartz_pointer_grab_window && pointer_grab_implicit)
|
||||
@ -1804,8 +1789,7 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
case NSMouseMoved:
|
||||
event = create_motion_event (window, nsevent, x, y);
|
||||
append_event (event);
|
||||
fill_motion_event (window, event, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSScrollWheel:
|
||||
@ -1827,15 +1811,7 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
while (dy > 0.0)
|
||||
{
|
||||
event = create_scroll_event (window, nsevent, direction);
|
||||
append_event (event);
|
||||
dy--;
|
||||
|
||||
/* Ignore the delta for now, things get too slow when the events queue up. */
|
||||
break;
|
||||
}
|
||||
fill_scroll_event (window, event, nsevent, direction);
|
||||
|
||||
/* Now do x events */
|
||||
if (dx < 0.0)
|
||||
@ -1846,16 +1822,7 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
else
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
|
||||
while (dx > 0.0)
|
||||
{
|
||||
event = create_scroll_event (window, nsevent, direction);
|
||||
append_event (event);
|
||||
dx--;
|
||||
|
||||
/* Ignore the delta for now, things get too slow when the events queue up. */
|
||||
break;
|
||||
}
|
||||
|
||||
fill_scroll_event (window, event, nsevent, direction);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1867,11 +1834,9 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
|
||||
type = _gdk_quartz_keys_event_type (nsevent);
|
||||
if (type == GDK_NOTHING)
|
||||
return FALSE;
|
||||
|
||||
event = create_key_event (window, nsevent, type);
|
||||
append_event (event);
|
||||
return TRUE;
|
||||
return_val = FALSE;
|
||||
else
|
||||
fill_key_event (window, event, nsevent, type);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1880,25 +1845,63 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
done:
|
||||
if (return_val)
|
||||
{
|
||||
if (event->any.window)
|
||||
g_object_ref (event->any.window);
|
||||
if (((event->any.type == GDK_ENTER_NOTIFY) ||
|
||||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
|
||||
(event->crossing.subwindow != NULL))
|
||||
g_object_ref (event->crossing.subwindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mark this event as having no resources to be freed */
|
||||
event->any.window = NULL;
|
||||
event->any.type = GDK_NOTHING;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_events_queue (GdkDisplay *display)
|
||||
{
|
||||
NSEvent *event;
|
||||
NSEvent *nsevent;
|
||||
|
||||
event = _gdk_quartz_event_loop_get_pending ();
|
||||
if (event)
|
||||
nsevent = _gdk_quartz_event_loop_get_pending ();
|
||||
if (nsevent)
|
||||
{
|
||||
if (!gdk_event_translate (event))
|
||||
GdkEvent *event;
|
||||
GList *node;
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
|
||||
event->any.window = NULL;
|
||||
event->any.send_event = FALSE;
|
||||
|
||||
((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
|
||||
if (gdk_event_translate (event, nsevent))
|
||||
{
|
||||
((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
|
||||
_gdk_windowing_got_event (display, node, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_event_queue_remove_link (display, node);
|
||||
g_list_free_1 (node);
|
||||
gdk_event_free (event);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
[NSApp sendEvent:event];
|
||||
[NSApp sendEvent:nsevent];
|
||||
GDK_THREADS_ENTER ();
|
||||
}
|
||||
|
||||
_gdk_quartz_event_loop_release_event (event);
|
||||
_gdk_quartz_event_loop_release_event (nsevent);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user