mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
Add position arguments for menus
...utilizing x,y coordinates where values can be a number, a negative
number, a percentage or "center".
- (0,0) is top left corner
- (-0,-0) is bottom right corner
- % is percentage of width and/or height
- 'center' centers the menu vertically and/or horizontally
<action name="ShowMenu">
<menu>root-menu</menu>
<position>
<x>0</x>
<y>0</y>
</position>
</action>
Note: both x and y values must be supplied for positioning to work.
This commit is contained in:
parent
f3b2766892
commit
8850368ab9
2 changed files with 78 additions and 2 deletions
|
|
@ -123,6 +123,17 @@ Actions are used in menus and keyboard/mouse bindings.
|
||||||
upper-left corner of the window associated with the action. Default is
|
upper-left corner of the window associated with the action. Default is
|
||||||
yes.
|
yes.
|
||||||
|
|
||||||
|
*position* Show the menu in the specified position on the monitor
|
||||||
|
that has cursor focus, see below.
|
||||||
|
|
||||||
|
The position tag has two sub-tags. <x> and <y> specify a position and
|
||||||
|
take either a pixel value, the string "center" which will center the
|
||||||
|
menu in that dimension, or a relative value specified as a percentage
|
||||||
|
A relative value is interpreted in terms of the monitor the menu will
|
||||||
|
be shown on, and will be relative to the left/top edge of the menu
|
||||||
|
window and monitor for positive values, and to the right/bottom edge
|
||||||
|
for negative values.
|
||||||
|
|
||||||
*<action name="SetDecorations" decorations="value" forceSSD="no" />*
|
*<action name="SetDecorations" decorations="value" forceSSD="no" />*
|
||||||
Set decorations of focused window.
|
Set decorations of focused window.
|
||||||
|
|
||||||
|
|
|
||||||
69
src/action.c
69
src/action.c
|
|
@ -343,6 +343,14 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
||||||
action_arg_add_bool(action, argument, parse_bool(content, true));
|
action_arg_add_bool(action, argument, parse_bool(content, true));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
if (!strcasecmp(argument, "x.position")) {
|
||||||
|
action_arg_add_str(action, argument, content);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(argument, "y.position")) {
|
||||||
|
action_arg_add_str(action, argument, content);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
||||||
case ACTION_TYPE_MAXIMIZE:
|
case ACTION_TYPE_MAXIMIZE:
|
||||||
|
|
@ -611,7 +619,8 @@ action_list_free(struct wl_list *action_list)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
show_menu(struct server *server, struct view *view,
|
show_menu(struct server *server, struct view *view,
|
||||||
const char *menu_name, bool at_cursor)
|
const char *menu_name, bool at_cursor,
|
||||||
|
const char *pos_x, const char *pos_y)
|
||||||
{
|
{
|
||||||
if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH
|
if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH
|
||||||
&& server->input_mode != LAB_INPUT_STATE_MENU) {
|
&& server->input_mode != LAB_INPUT_STATE_MENU) {
|
||||||
|
|
@ -638,8 +647,62 @@ show_menu(struct server *server, struct view *view,
|
||||||
y = view->current.y;
|
y = view->current.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* determine placement by looking at x and y
|
||||||
|
* x/y can be number, "center" or a %percent of screen dimensions
|
||||||
|
*/
|
||||||
|
if (pos_x && pos_y) {
|
||||||
|
struct output *output = output_nearest_to(server,
|
||||||
|
server->seat.cursor->x, server->seat.cursor->y);
|
||||||
|
struct menuitem *item;
|
||||||
|
struct theme *theme = server->theme;
|
||||||
|
int max_width = theme->menu_min_width;
|
||||||
|
|
||||||
|
wl_list_for_each(item, &menu->menuitems, link) {
|
||||||
|
if (item->native_width > max_width) {
|
||||||
|
max_width = item->native_width < theme->menu_max_width
|
||||||
|
? item->native_width : theme->menu_max_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(pos_x, "center")) {
|
||||||
|
x = (output->usable_area.width / 2) - (max_width / 2);
|
||||||
|
} else if (strchr(pos_x, '%')) {
|
||||||
|
x = (output->usable_area.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;
|
||||||
|
} else {
|
||||||
|
x = atoi(pos_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(pos_y, "center")) {
|
||||||
|
y = (output->usable_area.height / 2) - (menu->size.height / 2);
|
||||||
|
} else if (strchr(pos_y, '%')) {
|
||||||
|
y = (output->usable_area.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;
|
||||||
|
} else {
|
||||||
|
y = atoi(pos_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* keep menu from being off screen */
|
||||||
|
x = MAX(x, 0);
|
||||||
|
x = MIN(x, (output->usable_area.width -1));
|
||||||
|
y = MAX(y, 0);
|
||||||
|
y = MIN(y, (output->usable_area.height -1));
|
||||||
|
/* adjust for which monitor to appear on */
|
||||||
|
x += output->usable_area.x;
|
||||||
|
y += output->usable_area.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;
|
||||||
|
menu->server->menu_current = menu;
|
||||||
menu_open_root(menu, x, y);
|
menu_open_root(menu, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -843,7 +906,9 @@ actions_run(struct view *activator, struct server *server,
|
||||||
case ACTION_TYPE_SHOW_MENU:
|
case ACTION_TYPE_SHOW_MENU:
|
||||||
show_menu(server, view,
|
show_menu(server, view,
|
||||||
action_get_str(action, "menu", NULL),
|
action_get_str(action, "menu", NULL),
|
||||||
action_get_bool(action, "atCursor", true));
|
action_get_bool(action, "atCursor", true),
|
||||||
|
action_get_str(action, "x.position", NULL),
|
||||||
|
action_get_str(action, "y.position", NULL));
|
||||||
break;
|
break;
|
||||||
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
||||||
if (view) {
|
if (view) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue