From 600934f58bea87fb85854de486b0ad40cc8e6270 Mon Sep 17 00:00:00 2001 From: Philipp Kaeser Date: Mon, 30 Dec 2024 20:57:49 +0100 Subject: [PATCH] Adds basic window actions and populate XDG toplevel window menu. --- doc/ROADMAP.md | 3 +- src/action.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-- src/action.h | 9 +++++ src/xdg_toplevel.c | 8 +++- 4 files changed, 107 insertions(+), 5 deletions(-) diff --git a/doc/ROADMAP.md b/doc/ROADMAP.md index 2f50cb63..ef23bd95 100644 --- a/doc/ROADMAP.md +++ b/doc/ROADMAP.md @@ -21,7 +21,8 @@ Support for visual effects to improve usability, but not for pure show. * [done] Root menu: Basic actions (quit, lock, next- or previous workspace). * [done] Menu shown on right-button-down, items trigger on right-button-up. * [done] When invoked on unclaimed button, exits menu on button release. - * Available as window menu in windows. + * [done] Available as window menu in windows. + * Available also for X11 windows. * Available as (hardcoded) application menu. * Menu with submenus. * Window menu adapting to window state. diff --git a/src/action.c b/src/action.c index 5a710e56..bfd2b07c 100644 --- a/src/action.c +++ b/src/action.c @@ -108,8 +108,14 @@ const wlmcfg_enum_desc_t wlmaker_action_desc[] = { WLMCFG_ENUM("WindowRaise", WLMAKER_ACTION_WINDOW_RAISE), WLMCFG_ENUM("WindowLower", WLMAKER_ACTION_WINDOW_LOWER), - WLMCFG_ENUM("WindowFullscreen", WLMAKER_ACTION_WINDOW_TOGGLE_FULLSCREEN), - WLMCFG_ENUM("WindowMaximize", WLMAKER_ACTION_WINDOW_TOGGLE_MAXIMIZED), + WLMCFG_ENUM("WindowToggleFullscreen", WLMAKER_ACTION_WINDOW_TOGGLE_FULLSCREEN), + WLMCFG_ENUM("WindowToggleMaximized", WLMAKER_ACTION_WINDOW_TOGGLE_MAXIMIZED), + + WLMCFG_ENUM("WindowMaximize", WLMAKER_ACTION_WINDOW_MAXIMIZE), + WLMCFG_ENUM("WindowUnmaximize", WLMAKER_ACTION_WINDOW_UNMAXIMIZE), + WLMCFG_ENUM("WindowFullscreen", WLMAKER_ACTION_WINDOW_FULLSCREEN), + WLMCFG_ENUM("WindowShade", WLMAKER_ACTION_WINDOW_SHADE), + WLMCFG_ENUM("WindowUnshade", WLMAKER_ACTION_WINDOW_UNSHADE), WLMCFG_ENUM("RootMenu", WLMAKER_ACTION_ROOT_MENU), @@ -173,7 +179,7 @@ void wlmaker_action_unbind_keys(wlmaker_action_handle_t *handle_ptr) void wlmaker_action_execute(wlmaker_server_t *server_ptr, wlmaker_action_t action) { - wlmtk_workspace_t *workspace_ptr; + wlmtk_workspace_t *workspace_ptr, *next_workspace_ptr; wlmtk_window_t *window_ptr; switch (action) { @@ -254,6 +260,86 @@ void wlmaker_action_execute(wlmaker_server_t *server_ptr, } break; + case WLMAKER_ACTION_WINDOW_MAXIMIZE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_maximized(window_ptr, true); + } + break; + + case WLMAKER_ACTION_WINDOW_UNMAXIMIZE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_maximized(window_ptr, false); + } + break; + + case WLMAKER_ACTION_WINDOW_FULLSCREEN: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_fullscreen(window_ptr, true); + } + break; + + case WLMAKER_ACTION_WINDOW_SHADE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_shaded(window_ptr, true); + } + break; + + case WLMAKER_ACTION_WINDOW_UNSHADE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_shaded(window_ptr, false); + } + break; + + case WLMAKER_ACTION_WINDOW_TO_NEXT_WORKSPACE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + next_workspace_ptr = wlmtk_workspace_from_dlnode( + wlmtk_dlnode_from_workspace(workspace_ptr)->next_ptr); + if (NULL != window_ptr && + NULL != next_workspace_ptr) { + wlmtk_workspace_unmap_window(workspace_ptr, window_ptr); + wlmtk_workspace_map_window(next_workspace_ptr, window_ptr); + } + break; + + case WLMAKER_ACTION_WINDOW_TO_PREVIOUS_WORKSPACE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + next_workspace_ptr = wlmtk_workspace_from_dlnode( + wlmtk_dlnode_from_workspace(workspace_ptr)->prev_ptr); + if (NULL != window_ptr && + NULL != next_workspace_ptr) { + wlmtk_workspace_unmap_window(workspace_ptr, window_ptr); + wlmtk_workspace_map_window(next_workspace_ptr, window_ptr); + } + break; + + case WLMAKER_ACTION_WINDOW_CLOSE: + workspace_ptr = wlmtk_root_get_current_workspace( + server_ptr->root_ptr); + window_ptr = wlmtk_workspace_get_activated_window(workspace_ptr); + if (NULL != window_ptr) { + wlmtk_window_request_close(window_ptr); + } + break; + case WLMAKER_ACTION_ROOT_MENU: if (NULL == server_ptr->root_menu_ptr) { server_ptr->root_menu_ptr = wlmaker_root_menu_create( diff --git a/src/action.h b/src/action.h index 988296dd..f76cd316 100644 --- a/src/action.h +++ b/src/action.h @@ -47,6 +47,15 @@ typedef enum { WLMAKER_ACTION_WINDOW_TOGGLE_FULLSCREEN, WLMAKER_ACTION_WINDOW_TOGGLE_MAXIMIZED, + WLMAKER_ACTION_WINDOW_MAXIMIZE, + WLMAKER_ACTION_WINDOW_UNMAXIMIZE, + WLMAKER_ACTION_WINDOW_FULLSCREEN, + WLMAKER_ACTION_WINDOW_SHADE, + WLMAKER_ACTION_WINDOW_UNSHADE, + WLMAKER_ACTION_WINDOW_CLOSE, + WLMAKER_ACTION_WINDOW_TO_NEXT_WORKSPACE, + WLMAKER_ACTION_WINDOW_TO_PREVIOUS_WORKSPACE, + WLMAKER_ACTION_ROOT_MENU, // Note: Keep these numbered consecutively. diff --git a/src/xdg_toplevel.c b/src/xdg_toplevel.c index 8702f0f5..de294588 100644 --- a/src/xdg_toplevel.c +++ b/src/xdg_toplevel.c @@ -158,8 +158,14 @@ const wlmtk_content_vmt_t _xdg_toplevel_content_vmt = { /** Menu items for the XDG toplevel's window menu. */ static const wlmaker_window_menu_item_t _xdg_toplevel_menu_items[] = { - { "Maximize", WLMAKER_ACTION_WINDOW_TOGGLE_MAXIMIZED }, + { "Maximize", WLMAKER_ACTION_WINDOW_MAXIMIZE }, + { "Unmaximize", WLMAKER_ACTION_WINDOW_UNMAXIMIZE }, { "Fullscreen", WLMAKER_ACTION_WINDOW_TOGGLE_FULLSCREEN }, + { "Shade", WLMAKER_ACTION_WINDOW_SHADE }, + { "Unshade", WLMAKER_ACTION_WINDOW_UNSHADE }, + { "To prev. workspace", WLMAKER_ACTION_WINDOW_TO_PREVIOUS_WORKSPACE }, + { "To next workspace", WLMAKER_ACTION_WINDOW_TO_NEXT_WORKSPACE }, + { "Close", WLMAKER_ACTION_WINDOW_CLOSE }, { NULL, 0 } // Sentinel. };