[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
<!-- Resize via W-Numpad -->
<keybind key="W-KP_1">
    <action name="MoveResizeTo" x="0%" y="50%" height="50%" width="50%" />
</keybind>
<keybind key="W-KP_2">
    <action name="MoveResizeTo" x="0%" y="50%" height="50%" width="100%" />
</keybind>
<keybind key="W-KP_3">
    <action name="MoveResizeTo" x="50%" y="50%" height="50%" width="50%" />
</keybind>
<keybind key="W-KP_4">
    <action name="MoveResizeTo" x="0%" y="0%" height="100%" width="50%" />
</keybind>
<keybind key="W-KP_5">
    <action name="MoveResizeTo" />
</keybind>
<keybind key="W-KP_6">
    <action name="MoveResizeTo" x="50%" y="0%" height="100%" width="50%" />
</keybind>
<keybind key="W-KP_7">
    <action name="MoveResizeTo" x="0%" y="0%" height="50%" width="50%" />
</keybind>
<keybind key="W-KP_8">
    <action name="MoveResizeTo" x="0%" y="0%" height="50%" width="100%" />
</keybind>
<keybind key="W-KP_9">
    <action name="MoveResizeTo" x="50%" y="0%" height="50%" width="50%" />
</keybind>
```

Partly fixes #386
This commit is contained in:
Consolatis 2022-06-11 00:19:31 +02:00
parent a0e22d5e07
commit 7585c7c26a
4 changed files with 76 additions and 0 deletions

View file

@ -435,6 +435,8 @@ void view_adjust_for_layout_change(struct view *view);
void view_discover_output(struct view *view); void view_discover_output(struct view *view);
void view_move_to_edge(struct view *view, const char *direction); void view_move_to_edge(struct view *view, const char *direction);
void view_snap_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); const char *view_get_string_prop(struct view *view, const char *prop);
void view_update_title(struct view *view); void view_update_title(struct view *view);
void view_update_app_id(struct view *view); void view_update_app_id(struct view *view);

View file

@ -2,6 +2,7 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <assert.h> #include <assert.h>
#include <signal.h> #include <signal.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <unistd.h> #include <unistd.h>
@ -38,6 +39,7 @@ enum action_type {
ACTION_TYPE_RESIZE, ACTION_TYPE_RESIZE,
ACTION_TYPE_GO_TO_DESKTOP, ACTION_TYPE_GO_TO_DESKTOP,
ACTION_TYPE_SEND_TO_DESKTOP, ACTION_TYPE_SEND_TO_DESKTOP,
ACTION_TYPE_MOVE_RESIZE_TO,
}; };
const char *action_names[] = { const char *action_names[] = {
@ -63,6 +65,7 @@ const char *action_names[] = {
"Resize", "Resize",
"GoToDesktop", "GoToDesktop",
"SendToDesktop", "SendToDesktop",
"MoveResizeTo",
NULL NULL
}; };
@ -336,6 +339,16 @@ actions_run(struct view *activator, struct server *server,
} }
} }
break; 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: case ACTION_TYPE_NONE:
wlr_log(WLR_ERROR, "Not executing unknown action"); wlr_log(WLR_ERROR, "Not executing unknown action");
break; break;

View file

@ -32,6 +32,7 @@ static struct libinput_category *current_libinput_category;
static const char *current_mouse_context; static const char *current_mouse_context;
static struct action *current_keybind_action; static struct action *current_keybind_action;
static struct action *current_mousebind_action; static struct action *current_mousebind_action;
static struct wlr_box *current_action_box;
enum font_place { enum font_place {
FONT_PLACE_UNKNOWN = 0, FONT_PLACE_UNKNOWN = 0,
@ -43,6 +44,21 @@ enum font_place {
static void load_default_key_bindings(void); 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 static void
fill_keybind(char *nodename, char *content) fill_keybind(char *nodename, char *content)
{ {
@ -68,6 +84,12 @@ fill_keybind(char *nodename, char *content)
current_keybind_action = action_create(content); current_keybind_action = action_create(content);
wl_list_insert(current_keybind->actions.prev, wl_list_insert(current_keybind->actions.prev,
&current_keybind_action->link); &current_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) { } else if (!current_keybind_action) {
wlr_log(WLR_ERROR, "expect <action name=\"\"> element first. " wlr_log(WLR_ERROR, "expect <action name=\"\"> element first. "
"nodename: '%s' content: '%s'", nodename, content); "nodename: '%s' content: '%s'", nodename, content);
@ -83,6 +105,9 @@ fill_keybind(char *nodename, char *content)
} else if (!strcmp(nodename, "to.action")) { } else if (!strcmp(nodename, "to.action")) {
/* GoToDesktop, SendToDesktop */ /* GoToDesktop, SendToDesktop */
action_arg_add_str(current_keybind_action, NULL, content); action_arg_add_str(current_keybind_action, NULL, content);
} else if (current_action_box) {
/* MoveResizeTo */
fill_geo(nodename, content);
} }
} }

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#include <assert.h> #include <assert.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <strings.h> #include <strings.h>
#include <xcb/xcb_icccm.h> #include <xcb/xcb_icccm.h>
@ -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 void
view_snap_to_edge(struct view *view, const char *direction) view_snap_to_edge(struct view *view, const char *direction)
{ {