bug-gnustep
[Top][All Lists]
Advanced

[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)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]