From bb1d0b4352949943045d41ee0d818a1ff7487875 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Wed, 29 May 2024 11:06:39 +0900 Subject: [PATCH] Implement [yes|no] configures whether to let the clients redraw its window content content while resizing. When is set to no, a multi-rect is shown to indicate the geometry of the resized window. --- docs/labwc-config.5.scd | 5 ++++ docs/rc.xml.all | 8 ++++-- include/config/rcxml.h | 1 + include/resize-outlines.h | 13 +++++++++ include/view.h | 4 +++ src/config/rcxml.c | 3 ++ src/input/cursor.c | 10 ++++++- src/meson.build | 1 + src/resize-outlines.c | 56 ++++++++++++++++++++++++++++++++++++++ src/ssd/resize-indicator.c | 24 ++++++++++------ 10 files changed, 113 insertions(+), 12 deletions(-) create mode 100644 include/resize-outlines.h create mode 100644 src/resize-outlines.c diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 2f663820..f2088771 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -456,6 +456,11 @@ extending outward from the snapped edge. Default is Never. +** [yes|no] + Let the application redraw its contents while resizing. If disabled, an + outlined rectangle is shown to indicate the geometry of resized window. + Default is yes. + ## KEYBOARD ** [on|off] diff --git a/docs/rc.xml.all b/docs/rc.xml.all index a4e70efb..35e5c91b 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -103,8 +103,12 @@ 20 - - + + + Never + + yes + no diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 1ebfddee..8df7c9aa 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -118,6 +118,7 @@ struct rcxml { enum tiling_events_mode snap_tiling_events_mode; enum resize_indicator_mode resize_indicator; + bool resize_draw_contents; struct { int popuptime; diff --git a/include/resize-outlines.h b/include/resize-outlines.h new file mode 100644 index 00000000..f4613a4a --- /dev/null +++ b/include/resize-outlines.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_RESIZE_OUTLINES_H +#define LABWC_RESIZE_OUTLINES_H + +#include + +struct view; + +void resize_outlines_update(struct view *view, struct wlr_box new_geo); +void resize_outlines_finish(struct view *view); +bool resize_outlines_enabled(struct view *view); + +#endif /* LABWC_RESIZE_OUTLINES_H */ diff --git a/include/view.h b/include/view.h index 141038d3..b21d7ca2 100644 --- a/include/view.h +++ b/include/view.h @@ -238,6 +238,10 @@ struct view { struct wlr_scene_rect *background; struct scaled_font_buffer *text; } resize_indicator; + struct resize_outlines { + struct wlr_box view_geo; + struct multi_rect *rect; + } resize_outlines; struct foreign_toplevel { struct wlr_foreign_toplevel_handle_v1 *handle; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 0a5d225d..0ff52bf3 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1032,6 +1032,8 @@ entry(xmlNode *node, char *nodename, char *content) } else { wlr_log(WLR_ERROR, "Invalid value for "); } + } else if (!strcasecmp(nodename, "drawContents.resize")) { + set_bool(content, &rc.resize_draw_contents); } else if (!strcasecmp(nodename, "mouseEmulation.tablet")) { set_bool(content, &rc.tablet.force_mouse_emulation); } else if (!strcasecmp(nodename, "mapToOutput.tablet")) { @@ -1271,6 +1273,7 @@ rcxml_init(void) | LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER; rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER; + rc.resize_draw_contents = true; rc.workspace_config.popuptime = INT_MIN; rc.workspace_config.min_nr_workspaces = 1; diff --git a/src/input/cursor.c b/src/input/cursor.c index 3e3c0003..3c144154 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -24,6 +24,7 @@ #include "menu/menu.h" #include "regions.h" #include "resistance.h" +#include "resize-outlines.h" #include "ssd.h" #include "view.h" #include "xwayland.h" @@ -306,7 +307,11 @@ process_cursor_resize(struct server *server, uint32_t time) server->grab_box.width - new_view_geo.width; } - view_move_resize(view, new_view_geo); + if (rc.resize_draw_contents) { + view_move_resize(view, new_view_geo); + } else { + resize_outlines_update(view, new_view_geo); + } } void @@ -1134,6 +1139,9 @@ cursor_finish_button_release(struct seat *seat) if (server->input_mode == LAB_INPUT_STATE_MOVE || server->input_mode == LAB_INPUT_STATE_RESIZE) { + if (resize_outlines_enabled(server->grabbed_view)) { + resize_outlines_finish(server->grabbed_view); + } /* Exit interactive move/resize mode */ interactive_finish(server->grabbed_view); return true; diff --git a/src/meson.build b/src/meson.build index c88e6bc1..bc69eec4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -20,6 +20,7 @@ labwc_sources = files( 'placement.c', 'regions.c', 'resistance.c', + 'resize-outlines.c', 'seat.c', 'server.c', 'session-lock.c', diff --git a/src/resize-outlines.c b/src/resize-outlines.c new file mode 100644 index 00000000..fbb10c73 --- /dev/null +++ b/src/resize-outlines.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include "common/graphic-helpers.h" +#include "ssd.h" +#include "resize-outlines.h" +#include "labwc.h" + +bool +resize_outlines_enabled(struct view *view) +{ + return view->resize_outlines.rect + && view->resize_outlines.rect->tree->node.enabled; +} + +void +resize_outlines_update(struct view *view, struct wlr_box new_geo) +{ + struct resize_outlines *outlines = &view->resize_outlines; + + if (!outlines->rect) { + float *colors[3] = { + view->server->theme->osd_bg_color, + view->server->theme->osd_label_text_color, + view->server->theme->osd_bg_color, + }; + int width = 1; + outlines->rect = multi_rect_create( + view->scene_tree, colors, width); + } + + struct border margin = ssd_get_margin(view->ssd); + struct wlr_box box = { + .x = new_geo.x - margin.left, + .y = new_geo.y - margin.top, + .width = new_geo.width + margin.left + margin.right, + .height = new_geo.height + margin.top + margin.bottom, + }; + multi_rect_set_size(outlines->rect, box.width, box.height); + wlr_scene_node_set_position(&outlines->rect->tree->node, + box.x - view->current.x, box.y - view->current.y); + wlr_scene_node_set_enabled( + &view->resize_outlines.rect->tree->node, true); + + outlines->view_geo = new_geo; + + resize_indicator_update(view); +} + +void +resize_outlines_finish(struct view *view) +{ + view_move_resize(view, view->resize_outlines.view_geo); + wlr_scene_node_set_enabled( + &view->resize_outlines.rect->tree->node, false); +} diff --git a/src/ssd/resize-indicator.c b/src/ssd/resize-indicator.c index d0fbb8e5..e372ba01 100644 --- a/src/ssd/resize-indicator.c +++ b/src/ssd/resize-indicator.c @@ -7,6 +7,7 @@ #include "common/scaled-font-buffer.h" #include "labwc.h" #include "resize-indicator.h" +#include "resize-outlines.h" #include "view.h" static void @@ -159,25 +160,30 @@ resize_indicator_update(struct view *view) char text[32]; /* 12345 x 12345 would be 13 chars + 1 null byte */ - int eff_height = view_effective_height(view, /* use_pending */ false); - int eff_width = view->current.width; + struct wlr_box view_box; + if (resize_outlines_enabled(view)) { + view_box = view->resize_outlines.view_geo; + } else { + view_box = view->current; + view_box.height = view_effective_height(view, /* use_pending */ false); + } switch (view->server->input_mode) { case LAB_INPUT_STATE_RESIZE: ; /* works around "a label can only be part of a statement" */ struct view_size_hints hints = view_get_size_hints(view); snprintf(text, sizeof(text), "%d x %d", - MAX(0, eff_width - hints.base_width) + MAX(0, view_box.width - hints.base_width) / MAX(1, hints.width_inc), - MAX(0, eff_height - hints.base_height) + MAX(0, view_box.height - hints.base_height) / MAX(1, hints.height_inc)); break; case LAB_INPUT_STATE_MOVE: ; /* works around "a label can only be part of a statement" */ struct border margin = ssd_get_margin(view->ssd); snprintf(text, sizeof(text), "%d , %d", - view->current.x - margin.left, - view->current.y - margin.top); + view_box.x - margin.left, + view_box.y - margin.top); break; default: wlr_log(WLR_ERROR, "Invalid input mode for indicator update %u", @@ -194,9 +200,9 @@ resize_indicator_update(struct view *view) resize_indicator_set_size(indicator, width); /* Center the indicator in the window */ - wlr_scene_node_set_position(&indicator->tree->node, - (eff_width - indicator->width) / 2, - (eff_height - indicator->height) / 2); + int x = view_box.x - view->current.x + (view_box.width - indicator->width) / 2; + int y = view_box.y - view->current.y + (view_box.height - indicator->height) / 2; + wlr_scene_node_set_position(&indicator->tree->node, x, y); scaled_font_buffer_update(indicator->text, text, width, &rc.font_osd, rc.theme->osd_label_text_color, rc.theme->osd_bg_color,