[Xfce4-commits] r22806 - xfwm4/trunk/src

Olivier Fourdan olivier at xfce.org
Wed Aug 16 22:23:55 UTC 2006


Author: olivier
Date: 2006-08-16 22:23:52 +0000 (Wed, 16 Aug 2006)
New Revision: 22806

Modified:
   xfwm4/trunk/src/client.c
   xfwm4/trunk/src/client.h
   xfwm4/trunk/src/events.c
   xfwm4/trunk/src/focus.c
Log:
Unmap the client window when shaded. Some apps want to be notified when the client is not visible (Bug #2168). That change should work although I liked the previous implementation better as it was a lot less intrusive in focus management. Let's see how this goes for now...

Modified: xfwm4/trunk/src/client.c
===================================================================
--- xfwm4/trunk/src/client.c	2006-08-16 20:46:59 UTC (rev 22805)
+++ xfwm4/trunk/src/client.c	2006-08-16 22:23:52 UTC (rev 22806)
@@ -65,6 +65,7 @@
 #define FRAME_EVENT_MASK \
     SubstructureNotifyMask|\
     SubstructureRedirectMask|\
+    FocusChangeMask|\
     EnterWindowMask|\
     PropertyChangeMask
 
@@ -814,16 +815,8 @@
         }
     }
 
-    if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
-    {
-        XMoveResizeWindow (clientGetXDisplay (c), c->window, frameLeft (c), - c->height,
-                                c->width, c->height);
-    }
-    else
-    {
-        XMoveResizeWindow (clientGetXDisplay (c), c->window, frameLeft (c), frameTop (c),
-                                c->width, c->height);
-    }
+    XMoveResizeWindow (clientGetXDisplay (c), c->window, frameLeft (c), frameTop (c),
+                            c->width, c->height);
 
     if (mask & (CWWidth | CWHeight))
     {
@@ -1755,6 +1748,10 @@
     XSelectInput (display_info->dpy, c->window, 0);
     XSetWindowBorderWidth (display_info->dpy, c->window, 0);
     XReparentWindow (display_info->dpy, c->window, c->frame, frameLeft (c), frameTop (c));
+    if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
+    {
+        XUnmapWindow (display_info->dpy, c->window);
+    }
 
     valuemask = CWEventMask;
     attributes.event_mask = (CLIENT_EVENT_MASK);
@@ -2194,7 +2191,10 @@
         TRACE ("showing client \"%s\" (0x%lx)", c->name, c->window);
         FLAG_SET (c->xfwm_flags, XFWM_FLAG_VISIBLE);
         XMapWindow (display_info->dpy, c->frame);
-        XMapWindow (display_info->dpy, c->window);
+        if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
+        {
+            XMapWindow (display_info->dpy, c->window);
+        }
         /* Adjust to urgency state as the window is visible */
         clientUpdateUrgency (c);
     }
@@ -2489,6 +2489,8 @@
 clientShade (Client * c)
 {
     XWindowChanges wc;
+    ScreenInfo *screen_info;
+    DisplayInfo *display_info;
 
     g_return_if_fail (c != NULL);
     TRACE ("entering clientToggleShaded");
@@ -2506,17 +2508,33 @@
         return;
     }
 
+    screen_info = c->screen_info;
+    display_info = screen_info->display_info;
+
     c->win_state |= WIN_STATE_SHADED;
     FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
     clientSetNetState (c);
     if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
     {
         clientConstrainPos (c, FALSE);
-        wc.x = c->x;
-        wc.y = c->y;
+        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
+        {
+            c->ignore_unmap++;
+        }
+        /*
+         * Shading unmaps the client window. We therefore have to transfer focus to its frame
+         * so that focus doesn't return to root. clientSetFocus() will take care of focusing
+         * the window frame since the SHADED flag is now set.
+         */
+        if (c == clientGetFocus ())
+        {
+            clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_FORCE);
+        }
+        XUnmapWindow (display_info->dpy, c->window);
+
         wc.width = c->width;
         wc.height = c->height;
-        clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_FORCE_REDRAW);
+        clientConfigure (c, &wc, CWWidth | CWHeight, CFG_FORCE_REDRAW);
     }
 }
 
@@ -2524,6 +2542,8 @@
 clientUnshade (Client * c)
 {
     XWindowChanges wc;
+    ScreenInfo *screen_info;
+    DisplayInfo *display_info;
 
     g_return_if_fail (c != NULL);
     TRACE ("entering clientToggleShaded");
@@ -2534,11 +2554,27 @@
         TRACE ("\"%s\" (0x%lx) is not shaded", c->name, c->window);
         return;
     }
+
+    screen_info = c->screen_info;
+    display_info = screen_info->display_info;
+
     c->win_state &= ~WIN_STATE_SHADED;
     FLAG_UNSET (c->flags, CLIENT_FLAG_SHADED);
     clientSetNetState (c);
     if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
     {
+        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
+        {
+            XMapWindow (display_info->dpy, c->window);
+        }
+        /*
+         * Unshading will show the client window, so we need to focus it when unshading.
+         */
+        if (c == clientGetFocus ())
+        {
+            clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_FORCE);
+        }
+
         wc.width = c->width;
         wc.height = c->height;
         clientConfigure (c, &wc, CWWidth | CWHeight, CFG_FORCE_REDRAW);

Modified: xfwm4/trunk/src/client.h
===================================================================
--- xfwm4/trunk/src/client.h	2006-08-16 20:46:59 UTC (rev 22805)
+++ xfwm4/trunk/src/client.h	2006-08-16 22:23:52 UTC (rev 22806)
@@ -61,10 +61,11 @@
 #define CFG_FORCE_REDRAW                (1<<3)
 
 #define INCLUDE_HIDDEN                  (1<<0)
-#define INCLUDE_SKIP_FOCUS              (1<<1)
+#define INCLUDE_SHADED                  (1<<1)
 #define INCLUDE_ALL_WORKSPACES          (1<<2)
-#define INCLUDE_SKIP_PAGER              (1<<3)
-#define INCLUDE_SKIP_TASKBAR            (1<<4)
+#define INCLUDE_SKIP_FOCUS              (1<<3)
+#define INCLUDE_SKIP_PAGER              (1<<4)
+#define INCLUDE_SKIP_TASKBAR            (1<<5)
 
 #define NO_UPDATE_FLAG                  0
 #define UPDATE_KEY_GRABS                (1<<0)

Modified: xfwm4/trunk/src/events.c
===================================================================
--- xfwm4/trunk/src/events.c	2006-08-16 20:46:59 UTC (rev 22805)
+++ xfwm4/trunk/src/events.c	2006-08-16 22:23:52 UTC (rev 22806)
@@ -1176,7 +1176,6 @@
         }
 
         screen_info = c->screen_info;
-        clientPassFocus (screen_info, c, c);
 
         /*
          * ICCCM spec states that a client wishing to switch
@@ -1189,9 +1188,11 @@
         if ((ev->event == screen_info->xroot) && (ev->send_event))
         {
             TRACE ("ICCCM UnmapNotify for \"%s\"", c->name);
+            clientPassFocus (screen_info, c, c);
             clientUnframe (c, FALSE);
             return;
         }
+
         if (c->ignore_unmap)
         {
             c->ignore_unmap--;
@@ -1202,6 +1203,7 @@
         {
             TRACE ("unmapping \"%s\" as ignore_unmap is %i", 
                  c->name, c->ignore_unmap);
+            clientPassFocus (screen_info, c, c);
             clientUnframe (c, FALSE);
         }
     }
@@ -1630,7 +1632,7 @@
         return;
     }
 
-    c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
+    c = myDisplayGetClientFromWindow (display_info, ev->window, ANY);
     TRACE ("FocusIn on window (0x%lx)", ev->window);
     if (c)
     {
@@ -1687,7 +1689,7 @@
         && ((ev->detail == NotifyNonlinear) 
             || (ev->detail == NotifyNonlinearVirtual)))
     {
-        c = myDisplayGetClientFromWindow (display_info, ev->window, WINDOW);
+        c = myDisplayGetClientFromWindow (display_info, ev->window, ANY);
         TRACE ("FocusOut on window (0x%lx)", ev->window);
         if ((c) && (c == clientGetFocus ()))
         {

Modified: xfwm4/trunk/src/focus.c
===================================================================
--- xfwm4/trunk/src/focus.c	2006-08-16 20:46:59 UTC (rev 22805)
+++ xfwm4/trunk/src/focus.c	2006-08-16 22:23:52 UTC (rev 22806)
@@ -525,7 +525,18 @@
         if (FLAG_TEST (c->wm_flags, WM_FLAG_INPUT) || !(screen_info->params->focus_hint))
         {
             pending_focus = c;
-            XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp);
+            /* 
+             * When shaded, the client window is unmapped, so it can not be focused.
+             * Instead, we focus the frame that is still mapped.
+             */
+            if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
+            {
+                XSetInputFocus (myScreenGetXDisplay (screen_info), c->frame, RevertToPointerRoot, timestamp);
+            }
+            else
+            {
+                XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp);
+            }
             clientUpdateOpacity (screen_info, c);
         }
         if (FLAG_TEST(c->wm_flags, WM_FLAG_TAKEFOCUS))



More information about the Xfce4-commits mailing list