From f004f14b8976370804d34e9184fb930733021099 Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Tue, 23 Apr 2024 08:57:09 +0200 Subject: [PATCH 1/2] macos: fix in-app native shortcuts (again) Popping an event of the queue in the IMContext handler prevents it from being forwarded to the NSApp, in case the (key) event was not handled by IMContext. So I reverted to a mix of the original (4.13) and new (4.14.1) behavior for fetching events: NSEvent lookup for IMContext uses loose matching, so it can work with rewritten events. When sending events to NSApp, only we're checking for an exact match. Now in-app keyboard shortcuts (e.g. Ctrl-F2) work from within text fields again. --- gdk/macos/gdkmacosdisplay-private.h | 3 ++- gdk/macos/gdkmacosdisplay.c | 24 ++++++++++++++++++------ gdk/macos/gdkmacoseventsource.c | 2 +- gtk/gtkimcontextquartz.c | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/gdk/macos/gdkmacosdisplay-private.h b/gdk/macos/gdkmacosdisplay-private.h index 462d2cf66f..592e2ceff3 100644 --- a/gdk/macos/gdkmacosdisplay-private.h +++ b/gdk/macos/gdkmacosdisplay-private.h @@ -161,7 +161,8 @@ void _gdk_macos_display_send_event (GdkMacosDisp void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self, int x, int y); -NSEvent *_gdk_macos_display_pop_nsevent (GdkEvent *event); +NSEvent *_gdk_macos_display_get_matching_nsevent (GdkEvent *event); +NSEvent *_gdk_macos_display_get_exact_nsevent (GdkEvent *event); NSEvent *_gdk_macos_display_get_last_nsevent (void); GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self, NSInteger sequence_number); diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c index 9a603ffcdc..775394b13f 100644 --- a/gdk/macos/gdkmacosdisplay.c +++ b/gdk/macos/gdkmacosdisplay.c @@ -992,7 +992,7 @@ _gdk_macos_display_warp_pointer (GdkMacosDisplay *self, } NSEvent * -_gdk_macos_display_pop_nsevent (GdkEvent *event) +_gdk_macos_display_get_matching_nsevent (GdkEvent *event) { for (GList *iter = event_map.head; iter; iter = iter->next) { @@ -1002,11 +1002,23 @@ _gdk_macos_display_pop_nsevent (GdkEvent *event) map->gdk_event->device == event->device && map->gdk_event->time == event->time) { - NSEvent *nsevent = map->nsevent; - g_queue_unlink (&event_map, iter); - gdk_event_unref (map->gdk_event); - g_free (map); - return nsevent; + return map->nsevent; + } + } + + return NULL; +} + +NSEvent * +_gdk_macos_display_get_exact_nsevent (GdkEvent *event) +{ + for (GList *iter = event_map.head; iter; iter = iter->next) + { + GdkToNSEventMap *map = iter->data; + + if (map->gdk_event == event) + { + return map->nsevent; } } diff --git a/gdk/macos/gdkmacoseventsource.c b/gdk/macos/gdkmacoseventsource.c index 1724ad95be..b9384778ff 100644 --- a/gdk/macos/gdkmacoseventsource.c +++ b/gdk/macos/gdkmacoseventsource.c @@ -738,7 +738,7 @@ gdk_macos_event_source_dispatch (GSource *source, if (!handled) { - NSEvent *nsevent = _gdk_macos_display_pop_nsevent (event); + NSEvent *nsevent = _gdk_macos_display_get_exact_nsevent (event); if (nsevent != NULL) [NSApp sendEvent: nsevent]; } diff --git a/gtk/gtkimcontextquartz.c b/gtk/gtkimcontextquartz.c index afda65170d..e0e068c3ee 100644 --- a/gtk/gtkimcontextquartz.c +++ b/gtk/gtkimcontextquartz.c @@ -185,7 +185,7 @@ quartz_filter_keypress (GtkIMContext *context, keyval = gdk_key_event_get_keyval (event); keycode = gdk_key_event_get_keycode (event); - NSEvent *nsevent = _gdk_macos_display_pop_nsevent ((GdkEvent *)event); + NSEvent *nsevent = _gdk_macos_display_get_matching_nsevent ((GdkEvent *)event); if (!nsevent) { From 985e4906c85ee0114896f9f4d0838726a5341c3b Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Wed, 24 Apr 2024 23:49:37 +0200 Subject: [PATCH 2/2] macos: Add some docs for the different NSEvent getters --- gdk/macos/gdkmacosdisplay.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c index 775394b13f..6dad7fddd7 100644 --- a/gdk/macos/gdkmacosdisplay.c +++ b/gdk/macos/gdkmacosdisplay.c @@ -991,6 +991,9 @@ _gdk_macos_display_warp_pointer (GdkMacosDisplay *self, CGWarpMouseCursorPosition ((CGPoint) { x, y }); } +/* Find the matching `NSEvent` for an `GdkEvent`. This function + * return the `NSEvent`, also for rewritten `GdkEvent`'s. + */ NSEvent * _gdk_macos_display_get_matching_nsevent (GdkEvent *event) { @@ -1009,6 +1012,9 @@ _gdk_macos_display_get_matching_nsevent (GdkEvent *event) return NULL; } +/* Find the matching `NSEvent` for the original `GdkEvent`. + * If an event was rewritten, it returns `NULL`. + */ NSEvent * _gdk_macos_display_get_exact_nsevent (GdkEvent *event) {