From ad44e1a515a1bf7ea3f54b2bab99805b3bbd77ce Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 6 Jun 2018 22:53:07 +0530 Subject: [PATCH] macOS: Fix crash when triggering some global menu actions with the mouse --- kitty/child-monitor.c | 19 +++++++++++++++++++ kitty/cocoa_window.m | 4 ++-- kitty/state.h | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index a7f78f560..788c846f4 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -751,6 +751,18 @@ process_pending_closes(ChildMonitor *self) { return has_open_windows; } +#ifdef __APPLE__ +// If we create new OS windows during wait_events(), using global menu actions +// via the mouse causes a crash because of the way autorelease pools work in +// glfw/cocoa. So we use a flag instead. +static unsigned int cocoa_pending_actions = 0; + +void +set_cocoa_pending_action(CocoaPendingAction action) { + cocoa_pending_actions |= action; +} +#endif + static PyObject* main_loop(ChildMonitor *self, PyObject *a UNUSED) { #define main_loop_doc "The main thread loop" @@ -761,6 +773,13 @@ main_loop(ChildMonitor *self, PyObject *a UNUSED) { if (global_state.has_pending_resizes) process_pending_resizes(now); render(now); wait_for_events(); +#ifdef __APPLE__ + if (cocoa_pending_actions) { + if (cocoa_pending_actions & PREFERENCES_WINDOW) { call_boss(edit_config_file, NULL); } + if (cocoa_pending_actions & NEW_OS_WINDOW) { call_boss(new_os_window, NULL); } + cocoa_pending_actions = 0; + } +#endif parse_input(self); if (global_state.close_all_windows) close_all_windows(); has_open_windows = process_pending_closes(self); diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 4e0a2e882..a337b9382 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -65,12 +65,12 @@ find_app_name(void) { - (void) show_preferences : (id)sender { (void)sender; - call_boss(edit_config_file, NULL); + set_cocoa_pending_action(PREFERENCES_WINDOW); } - (void) new_os_window : (id)sender { (void)sender; - call_boss(new_os_window, NULL); + set_cocoa_pending_action(NEW_OS_WINDOW); } diff --git a/kitty/state.h b/kitty/state.h index 2daf6168e..bbea93059 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -190,4 +190,8 @@ FONTS_DATA_HANDLE load_fonts_data(double, double, double); void send_prerendered_sprites_for_window(OSWindow *w); #ifdef __APPLE__ void get_cocoa_key_equivalent(int, int, unsigned short*, int*); +typedef enum { + PREFERENCES_WINDOW = 1, NEW_OS_WINDOW = 2 +} CocoaPendingAction; +void set_cocoa_pending_action(CocoaPendingAction action); #endif