Keyboard focus handling fixes.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5264 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-11-23 14:11:14 +00:00
parent f6a85c5407
commit 9f320dec44
4 changed files with 175 additions and 38 deletions

View file

@ -1,10 +1,18 @@
Tue Nov 23 14:08:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSApplication.m: Rewrite focus handling, preliminary attempt
to cope with window close etc.
* Source/NSWindow.m: Some focus fixes etc.
* Source/NSMenuView.m: ([-sizeTofit]) hacked out reference to
_isBeholdenToPopUpButton to get this to compile again.
1999-11-22 Michael Hanni <mhanni@sprintmail.com> 1999-11-22 Michael Hanni <mhanni@sprintmail.com>
* Source/NSPopUpButton.m: rewrite. * Source/NSPopUpButton.m: rewrite.
* Source/NSPopUpButtonCell.m: ditto. * Source/NSPopUpButtonCell.m: ditto.
* Source/?.m: a few other misc fixes. will document. * Source/?.m: a few other misc fixes. will document.
Mon Nov 22 17:05:33:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Mon Nov 22 17:33:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSApplication.m: Start listening for window notifications * Source/NSApplication.m: Start listening for window notifications
whenm the app becomes active, and check to see which windows are key whenm the app becomes active, and check to see which windows are key

View file

@ -104,6 +104,11 @@ NSApplication *NSApp = nil;
return NO; return NO;
} }
- (BOOL) worksWhenModal
{
return YES;
}
- (void) initDefaults - (void) initDefaults
{ {
[super initDefaults]; [super initDefaults];
@ -146,19 +151,7 @@ static NSCell* tileCell = nil;
{ {
if ([theEvent clickCount] >= 2) if ([theEvent clickCount] >= 2)
{ {
NSWindow *kw = [NSApp keyWindow];
if (!kw)
kw = [self window];
[NSApp unhide: self]; [NSApp unhide: self];
if ([NSApp keyWindow] == nil && kw != nil)
{
NSGraphicsContext *context = GSCurrentContext();
[kw orderFrontRegardless];
DPSsetinputfocus(context, [kw windowNumber]);
}
} }
else else
{ {
@ -349,31 +342,157 @@ static NSCell* tileCell = nil;
- (void) _windowWillClose: (NSNotification*) notification - (void) _windowWillClose: (NSNotification*) notification
{ {
int count, wincount, realcount; NSWindow *win = [notification object];
id win = [self windows]; NSArray *windows_list = [self windows];
wincount = [win count]; unsigned count = [windows_list count];
realcount = 0; unsigned i;
for(count = 0; count < wincount; count++) NSMutableArray *list = [NSMutableArray arrayWithCapacity: count];
BOOL wasKey = [win isKeyWindow];
BOOL wasMain = [win isMainWindow];
for (i = 0; i < count; i++)
{ {
if([[win objectAtIndex: count] canBecomeMainWindow]) NSWindow *tmp = [windows_list objectAtIndex: i];
if ([tmp canBecomeMainWindow] == YES && [tmp isVisible] == YES)
{ {
realcount ++; [list addObject: tmp];
} }
} }
[list removeObjectIdenticalTo: win];
count = [list count];
/* If there's only one window left, and that's the one being closed, /* If there's only one window left, and that's the one being closed,
then we ask the delegate if the app is to be terminated. */ then we ask the delegate if the app is to be terminated. */
if ((realcount <= 1) && [[notification object] isMainWindow]) if (wasMain && count == 0)
{ {
NSLog(@"asking delegate whether to terminate app..."); NSLog(@"asking delegate whether to terminate app...");
if ([delegate respondsToSelector: @selector(applicationShouldTerminateAfterLastWindowClosed:)]) if ([delegate respondsToSelector:
@selector(applicationShouldTerminateAfterLastWindowClosed:)])
{ {
if([delegate applicationShouldTerminateAfterLastWindowClosed: self]) if ([delegate applicationShouldTerminateAfterLastWindowClosed: self])
{ {
[self terminate: self]; [self terminate: self];
} }
} }
} }
if (wasMain == YES)
{
[win resignMainWindow];
}
if (wasKey == YES)
{
[win resignKeyWindow];
}
if (app_should_quit == NO)
{
/*
* If we are not quitting, we may need to find a new key/main window.
*/
if (wasKey == YES && [self keyWindow] == nil)
{
win = [self mainWindow];
if (win != nil && [win canBecomeKeyWindow] == YES)
{
/*
* We have a main window that can become key, so do it.
*/
[win makeKeyAndOrderFront: self];
}
else if (win != nil)
{
/*
* We have a main window that can't become key, so we just
* find a new window to make into our key window.
*/
for (i = 0; i < count; i++)
{
win = [list objectAtIndex: i];
if ([win canBecomeKeyWindow] == YES)
{
[win makeKeyAndOrderFront: self];
}
}
}
else
{
/*
* Find a window that can be made key and main - and do it.
*/
for (i = 0; i < count; i++)
{
win = [list objectAtIndex: i];
if ([win canBecomeKeyWindow] && [win canBecomeMainWindow])
{
break;
}
}
if (i < count)
{
[win makeMainWindow];
[win makeKeyAndOrderFront: self];
}
else
{
/*
* No window we can use, so just find any candidate to
* be main window and another to be key window.
*/
for (i = 0; i < count; i++)
{
win = [list objectAtIndex: i];
if ([win canBecomeMainWindow] == YES)
{
[win makeMainWindow];
break;
}
}
for (i = 0; i < count; i++)
{
win = [list objectAtIndex: i];
if ([win canBecomeKeyWindow] == YES)
{
[win makeKeyAndOrderFront: self];
break;
}
}
}
}
}
else if ([self mainWindow] == nil)
{
win = [self keyWindow];
if ([win canBecomeMainWindow] == YES)
{
[win makeMainWindow];
}
else
{
for (i = 0; i < count; i++)
{
win = [list objectAtIndex: i];
if ([win canBecomeMainWindow] == YES)
{
[win makeMainWindow];
break;
}
}
}
}
/*
* If the app has no key window - we must make sure the icon window
* has keyboard focus, even though it doesn't actually use kb events.
*/
if ([self keyWindow] == nil)
{
NSGraphicsContext *context = GSCurrentContext();
DPSsetinputfocus(context, [app_icon_window windowNumber]);
}
}
} }
- (id) init - (id) init
@ -503,8 +622,10 @@ static NSCell* tileCell = nil;
{ {
[_main_window resignMainWindow]; [_main_window resignMainWindow];
[_main_window becomeMainWindow]; [_main_window becomeMainWindow];
[_main_window orderFrontRegardless];
[_key_window resignKeyWindow]; [_key_window resignKeyWindow];
[_key_window becomeKeyWindow]; [_key_window becomeKeyWindow];
[_key_window orderFrontRegardless];
} }
/* Register self as observer to window events. */ /* Register self as observer to window events. */
@ -596,8 +717,7 @@ static NSCell* tileCell = nil;
{ {
if (app_is_active == NO) if (app_is_active == NO)
{ {
NSGraphicsContext *context = GSCurrentContext(); NSWindow *kw;
NSWindow *kw = [self keyWindow];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
unsigned count = [_inactive count]; unsigned count = [_inactive count];
unsigned i; unsigned i;
@ -616,6 +736,10 @@ static NSCell* tileCell = nil;
{ {
[[_inactive objectAtIndex: i] orderFrontRegardless]; [[_inactive objectAtIndex: i] orderFrontRegardless];
} }
if ([self keyWindow] == nil && [_inactive containsObject: _hidden_key])
{
[_hidden_key makeKeyWindow];
}
[_inactive removeAllObjects]; [_inactive removeAllObjects];
[main_menu update]; [main_menu update];
@ -626,13 +750,14 @@ static NSCell* tileCell = nil;
[self unhide: nil]; [self unhide: nil];
} }
if (kw == nil || [kw isVisible] == NO) kw = [self keyWindow];
if (kw != nil)
{ {
kw = app_icon_window; [kw resignKeyWindow];
[kw orderFrontRegardless]; [kw orderFront: self];
} [kw makeKeyWindow];
}
DPSsetinputfocus(context, [kw windowNumber]);
NSDebugLog(@"activateIgnoringOtherApps end."); NSDebugLog(@"activateIgnoringOtherApps end.");
[nc postNotificationName: NSApplicationDidBecomeActiveNotification [nc postNotificationName: NSApplicationDidBecomeActiveNotification
@ -652,7 +777,10 @@ static NSCell* tileCell = nil;
[nc postNotificationName: NSApplicationWillResignActiveNotification [nc postNotificationName: NSApplicationWillResignActiveNotification
object: self]; object: self];
[[self context] flush]; if ([self keyWindow] != nil)
{
_hidden_key = [self keyWindow];
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSWindow *win = [windows_list objectAtIndex: i]; NSWindow *win = [windows_list objectAtIndex: i];
@ -1241,7 +1369,10 @@ NSAssert([event retainCount] > 0, NSInternalInconsistencyException);
[nc postNotificationName: NSApplicationWillHideNotification [nc postNotificationName: NSApplicationWillHideNotification
object: self]; object: self];
_hidden_key = [self keyWindow]; if ([self keyWindow] != nil)
{
_hidden_key = [self keyWindow];
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSWindow *win = [windows_list objectAtIndex: i]; NSWindow *win = [windows_list objectAtIndex: i];
@ -1312,8 +1443,7 @@ NSAssert([event retainCount] > 0, NSInternalInconsistencyException);
{ {
[[_hidden objectAtIndex: i] orderFrontRegardless]; [[_hidden objectAtIndex: i] orderFrontRegardless];
} }
[_hidden removeAllObjects]; if ([self keyWindow] == nil && [_hidden containsObject: _hidden_key])
if ([[self windows] containsObject: _hidden_key])
{ {
NSGraphicsContext *context = GSCurrentContext(); NSGraphicsContext *context = GSCurrentContext();
@ -1321,6 +1451,7 @@ NSAssert([event retainCount] > 0, NSInternalInconsistencyException);
DPSsetinputfocus(context, [_hidden_key windowNumber]); DPSsetinputfocus(context, [_hidden_key windowNumber]);
_hidden_key = nil; _hidden_key = nil;
} }
[_hidden removeAllObjects];
[nc postNotificationName: NSApplicationDidUnhideNotification [nc postNotificationName: NSApplicationDidUnhideNotification
object: self]; object: self];

View file

@ -472,8 +472,10 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
accumulatedOffset += neededKeyEquivalentWidth + menuv_horizontalEdgePad; accumulatedOffset += neededKeyEquivalentWidth + menuv_horizontalEdgePad;
// Calculate frame size. // Calculate frame size.
#if 0
if (![menuv_menu _isBeholdenToPopUpButton]) if (![menuv_menu _isBeholdenToPopUpButton])
cellSize.width = accumulatedOffset + 3; // Add the border width cellSize.width = accumulatedOffset + 3; // Add the border width
#endif
[self setFrameSize: NSMakeSize(cellSize.width + 1, howHigh)]; [self setFrameSize: NSMakeSize(cellSize.width + 1, howHigh)];

View file

@ -673,10 +673,6 @@ static NSMapTable* windowmaps = NULL;
- (void) orderWindow: (NSWindowOrderingMode)place relativeTo: (int)otherWin - (void) orderWindow: (NSWindowOrderingMode)place relativeTo: (int)otherWin
{ {
if (_f.is_key == YES && place == NSWindowOut)
{
[self resignKeyWindow];
}
DPSorderwindow(GSCurrentContext(), place, otherWin, [self windowNumber]); DPSorderwindow(GSCurrentContext(), place, otherWin, [self windowNumber]);
} }