mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -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