forked from AuroraMiddleware/gtk
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);
|
_gdk_event_queue_append (_gdk_display, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkFilterReturn
|
static gint
|
||||||
apply_filters (GdkWindow *window,
|
gdk_event_apply_filters (NSEvent *nsevent,
|
||||||
NSEvent *nsevent,
|
GdkEvent *event,
|
||||||
GList *filters)
|
GList *filters)
|
||||||
{
|
{
|
||||||
GdkFilterReturn result = GDK_FILTER_CONTINUE;
|
|
||||||
GdkEvent *event;
|
|
||||||
GList *node;
|
|
||||||
GList *tmp_list;
|
GList *tmp_list;
|
||||||
|
GdkFilterReturn result;
|
||||||
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);
|
|
||||||
|
|
||||||
tmp_list = filters;
|
tmp_list = filters;
|
||||||
|
|
||||||
while (tmp_list)
|
while (tmp_list)
|
||||||
{
|
{
|
||||||
GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
|
GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
|
||||||
|
|
||||||
tmp_list = tmp_list->next;
|
tmp_list = tmp_list->next;
|
||||||
result = filter->function (nsevent, event, filter->data);
|
result = filter->function (nsevent, event, filter->data);
|
||||||
if (result != GDK_FILTER_CONTINUE)
|
if (result != GDK_FILTER_CONTINUE)
|
||||||
break;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
|
return GDK_FILTER_CONTINUE;
|
||||||
{
|
|
||||||
_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks if the passed in window is interested in the event mask, and
|
/* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkEvent *
|
static void
|
||||||
create_button_event (GdkWindow *window,
|
fill_button_event (GdkWindow *window,
|
||||||
NSEvent *nsevent,
|
GdkEvent *event,
|
||||||
gint x,
|
NSEvent *nsevent,
|
||||||
gint y)
|
gint x,
|
||||||
|
gint y)
|
||||||
{
|
{
|
||||||
GdkEvent *event;
|
|
||||||
GdkEventType type;
|
GdkEventType type;
|
||||||
gint state;
|
gint state;
|
||||||
gint button;
|
gint button;
|
||||||
@ -1444,7 +1421,7 @@ create_button_event (GdkWindow *window,
|
|||||||
|
|
||||||
button = get_mouse_button_from_ns_event (nsevent);
|
button = get_mouse_button_from_ns_event (nsevent);
|
||||||
|
|
||||||
event = gdk_event_new (type);
|
event->any.type = type;
|
||||||
event->button.window = window;
|
event->button.window = window;
|
||||||
event->button.time = get_time_from_ns_event (nsevent);
|
event->button.time = get_time_from_ns_event (nsevent);
|
||||||
event->button.x = x;
|
event->button.x = x;
|
||||||
@ -1456,17 +1433,15 @@ create_button_event (GdkWindow *window,
|
|||||||
convert_window_coordinates_to_root (window, x, y,
|
convert_window_coordinates_to_root (window, x, y,
|
||||||
&event->button.x_root,
|
&event->button.x_root,
|
||||||
&event->button.y_root);
|
&event->button.y_root);
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkEvent *
|
static void
|
||||||
create_motion_event (GdkWindow *window,
|
fill_motion_event (GdkWindow *window,
|
||||||
NSEvent *nsevent,
|
GdkEvent *event,
|
||||||
gint x,
|
NSEvent *nsevent,
|
||||||
gint y)
|
gint x,
|
||||||
|
gint y)
|
||||||
{
|
{
|
||||||
GdkEvent *event;
|
|
||||||
GdkEventType type;
|
GdkEventType type;
|
||||||
GdkModifierType state = 0;
|
GdkModifierType state = 0;
|
||||||
|
|
||||||
@ -1486,7 +1461,7 @@ create_motion_event (GdkWindow *window,
|
|||||||
|
|
||||||
state |= get_keyboard_modifiers_from_ns_event (nsevent);
|
state |= get_keyboard_modifiers_from_ns_event (nsevent);
|
||||||
|
|
||||||
event = gdk_event_new (type);
|
event->any.type = type;
|
||||||
event->motion.window = window;
|
event->motion.window = window;
|
||||||
event->motion.time = get_time_from_ns_event (nsevent);
|
event->motion.time = get_time_from_ns_event (nsevent);
|
||||||
event->motion.x = x;
|
event->motion.x = x;
|
||||||
@ -1497,19 +1472,17 @@ create_motion_event (GdkWindow *window,
|
|||||||
event->motion.device = _gdk_display->core_pointer;
|
event->motion.device = _gdk_display->core_pointer;
|
||||||
convert_window_coordinates_to_root (window, x, y,
|
convert_window_coordinates_to_root (window, x, y,
|
||||||
&event->motion.x_root, &event->motion.y_root);
|
&event->motion.x_root, &event->motion.y_root);
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkEvent *
|
static void
|
||||||
create_scroll_event (GdkWindow *window,
|
fill_scroll_event (GdkWindow *window,
|
||||||
NSEvent *nsevent,
|
GdkEvent *event,
|
||||||
GdkScrollDirection direction)
|
NSEvent *nsevent,
|
||||||
|
GdkScrollDirection direction)
|
||||||
{
|
{
|
||||||
GdkEvent *event;
|
|
||||||
NSPoint point;
|
NSPoint point;
|
||||||
|
|
||||||
event = gdk_event_new (GDK_SCROLL);
|
event->any.type = GDK_SCROLL;
|
||||||
event->scroll.window = window;
|
event->scroll.window = window;
|
||||||
event->scroll.time = get_time_from_ns_event (nsevent);
|
event->scroll.time = get_time_from_ns_event (nsevent);
|
||||||
|
|
||||||
@ -1523,21 +1496,19 @@ create_scroll_event (GdkWindow *window,
|
|||||||
|
|
||||||
event->scroll.direction = direction;
|
event->scroll.direction = direction;
|
||||||
event->scroll.device = _gdk_display->core_pointer;
|
event->scroll.device = _gdk_display->core_pointer;
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkEvent *
|
static void
|
||||||
create_key_event (GdkWindow *window,
|
fill_key_event (GdkWindow *window,
|
||||||
NSEvent *nsevent,
|
GdkEvent *event,
|
||||||
GdkEventType type)
|
NSEvent *nsevent,
|
||||||
|
GdkEventType type)
|
||||||
{
|
{
|
||||||
GdkEvent *event;
|
|
||||||
GdkEventPrivate *priv;
|
GdkEventPrivate *priv;
|
||||||
gchar buf[7];
|
gchar buf[7];
|
||||||
gunichar c = 0;
|
gunichar c = 0;
|
||||||
|
|
||||||
event = gdk_event_new (type);
|
event->any.type = type;
|
||||||
|
|
||||||
priv = (GdkEventPrivate *) event;
|
priv = (GdkEventPrivate *) event;
|
||||||
priv->windowing_data = [nsevent retain];
|
priv->windowing_data = [nsevent retain];
|
||||||
@ -1644,7 +1615,6 @@ create_key_event (GdkWindow *window,
|
|||||||
event->key.window,
|
event->key.window,
|
||||||
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
|
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
|
||||||
event->key.keyval));
|
event->key.keyval));
|
||||||
return event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkEventMask
|
GdkEventMask
|
||||||
@ -1654,13 +1624,13 @@ _gdk_quartz_events_get_current_event_mask (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_event_translate (NSEvent *nsevent)
|
gdk_event_translate (GdkEvent *event,
|
||||||
|
NSEvent *nsevent)
|
||||||
{
|
{
|
||||||
NSWindow *nswindow;
|
NSWindow *nswindow;
|
||||||
GdkWindow *window;
|
GdkWindow *window;
|
||||||
GdkFilterReturn result;
|
|
||||||
GdkEvent *event;
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
gboolean return_val;
|
||||||
|
|
||||||
/* There is no support for real desktop wide grabs, so we break
|
/* There is no support for real desktop wide grabs, so we break
|
||||||
* grabs when the application loses focus (gets deactivated).
|
* grabs when the application loses focus (gets deactivated).
|
||||||
@ -1705,17 +1675,17 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
|
|
||||||
nswindow = [nsevent window];
|
nswindow = [nsevent window];
|
||||||
|
|
||||||
/* Apply any global filters. */
|
|
||||||
if (_gdk_default_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
|
result = gdk_event_apply_filters (nsevent, event, _gdk_default_filters);
|
||||||
* happened. If it is GDK_FILTER_REMOVE,
|
if (result != GDK_FILTER_CONTINUE)
|
||||||
* we return TRUE and won't send the message to Quartz.
|
{
|
||||||
*/
|
return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
|
||||||
if (result == GDK_FILTER_REMOVE)
|
goto done;
|
||||||
return TRUE;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore events for no window or ones not created by GDK. */
|
/* Ignore events for no window or ones not created by GDK. */
|
||||||
@ -1745,9 +1715,26 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Apply any window filters. */
|
/* Apply any window filters. */
|
||||||
result = apply_filters (window, nsevent, ((GdkWindowObject *) window)->filters);
|
if (GDK_IS_WINDOW (window))
|
||||||
if (result == GDK_FILTER_REMOVE)
|
{
|
||||||
return TRUE;
|
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
|
/* We need the appliction to be activated on clicks so that popups
|
||||||
* like context menus get events routed properly. This is handled
|
* 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);
|
current_event_mask = get_event_mask_from_ns_event (nsevent);
|
||||||
|
|
||||||
|
return_val = TRUE;
|
||||||
|
|
||||||
switch ([nsevent type])
|
switch ([nsevent type])
|
||||||
{
|
{
|
||||||
case NSLeftMouseDown:
|
case NSLeftMouseDown:
|
||||||
@ -1783,17 +1772,13 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event = create_button_event (window, nsevent, x, y);
|
fill_button_event (window, event, nsevent, x, y);
|
||||||
append_event (event);
|
|
||||||
|
|
||||||
_gdk_event_button_generate (_gdk_display, event);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NSLeftMouseUp:
|
case NSLeftMouseUp:
|
||||||
case NSRightMouseUp:
|
case NSRightMouseUp:
|
||||||
case NSOtherMouseUp:
|
case NSOtherMouseUp:
|
||||||
event = create_button_event (window, nsevent, x, y);
|
fill_button_event (window, event, nsevent, x, y);
|
||||||
append_event (event);
|
|
||||||
|
|
||||||
/* Ungrab implicit grab */
|
/* Ungrab implicit grab */
|
||||||
if (_gdk_quartz_pointer_grab_window && pointer_grab_implicit)
|
if (_gdk_quartz_pointer_grab_window && pointer_grab_implicit)
|
||||||
@ -1804,8 +1789,7 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
case NSRightMouseDragged:
|
case NSRightMouseDragged:
|
||||||
case NSOtherMouseDragged:
|
case NSOtherMouseDragged:
|
||||||
case NSMouseMoved:
|
case NSMouseMoved:
|
||||||
event = create_motion_event (window, nsevent, x, y);
|
fill_motion_event (window, event, nsevent, x, y);
|
||||||
append_event (event);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NSScrollWheel:
|
case NSScrollWheel:
|
||||||
@ -1827,15 +1811,7 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
else
|
else
|
||||||
direction = GDK_SCROLL_UP;
|
direction = GDK_SCROLL_UP;
|
||||||
|
|
||||||
while (dy > 0.0)
|
fill_scroll_event (window, event, nsevent, direction);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now do x events */
|
/* Now do x events */
|
||||||
if (dx < 0.0)
|
if (dx < 0.0)
|
||||||
@ -1846,16 +1822,7 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
else
|
else
|
||||||
direction = GDK_SCROLL_LEFT;
|
direction = GDK_SCROLL_LEFT;
|
||||||
|
|
||||||
while (dx > 0.0)
|
fill_scroll_event (window, event, nsevent, direction);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1867,11 +1834,9 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
|
|
||||||
type = _gdk_quartz_keys_event_type (nsevent);
|
type = _gdk_quartz_keys_event_type (nsevent);
|
||||||
if (type == GDK_NOTHING)
|
if (type == GDK_NOTHING)
|
||||||
return FALSE;
|
return_val = FALSE;
|
||||||
|
else
|
||||||
event = create_key_event (window, nsevent, type);
|
fill_key_event (window, event, nsevent, type);
|
||||||
append_event (event);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1880,25 +1845,63 @@ gdk_event_translate (NSEvent *nsevent)
|
|||||||
break;
|
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
|
void
|
||||||
_gdk_events_queue (GdkDisplay *display)
|
_gdk_events_queue (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
NSEvent *event;
|
NSEvent *nsevent;
|
||||||
|
|
||||||
event = _gdk_quartz_event_loop_get_pending ();
|
nsevent = _gdk_quartz_event_loop_get_pending ();
|
||||||
if (event)
|
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 ();
|
GDK_THREADS_LEAVE ();
|
||||||
[NSApp sendEvent:event];
|
[NSApp sendEvent:nsevent];
|
||||||
GDK_THREADS_ENTER ();
|
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