From 5e422a0bc2f2f8cb14d154f6891859ae330e9d75 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sun, 8 Dec 2024 17:59:56 +0900 Subject: [PATCH] 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. --- include/labwc.h | 1 + src/action.c | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index b02868a6..ef5d9c03 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -397,6 +397,7 @@ struct output { struct wlr_scene_tree *osd_tree; struct wlr_scene_tree *session_lock_tree; struct wlr_scene_buffer *workspace_osd; + /* In output-relative scene coordinates */ struct wlr_box usable_area; struct wl_list regions; /* struct region.link */ diff --git a/src/action.c b/src/action.c index 9da1b796..fdce2b4f 100644 --- a/src/action.c +++ b/src/action.c @@ -688,40 +688,41 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx, if (pos_x && pos_y) { struct output *output = output_nearest_to(server, server->seat.cursor->x, server->seat.cursor->y); + struct wlr_box usable = output_usable_area_in_layout_coords(output); 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, '%')) { - x = (output->usable_area.width * atoi(pos_x)) / 100; + x = (usable.width * atoi(pos_x)) / 100; } else { if (pos_x[0] == '-') { int neg_x = strtol(pos_x, NULL, 10); - x = output->usable_area.width + neg_x; + x = usable.width + neg_x; } else { x = atoi(pos_x); } } 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, '%')) { - y = (output->usable_area.height * atoi(pos_y)) / 100; + y = (usable.height * atoi(pos_y)) / 100; } else { if (pos_y[0] == '-') { int neg_y = strtol(pos_y, NULL, 10); - y = output->usable_area.height + neg_y; + y = usable.height + neg_y; } else { y = atoi(pos_y); } } /* keep menu from being off screen */ x = MAX(x, 0); - x = MIN(x, output->usable_area.width - 1); + x = MIN(x, usable.width - 1); 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 */ - x += output->usable_area.x; - y += output->usable_area.y; + x += usable.x; + y += usable.y; } /* Replaced by next show_menu() or cleaned on view_destroy() */