diff --git a/ChangeLog b/ChangeLog index 85f1db1..519a632 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-08-21 Fred Kiefer + + * Source/x11/XGServerEvent.m (-processEvent:): Made handling of + focus in and out more explicit. + 2007-08-16 Fred Kiefer * Source/xlib/XGFontManager.m (load_cache), diff --git a/Source/x11/XGServerEvent.m b/Source/x11/XGServerEvent.m index b628351..aa8a9a6 100644 --- a/Source/x11/XGServerEvent.m +++ b/Source/x11/XGServerEvent.m @@ -982,116 +982,121 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym, break; } - // keyboard focus entered a window + // keyboard focus entered a window case FocusIn: - NSDebugLLog(@"NSEvent", @"%d FocusIn\n", - xEvent.xfocus.window); - if (cWin == 0 || xEvent.xfocus.window != cWin->ident) - { - generic.cachedWindow - = [XGServer _windowForXWindow:xEvent.xfocus.window]; - } - if (cWin == 0) - break; - NSDebugLLog(@"Focus", @"%d got focus on %d\n", - xEvent.xfocus.window, cWin->number); - generic.currentFocusWindow = cWin->number; - if (xEvent.xfocus.serial == generic.focusRequestNumber) - { - /* - * This is a response to our own request - so we mark the - * request as complete. - */ - generic.desiredFocusWindow = 0; - generic.focusRequestNumber = 0; - } - break; - + NSDebugLLog(@"NSEvent", @"%d FocusIn\n", + xEvent.xfocus.window); + if (cWin == 0 || xEvent.xfocus.window != cWin->ident) + { + generic.cachedWindow + = [XGServer _windowForXWindow:xEvent.xfocus.window]; + } + if (cWin == 0) + break; + NSDebugLLog(@"Focus", @"%d got focus on %d\n", + xEvent.xfocus.window, cWin->number); + // Store this for debugging, may not be the real focus window + generic.currentFocusWindow = cWin->number; + if (xEvent.xfocus.serial == generic.focusRequestNumber) + { + /* + * This is a response to our own request - so we mark the + * request as complete. + */ + generic.desiredFocusWindow = 0; + generic.focusRequestNumber = 0; + } + break; + // keyboard focus left a window case FocusOut: - { - Window fw; - int rev; + { + Window fw; + int rev; + + /* + * See where the focus has moved to - + * If it has gone to 'none' or 'PointerRoot' then + * it's not one of ours. + * If it has gone to our root window - use the icon window. + * If it has gone to a window - we see if it is one of ours. + */ + XGetInputFocus(xEvent.xfocus.display, &fw, &rev); + NSDebugLLog(@"NSEvent", @"%d FocusOut\n", + xEvent.xfocus.window); + if (fw != None && fw != PointerRoot) + { + generic.cachedWindow = [XGServer _windowForXWindow: fw]; + if (cWin == 0) + { + generic.cachedWindow = [XGServer _windowForXParent: fw]; + } + if (cWin == 0) + { + nswin = nil; + } + else + { + nswin = GSWindowWithNumber(cWin->number); + } + } + else + { + nswin = nil; + } + NSDebugLLog(@"Focus", @"Focus went to %d (xwin %d)\n", + (nswin != nil) ? cWin->number : 0, fw); - /* - * See where the focus has moved to - - * If it has gone to 'none' or 'PointerRoot' then - * it's not one of ours. - * If it has gone to our root window - use the icon window. - * If it has gone to a window - we see if it is one of ours. - */ - XGetInputFocus(xEvent.xfocus.display, &fw, &rev); - NSDebugLLog(@"NSEvent", @"%d FocusOut\n", - xEvent.xfocus.window); - generic.cachedWindow = [XGServer _windowForXWindow: fw]; - if (cWin == 0) - { - generic.cachedWindow = [XGServer _windowForXParent: fw]; - } - if (cWin == 0) - { - nswin = nil; - } - else - { - nswin = GSWindowWithNumber(cWin->number); - } - NSDebugLLog(@"Focus", @"Focus went to %d (xwin %d)\n", - (cWin) ? cWin->number : 0, fw); - if (nswin == nil) - { - if (fw == 0) - { - /* What? This is bogus. Focus has to go somewhere. */ - } - else - { - [NSApp deactivate]; - } - } - generic.cachedWindow - = [XGServer _windowForXWindow: xEvent.xfocus.window]; - NSDebugLLog(@"Focus", @"%d lost focus on %d\n", - xEvent.xfocus.window, (cWin) ? cWin->number : 0); - generic.currentFocusWindow = 0; - if (cWin && generic.desiredFocusWindow == cWin->number) - { - /* Request not valid anymore since we lost focus */ - generic.focusRequestNumber = 0; - } - } - break; + // Focus went to a window not in this application. + if (nswin == nil) + { + [NSApp deactivate]; + } + + // Clean up old focus request + generic.cachedWindow + = [XGServer _windowForXWindow: xEvent.xfocus.window]; + NSDebugLLog(@"Focus", @"%d lost focus on %d\n", + xEvent.xfocus.window, (cWin) ? cWin->number : 0); + generic.currentFocusWindow = 0; + if (cWin && generic.desiredFocusWindow == cWin->number) + { + /* Request not valid anymore since we lost focus */ + generic.focusRequestNumber = 0; + } + } + break; case GraphicsExpose: - NSDebugLLog(@"NSEvent", @"%d GraphicsExpose\n", - xEvent.xexpose.window); - break; + NSDebugLLog(@"NSEvent", @"%d GraphicsExpose\n", + xEvent.xexpose.window); + break; case NoExpose: - NSDebugLLog(@"NSEvent", @"NoExpose\n"); - break; + NSDebugLLog(@"NSEvent", @"NoExpose\n"); + break; - // window is moved because of a change in the size of its parent + // window is moved because of a change in the size of its parent case GravityNotify: - NSDebugLLog(@"NSEvent", @"%d GravityNotify\n", - xEvent.xgravity.window); - break; + NSDebugLLog(@"NSEvent", @"%d GravityNotify\n", + xEvent.xgravity.window); + break; // a key has been pressed case KeyPress: - NSDebugLLog(@"NSEvent", @"%d KeyPress\n", - xEvent.xkey.window); - generic.lastTime = xEvent.xkey.time; - e = process_key_event (&xEvent, self, NSKeyDown, event_queue); - break; + NSDebugLLog(@"NSEvent", @"%d KeyPress\n", + xEvent.xkey.window); + generic.lastTime = xEvent.xkey.time; + e = process_key_event (&xEvent, self, NSKeyDown, event_queue); + break; // a key has been released case KeyRelease: - NSDebugLLog(@"NSEvent", @"%d KeyRelease\n", - xEvent.xkey.window); - generic.lastTime = xEvent.xkey.time; - e = process_key_event (&xEvent, self, NSKeyUp, event_queue); - break; + NSDebugLLog(@"NSEvent", @"%d KeyRelease\n", + xEvent.xkey.window); + generic.lastTime = xEvent.xkey.time; + e = process_key_event (&xEvent, self, NSKeyUp, event_queue); + break; // reports the state of the keyboard when pointer or // focus enters a window @@ -1164,34 +1169,34 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym, // when a window changes state from ummapped to // mapped or vice versa case MapNotify: - NSDebugLLog(@"NSEvent", @"%d MapNotify\n", - xEvent.xmap.window); - if (cWin == 0 || xEvent.xmap.window != cWin->ident) - { - generic.cachedWindow - = [XGServer _windowForXWindow:xEvent.xmap.window]; - } - if (cWin != 0) - { - cWin->map_state = IsViewable; - /* - * if the window that was just mapped wants the input - * focus, re-do the request. - */ - if (generic.desiredFocusWindow == cWin->number - && generic.focusRequestNumber == 0) - { - NSDebugLLog(@"Focus", @"Refocusing %d on map notify", - cWin->number); - [self setinputfocus: cWin->number]; - } - /* - * Make sure that the newly mapped window displays. - */ - nswin = GSWindowWithNumber(cWin->number); - [nswin update]; - } - break; + NSDebugLLog(@"NSEvent", @"%d MapNotify\n", + xEvent.xmap.window); + if (cWin == 0 || xEvent.xmap.window != cWin->ident) + { + generic.cachedWindow + = [XGServer _windowForXWindow:xEvent.xmap.window]; + } + if (cWin != 0) + { + cWin->map_state = IsViewable; + /* + * if the window that was just mapped wants the input + * focus, re-do the request. + */ + if (generic.desiredFocusWindow == cWin->number + && generic.focusRequestNumber == 0) + { + NSDebugLLog(@"Focus", @"Refocusing %d on map notify", + cWin->number); + [self setinputfocus: cWin->number]; + } + /* + * Make sure that the newly mapped window displays. + */ + nswin = GSWindowWithNumber(cWin->number); + [nswin update]; + } + break; // Window is no longer visible. case UnmapNotify: @@ -1553,7 +1558,7 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym, * WM is asking us to take the keyboard focus */ - (NSEvent *)_handleTakeFocusAtom: (XEvent)xEvent - forContext: (NSGraphicsContext *)gcontext + forContext: (NSGraphicsContext *)gcontext { int key_num; NSWindow *key_win; @@ -1564,7 +1569,8 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym, cWin->number, generic.currentFocusWindow, key_num); /* Sometimes window managers lose the setinputfocus on the key window - * e.g. when ordering out a window with focus then ordering in the key window. * it might search for a window until one accepts its take focus request. + * e.g. when ordering out a window with focus then ordering in the key window. + * it might search for a window until one accepts its take focus request. */ if (key_num == cWin->number) cWin->ignore_take_focus = NO;