diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd
index bd03fd6b..1ca8305b 100644
--- a/docs/labwc-config.5.scd
+++ b/docs/labwc-config.5.scd
@@ -498,6 +498,21 @@ extending outward from the snapped edge.
outlined rectangle is shown to indicate the geometry of resized window.
Default is yes.
+** 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.
+
+**
+ 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
** [on|off]
diff --git a/docs/rc.xml.all b/docs/rc.xml.all
index f71014a6..64690ca6 100644
--- a/docs/rc.xml.all
+++ b/docs/rc.xml.all
@@ -115,7 +115,26 @@
Never
yes
-
+
+
+
+
+
+
+
+
+ 10
+ 10
+
+
no
diff --git a/include/config/rcxml.h b/include/config/rcxml.h
index 2b5da588..0a0ed86a 100644
--- a/include/config/rcxml.h
+++ b/include/config/rcxml.h
@@ -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;
diff --git a/src/action.c b/src/action.c
index 69a317bb..67e4fe0e 100644
--- a/src/action.c
+++ b/src/action.c
@@ -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;
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index da0bbde3..65a821ea 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -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;