From 7585c7c26a0ce9cece6b160047872b43260fcb4d Mon Sep 17 00:00:00 2001
From: Consolatis <35009135+Consolatis@users.noreply.github.com>
Date: Sat, 11 Jun 2022 00:19:31 +0200
Subject: [PATCH] [wip] Add MoveResizeTo
Loosely based on http://openbox.org/wiki/Help:Actions#MoveResizeTo
Only allows to use percent values for x, y, width and height attributes.
Does not support `monitor` argument.
Example config:
```xml
```
Partly fixes #386
---
include/labwc.h | 2 ++
src/action.c | 13 +++++++++++++
src/config/rcxml.c | 25 +++++++++++++++++++++++++
src/view.c | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+)
diff --git a/include/labwc.h b/include/labwc.h
index 0af693ea..09413391 100644
--- a/include/labwc.h
+++ b/include/labwc.h
@@ -435,6 +435,8 @@ void view_adjust_for_layout_change(struct view *view);
void view_discover_output(struct view *view);
void view_move_to_edge(struct view *view, const char *direction);
void view_snap_to_edge(struct view *view, const char *direction);
+void view_rel_move_resize_to(struct view *view, struct wlr_box *rel_box);
+
const char *view_get_string_prop(struct view *view, const char *prop);
void view_update_title(struct view *view);
void view_update_app_id(struct view *view);
diff --git a/src/action.c b/src/action.c
index 15970df1..63c91c10 100644
--- a/src/action.c
+++ b/src/action.c
@@ -2,6 +2,7 @@
#define _POSIX_C_SOURCE 200809L
#include
#include
+#include
#include
#include
#include
@@ -38,6 +39,7 @@ enum action_type {
ACTION_TYPE_RESIZE,
ACTION_TYPE_GO_TO_DESKTOP,
ACTION_TYPE_SEND_TO_DESKTOP,
+ ACTION_TYPE_MOVE_RESIZE_TO,
};
const char *action_names[] = {
@@ -63,6 +65,7 @@ const char *action_names[] = {
"Resize",
"GoToDesktop",
"SendToDesktop",
+ "MoveResizeTo",
NULL
};
@@ -336,6 +339,16 @@ actions_run(struct view *activator, struct server *server,
}
}
break;
+ case ACTION_TYPE_MOVE_RESIZE_TO:
+ if (!arg) {
+ wlr_log(WLR_ERROR, "Missing argument for MoveResizeTo");
+ break;
+ }
+ if (view) {
+ struct wlr_box *box = action_box_from_arg(arg);
+ view_rel_move_resize_to(view, box);
+ }
+ break;
case ACTION_TYPE_NONE:
wlr_log(WLR_ERROR, "Not executing unknown action");
break;
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index 1d950f7a..14168bcd 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -32,6 +32,7 @@ static struct libinput_category *current_libinput_category;
static const char *current_mouse_context;
static struct action *current_keybind_action;
static struct action *current_mousebind_action;
+static struct wlr_box *current_action_box;
enum font_place {
FONT_PLACE_UNKNOWN = 0,
@@ -43,6 +44,21 @@ enum font_place {
static void load_default_key_bindings(void);
+static void
+fill_geo(char *key, char *content)
+{
+ assert(current_action_box);
+ if (!strcmp(key, "x.action")) {
+ current_action_box->x = atoi(content);
+ } else if (!strcmp(key, "y.action")) {
+ current_action_box->y = atoi(content);
+ } else if (!strcmp(key, "width.action")) {
+ current_action_box->width = atoi(content);
+ } else if (!strcmp(key, "height.action")) {
+ current_action_box->height = atoi(content);
+ }
+}
+
static void
fill_keybind(char *nodename, char *content)
{
@@ -68,6 +84,12 @@ fill_keybind(char *nodename, char *content)
current_keybind_action = action_create(content);
wl_list_insert(current_keybind->actions.prev,
¤t_keybind_action->link);
+ if (!strcmp(content, "MoveResizeTo")) {
+ current_action_box = action_arg_add_box(
+ current_keybind_action, NULL);
+ } else {
+ current_action_box = NULL;
+ }
} else if (!current_keybind_action) {
wlr_log(WLR_ERROR, "expect element first. "
"nodename: '%s' content: '%s'", nodename, content);
@@ -83,6 +105,9 @@ fill_keybind(char *nodename, char *content)
} else if (!strcmp(nodename, "to.action")) {
/* GoToDesktop, SendToDesktop */
action_arg_add_str(current_keybind_action, NULL, content);
+ } else if (current_action_box) {
+ /* MoveResizeTo */
+ fill_geo(nodename, content);
}
}
diff --git a/src/view.c b/src/view.c
index 6288d671..6f0c9c7b 100644
--- a/src/view.c
+++ b/src/view.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
#include
+#include
#include
#include
#include
@@ -658,6 +659,41 @@ view_edge_parse(const char *direction)
}
}
+/* Move and resize view based on percent output local values in rel_box */
+void
+view_rel_move_resize_to(struct view *view, struct wlr_box *rel_box)
+{
+ assert(view);
+ assert(rel_box);
+
+ struct output *output = view_output(view);
+ if (!output) {
+ return;
+ }
+ struct wlr_box usable = output_usable_area_in_layout_coords(output);
+
+ /* Calculate new size and position */
+ struct wlr_box new_geo = { view->x, view->y, view->w, view->h };
+ if (rel_box->x != INT_MIN) {
+ new_geo.x = usable.width * rel_box->x / 100;
+ new_geo.x += usable.x + view->margin.left;
+ }
+ if (rel_box->y != INT_MIN) {
+ new_geo.y = usable.height * rel_box->y / 100;
+ new_geo.y += usable.y + view->margin.top;
+ }
+ if (rel_box->width != INT_MIN) {
+ new_geo.width = usable.width * rel_box->width / 100;
+ new_geo.width -= view->margin.left + view->margin.right;
+ }
+ if (rel_box->height != INT_MIN) {
+ new_geo.height = usable.height * rel_box->height / 100;
+ new_geo.height -= view->margin.top + view->margin.bottom;
+ }
+
+ view_move_resize(view, new_geo);
+}
+
void
view_snap_to_edge(struct view *view, const char *direction)
{