diff --git a/ChangeLog b/ChangeLog index 64c9272bb..1afde66c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2003-11-19 Adam Fedor + + * Window Focus fixes. + * Source/NSApplication.m (-activateIgnoringOtherApps:): Make + hidden_key key only if we have no key, make main key if neither, + make menu key as last resort. + (-deactivate): Resign main window. + (Patches from Benhur Stein ). + (-unhideWithoutActivation): Set hidden=no before ordering windows + to avoid possible recursive loops. + * Source/NSWindow.m (-sendEvent:)(NSLeftMouseDown): Activate app + after ordering window front. + (-sendEvent:)(GSAppKitWindowFocusIn): Don't make ourselves key + if we're not the modal window. Remove check for app isHidden. + 2003-11-19 03:17 Alexander Malmberg * Source/NSClipView.m (-autoscroll:): Reimplement correctly. diff --git a/Source/NSApplication.m b/Source/NSApplication.m index a919292c5..7270a7bd1 100644 --- a/Source/NSApplication.m +++ b/Source/NSApplication.m @@ -931,7 +931,7 @@ static NSCell* tileCell = nil; [[_inactive objectAtIndex: i] orderFrontRegardless]; } [_inactive removeAllObjects]; - if (_hidden_key != nil + if ([self keyWindow] == nil && _hidden_key != nil && [[self windows] indexOfObjectIdenticalTo: _hidden_key] != NSNotFound) { [_hidden_key makeKeyWindow]; @@ -949,8 +949,17 @@ static NSCell* tileCell = nil; } else if ([self mainWindow] != nil) { - [[self mainWindow] orderFront: self]; + [[self mainWindow] makeKeyAndOrderFront: self]; } + else + { + /* We need give input focus to some window otherwise we'll never get + keyboard events. FIXME: doesn't work. */ + NSWindow *menu_window= [[self mainMenu] window]; + NSDebugLLog(@"Focus", @"No key on activation - make menu key"); + [GSServerForWindow(menu_window) setinputfocus: + [menu_window windowNumber]]; + } [nc postNotificationName: NSApplicationDidBecomeActiveNotification object: self]; @@ -975,6 +984,10 @@ static NSCell* tileCell = nil; _hidden_key = [self keyWindow]; [_hidden_key resignKeyWindow]; } + // FIXME: main window is not saved for when the app is activated again. + // This is not a problem if it is also key, and I'm not sure if it + // is a problem at all. May be annoying in the case of workspace switch. + [[self mainWindow] resignMainWindow]; for (i = 0; i < count; i++) { NSModalSession theSession; @@ -1496,13 +1509,11 @@ See -runModalForWindow: if (!theEvent) NSDebugLLog(@"NSEvent", @"NSEvent is nil!\n"); if (type == NSMouseMoved) - NSDebugLLog(@"NSMotionEvent", @"Send move (%d) to window %@", - type, ((window != nil) ? [window description] - : @"No window")); + NSDebugLLog(@"NSMotionEvent", @"Send move (%d) to window %d", + type, [window windowNumber]); else - NSDebugLLog(@"NSEvent", @"Send NSEvent type: %d to window %@", - type, ((window != nil) ? [window description] - : @"No window")); + NSDebugLLog(@"NSEvent", @"Send NSEvent type: %d to window %d", + type, [window windowNumber]); if (window) [window sendEvent: theEvent]; else if (type == NSRightMouseDown) @@ -1884,6 +1895,11 @@ image. [nc postNotificationName: NSApplicationWillUnhideNotification object: self]; + /* Make sure we set this before ordering windows to avoid possible + recursive loops (some methods window/backend methods check if + the app is hidden before ordering a window). */ + _app_is_hidden = NO; + count = [_hidden count]; for (i = 0; i < count; i++) { @@ -1897,8 +1913,6 @@ image. _hidden_key = nil; } - _app_is_hidden = NO; - [nc postNotificationName: NSApplicationDidUnhideNotification object: self]; } diff --git a/Source/NSWindow.m b/Source/NSWindow.m index c19127672..03fd4a5e8 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -2852,10 +2852,6 @@ Code shared with [NSPanel -sendEvent:], remember to update both places. { BOOL wasKey = _f.is_key; - if ([NSApp isActive] == NO && self != [NSApp iconWindow]) - { - [NSApp activateIgnoringOtherApps: YES]; - } if (_f.has_closed == NO) { v = [_contentView hitTest: [theEvent locationInWindow]]; @@ -2863,6 +2859,12 @@ Code shared with [NSPanel -sendEvent:], remember to update both places. { [self makeKeyAndOrderFront: self]; } + /* Activate the app *after* making the receiver key, as app + activation tries to make the previous key window key. */ + if ([NSApp isActive] == NO && self != [NSApp iconWindow]) + { + [NSApp activateIgnoringOtherApps: YES]; + } if (_firstResponder != v) { [self makeFirstResponder: v]; @@ -3075,19 +3077,17 @@ Code shared with [NSPanel -sendEvent:], remember to update both places. { /* Window Manager just deminiaturized us */ [self deminiaturize: self]; - //[self _didDeminiaturize: self]; } - if ([NSApp isHidden]) + if ([NSApp modalWindow] + && self != [NSApp modalWindow]) { - /* This often occurs when hidding an app, since a bunch - of windows get hidden at once, and the WM is searching - for a window to take focus after each one gets - hidden. */ - NSDebugLLog(@"Focus", @"WM take focus while hiding"); + /* Ignore this request. We're in a modal loop and the + user pressed on the title bar of another window. */ break; } if ([self canBecomeKeyWindow] == YES) { + NSDebugLLog(@"Focus", @"Making %d key", _windowNum); [self makeKeyWindow]; [self makeMainWindow]; [NSApp activateIgnoringOtherApps: YES];