menu placement

allow placement using x,y coordinates as well as centered in the output, set globally
This commit is contained in:
Droc 2024-08-17 08:47:14 -05:00
parent 13dee64828
commit 38659ff928
5 changed files with 87 additions and 1 deletions

View file

@ -498,6 +498,21 @@ extending outward from the snapped edge.
outlined rectangle is shown to indicate the geometry of resized window.
Default is yes.
*<resize><popupPosition>* see rc.xml.all for example
Lets the menu placement be set by a fixed position or centered on
screen. If set then the atCursor placement is overridden. Not enabled
by default. Fixed takes x,y coordinates for placement.
Note: openbox allows 'Center', 'Top', or 'Fixed' we use Center & Fixed.
Positioning is per monitor based on which monitor the cursor is in.
*<resize><popupFixedPosition>*
set x, y coordinates for menu placement
- x,y accept positive offsets only.
- 0,0 places menu at top left corner of desktop
- monitor width -1, monitor height -1 places menu at bottom right.
## KEYBOARD
*<keyboard><numlock>* [on|off]

View file

@ -115,7 +115,26 @@
<popupShow>Never</popupShow>
<!-- Let client redraw its contents while resizing -->
<drawContents>yes</drawContents>
</resize>
<!-- options for fixed menu placement
will override all atCursor placement -->
<!--
<popupPosition>Fixed</popupPosition>
-->
<!-- openbox uses 'Center', 'Top', or 'Fixed'
but we use Fixed & Center for now', positioning
is per output. -->
<popupFixedPosition>
<!-- openbox allows - negative offsets but that's because of X
we use positive offset, 0,0 is top left corner
monitor width - 1, monitor height - 1
will put the menu at bottom right corner -->
<x>10</x> <!-- 10 pixel from top left corner -->
<y>10</y>
</popupFixedPosition>
</resize>
<focus>
<followMouse>no</followMouse>

View file

@ -45,6 +45,12 @@ enum tiling_events_mode {
(LAB_TILING_EVENTS_REGION | LAB_TILING_EVENTS_EDGE),
};
enum menu_placement_policy {
LAB_MENU_ATCURSOR = 0,
LAB_MENU_CENTER,
LAB_MENU_FIXED,
};
struct usable_area_override {
struct border margin;
char *output;
@ -136,6 +142,13 @@ struct rcxml {
enum resize_indicator_mode resize_indicator;
bool resize_draw_contents;
/* x,y and center placement for menu */
enum menu_placement_policy resize_popup_position;
struct {
int x;
int y;
} resize_popup_fixed_position;
struct {
int popuptime;

View file

@ -25,6 +25,7 @@
#include "view.h"
#include "workspaces.h"
#include "input/keyboard.h"
#include "config/rcxml.h"
enum action_arg_type {
LAB_ACTION_ARG_STR = 0,
@ -642,6 +643,31 @@ show_menu(struct server *server, struct view *view,
x = view->current.x;
y = view->current.y;
}
/* Fixed placement overrides atCursor menu placement */
if (rc.resize_popup_position) {
struct output *output = output_nearest_to(server,
server->seat.cursor->x, server->seat.cursor->y);
struct wlr_box output_box;
wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output_box);
if (rc.resize_popup_position == LAB_MENU_FIXED) {
x = rc.resize_popup_fixed_position.x + output_box.x;
y = rc.resize_popup_fixed_position.y + output_box.y;
} else { /* Center the menu */
struct menuitem *item;
int max_width = 0;
wl_list_for_each(item, &menu->menuitems, link) {
if (item->native_width > max_width) {
max_width = item->native_width;
}
}
x = (output->usable_area.width / 2) -
(max_width / 2) + output_box.x;
y = (output->usable_area.height / 2) -
(menu->size.height / 2) + output_box.y;
}
}
/* Replaced by next show_menu() or cleaned on view_destroy() */
menu->triggered_by_view = view;

View file

@ -1051,6 +1051,18 @@ entry(xmlNode *node, char *nodename, char *content)
}
} else if (!strcasecmp(nodename, "drawContents.resize")) {
set_bool(content, &rc.resize_draw_contents);
} else if (!strcasecmp(nodename, "popupPosition.resize")) {
rc.resize_popup_position = LAB_MENU_ATCURSOR;
if (!strcasecmp(content, "Fixed")) {
rc.resize_popup_position = LAB_MENU_FIXED;
}
if (!strcasecmp(content, "Center")) {
rc.resize_popup_position = LAB_MENU_CENTER;
}
} else if (!strcasecmp(nodename, "x.popupFixedPosition.resize")) {
rc.resize_popup_fixed_position.x = atoi(content);
} else if (!strcasecmp(nodename, "y.popupFixedPosition.resize")) {
rc.resize_popup_fixed_position.y = atoi(content);
} else if (!strcasecmp(nodename, "mouseEmulation.tablet")) {
set_bool(content, &rc.tablet.force_mouse_emulation);
} else if (!strcasecmp(nodename, "mapToOutput.tablet")) {
@ -1307,6 +1319,7 @@ rcxml_init(void)
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
rc.resize_draw_contents = true;
rc.resize_popup_position = LAB_MENU_ATCURSOR;
rc.workspace_config.popuptime = INT_MIN;
rc.workspace_config.min_nr_workspaces = 1;