]> Dogcows Code - chaz/openbox/blobdiff - openbox/screen.c
missing header
[chaz/openbox] / openbox / screen.c
index 92d4d9a421bac5db1a62a8b59fc81cc9fee8f6b4..926b21e45d8ea4d75d400e82f5a4d88986185c62 100644 (file)
@@ -27,6 +27,7 @@
 #include "moveresize.h"
 #include "config.h"
 #include "screen.h"
+#include "composite.h"
 #include "client.h"
 #include "session.h"
 #include "frame.h"
@@ -490,13 +491,16 @@ void screen_resize()
 
     for (it = client_list; it; it = g_list_next(it))
         client_move_onscreen(it->data, FALSE);
+
+    /* this needs to be setup whenever the root window's size changes */
+    composite_setup_root_window();
 }
 
 void screen_set_num_desktops(guint num)
 {
     guint old;
     gulong *viewport;
-    GList *it;
+    GList *it, *stacking_copy;
 
     g_assert(num > 0);
 
@@ -516,11 +520,21 @@ 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);
+    /* 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 (screen_desktop == num - 1 &&
+                     (c->desktop == DESKTOP_ALL ||
+                      c->desktop == screen_desktop))
+                stacking_raise(CLIENT_AS_WINDOW(c));
+        }
     }
  
     /* change our struts/area to match (after moving windows) */
@@ -561,7 +575,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
     ignore_start = event_start_ignore_all_enters();
 
     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 */
 
@@ -579,6 +593,11 @@ void screen_set_desktop(guint num, gboolean dofocus)
     allow_omni = focus_client && (client_normal(focus_client) &&
                                   focus_client->desktop == DESKTOP_ALL);
 
+    /* the client moved there already so don't move focus. prevent flicker
+       on sendtodesktop + follow */
+    if (focus_client && focus_client->desktop == screen_desktop)
+        dofocus = FALSE;
+
     /* have to try focus here because when you leave an empty desktop
        there is no focus out to watch for. also, we have different rules
        here. we always allow it to look under the mouse pointer if
@@ -616,6 +635,72 @@ void screen_set_desktop(guint num, gboolean dofocus)
         screen_desktop_user_time = event_curtime;
 }
 
+void screen_add_desktop(gboolean current)
+{
+    screen_set_num_desktops(screen_num_desktops+1);
+
+    /* move all the clients over */
+    if (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);
+        }
+    }
+}
+
+void screen_remove_desktop(gboolean current)
+{
+    guint rmdesktop, movedesktop;
+    GList *it, *stacking_copy;
+
+    if (screen_num_desktops <= 1) return;
+
+    /* what desktop are we removing and moving to? */
+    if (current)
+        rmdesktop = screen_desktop;
+    else
+        rmdesktop = screen_num_desktops - 1;
+    if (rmdesktop < screen_num_desktops - 1)
+        movedesktop = rmdesktop + 1;
+    else
+        movedesktop = rmdesktop;
+
+    /* 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;
+            guint d = c->desktop;
+            if (d != DESKTOP_ALL && d >= movedesktop) {
+                client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
+                ob_debug("moving window %s\n", c->title);
+            }
+            /* raise all the windows that are on the current desktop which
+               is being merged */
+            if ((screen_desktop == rmdesktop - 1 ||
+                 screen_desktop == rmdesktop) &&
+                (d == DESKTOP_ALL || d == screen_desktop))
+            {
+                stacking_raise(CLIENT_AS_WINDOW(c));
+                ob_debug("raising window %s\n", c->title);
+            }
+        }
+    }
+
+    /* 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);
+}
+
 static void get_row_col(guint d, guint *r, guint *c)
 {
     switch (screen_desktop_layout.orientation) {
This page took 0.025019 seconds and 4 git commands to generate.