improve the add/remove desktop actions a bunch.
authorDana Jansens <danakj@orodu.net>
Wed, 13 Jun 2007 16:47:53 +0000 (16:47 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 13 Jun 2007 16:47:53 +0000 (16:47 +0000)
make the lastdesktop action not assert if you remove a desktop (i think it could have)

openbox/action.c
openbox/client.c
openbox/screen.c

index da4eee7..1ff4a6c 100644 (file)
@@ -1677,7 +1677,8 @@ void action_send_to_desktop_dir(union ActionData *data)
 
 void action_desktop_last(union ActionData *data)
 {
-    screen_set_desktop(screen_last_desktop, TRUE);
+    if (screen_last_desktop < screen_num_desktops)
+        screen_set_desktop(screen_last_desktop, TRUE);
 }
 
 void action_toggle_decorations(union ActionData *data)
@@ -2036,6 +2037,7 @@ void action_break_chroot(union ActionData *data)
 
 void action_add_desktop(union ActionData *data)
 {
+    client_action_start(data);
     screen_set_num_desktops(screen_num_desktops+1);
 
     /* move all the clients over */
@@ -2048,22 +2050,45 @@ void action_add_desktop(union ActionData *data)
                 client_set_desktop(c, c->desktop+1, FALSE, TRUE);
         }
     }
+
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_remove_desktop(union ActionData *data)
 {
     if (screen_num_desktops < 2) return;
 
+    client_action_start(data);
+
     /* move all the clients over */
     if (data->addremovedesktop.current) {
-        GList *it;
-
-        for (it = client_list; it; it = g_list_next(it)) {
-            ObClient *c = it->data;
-            if (c->desktop != DESKTOP_ALL && c->desktop > screen_desktop)
-                client_set_desktop(c, c->desktop-1, FALSE, TRUE);
+        GList *it, *stacking_copy;
+
+        /* make a copy of the list cuz we're changing it */
+        stacking_copy = g_list_copy(stacking_list);
+        for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
+            if (WINDOW_IS_CLIENT(it->data)) {
+                ObClient *c = it->data;
+                if (c->desktop != DESKTOP_ALL && c->desktop > screen_desktop)
+                    client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
+                /* raise all the windows that are on the current desktop which
+                   is being merged */
+                else if (c->desktop == DESKTOP_ALL ||
+                         c->desktop == screen_desktop)
+                    stacking_raise(CLIENT_AS_WINDOW(c));
+            }
         }
     }
 
+    /* act like we're changing desktops */
+    if (screen_desktop < screen_num_desktops - 1) {
+        gint d = screen_desktop;
+        screen_desktop = screen_last_desktop;
+        screen_set_desktop(d, TRUE);
+        ob_debug("fake desktop change\n");
+    }
+
     screen_set_num_desktops(screen_num_desktops-1);
+
+    client_action_end(data, config_focus_under_mouse);
 }
index 92f7a4b..fed902f 100644 (file)
@@ -2509,6 +2509,7 @@ gboolean client_hide(ObClient *self)
 
         frame_hide(self->frame);
         hide = TRUE;
+        ob_debug("hiding client %s\n", self->title);
 
         /* According to the ICCCM (sec 4.1.3.1) when a window is not visible,
            it needs to be in IconicState. This includes when it is on another
@@ -2941,7 +2942,7 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
        in this case (if force_reply is true)
 
        When user = TRUE, then the request is coming from "us", like when we
-       maximize a window or sometihng.  In this case we are more lenient.  We
+       maximize a window or something.  In this case we are more lenient.  We
        used to follow the same rules as above, but _Java_ Swing can't handle
        this. So just to appease Swing, when user = TRUE, we always send
        a synthetic ConfigureNotify to give the window its root coordinates.
index d092ec2..720fc04 100644 (file)
@@ -496,7 +496,7 @@ void screen_set_num_desktops(guint num)
 {
     guint old;
     gulong *viewport;
-    GList *it;
+    GList *it, *stacking_copy;
 
     g_assert(num > 0);
 
@@ -516,11 +516,20 @@ void screen_set_num_desktops(guint num)
     /* the number of rows/columns will differ */
     screen_update_layout();
 
-    /* move windows on desktops that will no longer exist! */
-    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, TRUE);
+    /* move windows on desktops that will no longer exist!
+       make a copy of the list cuz we're changing it */
+    stacking_copy = g_list_copy(stacking_list);
+    for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
+        if (WINDOW_IS_CLIENT(it->data)) {
+            ObClient *c = it->data;
+            if (c->desktop != DESKTOP_ALL && c->desktop >= num)
+                client_set_desktop(c, num - 1, FALSE, TRUE);
+            /* raise all the windows that are on the current desktop which
+               is being merged */
+            else if (c->desktop == DESKTOP_ALL ||
+                     c->desktop == num - 1)
+                stacking_raise(WINDOW_AS_CLIENT(c));
+        }
     }
  
     /* change our struts/area to match (after moving windows) */