[Bf-blender-cvs] [b28bd7c5a4c] master: Cocoa: Fix missing key window after closing "About"

Sergey Sharybin noreply at git.blender.org
Sun Mar 17 13:25:18 CET 2019


Commit: b28bd7c5a4c6fa66f6e54ffb9f186617f2d5a533
Author: Sergey Sharybin
Date:   Sun Mar 17 12:14:09 2019 +0100
Branches: master
https://developer.blender.org/rBb28bd7c5a4c6fa66f6e54ffb9f186617f2d5a533

Cocoa: Fix missing key window after closing "About"

The cause of this issue goes deeper inside of the custom nature of
the event loop. In short, when not using [NSApp run] closing "About"
window does not make previous key window a key again.

The solution is quite similar to other projects, but we only force
key window from handler when closing one appears to be "About" window.
In all other cases we leave it up to Blender's window manager to make
decision and do not interfere with it.

Test plan:
- Open Blender application
- Go to Blender -> About Blender menu item
- Close About window
- Note that Blender's window does not become active again.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D4534

===================================================================

M	intern/ghost/intern/GHOST_SystemCocoa.mm

===================================================================

diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index b7495873386..52031e77cc7 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -282,6 +282,9 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
 
 	GHOST_SystemCocoa *systemCocoa;
 }
+
+- (id)init;
+- (void)dealloc;
 - (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
@@ -289,9 +292,28 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
 - (void)applicationWillTerminate:(NSNotification *)aNotification;
 - (void)applicationWillBecomeActive:(NSNotification *)aNotification;
 - (void)toggleFullScreen:(NSNotification *)notification;
+- (void)windowWillClose:(NSNotification*)notification;
 @end
 
 @implementation CocoaAppDelegate : NSObject
+- (id)init {
+	self = [super init];
+	if (self) {
+		NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+		[center addObserver:self
+		           selector:@selector(windowWillClose:)
+		               name:NSWindowWillCloseNotification
+		             object:nil];
+	}
+	return self;
+}
+
+- (void)dealloc {
+	NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+	[center removeObserver:self name:NSWindowWillCloseNotification object:nil];
+	[super dealloc];
+}
+
 -(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa
 {
 	systemCocoa = sysCocoa;
@@ -341,6 +363,53 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
 {
 }
 
+// The purpose of this function is to make sure closing "About" window does not
+// leave Blender with no key windows. This is needed due to a custom event loop
+// nature of the application: for some reason only using [NSApp run] will ensure
+// correct behavior in this case.
+//
+// This is similar to an issue solved in SDL:
+//   https://bugzilla.libsdl.org/show_bug.cgi?id=1825
+//
+// Our solution is different, since we want Blender to keep track of what is
+// the key window during normal operation. In order to do so we exploit the
+// fact that "About" window is never in the orderedWindows array: we only force
+// key window from here if the closing one is not in the orderedWindows. This
+// saves lack of key windows when closing "About", but does not interfere with
+// Blender's window manager when closing Blender's windows.
+- (void)windowWillClose:(NSNotification*)notification {
+	NSWindow* closing_window = (NSWindow*)[notification object];
+	NSInteger index = [[NSApp orderedWindows] indexOfObject:closing_window];
+	if (index != NSNotFound) {
+		return;
+	}
+	// Find first suitable window from the current space.
+	for (NSWindow* current_window in [NSApp orderedWindows]) {
+		if (current_window == closing_window) {
+			continue;
+		}
+		if ([current_window isOnActiveSpace] &&
+		    [current_window canBecomeKeyWindow])
+		{
+			[current_window makeKeyAndOrderFront:nil];
+			return;
+		}
+	}
+	// If that didn't find any windows, we try to find any suitable window of
+	// the application.
+	for (NSNumber* window_number in [NSWindow windowNumbersWithOptions:0]) {
+		NSWindow* current_window =
+		          [NSApp windowWithWindowNumber:[window_number integerValue]];
+		if (current_window == closing_window) {
+			continue;
+		}
+		if ([current_window canBecomeKeyWindow]) {
+			[current_window makeKeyAndOrderFront:nil];
+			return;
+		}
+	}
+}
+
 @end



More information about the Bf-blender-cvs mailing list