From 4a1375c7011e32e26150339a704454821282ebbb Mon Sep 17 00:00:00 2001 From: Droc Date: Wed, 18 Sep 2024 19:01:28 -0500 Subject: [PATCH] client send to menu Shows all workspaces that current view can be sent to. Works best when added to Client menu. Menu uses ">" and "<" to highlight the current workspace --- docs/labwc-actions.5.scd | 6 ++--- docs/labwc-menu.5.scd | 6 ++++- docs/menu.xml | 7 ++++++ include/menu/menu.h | 1 + src/action.c | 8 ++++--- src/menu/menu.c | 47 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 7092a44c..85595c93 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -115,9 +115,9 @@ Actions are used in menus and keyboard/mouse bindings. Show a menu. *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. + "client-menu", "client-send-to-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 diff --git a/docs/labwc-menu.5.scd b/docs/labwc-menu.5.scd index f017d986..072a7ea7 100644 --- a/docs/labwc-menu.5.scd +++ b/docs/labwc-menu.5.scd @@ -49,7 +49,11 @@ The menu file must be entirely enclosed within and - "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 + all workspaces. Will change focus to the app that gets + selected or go to workspace without activating any app if + "Go there" is selected. + - "client-send-to-menu" shows all workspaces and sends current + view to that workspace when selected. *menu.id* (when nested under other ** element) Link to a submenu defined elsewhere (by a ** at toplevel) diff --git a/docs/menu.xml b/docs/menu.xml index 2fd2c094..f64228a6 100644 --- a/docs/menu.xml +++ b/docs/menu.xml @@ -37,6 +37,13 @@ + diff --git a/include/menu/menu.h b/include/menu/menu.h index 424d47f9..f55bc365 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -137,5 +137,6 @@ void menu_close_root(struct server *server); void menu_reconfigure(struct server *server); void update_client_list_combined_menu(struct server *server); +void update_client_send_to_menu(struct server *server); #endif /* LABWC_MENU_H */ diff --git a/src/action.c b/src/action.c index 67067ad3..a5435387 100644 --- a/src/action.c +++ b/src/action.c @@ -680,10 +680,12 @@ show_menu(struct server *server, struct view *view, /* The client menu needs an active client */ bool is_client_menu = !strcasecmp(menu_name, "client-menu"); - if (!view && is_client_menu) { - return; + if (is_client_menu) { + if (!view) { + return; + } + update_client_send_to_menu(menu->server); } - /* Place menu in the view corner if desired (and menu is not root-menu) */ if (!at_cursor && view) { /* push the client menu underneath the window menu button */ diff --git a/src/menu/menu.c b/src/menu/menu.c index 321826f5..94b7b3f3 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -910,6 +910,52 @@ menu_hide_submenu(struct server *server, const char *id) } } +static void +init_client_send_to_menu(struct server *server) +{ + /* Just create placeholder. Contents will be created when launched */ + menu_create(server, "client-send-to-menu", ""); +} + +/* + * This is client-send-to-menu + * an internal menu similar to root-menu and client-menu + * + * This will look at workspaces and produce a menu + * with the workspace names that can be used with + * SendToDesktop, left/right options are included. + */ +void +update_client_send_to_menu(struct server *server) +{ + struct menu *menu = menu_get_by_id(server, + "client-send-to-menu"); + + if (menu) { + struct menuitem *item, *next; + wl_list_for_each_safe(item, next, &menu->menuitems, link) { + item_destroy(item); + } + } + + menu->size.height = 0; + + struct workspace *workspace; + + wl_list_for_each(workspace, &server->workspaces, link) { + if (workspace == server->workspace_current) { + current_item = item_create(menu, strdup_printf(">%s<", workspace->name), + /*show arrow*/ false); + } else { + current_item = item_create(menu, workspace->name, /*show arrow*/ false); + } + fill_item("name.action", "SendToDesktop"); + fill_item("to.action", workspace->name); + } + + menu_update_width(menu); +} + static void init_client_list_combined_menu(struct server *server) { @@ -1056,6 +1102,7 @@ menu_init(struct server *server) init_rootmenu(server); init_windowmenu(server); init_client_list_combined_menu(server); + init_client_send_to_menu(server); post_processing(server); validate(server); }