[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: maintaining key window on unhide
From: |
Matt Rice |
Subject: |
Re: maintaining key window on unhide |
Date: |
Fri, 20 Oct 2006 08:35:13 -0700 (PDT) |
--- Matt Rice <ratmice@yahoo.com> wrote:
> --- Matt Rice <ratmice@yahoo.com> wrote:
>
> > heres some horrible patches i wouldn't even
> consider
> > commiting
> >
> <snip>
>
> this much cleaner diff seems to work...
>
> it seems as though generic.desiredOrderedWindow only
> works if theres one ordered window between event
> handling
>
> though i probably should have removed the
> generic.desiredOrderedWindow stuff
>
> and in this version i just removed the
> makeKeyAndOrderFront: calls from
> -unhideWithoutActivation
>
ok... one last patch i'd like to commit this if theres
no objections..
bug in previous ignore_take_focus needed to be before
the 'Reasserting key window' one.
also adds a method to maintain the window stack order.
and changes gui to use it.
Note: there seems to be a bug in windowmaker-0.92
where the _NET_CLIENT_LIST_STACKING property is only
updated if you actually click on the title bar
I think ideally it should return the window order in
front to back, then NSApp -unhideWithoutActivation and
-activateIgnoringOtherApps: should order front the
top-most window, then order the rest of the windows
below that, but that doesn't seem to work
at least with windowmaker...
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Index: Source/GSDisplayServer.m
===================================================================
--- Source/GSDisplayServer.m (revision 23902)
+++ Source/GSDisplayServer.m (working copy)
@@ -33,6 +33,7 @@
#include <Foundation/NSThread.h>
#include <Foundation/NSGeometry.h>
+#include "AppKit/NSApplication.h"
#include "AppKit/NSEvent.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSWindow.h"
@@ -671,6 +672,17 @@
return nil;
}
+/** Backends can override this method to return an array of windows
+ ordered back to front. The front most window being the last object
+ in the array.
+ The default implementation returns the windows in an unspecified order.
+ */
+- (NSArray *) windowsordered
+{
+ //TODO maybe this should default to just visible windows??
+ return [NSApp windows];
+}
+
/** Returns the depth of the window */
- (int) windowdepth: (int) win
{
Index: Source/NSApplication.m
===================================================================
--- Source/NSApplication.m (revision 23902)
+++ Source/NSApplication.m (working copy)
@@ -523,8 +523,8 @@
if ([NSApp isHidden] == NO)
{
int i;
- NSArray *windows = RETAIN([NSApp windows]);
-
+ NSArray *windows = RETAIN([GSCurrentServer() windowsordered]);
+
for (i = 0; i < [windows count]; i++)
{
NSWindow *aWin = [windows objectAtIndex:i];
@@ -561,8 +561,10 @@
RELEASE(windows);
}
-
- [NSApp unhide: self];
+ else
+ {
+ [NSApp unhide: self];
+ }
}
else
{
@@ -1167,6 +1169,12 @@
[[_inactive objectAtIndex: i] orderFrontRegardless];
}
[_inactive removeAllObjects];
+
+ if (_unhide_on_activation)
+ {
+ [self unhide: nil];
+ }
+
if ([self keyWindow] == nil && _hidden_key != nil
&& [[self windows] indexOfObjectIdenticalTo: _hidden_key] != NSNotFound)
{
@@ -1174,11 +1182,6 @@
_hidden_key = nil;
}
- if (_unhide_on_activation)
- {
- [self unhide: nil];
- }
-
if ([self keyWindow] != nil)
{
[[self keyWindow] orderFront: self];
@@ -1216,7 +1219,7 @@
{
if (_app_is_active == YES)
{
- NSArray *windows_list = [self windows];
+ NSArray *windows_list = [GSCurrentServer() windowsordered];
unsigned count = [windows_list count];
unsigned i;
NSDictionary *info;
@@ -2205,7 +2208,7 @@
{
if (_app_is_hidden == NO)
{
- NSArray *windows_list = [self windows];
+ NSArray *windows_list = [GSCurrentServer() windowsordered];
unsigned count = [windows_list count];
NSDictionary *info;
unsigned i;
@@ -2314,12 +2317,6 @@
[[_hidden objectAtIndex: i] orderFrontRegardless];
}
[_hidden removeAllObjects];
- if (_hidden_key != nil
- && [[self windows] indexOfObjectIdenticalTo: _hidden_key] != NSNotFound)
- {
- [_hidden_key makeKeyAndOrderFront: self];
- _hidden_key = nil;
- }
[[_app_icon_window contentView] setNeedsDisplay: YES];
info = [self _notificationUserInfo];
@@ -2393,10 +2390,19 @@
*/
- (NSWindow*) makeWindowsPerform: (SEL)aSelector inOrder: (BOOL)flag
{
- NSArray *window_list = [self windows];
+ NSArray *window_list;
unsigned i;
- // FIXME flag ignored
+ // so i suppose when flag is YES it only runs on visible windows
+ if (flag)
+ {
+ window_list = [GSCurrentServer() windowsordered];
+ }
+ else
+ {
+ window_list = [self windows];
+ }
+
i = [window_list count];
while (i-- > 0)
{
@@ -3257,8 +3263,16 @@
*/
- (NSArray *) orderedWindows
{
- // FIXME
- return [self windows];
+ NSArray *arr = [GSCurrentServer() windowsordered];
+ NSMutableArray *ret = [[NSArray alloc] initWithCapacity:[arr count]];
+ NSEnumerator *iter = [arr reverseObjectEnumerator];
+ id win;
+ while ((win = [iter nextObject]))
+ {
+ [ret addObject:win];
+ }
+
+ return AUTORELEASE(ret);
}
/*
@@ -3478,20 +3492,20 @@
- (void) _windowWillClose: (NSNotification*) notification
{
NSWindow *win = [notification object];
- NSArray *windows_list = [self windows];
+ NSArray *windows_list = [GSCurrentServer() windowsordered];
unsigned count = [windows_list count];
unsigned i;
NSMutableArray *list = [NSMutableArray arrayWithCapacity: count];
BOOL wasKey = [win isKeyWindow];
BOOL wasMain = [win isMainWindow];
+ NSEnumerator *iter = [windows_list reverseObjectEnumerator];
+ NSWindow *aWin;
- for (i = 0; i < count; i++)
+ while ((aWin = [iter nextObject]))
{
- NSWindow *tmp = [windows_list objectAtIndex: i];
-
- if ([tmp canBecomeMainWindow] == YES && [tmp isVisible] == YES)
+ if ([aWin canBecomeMainWindow] == YES && [aWin isVisible] == YES)
{
- [list addObject: tmp];
+ [list addObject: aWin];
}
}
[list removeObjectIdenticalTo: win];
Index: Source/NSView.m
===================================================================
--- Source/NSView.m (revision 23902)
+++ Source/NSView.m (working copy)
@@ -52,6 +52,7 @@
#include "AppKit/NSAffineTransform.h"
#include "AppKit/NSApplication.h"
+#include "AppKit/NSCursor.h"
#include "AppKit/NSDocumentController.h"
#include "AppKit/NSDocument.h"
#include "AppKit/NSClipView.h"
Index: Headers/Additions/GNUstepGUI/GSDisplayServer.h
===================================================================
--- Headers/Additions/GNUstepGUI/GSDisplayServer.h (revision 23902)
+++ Headers/Additions/GNUstepGUI/GSDisplayServer.h (working copy)
@@ -135,6 +135,7 @@
- (void) setwindowlevel: (int) level : (int) win;
- (int) windowlevel: (int) win;
- (NSArray *) windowlist;
+- (NSArray *) windowsordered;
- (int) windowdepth: (int) win;
- (void) setmaxsize: (NSSize)size : (int) win;
- (void) setminsize: (NSSize)size : (int) win;
Index: Source/x11/XGServerWindow.m
===================================================================
--- Source/x11/XGServerWindow.m (revision 23902)
+++ Source/x11/XGServerWindow.m (working copy)
@@ -2619,7 +2619,7 @@
window->siz_hints.y);
setNormalHints(dpy, window);
/* Set this to ignore any take focus events for this window */
- generic.desiredOrderedWindow = winNum;
+ window->ignore_take_focus = YES;
}
switch (op)
@@ -3038,6 +3038,45 @@
return nil;
}
+- (NSArray *) windowsordered
+{
+ gswindow_device_t *rootWindow;
+ Window *windowOrder;
+ gswindow_device_t *tmp;
+ NSMutableArray *ret;
+ int i, c;
+ static Atom client_stack_atom = None;
+
+ if (!client_stack_atom)
+ client_stack_atom = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
+
+ rootWindow = [self _rootWindowForScreen:0];
+
+ windowOrder = (Window *)PropGetCheckProperty(dpy, rootWindow->ident,
+ client_stack_atom,
+ XA_WINDOW, 32, -1, &c);
+ if (windowOrder == NULL || !c)
+ {
+ return [super windowsordered];
+ }
+
+ ret = [NSMutableArray array];
+
+ for (i = 0; i < c; i++)
+ {
+ tmp = [[self class]_windowForXWindow:windowOrder[i]];
+ /* CLIENT_LIST_STACKING returns all windows on the server, we're only
+ * interested in the ones which are ours. */
+ if (tmp)
+ {
+ [ret addObject:[NSApp windowWithWindowNumber:tmp->number]];
+ }
+ }
+
+ XFree(windowOrder);
+ return ret;
+}
+
- (int) windowdepth: (int)win
{
gswindow_device_t *window;
@@ -3328,7 +3367,6 @@
NSDebugLLog(@"Focus", @"Setting focus to %d", window->number);
generic.desiredFocusWindow = win;
generic.focusRequestNumber = XNextRequest(dpy);
- generic.desiredOrderedWindow = 0;
XSetInputFocus(dpy, window->ident, RevertToParent, generic.lastTime);
[inputServer ximFocusICWindow: window];
}
Index: Source/x11/XGServerEvent.m
===================================================================
--- Source/x11/XGServerEvent.m (revision 23902)
+++ Source/x11/XGServerEvent.m (working copy)
@@ -1540,6 +1540,11 @@
window to take focus after each one gets hidden. */
NSDebugLLog(@"Focus", @"WM take focus while hiding");
}
+ else if (cWin->ignore_take_focus == YES)
+ {
+ NSDebugLLog(@"Focus", @"Ignoring window focus request");
+ cWin->ignore_take_focus = NO;
+ }
else if (cWin->number == key_num)
{
NSDebugLLog(@"Focus", @"Reasserting key window");
@@ -1555,12 +1560,6 @@
NSDebugLLog(@"Focus", @"Key window is already %d", key_num);
[GSServerForWindow(key_win) setinputfocus: key_num];
}
- else if (generic.desiredOrderedWindow == cWin->number)
- {
- /* We just want to order the window, not give it focus */
- NSDebugLLog(@"Focus", @"Ignoring focus request");
- generic.desiredOrderedWindow = 0;
- }
else
{
NSPoint eventLocation;
Index: Headers/x11/XGGeneric.h
===================================================================
--- Headers/x11/XGGeneric.h (revision 23902)
+++ Headers/x11/XGGeneric.h (working copy)
@@ -49,6 +49,7 @@
Atom win_splash_atom;
Atom win_override_atom;
Atom win_topmenu_atom;
+ Atom net_client_list_stacking_atom;
} XGWMWinTypes;
/*
@@ -89,7 +90,6 @@
long currentFocusWindow;
long desiredFocusWindow;
unsigned long focusRequestNumber;
- unsigned long desiredOrderedWindow;
unsigned char lMouse;
unsigned char mMouse;
unsigned char rMouse;
Index: Headers/x11/XGServerWindow.h
===================================================================
--- Headers/x11/XGServerWindow.h (revision 23902)
+++ Headers/x11/XGServerWindow.h (working copy)
@@ -111,6 +111,7 @@
XIC ic;
void *gdriver; /* gdriver ident. Managed by gdriver */
int gdriverProtocol; /* Managed by gdriver */
+ BOOL ignore_take_focus;
} gswindow_device_t;
#define GET_XDRAWABLE(win) ((win)->buffer ? (win)->buffer: (win)->ident)