diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index fe468cd1..aa524d3f 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -424,6 +424,11 @@ Actions are used in menus and keyboard/mouse bindings. Toggle the screen magnifier on or off at the last magnification level used. +** + Hide all windows in the current workspace so that the desktop is visible. On + calling the action again the hidden windows are un-minimized, as long as no + windows were un-minimized in the meantime. + **++ ** 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..2a9da708 --- /dev/null +++ b/include/show-desktop.h @@ -0,0 +1,9 @@ +/* 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); +void show_desktop_finish(void); + +#endif /* LABWC_SHOW_DESKTOP_H */ diff --git a/include/view.h b/include/view.h index c2764f94..55c8073e 100644 --- a/include/view.h +++ b/include/view.h @@ -487,6 +487,7 @@ void view_resize_relative(struct view *view, void view_move_relative(struct view *view, int x, int y); void view_move(struct view *view, int x, int y); void view_moved(struct view *view); +void view_minimize_no_show_desktop_reset(struct view *view, bool minimized); void view_minimize(struct view *view, bool minimized); bool view_compute_centered_position(struct view *view, const struct wlr_box *ref, int w, int h, int *x, int *y); diff --git a/src/action.c b/src/action.c index 66fa9b20..4bb2929b 100644 --- a/src/action.c +++ b/src/action.c @@ -27,6 +27,7 @@ #include "output.h" #include "output-virtual.h" #include "regions.h" +#include "show-desktop.h" #include "ssd.h" #include "theme.h" #include "translate.h" @@ -132,6 +133,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") @@ -1560,6 +1562,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/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/server.c b/src/server.c index fd48efed..298a36e5 100644 --- a/src/server.c +++ b/src/server.c @@ -68,6 +68,7 @@ #include "resize-indicator.h" #include "scaled-buffer/scaled-buffer.h" #include "session-lock.h" +#include "show-desktop.h" #include "ssd.h" #include "theme.h" #include "view.h" @@ -786,6 +787,8 @@ server_finish(void) wl_display_destroy_clients(server.wl_display); + show_desktop_finish(); + seat_finish(); output_finish(); xdg_shell_finish(); diff --git a/src/show-desktop.c b/src/show-desktop.c new file mode 100644 index 00000000..fe0e054d --- /dev/null +++ b/src/show-desktop.c @@ -0,0 +1,90 @@ +// 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 struct wl_array views; +static bool is_showing_desktop; + +static void +stash_unminimized_windows_on_current_workspace(void) +{ + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + if (view->minimized) { + continue; + } + array_add(&views, view); + } +} + +static void +show(void) +{ + /* + * Build array before acting on it because actions like minimize change + * server.views + */ + stash_unminimized_windows_on_current_workspace(); + + struct view **view; + wl_array_for_each(view, &views) { + view_minimize_no_show_desktop_reset(*view, true); + } + + is_showing_desktop = true; +} + +static void +restore(void) +{ + struct view **view; + wl_array_for_each_reverse(view, &views) { + if (!*view) { + continue; + } + view_minimize_no_show_desktop_reset(*view, false); + } + show_desktop_reset(); +} + +static void +init(void) +{ + static bool has_been_initialized; + if (has_been_initialized) { + return; + } + has_been_initialized = true; + wl_array_init(&views); +} + +void +show_desktop_toggle(void) +{ + init(); + if (is_showing_desktop) { + restore(); + } else { + show(); + } +} + +void +show_desktop_reset(void) +{ + init(); + wl_array_release(&views); + wl_array_init(&views); + is_showing_desktop = false; +} + +void +show_desktop_finish(void) +{ + init(); + wl_array_release(&views); +} diff --git a/src/view.c b/src/view.c index 1d43fcfa..240265b2 100644 --- a/src/view.c +++ b/src/view.c @@ -26,6 +26,7 @@ #include "regions.h" #include "resize-indicator.h" #include "session-lock.h" +#include "show-desktop.h" #include "snap-constraints.h" #include "snap.h" #include "ssd.h" @@ -782,7 +783,7 @@ minimize_sub_views(struct view *view, bool minimized, bool *need_refocus) * versa. */ void -view_minimize(struct view *view, bool minimized) +view_minimize_no_show_desktop_reset(struct view *view, bool minimized) { assert(view); bool need_refocus = false; @@ -814,6 +815,13 @@ view_minimize(struct view *view, bool minimized) } } +void +view_minimize(struct view *view, bool minimized) +{ + view_minimize_no_show_desktop_reset(view, minimized); + show_desktop_reset(); +} + bool view_compute_centered_position(struct view *view, const struct wlr_box *ref, int w, int h, int *x, int *y)