mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
src/menu: Attach view to menu and use it when executing actions
This fixes #380
This commit is contained in:
parent
ca9226a7a6
commit
5a4c5de332
5 changed files with 63 additions and 30 deletions
|
|
@ -4,7 +4,12 @@
|
||||||
|
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
/* forward declare arguments */
|
||||||
|
struct view;
|
||||||
|
struct server;
|
||||||
|
struct wl_list;
|
||||||
struct lab_data_buffer;
|
struct lab_data_buffer;
|
||||||
|
struct wlr_scene_tree;
|
||||||
struct wlr_scene_node;
|
struct wlr_scene_node;
|
||||||
|
|
||||||
enum menu_align {
|
enum menu_align {
|
||||||
|
|
@ -49,6 +54,9 @@ struct menu {
|
||||||
struct menuitem *item;
|
struct menuitem *item;
|
||||||
} selection;
|
} selection;
|
||||||
struct wlr_scene_tree *scene_tree;
|
struct wlr_scene_tree *scene_tree;
|
||||||
|
|
||||||
|
/* Used to match a window-menu to the view that triggered it. */
|
||||||
|
struct view *triggered_by_view; /* may be NULL */
|
||||||
};
|
};
|
||||||
|
|
||||||
void menu_init_rootmenu(struct server *server);
|
void menu_init_rootmenu(struct server *server);
|
||||||
|
|
@ -92,8 +100,15 @@ void menu_process_cursor_motion(struct wlr_scene_node *node);
|
||||||
*/
|
*/
|
||||||
bool menu_call_actions(struct wlr_scene_node *node);
|
bool menu_call_actions(struct wlr_scene_node *node);
|
||||||
|
|
||||||
/* menu_close - close menu */
|
/**
|
||||||
void menu_close(struct menu *menu);
|
* menu_close_root- close root menu
|
||||||
|
*
|
||||||
|
* This function will close server->menu_current and set it to NULL.
|
||||||
|
* Asserts that server->input_mode is set to LAB_INPUT_STATE_MENU.
|
||||||
|
*
|
||||||
|
* Additionally, server->input_mode wil be set to LAB_INPUT_STATE_PASSTHROUGH.
|
||||||
|
*/
|
||||||
|
void menu_close_root(struct server *server);
|
||||||
|
|
||||||
/* menu_reconfigure - reload theme and content */
|
/* menu_reconfigure - reload theme and content */
|
||||||
void menu_reconfigure(struct server *server);
|
void menu_reconfigure(struct server *server);
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,8 @@ show_menu(struct server *server, struct view *view, const char *menu_name)
|
||||||
x = server->seat.cursor->x;
|
x = server->seat.cursor->x;
|
||||||
y = server->seat.cursor->y;
|
y = server->seat.cursor->y;
|
||||||
}
|
}
|
||||||
|
/* Replaced by next show_menu() or cleaned on view_destroy() */
|
||||||
|
menu->triggered_by_view = view;
|
||||||
menu_open(menu, x, y);
|
menu_open(menu, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
19
src/cursor.c
19
src/cursor.c
|
|
@ -718,13 +718,8 @@ cursor_button(struct wl_listener *listener, void *data)
|
||||||
seat->pressed.surface = NULL;
|
seat->pressed.surface = NULL;
|
||||||
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
||||||
if (close_menu) {
|
if (close_menu) {
|
||||||
if (server->menu_current) {
|
menu_close_root(server);
|
||||||
menu_close(server->menu_current);
|
cursor_rebase(&server->seat, event->time_msec, false);
|
||||||
server->menu_current = NULL;
|
|
||||||
}
|
|
||||||
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
|
||||||
cursor_rebase(&server->seat,
|
|
||||||
event->time_msec, false);
|
|
||||||
close_menu = false;
|
close_menu = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -755,17 +750,11 @@ cursor_button(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
||||||
|
/* We are closing the menu on RELEASE to not leak a stray release */
|
||||||
if (view_area != LAB_SSD_MENU) {
|
if (view_area != LAB_SSD_MENU) {
|
||||||
/*
|
|
||||||
* We close the menu on release so we don't leak a stray
|
|
||||||
* release
|
|
||||||
*/
|
|
||||||
close_menu = true;
|
close_menu = true;
|
||||||
} else if (menu_call_actions(node)) {
|
} else if (menu_call_actions(node)) {
|
||||||
/*
|
/* Action was successfull, may fail if item just opens a submenu */
|
||||||
* Action was successfull, may fail if item just opens a
|
|
||||||
* submenu
|
|
||||||
*/
|
|
||||||
close_menu = true;
|
close_menu = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -548,6 +548,21 @@ close_all_submenus(struct menu *menu)
|
||||||
menu->selection.menu = NULL;
|
menu->selection.menu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_close(struct menu *menu)
|
||||||
|
{
|
||||||
|
if (!menu) {
|
||||||
|
wlr_log(WLR_ERROR, "Trying to close non exiting menu");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wlr_scene_node_set_enabled(&menu->scene_tree->node, false);
|
||||||
|
menu_set_selection(menu, NULL);
|
||||||
|
if (menu->selection.menu) {
|
||||||
|
menu_close(menu->selection.menu);
|
||||||
|
menu->selection.menu = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
menu_open(struct menu *menu, int x, int y)
|
menu_open(struct menu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
@ -582,7 +597,9 @@ menu_process_cursor_motion(struct wlr_scene_node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->submenu) {
|
if (item->submenu) {
|
||||||
/* And open the new one */
|
/* Sync the triggering view */
|
||||||
|
item->submenu->triggered_by_view = item->parent->triggered_by_view;
|
||||||
|
/* And open the new submenu tree */
|
||||||
wlr_scene_node_set_enabled(
|
wlr_scene_node_set_enabled(
|
||||||
&item->submenu->scene_tree->node, true);
|
&item->submenu->scene_tree->node, true);
|
||||||
}
|
}
|
||||||
|
|
@ -600,26 +617,29 @@ menu_call_actions(struct wlr_scene_node *node)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
actions_run(NULL, item->parent->server, &item->actions, 0);
|
actions_run(item->parent->triggered_by_view,
|
||||||
|
item->parent->server, &item->actions, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We close the menu here to provide a faster feedback to the user.
|
||||||
|
* We do that without resetting the input state so src/cursor.c
|
||||||
|
* can do its own clean up on the following RELEASE event.
|
||||||
|
*/
|
||||||
menu_close(item->parent->server->menu_current);
|
menu_close(item->parent->server->menu_current);
|
||||||
item->parent->server->menu_current = NULL;
|
item->parent->server->menu_current = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
menu_close(struct menu *menu)
|
menu_close_root(struct server *server)
|
||||||
{
|
{
|
||||||
if (!menu) {
|
assert(server->input_mode == LAB_INPUT_STATE_MENU);
|
||||||
wlr_log(WLR_ERROR, "Trying to close non exiting menu");
|
if (server->menu_current) {
|
||||||
return;
|
menu_close(server->menu_current);
|
||||||
}
|
server->menu_current = NULL;
|
||||||
/* TODO: Maybe reset input state here instead of in cursor.c ? */
|
|
||||||
wlr_scene_node_set_enabled(&menu->scene_tree->node, false);
|
|
||||||
menu_set_selection(menu, NULL);
|
|
||||||
if (menu->selection.menu) {
|
|
||||||
menu_close(menu->selection.menu);
|
|
||||||
menu->selection.menu = NULL;
|
|
||||||
}
|
}
|
||||||
|
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "ssd.h"
|
#include "ssd.h"
|
||||||
|
#include "menu/menu.h"
|
||||||
|
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
|
@ -756,6 +757,12 @@ view_destroy(struct view *view)
|
||||||
wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true);
|
wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we spawned a window menu, close it */
|
||||||
|
if (server->menu_current
|
||||||
|
&& server->menu_current->triggered_by_view == view) {
|
||||||
|
menu_close_root(server);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove view from server->views */
|
/* Remove view from server->views */
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
free(view);
|
free(view);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue