From 4a3fe0e3c041db90acb92f42e0ee0622f862fa7a Mon Sep 17 00:00:00 2001 From: Arjan Molenaar Date: Sun, 10 Nov 2024 19:25:25 +0100 Subject: [PATCH] macos: Actions from menu also work for GTK widgets If we have a menu item, once would expect it would work. Therefore, if we deal with a GTK window, we need activate the action on the focused widget of the active window. --- gtk/gtkapplication-quartz.c | 59 ++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/gtk/gtkapplication-quartz.c b/gtk/gtkapplication-quartz.c index 1aa37d7dd8..b5c80941c1 100644 --- a/gtk/gtkapplication-quartz.c +++ b/gtk/gtkapplication-quartz.c @@ -22,7 +22,9 @@ #include "gtkapplicationprivate.h" #include "gtkbuilder.h" +#include "gtknative.h" #import +#include typedef struct { @@ -126,6 +128,49 @@ G_DEFINE_TYPE (GtkApplicationImplQuartz, gtk_application_impl_quartz, GTK_TYPE_A } @end +static GtkWindow* +gtk_application_impl_quartz_find_window(GdkMacosWindow *keyWindow) +{ + GListModel *top_levels = gtk_window_get_toplevels (); + + for (guint i = 0; i < g_list_model_get_n_items (top_levels); i++) + { + GtkWindow *win = (GtkWindow *) g_list_model_get_item (top_levels, i); + if (gtk_native_get_surface (GTK_NATIVE (win)) == (GdkSurface *) [keyWindow gdkSurface]) + return win; + } + + return NULL; +} + +static void +gtk_application_impl_quartz_send_action (const gchar *action_name, SEL action) +{ + static guint semaphore = 0; + NSWindow *keyWindow = [NSApp keyWindow]; + + if (keyWindow == NULL) + return; + + if (semaphore == 0 && [keyWindow isKindOfClass:[GdkMacosWindow class]]) + { + GtkWindow *window = gtk_application_impl_quartz_find_window ((GdkMacosWindow *) keyWindow); + + if (window) + { + GtkWidget *focus = gtk_window_get_focus (window); + if (focus) + { + semaphore += 1; + gtk_widget_activate_action (focus, action_name, NULL); + semaphore -= 1; + } + } + } + else + [NSApp sendAction:action to:nil from:NSApp]; +} + /* these exist only for accel handling */ static void gtk_application_impl_quartz_hide (GSimpleAction *action, @@ -162,7 +207,7 @@ gtk_application_impl_quartz_undo (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(undo:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("text.undo", @selector(undo:)); } static void @@ -170,7 +215,7 @@ gtk_application_impl_quartz_redo (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(redo:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("text.redo", @selector(redo:)); } static GActionEntry gtk_application_impl_quartz_text_actions[] = { @@ -183,7 +228,7 @@ gtk_application_impl_quartz_cut (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(cut:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("clipboard.cut", @selector(cut:)); } static void @@ -191,7 +236,7 @@ gtk_application_impl_quartz_copy (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(copy:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("clipboard.copy", @selector(copy:)); } static void @@ -199,7 +244,7 @@ gtk_application_impl_quartz_paste (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(paste:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("clipboard.paste", @selector(paste:)); } static GActionEntry gtk_application_impl_quartz_clipboard_actions[] = { @@ -213,7 +258,7 @@ gtk_application_impl_quartz_delete (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(delete:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("selection.delete", @selector(delete:)); } static void @@ -221,7 +266,7 @@ gtk_application_impl_quartz_select_all (GSimpleAction *action, GVariant *parameter, gpointer user_data) { - [NSApp sendAction:@selector(selectAll:) to:nil from:NSApp]; + gtk_application_impl_quartz_send_action ("selection.select-all", @selector(selectAll:)); } static GActionEntry gtk_application_impl_quartz_selection_actions[] = {