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
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));
|
||||
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;
|
||||
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
||||
case ACTION_TYPE_MAXIMIZE:
|
||||
|
|
@ -611,7 +619,8 @@ action_list_free(struct wl_list *action_list)
|
|||
|
||||
static void
|
||||
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
|
||||
&& server->input_mode != LAB_INPUT_STATE_MENU) {
|
||||
|
|
@ -638,8 +647,62 @@ show_menu(struct server *server, struct view *view,
|
|||
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() */
|
||||
menu->triggered_by_view = view;
|
||||
menu->server->menu_current = menu;
|
||||
menu_open_root(menu, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -843,7 +906,9 @@ actions_run(struct view *activator, struct server *server,
|
|||
case ACTION_TYPE_SHOW_MENU:
|
||||
show_menu(server, view,
|
||||
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;
|
||||
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
||||
if (view) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue