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. outlined rectangle is shown to indicate the geometry of resized window.
Default is yes. 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
*<keyboard><numlock>* [on|off] *<keyboard><numlock>* [on|off]

View file

@ -115,7 +115,26 @@
<popupShow>Never</popupShow> <popupShow>Never</popupShow>
<!-- Let client redraw its contents while resizing --> <!-- Let client redraw its contents while resizing -->
<drawContents>yes</drawContents> <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> <focus>
<followMouse>no</followMouse> <followMouse>no</followMouse>

View file

@ -45,6 +45,12 @@ enum tiling_events_mode {
(LAB_TILING_EVENTS_REGION | LAB_TILING_EVENTS_EDGE), (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 usable_area_override {
struct border margin; struct border margin;
char *output; char *output;
@ -136,6 +142,13 @@ struct rcxml {
enum resize_indicator_mode resize_indicator; enum resize_indicator_mode resize_indicator;
bool resize_draw_contents; 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 { struct {
int popuptime; int popuptime;

View file

@ -25,6 +25,7 @@
#include "view.h" #include "view.h"
#include "workspaces.h" #include "workspaces.h"
#include "input/keyboard.h" #include "input/keyboard.h"
#include "config/rcxml.h"
enum action_arg_type { enum action_arg_type {
LAB_ACTION_ARG_STR = 0, LAB_ACTION_ARG_STR = 0,
@ -642,6 +643,31 @@ show_menu(struct server *server, struct view *view,
x = view->current.x; x = view->current.x;
y = view->current.y; 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() */ /* Replaced by next show_menu() or cleaned on view_destroy() */
menu->triggered_by_view = view; menu->triggered_by_view = view;

View file

@ -1051,6 +1051,18 @@ entry(xmlNode *node, char *nodename, char *content)
} }
} else if (!strcasecmp(nodename, "drawContents.resize")) { } else if (!strcasecmp(nodename, "drawContents.resize")) {
set_bool(content, &rc.resize_draw_contents); 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")) { } else if (!strcasecmp(nodename, "mouseEmulation.tablet")) {
set_bool(content, &rc.tablet.force_mouse_emulation); set_bool(content, &rc.tablet.force_mouse_emulation);
} else if (!strcasecmp(nodename, "mapToOutput.tablet")) { } else if (!strcasecmp(nodename, "mapToOutput.tablet")) {
@ -1307,6 +1319,7 @@ rcxml_init(void)
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER; rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
rc.resize_draw_contents = true; rc.resize_draw_contents = true;
rc.resize_popup_position = LAB_MENU_ATCURSOR;
rc.workspace_config.popuptime = INT_MIN; rc.workspace_config.popuptime = INT_MIN;
rc.workspace_config.min_nr_workspaces = 1; rc.workspace_config.min_nr_workspaces = 1;