]> git.mdlowis.com Git - proto/labwc.git/commitdiff
menu: support client-list-combined-menu
authorDroc <japhack@yahoo.com>
Tue, 17 Sep 2024 11:52:10 +0000 (06:52 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 17 Sep 2024 21:13:23 +0000 (22:13 +0100)
...showing windows across all workspaces.

<action name="ShowMenu" menu="client-list-combined-menu"/>

docs/labwc-actions.5.scd
docs/labwc-menu.5.scd
include/menu/menu.h
src/action.c
src/menu/menu.c

index 443268e891d819e2a0a6c38b3279ca7fae283437..7092a44c28ce21d096e6b141ad3efb9be9159fe6 100644 (file)
@@ -114,9 +114,10 @@ Actions are used in menus and keyboard/mouse bindings.
 *<action name="ShowMenu" menu="value" atCursor="yes" />*
        Show a menu.
 
-       *menu* The name of the menu to show. The menus "root-menu" and
-       "client-menu" are guaranteed to exist, but others may be defined
-       explicitly. See labwc-menu(5) for more information.
+       *menu* The name of the menu to show. The menus "root-menu",
+       "client-menu", and "client-list-combined-menu" are guaranteed to exist,
+       but others may be defined explicitly. See labwc-menu(5) for more
+       information.
 
        *atCursor* [yes|no] When opening a menu, open the menu at the location
        of the mouse cursor. When set to no, the menu will appear at the
index a50fa2544be3fc201635cef2246389d153ba6011..f017d986b7db87e6ae6e1d5be3d20fb1fb2b5485 100644 (file)
@@ -48,6 +48,8 @@ The menu file must be entirely enclosed within <openbox_menu> and
        ShowMenu action. Default identifiers are
                - "root-menu" for the root window context menu
                - "client-menu" for a window's titlebar context menu
+               - "client-list-combined-menu" for a list of all windows across
+                 all workspaces
 
 *menu.id* (when nested under other *<menu>* element)
        Link to a submenu defined elsewhere (by a *<menu id="">* at toplevel)
index 980eaa7c1a441f6c9fa55236bc0c625d59c5fcb8..424d47f99b7f1db8328e17c9dabaf5c156d44c8e 100644 (file)
@@ -47,6 +47,7 @@ struct menuitem {
        struct menu_scene normal;
        struct menu_scene selected;
        struct menu_pipe_context *pipe_ctx;
+       struct view *client_list_view;  /* used by internal client-list */
        struct wl_list link; /* menu.menuitems */
 };
 
@@ -135,4 +136,6 @@ void menu_close_root(struct server *server);
 /* menu_reconfigure - reload theme and content */
 void menu_reconfigure(struct server *server);
 
+void update_client_list_combined_menu(struct server *server);
+
 #endif /* LABWC_MENU_H */
index 73ef48a59e72ff75d15d3eec1af242b01a8be3f2..493ba73484989f17abf13f8f0ad0fad741ee8a91 100644 (file)
@@ -665,6 +665,11 @@ show_menu(struct server *server, struct view *view,
                return;
        }
 
+       /* Need to refresh to show current windows and recalculate width */
+       if (!strcasecmp(menu_name, "client-list-combined-menu")) {
+               update_client_list_combined_menu(menu->server);
+       }
+
        int x = server->seat.cursor->x;
        int y = server->seat.cursor->y;
 
index f8653d648923267090c585efd1ef2517f30eb5dd..321826f5bc8dd12dead1e86a550f3a4787879d88 100644 (file)
@@ -23,6 +23,8 @@
 #include "common/string-helpers.h"
 #include "labwc.h"
 #include "menu/menu.h"
+#include "workspaces.h"
+#include "view.h"
 #include "node.h"
 #include "theme.h"
 
@@ -908,6 +910,73 @@ menu_hide_submenu(struct server *server, const char *id)
        }
 }
 
+static void
+init_client_list_combined_menu(struct server *server)
+{
+       /* Just create placeholder. Contents will be created when launched */
+       menu_create(server, "client-list-combined-menu", "");
+}
+
+/*
+ * This is client-list-combined-menu an internal menu similar to root-menu and
+ * client-menu.
+ *
+ * This will look at workspaces and produce a menu with the workspace name as a
+ * separator label and the titles of the view, if any, below each workspace
+ * name. Active view is indicated by "*" preceeding title.
+ */
+void
+update_client_list_combined_menu(struct server *server)
+{
+       struct menu *menu = menu_get_by_id(server, "client-list-combined-menu");
+
+       if (!menu) {
+               /* Menu is created on compositor startup/reconfigure */
+               wlr_log(WLR_ERROR, "client-list-combined-menu does not exist");
+               return;
+       }
+
+       struct menuitem *item, *next;
+       wl_list_for_each_safe(item, next, &menu->menuitems, link) {
+               item_destroy(item);
+       }
+
+       menu->size.height = 0;
+
+       struct workspace *workspace;
+       struct view *view;
+       struct buf buffer = BUF_INIT;
+
+       wl_list_for_each(workspace, &server->workspaces, link) {
+               buf_add_fmt(&buffer, workspace == server->workspace_current ? ">%s<" : "%s",
+                               workspace->name);
+               current_item = separator_create(menu, buffer.data);
+               buf_clear(&buffer);
+
+               wl_list_for_each(view, &server->views, link) {
+                       if (view->workspace == workspace) {
+                               if (view == server->active_view) {
+                                       buf_add(&buffer, "*");
+                               }
+                               buf_add(&buffer, view_get_string_prop(view, "title"));
+
+                               current_item = item_create(menu, buffer.data, /*show arrow*/ false);
+                               current_item->id = xstrdup(menu->id);
+                               current_item->client_list_view = view;
+                               fill_item("name.action", "Focus");
+                               fill_item("name.action", "Raise");
+                               buf_clear(&buffer);
+                       }
+               }
+               current_item = item_create(menu, _("Go there..."), /*show arrow*/ false);
+               current_item->id = xstrdup(menu->id);
+               fill_item("name.action", "GoToDesktop");
+               fill_item("to.action", workspace->name);
+       }
+       buf_reset(&buffer);
+       menu_update_width(menu);
+}
+
 static void
 init_rootmenu(struct server *server)
 {
@@ -986,6 +1055,7 @@ menu_init(struct server *server)
        parse_xml("menu.xml", server);
        init_rootmenu(server);
        init_windowmenu(server);
+       init_client_list_combined_menu(server);
        post_processing(server);
        validate(server);
 }
@@ -1467,7 +1537,13 @@ menu_execute_item(struct menuitem *item)
         * menu_close() and destroy_pipemenus() which we have to handle
         * before/after action_run() respectively.
         */
-       actions_run(item->parent->triggered_by_view, server, &item->actions, 0);
+       if (item->id && !strcmp(item->id, "client-list-combined-menu")
+                       && item->client_list_view) {
+               actions_run(item->client_list_view, server, &item->actions, 0);
+       } else {
+               actions_run(item->parent->triggered_by_view, server,
+                               &item->actions, 0);
+       }
 
        server->menu_current = NULL;
        destroy_pipemenus(server);