From da37e97a450d5e094a58dcd34c729c937ba01b30 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 6 Apr 2026 22:05:37 +0100 Subject: [PATCH] Add action `ToggleShowDesktop` --- docs/labwc-actions.5.scd | 7 ++++ include/show-desktop.h | 8 +++++ include/view.h | 1 + src/action.c | 5 +++ src/desktop.c | 3 ++ src/meson.build | 1 + src/show-desktop.c | 78 ++++++++++++++++++++++++++++++++++++++++ src/workspaces.c | 3 ++ 8 files changed, 106 insertions(+) create mode 100644 include/show-desktop.h create mode 100644 src/show-desktop.c diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index a70c0086..de1dc00d 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -424,6 +424,13 @@ Actions are used in menus and keyboard/mouse bindings. Toggle the screen magnifier on or off at the last magnification level used. +** + Minimize all windows in the current workspace so that the desktop becomes + visible. On calling the action again the hidden windows are unminimized, + provided that - since the initial `ShowDesktop` - (a) no windows have been + unminimized; (b) workspaces have not been switched; and (c) no new + applications have been started. + **++ ** Increase or decrease the magnification level for the screen magnifier. diff --git a/include/show-desktop.h b/include/show-desktop.h new file mode 100644 index 00000000..cc86bcb4 --- /dev/null +++ b/include/show-desktop.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_SHOW_DESKTOP_H +#define LABWC_SHOW_DESKTOP_H + +void show_desktop_toggle(void); +void show_desktop_reset(void); + +#endif /* LABWC_SHOW_DESKTOP_H */ diff --git a/include/view.h b/include/view.h index c2764f94..da7aef02 100644 --- a/include/view.h +++ b/include/view.h @@ -184,6 +184,7 @@ struct view { enum ssd_preference ssd_preference; bool shaded; bool minimized; + bool was_minimized_by_show_desktop_action; enum view_axis maximized; bool fullscreen; bool tearing_hint; diff --git a/src/action.c b/src/action.c index 2cfa6be6..34435e02 100644 --- a/src/action.c +++ b/src/action.c @@ -28,6 +28,7 @@ #include "output.h" #include "output-virtual.h" #include "regions.h" +#include "show-desktop.h" #include "ssd.h" #include "theme.h" #include "translate.h" @@ -133,6 +134,7 @@ struct action_arg_list { X(TOGGLE_MAGNIFY, "ToggleMagnify") \ X(ZOOM_IN, "ZoomIn") \ X(ZOOM_OUT, "ZoomOut") \ + X(TOGGLE_SHOW_DESKTOP, "ToggleShowDesktop") \ X(WARP_CURSOR, "WarpCursor") \ X(HIDE_CURSOR, "HideCursor") \ X(DEBUG_TOGGLE_KEY_STATE_INDICATOR, "DebugToggleKeyStateIndicator") @@ -1562,6 +1564,9 @@ run_action(struct view *view, struct action *action, case ACTION_TYPE_ZOOM_OUT: magnifier_set_scale(MAGNIFY_DECREASE); break; + case ACTION_TYPE_TOGGLE_SHOW_DESKTOP: + show_desktop_toggle(); + break; case ACTION_TYPE_WARP_CURSOR: { const char *to = action_get_str(action, "to", "output"); const char *x = action_get_str(action, "x", "center"); diff --git a/src/desktop.c b/src/desktop.c index 28bf4464..4c7870f1 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -14,6 +14,7 @@ #include "layers.h" #include "node.h" #include "output.h" +#include "show-desktop.h" #include "ssd.h" #include "view.h" #include "workspaces.h" @@ -113,6 +114,8 @@ desktop_focus_view(struct view *view, bool raise) */ struct view *dialog = view_get_modal_dialog(view); set_or_offer_focus(dialog ? dialog : view); + + show_desktop_reset(); } /* TODO: focus layer-shell surfaces also? */ diff --git a/src/meson.build b/src/meson.build index 40ec3170..05163cfa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,6 +22,7 @@ labwc_sources = files( 'seat.c', 'server.c', 'session-lock.c', + 'show-desktop.c', 'snap-constraints.c', 'snap.c', 'tearing.c', diff --git a/src/show-desktop.c b/src/show-desktop.c new file mode 100644 index 00000000..efddf2de --- /dev/null +++ b/src/show-desktop.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include "show-desktop.h" +#include +#include "common/array.h" +#include "config/types.h" +#include "labwc.h" +#include "view.h" + +static bool is_showing_desktop; + +static void +minimize_views(struct wl_array *views, bool minimize) +{ + struct view **view; + wl_array_for_each_reverse(view, views) { + view_minimize(*view, minimize); + } +} + +static void +show(void) +{ + static struct wl_array views; + wl_array_init(&views); + + /* Build array first as minimize changes server.views */ + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + if (view->minimized) { + continue; + } + view->was_minimized_by_show_desktop_action = true; + array_add(&views, view); + } + minimize_views(&views, true); + is_showing_desktop = true; + + wl_array_release(&views); +} + +static void +restore(void) +{ + static struct wl_array views; + wl_array_init(&views); + + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + if (view->was_minimized_by_show_desktop_action) { + array_add(&views, view); + } + } + minimize_views(&views, false); + show_desktop_reset(); + + wl_array_release(&views); +} + +void +show_desktop_toggle(void) +{ + if (is_showing_desktop) { + restore(); + } else { + show(); + } +} + +void +show_desktop_reset(void) +{ + is_showing_desktop = false; + + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) { + view->was_minimized_by_show_desktop_action = false; + } +} diff --git a/src/workspaces.c b/src/workspaces.c index 7ff471a5..a1ed9112 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -21,6 +21,7 @@ #include "input/keyboard.h" #include "labwc.h" #include "output.h" +#include "show-desktop.h" #include "theme.h" #include "view.h" @@ -495,6 +496,8 @@ workspaces_switch_to(struct workspace *target, bool update_focus) desktop_update_top_layer_visibility(); wlr_ext_workspace_handle_v1_set_active(target->ext_workspace, true); + + show_desktop_reset(); } void