make helper windows share desktops with all their application top level windows
authorDana Jansens <danakj@orodu.net>
Tue, 8 May 2007 01:25:30 +0000 (01:25 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 8 May 2007 01:25:30 +0000 (01:25 +0000)
openbox/action.c
openbox/client.c
openbox/client.h
openbox/event.c
openbox/screen.c

index f8b2b7b..f8e6643 100644 (file)
@@ -1351,7 +1351,7 @@ void action_toggle_omnipresent(union ActionData *data)
 { 
     client_set_desktop(data->client.any.c,
                        data->client.any.c->desktop == DESKTOP_ALL ?
-                       screen_desktop : DESKTOP_ALL, FALSE);
+                       screen_desktop : DESKTOP_ALL, FALSE, FALSE);
 }
 
 void action_move_relative_horz(union ActionData *data)
@@ -1515,7 +1515,7 @@ void action_send_to_desktop(union ActionData *data)
 
     if (data->sendto.desk < screen_num_desktops ||
         data->sendto.desk == DESKTOP_ALL) {
-        client_set_desktop(c, data->sendto.desk, data->sendto.follow);
+        client_set_desktop(c, data->sendto.desk, data->sendto.follow, FALSE);
         if (data->sendto.follow)
             screen_set_desktop(data->sendto.desk, TRUE);
     }
@@ -1582,7 +1582,7 @@ void action_send_to_desktop_dir(union ActionData *data)
         !data->sendtodir.inter.final ||
         data->sendtodir.inter.cancel)
     {
-        client_set_desktop(c, d, data->sendtodir.follow);
+        client_set_desktop(c, d, data->sendtodir.follow, FALSE);
         if (data->sendtodir.follow)
             screen_set_desktop(d, TRUE);
     }
index 54ae99f..87156eb 100644 (file)
@@ -2812,7 +2812,7 @@ static void client_iconify_recursive(ObClient *self,
 
             if (curdesk && self->desktop != screen_desktop &&
                 self->desktop != DESKTOP_ALL)
-                client_set_desktop(self, screen_desktop, FALSE);
+                client_set_desktop(self, screen_desktop, FALSE, FALSE);
 
             /* this puts it after the current focused window */
             focus_order_remove(self);
@@ -2992,7 +2992,9 @@ void client_hilite(ObClient *self, gboolean hilite)
 }
 
 void client_set_desktop_recursive(ObClient *self,
-                                  guint target, gboolean donthide)
+                                  guint target,
+                                  gboolean donthide,
+                                  gboolean focus_nonintrusive)
 {
     guint old;
     GSList *it;
@@ -3004,7 +3006,8 @@ void client_set_desktop_recursive(ObClient *self,
         g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
 
         /* remove from the old desktop(s) */
-        focus_order_remove(self);
+        if (!focus_nonintrusive)
+            focus_order_remove(self);
 
         old = self->desktop;
         self->desktop = target;
@@ -3021,10 +3024,12 @@ void client_set_desktop_recursive(ObClient *self,
             screen_update_areas();
 
         /* add to the new desktop(s) */
-        if (config_focus_new)
-            focus_order_to_top(self);
-        else
-            focus_order_to_bottom(self);
+        if (!focus_nonintrusive) {
+            if (config_focus_new)
+                focus_order_to_top(self);
+            else
+                focus_order_to_bottom(self);
+        }
 
         /* call the notifies */
         GSList *it;
@@ -3038,13 +3043,15 @@ void client_set_desktop_recursive(ObClient *self,
     for (it = self->transients; it; it = g_slist_next(it))
         if (it->data != self)
             if (client_is_direct_child(self, it->data))
-                client_set_desktop_recursive(it->data, target, donthide);
+                client_set_desktop_recursive(it->data, target,
+                                             donthide, focus_nonintrusive);
 }
 
-void client_set_desktop(ObClient *self, guint target, gboolean donthide)
+void client_set_desktop(ObClient *self, guint target,
+                        gboolean donthide, gboolean focus_nonintrusive)
 {
     self = client_search_top_normal_parent(self);
-    client_set_desktop_recursive(self, target, donthide);
+    client_set_desktop_recursive(self, target, donthide, focus_nonintrusive);
 }
 
 gboolean client_is_direct_child(ObClient *parent, ObClient *child)
@@ -3378,7 +3385,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
         self->desktop != screen_desktop)
     {
         if (here)
-            client_set_desktop(self, screen_desktop, FALSE);
+            client_set_desktop(self, screen_desktop, FALSE, FALSE);
         else
             screen_set_desktop(self->desktop, FALSE);
     } else if (!self->frame->visible)
@@ -3426,6 +3433,26 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
     }
 }
 
+static void client_bring_non_application_windows_recursive(ObClient *self,
+                                                           guint desktop)
+{
+    GSList *it;
+
+    for (it = self->transients; it; it = g_slist_next(it))
+        client_bring_non_application_windows_recursive(it->data, desktop);
+
+    if (client_normal(self) && !client_application(self) &&
+        self->desktop != desktop && self->desktop != DESKTOP_ALL)
+    {
+        client_set_desktop(self, desktop, FALSE, TRUE);
+    }
+}
+
+void client_bring_non_application_windows(ObClient *self)
+{
+    client_bring_non_application_windows_recursive(self, self->desktop);
+}
+
 void client_raise(ObClient *self)
 {
     action_run_string("Raise", self, CurrentTime);
index d902f72..3d30c6a 100644 (file)
@@ -465,8 +465,13 @@ void client_kill(ObClient *self);
 
 /*! Sends the window to the specified desktop
   @param donthide If TRUE, the window will not be shown/hidden after its
-         desktop has been changed. Generally this should be FALSE. */
-void client_set_desktop(ObClient *self, guint target, gboolean donthide);
+         desktop has been changed. Generally this should be FALSE.
+  @param focus_nonintrusive If TRUE, the window will not be moved in the
+         focus order at all. Do this when moving windows to a desktop in
+         the "background" or something. It can be used to make a window share
+         multiple desktops. Generally this should be FALSE. */
+void client_set_desktop(ObClient *self, guint target,
+                        gboolean donthide, gboolean focus_nonintrusive);
 
 /*! Show the client if it should be shown. */
 void client_show(ObClient *self);
@@ -520,6 +525,10 @@ gboolean client_focus(ObClient *self);
 */
 void client_activate(ObClient *self, gboolean here, gboolean user);
 
+/*! Bring all of its non-application windows to its desktop. These are the
+  utility and stuff windows. */
+void client_bring_non_application_windows(ObClient *client);
+
 /*! Calculates the stacking layer for the client window */
 void client_calc_layer(ObClient *self);
 
index a3ca558..9a1ebb2 100644 (file)
@@ -504,6 +504,7 @@ static void event_process(const XEvent *ec, gpointer data)
             frame_adjust_focus(client->frame, TRUE);
             focus_set_client(client);
             client_calc_layer(client);
+            client_bring_non_application_windows(client);
         }
     } else if (e->type == FocusOut) {
         gboolean nomove = FALSE;
@@ -1024,7 +1025,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
                 (unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
                 client_set_desktop(client, (unsigned)e->xclient.data.l[0],
-                                   FALSE);
+                                   FALSE, FALSE);
         } else if (msgtype == prop_atoms.net_wm_state) {
             /* can't compress these */
             ob_debug("net_wm_state %s %ld %ld for 0x%lx\n",
index 5fc2bb9..ffbe712 100644 (file)
@@ -438,7 +438,7 @@ void screen_set_num_desktops(guint num)
     for (it = client_list; it; it = g_list_next(it)) {
         ObClient *c = it->data;
         if (c->desktop >= num && c->desktop != DESKTOP_ALL)
-            client_set_desktop(c, num - 1, FALSE);
+            client_set_desktop(c, num - 1, FALSE, FALSE);
     }
  
     /* change our struts/area to match (after moving windows) */
@@ -473,7 +473,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
     ob_debug("Moving to desktop %d\n", num+1);
 
     if (moveresize_client)
-        client_set_desktop(moveresize_client, num, TRUE);
+        client_set_desktop(moveresize_client, num, TRUE, FALSE);
 
     /* show windows before hiding the rest to lessen the enter/leave events */
 
@@ -485,6 +485,27 @@ void screen_set_desktop(guint num, gboolean dofocus)
         }
     }
 
+    /* have to try focus here because when you leave an empty desktop
+       there is no focus out to watch for
+
+       do this before hiding the windows so if helper windows are coming
+       with us, they don't get hidden
+    */
+    if (dofocus && (c = focus_fallback_target(TRUE, focus_client))) {
+        /* only do the flicker reducing stuff ahead of time if we are going
+           to call xsetinputfocus on the window ourselves. otherwise there is
+           no guarantee the window will actually take focus.. */
+        if (c->can_focus) {
+            /* do this here so that if you switch desktops to a window with
+               helper windows then the helper windows won't flash */
+            client_bring_non_application_windows(c);
+            /* reduce flicker by hiliting now rather than waiting for the
+               server FocusIn event */
+            frame_adjust_focus(c->frame, TRUE);
+        }
+        client_focus(c);
+    }
+
     /* hide windows from bottom to top */
     for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {
         if (WINDOW_IS_CLIENT(it->data)) {
@@ -493,15 +514,6 @@ void screen_set_desktop(guint num, gboolean dofocus)
         }
     }
 
-    /* have to try focus here because when you leave an empty desktop
-       there is no focus out to watch for */
-    if (dofocus && (c = focus_fallback_target(TRUE, focus_client))) {
-        /* reduce flicker by hiliting now rather than waiting for the server
-           FocusIn event */
-        frame_adjust_focus(c->frame, TRUE);
-        client_focus(c);
-    }
-
     event_ignore_queued_enters();
 
     if (event_curtime != CurrentTime)