]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Correctly re-assign dock_clients to the first screen when their screen disappears
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 28 Oct 2009 14:37:34 +0000 (15:37 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 28 Oct 2009 14:37:34 +0000 (15:37 +0100)
This could lead to a null-pointer dereference when closing dock
clients that got lost.

src/xinerama.c

index e15816129feabcc063cfab015c19a1abc649b797..6c87e775028a8905b7debb554e7ecb8cc5ec3ab6 100644 (file)
@@ -333,6 +333,7 @@ void xinerama_requery_screens(xcb_connection_t *conn) {
 
                         /* Copy the list head for the dock clients */
                         screen->dock_clients = old_screen->dock_clients;
+                        SLIST_INIT(&(old_screen->dock_clients));
 
                         /* Update the dimensions */
                         Workspace *ws;
@@ -364,6 +365,27 @@ void xinerama_requery_screens(xcb_connection_t *conn) {
                 screen_count++;
         }
 
+        /* check for dock_clients which are out of bounds */
+        TAILQ_FOREACH(old_screen, virtual_screens, screens) {
+                if (SLIST_EMPTY(&(old_screen->dock_clients)))
+                        continue;
+
+                LOG("dock_clients out of bounds at screen %p, reassigning\n", old_screen);
+                if (SLIST_EMPTY(&(first->dock_clients))) {
+                        first->dock_clients = old_screen->dock_clients;
+                        continue;
+                }
+
+                /* We need to merge the lists */
+                Client *dock_client;
+
+                while (!SLIST_EMPTY(&(old_screen->dock_clients))) {
+                        dock_client = SLIST_FIRST(&(old_screen->dock_clients));
+                        SLIST_INSERT_HEAD(&(first->dock_clients), dock_client, dock_clients);
+                        SLIST_REMOVE_HEAD(&(old_screen->dock_clients), dock_clients);
+                }
+        }
+
         /* Check for workspaces which are out of bounds */
         TAILQ_FOREACH(ws, workspaces, workspaces) {
                 if (ws->reassigned)