]> git.mdlowis.com Git - proto/labwc.git/commitdiff
workspaces: react to Reconfigure
authortokyo4j <hrak1529@gmail.com>
Wed, 17 Apr 2024 09:09:01 +0000 (18:09 +0900)
committerHiroaki Yamamoto <hrak1529@gmail.com>
Sun, 21 Apr 2024 20:44:52 +0000 (05:44 +0900)
Changes in `<desktops><names>` or `<desktop><number="" prefix="">` required
restarting labwc to take effect.

This commit adds `workspaces_reconfigure()` to update `server->workspaces` on
Reconfigure.

include/workspaces.h
src/server.c
src/workspaces.c

index 997865f272f1708841df6d173c26297f3a99bf60..a558a00ecd7f0404d2d3557f556a1299da76a46b 100644 (file)
@@ -27,5 +27,6 @@ void workspaces_destroy(struct server *server);
 void workspaces_osd_hide(struct seat *seat);
 struct workspace *workspaces_find(struct workspace *anchor, const char *name,
        bool wrap);
+void workspaces_reconfigure(struct server *server);
 
 #endif /* LABWC_WORKSPACES_H */
index 9c79d90d0ccf99fcf4ad241ac6a0072ebcfd6d43..58b95e55adb5a79c37712a2b80927d27e1406e0c 100644 (file)
@@ -63,6 +63,7 @@ reload_config_and_theme(struct server *server)
        regions_reconfigure(server);
        resize_indicator_reconfigure(server);
        kde_server_decoration_update_default();
+       workspaces_reconfigure(server);
 }
 
 static int
index fc8c26a9fe5d8f3a9c3e156be8042038b4ad2f54..0fcef01a4f62de78e3551ad8fb26d8a473a7e32c 100644 (file)
@@ -388,15 +388,92 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap)
        return NULL;
 }
 
+static void
+destroy_workspace(struct workspace *workspace)
+{
+       wlr_scene_node_destroy(&workspace->tree->node);
+       zfree(workspace->name);
+       wl_list_remove(&workspace->link);
+       free(workspace);
+}
+
+void
+workspaces_reconfigure(struct server *server)
+{
+       /*
+        * Compare actual workspace list with the new desired configuration to:
+        *   - Update names
+        *   - Add workspaces if more workspaces are desired
+        *   - Destroy workspaces if fewer workspace are desired
+        */
+
+       struct wl_list *actual_workspace_link = server->workspaces.next;
+
+       struct workspace *configured_workspace;
+       wl_list_for_each(configured_workspace,
+                       &rc.workspace_config.workspaces, link) {
+               struct workspace *actual_workspace = wl_container_of(
+                       actual_workspace_link, actual_workspace, link);
+
+               if (actual_workspace_link == &server->workspaces) {
+                       /* # of configured workspaces increased */
+                       wlr_log(WLR_DEBUG, "Adding workspace \"%s\"",
+                               configured_workspace->name);
+                       add_workspace(server, configured_workspace->name);
+                       continue;
+               }
+               if (strcmp(actual_workspace->name, configured_workspace->name)) {
+                       /* Workspace is renamed */
+                       wlr_log(WLR_DEBUG, "Renaming workspace \"%s\" to \"%s\"",
+                               actual_workspace->name, configured_workspace->name);
+                       free(actual_workspace->name);
+                       actual_workspace->name = xstrdup(configured_workspace->name);
+               }
+               actual_workspace_link = actual_workspace_link->next;
+       }
+
+       if (actual_workspace_link == &server->workspaces) {
+               return;
+       }
+
+       /* # of configured workspaces decreased */
+       overlay_hide(&server->seat);
+       struct workspace *first_workspace =
+               wl_container_of(server->workspaces.next, first_workspace, link);
+
+       while (actual_workspace_link != &server->workspaces) {
+               struct workspace *actual_workspace = wl_container_of(
+                       actual_workspace_link, actual_workspace, link);
+
+               wlr_log(WLR_DEBUG, "Destroying workspace \"%s\"",
+                       actual_workspace->name);
+
+               struct view *view;
+               wl_list_for_each(view, &server->views, link) {
+                       if (view->workspace == actual_workspace) {
+                               view_move_to_workspace(view, first_workspace);
+                       }
+               }
+
+               if (server->workspace_current == actual_workspace) {
+                       workspaces_switch_to(first_workspace,
+                               /* update_focus */ true);
+               }
+               if (server->workspace_last == actual_workspace) {
+                       server->workspace_last = first_workspace;
+               }
+
+               actual_workspace_link = actual_workspace_link->next;
+               destroy_workspace(actual_workspace);
+       }
+}
+
 void
 workspaces_destroy(struct server *server)
 {
        struct workspace *workspace, *tmp;
        wl_list_for_each_safe(workspace, tmp, &server->workspaces, link) {
-               wlr_scene_node_destroy(&workspace->tree->node);
-               zfree(workspace->name);
-               wl_list_remove(&workspace->link);
-               free(workspace);
+               destroy_workspace(workspace);
        }
        assert(wl_list_empty(&server->workspaces));
 }