This commit is contained in:
Johan Malm 2026-06-13 18:55:57 +02:00 committed by GitHub
commit f503a5b8a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 4 deletions

View file

@ -77,6 +77,18 @@ Actions are used in menus and keyboard/mouse bindings.
*<action name="MoveTo" x="" y="" />*
Move to position (x, y).
*x* and *y* take the following types of value:
- A positive number like *10*. This will position the window at the
specified distance (in pixels) from the top/left edge of the output
(monitor).
- A negative number like *-5* which will similarly position the window
but relative to the bottom/right edge.
- The string *center* which will center the window relative to the
output in that dimension
- A percentage like *33%* which is interpreted as a relative value of
the output dimensions and will position the window by that amount
from the top/left edge.
*<action name="ResizeTo" width="" height="" />*
Resize window.

View file

@ -447,6 +447,11 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
}
break;
case ACTION_TYPE_MOVETO:
if (!strcmp(argument, "x") || !strcmp(argument, "y")) {
action_arg_add_str(action, argument, content);
goto cleanup;
}
break;
case ACTION_TYPE_MOVE_RELATIVE:
if (!strcmp(argument, "x") || !strcmp(argument, "y")) {
action_arg_add_int(action, argument, atoi(content));
@ -1054,6 +1059,54 @@ warp_cursor(struct view *view, const char *to, const char *x, const char *y)
cursor_update_focus();
}
struct point {
int x;
int y;
};
static struct point
get_moveto_point(struct view *view, const char *pos_x, const char *pos_y)
{
struct point point = { 0 };
struct border margin = ssd_thickness(view);
struct wlr_box max_extents = ssd_max_extents(view);
struct wlr_box usable = output_usable_area_in_layout_coords(view->output);
point.x += usable.x;
point.y += usable.y;
/* Parse horizontal position */
if (!strcasecmp(pos_x, "center")) {
point.x += (usable.width - max_extents.width) / 2;
point.x += margin.left;
} else if (strchr(pos_x, '%')) {
point.x += (usable.width * atoi(pos_x)) / 100;
point.x += margin.left;
} else if (pos_x[0] == '-') {
point.x += usable.width - view->current.width + strtol(pos_x, NULL, 10);
point.x -= margin.right;
} else {
point.x += atoi(pos_x);
point.x += margin.left;
}
/* Parse veritcal position */
if (!strcasecmp(pos_y, "center")) {
point.y += (usable.height - max_extents.height) / 2;
point.y += margin.top;
} else if (strchr(pos_y, '%')) {
point.y += (usable.height * atoi(pos_y)) / 100;
point.y += margin.top;
} else if (pos_y[0] == '-') {
point.y += usable.height - view->current.height + strtol(pos_y, NULL, 10);
point.y -= margin.bottom;
} else {
point.y += atoi(pos_y);
point.y += margin.top;
}
return point;
}
static void
run_action(struct view *view, struct action *action,
struct cursor_context *ctx)
@ -1299,10 +1352,10 @@ run_action(struct view *view, struct action *action,
break;
case ACTION_TYPE_MOVETO:
if (view) {
int x = action_get_int(action, "x", 0);
int y = action_get_int(action, "y", 0);
struct border margin = ssd_thickness(view);
view_move(view, x + margin.left, y + margin.top);
const char *x = action_get_str(action, "x", "0");
const char *y = action_get_str(action, "y", "0");
struct point point = get_moveto_point(view, x, y);
view_move(view, point.x, point.y);
}
break;
case ACTION_TYPE_RESIZETO: