From 759b26b5c1834b7929bc7cca5b667a903d82e3d5 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Wed, 26 Jan 2022 00:07:10 +0100 Subject: [PATCH] Add window menu --- docs/labwc-actions.5.scd | 2 +- docs/labwc-config.5.scd | 1 + docs/menu.xml | 18 +++++++++++++++++- docs/rc.xml.all | 10 ++++++++++ include/labwc.h | 1 + include/menu/menu.h | 1 + src/action.c | 35 ++++++++++++++++++++++++++++------- src/config/rcxml.c | 4 ++++ src/cursor.c | 16 ++++++++++++++-- src/main.c | 1 + src/menu/menu.c | 29 +++++++++++++++++++++++++++++ src/output.c | 1 + 12 files changed, 108 insertions(+), 11 deletions(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 2a43c73b..a47f93e7 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -50,7 +50,7 @@ Actions are used in keyboard bindings. Re-load configuration and theme files. ** - Show menu. Valid menu name is "root-menu". + Show menu. Valid menu names are "root-menu" and "client-menu". ** Toggle decorations of focused window. diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 8f352ac3..739ee4b4 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -120,6 +120,7 @@ Configuration must be wrapped in a root-node. Define a mouse binding. Supported context-names include: - TitleBar: The area where the title of the window is shown. - Title: The title of the window itself. + - WindowMenu: The button on the left. - Iconify: The button that looks like an underline. - Maximize: The button that looks like a box. - Close: The button that looks like an X. diff --git a/docs/menu.xml b/docs/menu.xml index 07dc1be1..45c4ba98 100644 --- a/docs/menu.xml +++ b/docs/menu.xml @@ -1,7 +1,23 @@ - + + + + + + + + + + + + + + + + + firefox diff --git a/docs/rc.xml.all b/docs/rc.xml.all index f3e29eea..399f11ed 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -97,6 +97,9 @@ down + + client-menu + amixer sset Master 5%- @@ -190,6 +193,13 @@ + + + + + client-menu + + diff --git a/include/labwc.h b/include/labwc.h index d0f50ae0..3b46d941 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -165,6 +165,7 @@ struct server { struct theme *theme; struct menu *rootmenu; + struct menu *windowmenu; }; struct output { diff --git a/include/menu/menu.h b/include/menu/menu.h index 627b9b63..9cdc8c6f 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -31,6 +31,7 @@ struct menu { }; void menu_init_rootmenu(struct server *server); +void menu_init_windowmenu(struct server *server); void menu_finish(void); /* menu_move - move to position (x, y) */ diff --git a/src/action.c b/src/action.c index 88f578c5..ad3e8dab 100644 --- a/src/action.c +++ b/src/action.c @@ -87,16 +87,37 @@ void action_list_free(struct wl_list *action_list) { } static void -show_menu(struct server *server, const char *menu) +show_menu(struct server *server, struct view *view, const char *menu_name) { - if (!menu) { + struct menu *menu = NULL; + bool force_menu_top_left = false; + + if (!menu_name) { return; } - if (!strcasecmp(menu, "root-menu")) { - server->input_mode = LAB_INPUT_STATE_MENU; - menu_move(server->rootmenu, server->seat.cursor->x, - server->seat.cursor->y); + + if (!strcasecmp(menu_name, "root-menu")) { + menu = server->rootmenu; + server->windowmenu->visible = false; + } else if (!strcasecmp(menu_name, "client-menu") && view) { + menu = server->windowmenu; + server->rootmenu->visible = false; + } else { + return; } + + menu->visible = true; + server->input_mode = LAB_INPUT_STATE_MENU; + + int x, y; + if (force_menu_top_left) { + x = view->x; + y = view->y; + } else { + x = server->seat.cursor->x; + y = server->seat.cursor->y; + } + menu_move(menu, x, y); damage_all_outputs(server); } @@ -166,7 +187,7 @@ action(struct view *activator, struct server *server, struct wl_list *actions, u spawn_async_no_shell("killall -SIGHUP labwc"); break; case ACTION_TYPE_SHOW_MENU: - show_menu(server, action->arg); + show_menu(server, view, action->arg); break; case ACTION_TYPE_TOGGLE_MAXIMIZE: if (view) { diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 588f8cdb..a541970f 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -504,6 +504,7 @@ static struct { { "W-Right", "SnapToEdge", "right" }, { "W-Up", "SnapToEdge", "up" }, { "W-Down", "SnapToEdge", "down" }, + { "A-Space", "ShowMenu", "client-menu"}, { "XF86_AudioLowerVolume", "Execute", "amixer sset Master 5%-" }, { "XF86_AudioRaiseVolume", "Execute", "amixer sset Master 5%+" }, { "XF86_AudioMute", "Execute", "amixer sset Master toggle" }, @@ -553,6 +554,9 @@ static struct { { "Titlebar", "Left", "Press", "Raise", NULL}, { "TitleBar", "Left", "Drag", "Move", NULL }, { "TitleBar", "Left", "DoubleClick", "ToggleMaximize", NULL }, + { "TitleBar", "Right", "Click", "Focus", NULL}, + { "TitleBar", "Right", "Click", "Raise", NULL}, + { "TitleBar", "Right", "Click", "ShowMenu", "client-menu"}, { "Close", "Left", "Click", "Close", NULL }, { "Iconify", "Left", "Click", "Iconify", NULL}, { "Maximize", "Left", "Click", "ToggleMaximize", NULL}, diff --git a/src/cursor.c b/src/cursor.c index f88f3a41..a7b72810 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -183,7 +183,15 @@ process_cursor_motion(struct server *server, uint32_t time) process_cursor_resize(server, time); return; } else if (server->input_mode == LAB_INPUT_STATE_MENU) { - menu_set_selected(server->rootmenu, + struct menu *menu = NULL; + if (server->rootmenu->visible) { + menu = server->rootmenu; + } else if (server->windowmenu->visible) { + menu = server->windowmenu; + } else { + return; + } + menu_set_selected(menu, server->seat.cursor->x, server->seat.cursor->y); damage_all_outputs(server); return; @@ -615,7 +623,11 @@ cursor_button(struct wl_listener *listener, void *data) } if (server->input_mode == LAB_INPUT_STATE_MENU) { - menu_action_selected(server, server->rootmenu); + if (server->rootmenu->visible) { + menu_action_selected(server, server->rootmenu); + } else if (server->windowmenu->visible) { + menu_action_selected(server, server->windowmenu); + } server->input_mode = LAB_INPUT_STATE_PASSTHROUGH; cursor_rebase(&server->seat, event->time_msec); return; diff --git a/src/main.c b/src/main.c index ced17f76..4e419e5e 100644 --- a/src/main.c +++ b/src/main.c @@ -72,6 +72,7 @@ main(int argc, char *argv[]) server.theme = &theme; menu_init_rootmenu(&server); + menu_init_windowmenu(&server); session_autostart_init(); if (startup_cmd) { diff --git a/src/menu/menu.c b/src/menu/menu.c index 21ea2a33..48b18336 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -313,6 +313,7 @@ menu_init_rootmenu(struct server *server) /* Default menu if no menu.xml found */ if (!server->rootmenu) { + current_menu = NULL; server->rootmenu = menu_create(server, "root-menu", ""); } if (wl_list_empty(&server->rootmenu->menuitems)) { @@ -326,6 +327,33 @@ menu_init_rootmenu(struct server *server) menu_configure(server->rootmenu, 100, 100); } +void +menu_init_windowmenu(struct server *server) +{ + server->windowmenu = get_menu_by_id("client-menu"); + + /* Default menu if no menu.xml found */ + if (!server->windowmenu) { + current_menu = NULL; + server->windowmenu = menu_create(server, "client-menu", ""); + } + if (wl_list_empty(&server->windowmenu->menuitems)) { + current_item = item_create(server->windowmenu, "Minimize"); + fill_item("name.action", "Iconify"); + current_item = item_create(server->windowmenu, "Maximize"); + fill_item("name.action", "ToggleMaximize"); + current_item = item_create(server->windowmenu, "Fullscreen"); + fill_item("name.action", "ToggleFullscreen"); + current_item = item_create(server->windowmenu, "Decorations"); + fill_item("name.action", "ToggleDecorations"); + current_item = item_create(server->windowmenu, "Close"); + fill_item("name.action", "Close"); + } + + server->windowmenu->visible = true; + menu_configure(server->windowmenu, 100, 100); +} + void menu_finish(void) { @@ -437,4 +465,5 @@ menu_reconfigure(struct server *server, struct menu *menu) { menu_finish(); menu_init_rootmenu(server); + menu_init_windowmenu(server); } diff --git a/src/output.c b/src/output.c index bccfb12c..6295c180 100644 --- a/src/output.c +++ b/src/output.c @@ -832,6 +832,7 @@ output_render(struct output *output, pixman_region32_t *damage) if (output->server->input_mode == LAB_INPUT_STATE_MENU) { render_menu(output, damage, server->rootmenu); + render_menu(output, damage, server->windowmenu); } renderer_end: