action: fix menu position with "x"/"y" arguments in multi-monitor setup

Prior to this commit, output-relative coordinate was passed to
menu_open_root() as the menu position when it's designated via "x"/"y"
arguments in ShowMenu action, so menu can be misplaced to the output other
than the one in which the cursor is in.
This commit is contained in:
tokyo4j 2024-12-08 17:59:56 +09:00 committed by Johan Malm
parent 21bd5b0025
commit 5e422a0bc2
2 changed files with 12 additions and 10 deletions

View file

@ -397,6 +397,7 @@ struct output {
struct wlr_scene_tree *osd_tree; struct wlr_scene_tree *osd_tree;
struct wlr_scene_tree *session_lock_tree; struct wlr_scene_tree *session_lock_tree;
struct wlr_scene_buffer *workspace_osd; struct wlr_scene_buffer *workspace_osd;
/* In output-relative scene coordinates */
struct wlr_box usable_area; struct wlr_box usable_area;
struct wl_list regions; /* struct region.link */ struct wl_list regions; /* struct region.link */

View file

@ -688,40 +688,41 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx,
if (pos_x && pos_y) { if (pos_x && pos_y) {
struct output *output = output_nearest_to(server, struct output *output = output_nearest_to(server,
server->seat.cursor->x, server->seat.cursor->y); server->seat.cursor->x, server->seat.cursor->y);
struct wlr_box usable = output_usable_area_in_layout_coords(output);
if (!strcasecmp(pos_x, "center")) { if (!strcasecmp(pos_x, "center")) {
x = (output->usable_area.width - menu->size.width) / 2; x = (usable.width - menu->size.width) / 2;
} else if (strchr(pos_x, '%')) { } else if (strchr(pos_x, '%')) {
x = (output->usable_area.width * atoi(pos_x)) / 100; x = (usable.width * atoi(pos_x)) / 100;
} else { } else {
if (pos_x[0] == '-') { if (pos_x[0] == '-') {
int neg_x = strtol(pos_x, NULL, 10); int neg_x = strtol(pos_x, NULL, 10);
x = output->usable_area.width + neg_x; x = usable.width + neg_x;
} else { } else {
x = atoi(pos_x); x = atoi(pos_x);
} }
} }
if (!strcasecmp(pos_y, "center")) { if (!strcasecmp(pos_y, "center")) {
y = (output->usable_area.height / 2) - (menu->size.height / 2); y = (usable.height / 2) - (menu->size.height / 2);
} else if (strchr(pos_y, '%')) { } else if (strchr(pos_y, '%')) {
y = (output->usable_area.height * atoi(pos_y)) / 100; y = (usable.height * atoi(pos_y)) / 100;
} else { } else {
if (pos_y[0] == '-') { if (pos_y[0] == '-') {
int neg_y = strtol(pos_y, NULL, 10); int neg_y = strtol(pos_y, NULL, 10);
y = output->usable_area.height + neg_y; y = usable.height + neg_y;
} else { } else {
y = atoi(pos_y); y = atoi(pos_y);
} }
} }
/* keep menu from being off screen */ /* keep menu from being off screen */
x = MAX(x, 0); x = MAX(x, 0);
x = MIN(x, output->usable_area.width - 1); x = MIN(x, usable.width - 1);
y = MAX(y, 0); y = MAX(y, 0);
y = MIN(y, output->usable_area.height - 1); y = MIN(y, usable.height - 1);
/* adjust for which monitor to appear on */ /* adjust for which monitor to appear on */
x += output->usable_area.x; x += usable.x;
y += output->usable_area.y; y += usable.y;
} }
/* Replaced by next show_menu() or cleaned on view_destroy() */ /* Replaced by next show_menu() or cleaned on view_destroy() */