From 16269d55a34cbc74335fc3729e92bcea1497842c Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 27 Jan 2022 12:00:01 +0100 Subject: [PATCH] Make other-frame cycle on current space only (nsterm) To: emacs-devel@gnu.org In nsterm, update frame visibility on space change and application hide/unhide. This makes other-frame cycle through windows correctly. * nsterm.m (updateVisibility:): New function from code in windowDidMiniaturize and windowDidDeminiaturize. (windowDidMiniaturize:, windowDidDeminiaturize:): Call updateVisibility. (initFrameFromEmacs:): Register for notifications of application hide/unhide and, on Cocoa, space changes. (dealloc): Clean up notifications. * nsterm.h (EmacsView): Declaration for updateVisibility. --- src/nsterm.h | 1 + src/nsterm.m | 113 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 96 insertions(+), 18 deletions(-) diff --git a/src/nsterm.h b/src/nsterm.h index f027646123..db4e75641b 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -481,6 +481,7 @@ #define NSTRACE_UNSILENCE() #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - (void) updateCollectionBehavior; #endif +- (void) updateVisibility: (NSNotification *)notification; #ifdef NS_IMPL_GNUSTEP - (void)windowDidMove: (id)sender; diff --git a/src/nsterm.m b/src/nsterm.m index a3c7b55218..cce2ada317 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -5959,6 +5959,22 @@ - (void)dealloc { NSTRACE ("[EmacsView dealloc]"); + [[NSNotificationCenter defaultCenter] + removeObserver: self + name: NSApplicationDidHideNotification + object: nil]; + [[NSNotificationCenter defaultCenter] + removeObserver: self + name: NSApplicationDidUnhideNotification + object: nil]; +#if defined(NS_IMPL_COCOA) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + [[[NSWorkspace sharedWorkspace] notificationCenter] + removeObserver: self + name: NSWorkspaceActiveSpaceDidChangeNotification + object: nil]; +#endif /* NS_IMPL_COCOA && >= MAC_OS_X_VERSION_10_6 */ + /* Clear the view resize notification. */ [[NSNotificationCenter defaultCenter] removeObserver:self @@ -7066,7 +7082,6 @@ - (void)windowDidBecomeKey: (NSNotification *)notification [self windowDidBecomeKey]; } - - (void)windowDidBecomeKey /* for direct calls */ { struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); @@ -7086,7 +7101,27 @@ - (void)windowDidBecomeKey /* for direct calls */ XSETFRAME (event.frame_or_window, emacsframe); kbd_buffer_store_event (&event); } +#if 0 +- (void)windowDidBecomeKey /* for direct calls */ +{ + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); + struct frame *old_focus = dpyinfo->ns_focus_frame; + struct input_event event; + + EVENT_INIT (event); + + NSTRACE ("[EmacsView windowDidBecomeKey]"); + if (emacsframe != old_focus) + dpyinfo->ns_focus_frame = emacsframe; + + ns_frame_rehighlight (emacsframe); + + event.kind = FOCUS_IN_EVENT; + XSETFRAME (event.frame_or_window, emacsframe); + kbd_buffer_store_event (&event); +} +#endif - (void)windowDidResignKey: (NSNotification *)notification /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ @@ -7214,6 +7249,27 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [NSApp registerServicesMenuSendTypes: ns_send_types returnTypes: [NSArray array]]; + /* Update visibility state on application hide and unhide. */ + [[NSNotificationCenter defaultCenter] + addObserver: self + selector: @selector (updateVisibility:) + name: NSApplicationDidHideNotification + object: nil]; + [[NSNotificationCenter defaultCenter] + addObserver: self + selector: @selector (updateVisibility:) + name: NSApplicationDidUnhideNotification + object: nil]; + +#if defined(NS_IMPL_COCOA) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + [[[NSWorkspace sharedWorkspace] notificationCenter] + addObserver: self + selector: @selector (updateVisibility:) + name: NSWorkspaceActiveSpaceDidChangeNotification + object: nil]; +#endif /* NS_IMPL_COCOA && >= MAC_OS_X_VERSION_10_6 */ + ns_window_num++; return self; } @@ -7383,18 +7439,7 @@ - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender - (void)windowDidDeminiaturize: sender { NSTRACE ("[EmacsView windowDidDeminiaturize:]"); - if (!emacsframe->output_data.ns) - return; - - SET_FRAME_ICONIFIED (emacsframe, 0); - SET_FRAME_VISIBLE (emacsframe, 1); - windows_or_buffers_changed = 63; - - if (emacs_event) - { - emacs_event->kind = DEICONIFY_EVENT; - EV_TRAILER ((id)nil); - } + [self updateVisibility:nil]; } @@ -7415,16 +7460,48 @@ - (void)windowDidExpose: sender - (void)windowDidMiniaturize: sender { NSTRACE ("[EmacsView windowDidMiniaturize:]"); + [self updateVisibility:nil]; +} + +- (void)updateVisibility: (NSNotification *)notification +{ + NSTRACE (updateVisibility); + if (!emacsframe->output_data.ns) return; - SET_FRAME_ICONIFIED (emacsframe, 1); - SET_FRAME_VISIBLE (emacsframe, 0); + NSWindow *win = [self window]; + BOOL on_active_space = YES; + if ([win respondsToSelector: @selector (isOnActiveSpace)]) + on_active_space = [win isOnActiveSpace]; + if (on_active_space && [win isVisible]) + { + if (FRAME_VISIBLE_P (emacsframe) && !FRAME_ICONIFIED_P (emacsframe)) + return; - if (emacs_event) + SET_FRAME_ICONIFIED (emacsframe, 0); + SET_FRAME_VISIBLE (emacsframe, 1); + windows_or_buffers_changed = 63; + + if (emacs_event) + { + emacs_event->kind = DEICONIFY_EVENT; + EV_TRAILER ((id)nil); + } + } + else { - emacs_event->kind = ICONIFY_EVENT; - EV_TRAILER ((id)nil); + if (!FRAME_VISIBLE_P (emacsframe) && FRAME_ICONIFIED_P (emacsframe)) + return; + + SET_FRAME_ICONIFIED (emacsframe, 1); + SET_FRAME_VISIBLE (emacsframe, 0); + + if (emacs_event) + { + emacs_event->kind = ICONIFY_EVENT; + EV_TRAILER ((id)nil); + } } } -- 2.34.0