]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Convert menu to node_descriptors
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 3 Mar 2022 03:33:33 +0000 (04:33 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Thu, 3 Mar 2022 17:49:54 +0000 (17:49 +0000)
include/menu/menu.h
include/node.h
src/cursor.c
src/desktop.c
src/menu/menu.c
src/node.c

index a5ec7dd89832da88d811e67919185390077e15a5..777bc6af70eebb437dce1f577cc8ba2a43e0c2c9 100644 (file)
@@ -23,6 +23,7 @@ struct menu_scene {
 
 struct menuitem {
        struct wl_list actions;
+       struct menu *parent;
        struct menu *submenu;
        struct menu_scene normal;
        struct menu_scene selected;
@@ -75,15 +76,19 @@ void menu_open(struct menu *menu, int x, int y);
  * - handles hover effects
  * - may open/close submenus
  */
-void menu_process_cursor_motion(struct menu *menu, struct wlr_scene_node *node);
+void menu_process_cursor_motion(struct wlr_scene_node *node);
 
 /**
- * menu_call_actions - call actions associated with a menu entry
+ * menu_call_actions - call actions associated with a menu node
+ *
+ * If menuitem connected to @node does not just open a submenu:
+ * - associated actions will be called
+ * - server->menu_current will be closed
+ * - server->menu_current will be set to NULL
  *
- * If actions are found, server->menu_current will be closed and set to NULL
- * Returns true if handled
+ * Returns true if actions have actually been executed
  */
-bool menu_call_actions(struct menu *menu, struct wlr_scene_node *node);
+bool menu_call_actions(struct wlr_scene_node *node);
 
 /* menu_close - close menu */
 void menu_close(struct menu *menu);
index b1fffb9abd18025e9aeae9c12fe0f196e9654066..5cc7220eb6ccc8b97542ce083c1b28969e458abf 100644 (file)
@@ -6,6 +6,7 @@
 struct view;
 struct lab_layer_surface;
 struct lab_layer_popup;
+struct menuitem;
 
 enum node_descriptor_type {
        LAB_NODE_DESC_NODE = 0,
@@ -13,6 +14,7 @@ enum node_descriptor_type {
        LAB_NODE_DESC_XDG_POPUP,
        LAB_NODE_DESC_LAYER_SURFACE,
        LAB_NODE_DESC_LAYER_POPUP,
+       LAB_NODE_DESC_MENUITEM,
 };
 
 struct node_descriptor {
@@ -54,4 +56,11 @@ struct lab_layer_surface *node_layer_surface_from_node(
 struct lab_layer_popup *node_layer_popup_from_node(
        struct wlr_scene_node *wlr_scene_node);
 
+/**
+ * node_menuitem_from_node - return menuitem struct from node
+ * @wlr_scene_node: wlr_scene_node from which to return data
+ */
+struct menuitem *node_menuitem_from_node(
+       struct wlr_scene_node *wlr_scene_node);
+
 #endif /* __LABWC_NODE_DESCRIPTOR_H */
index f6716cb71cddfa9346f8ae126be0ad03994593c7..7aa32d35a5618f3ca430f6d068c95a8ff540e40c 100644 (file)
@@ -233,7 +233,7 @@ process_cursor_motion(struct server *server, uint32_t time)
        }
 
        if (view_area == LAB_SSD_MENU) {
-               menu_process_cursor_motion(server->menu_current, node);
+               menu_process_cursor_motion(node);
                return;
        }
 
@@ -677,8 +677,8 @@ cursor_button(struct wl_listener *listener, void *data)
                if (view_area != LAB_SSD_MENU) {
                        /* We close the menu on release so we don't leak a stray release */
                        close_menu = true;
-               } else if (menu_call_actions(server->menu_current, node)) {
-                       /* Action was successfull, may fail if item contains a submenu */
+               } else if (menu_call_actions(node)) {
+                       /* Action was successfull, may fail if item just opens a submenu */
                        close_menu = true;
                }
                return;
index 8c1c740165b840b3fad4740d57af2d32475e2333..d8768de57f13f2fc4bd7c5fc9fc399d683b25a5f 100644 (file)
@@ -284,9 +284,9 @@ desktop_node_and_view_at(struct server *server, double lx, double ly,
 #endif
        }
        struct wlr_scene_node *osd = &server->osd_tree->node;
-       struct wlr_scene_node *menu = &server->menu_tree->node;
        while (node) {
                struct node_descriptor *desc = node->data;
+               /* TODO: convert to switch() */
                if (desc) {
                        if (desc->type == LAB_NODE_DESC_VIEW) {
                                goto has_view_data;
@@ -299,13 +299,16 @@ desktop_node_and_view_at(struct server *server, double lx, double ly,
                                *view_area = LAB_SSD_CLIENT;
                                return NULL;
                        }
+                       if (desc->type == LAB_NODE_DESC_MENUITEM) {
+                               /* Always return the top scene node for menu items */
+                               *scene_node = node;
+                               *view_area = LAB_SSD_MENU;
+                               return NULL;
+                       }
                }
                if (node == osd) {
                        *view_area = LAB_SSD_OSD;
                        return NULL;
-               } else if (node == menu) {
-                       *view_area = LAB_SSD_MENU;
-                       return NULL;
                }
                node = node->parent;
        }
index ff9a8b6acd875628f24d49b51385107b1ca8b07a..2f34d4e39a1e2841459e1bb2772ba0ba06c8002e 100644 (file)
@@ -20,6 +20,7 @@
 #include "theme.h"
 #include "action.h"
 #include "buffer.h"
+#include "node.h"
 
 #define MENUWIDTH (110)
 #define MENU_ITEM_PADDING_Y (4)
@@ -82,6 +83,7 @@ item_create(struct menu *menu, const char *text)
        if (!menuitem) {
                return NULL;
        }
+       menuitem->parent = menu;
        struct server *server = menu->server;
        struct theme *theme = server->theme;
        struct font font = {
@@ -117,6 +119,12 @@ item_create(struct menu *menu, const char *text)
        menuitem->selected.text = &wlr_scene_buffer_create(
                menuitem->selected.background, &menuitem->selected.buffer->base)->node;
 
+       /* Node descriptors for top scene nodes of menuitem */
+       node_descriptor_create(menuitem->normal.background,
+               LAB_NODE_DESC_MENUITEM, menuitem);
+       node_descriptor_create(menuitem->selected.background,
+               LAB_NODE_DESC_MENUITEM, menuitem);
+
        /* Center font nodes */
        y = (menu->item_height - menuitem->normal.buffer->base.height) / 2;
        x = MENU_ITEM_PADDING_X;
@@ -132,7 +140,7 @@ item_create(struct menu *menu, const char *text)
        /* Hide selected state */
        wlr_scene_node_set_enabled(menuitem->selected.background, false);
 
-       /* Update menu extends */
+       /* Update menu extents */
        menu->size.height = (item_count + 1) * menu->item_height;
 
        wl_list_insert(&menu->menuitems, &menuitem->link);
@@ -516,74 +524,47 @@ menu_open(struct menu *menu, int x, int y)
 }
 
 void
-menu_process_cursor_motion(struct menu *menu, struct wlr_scene_node *node)
+menu_process_cursor_motion(struct wlr_scene_node *node)
 {
-       if (!node) {
-               wlr_log(WLR_ERROR, "%s() node == NULL", __func__);
+       assert(node && node->data);
+       struct menuitem *item = node_menuitem_from_node(node);
+
+       if (node == item->selected.background) {
+               /* We are on an already selected item */
                return;
        }
-       assert(menu);
 
-       /* TODO: this would be much easier if we could use node->data */
+       /* We are on an item that has new mouse-focus */
+       menu_set_selection(item->parent, item);
+       if (item->parent->selection.menu) {
+               /* Close old submenu tree */
+               menu_close(item->parent->selection.menu);
+       }
 
-       struct menuitem *item;
-       wl_list_for_each (item, &menu->menuitems, link) {
-               if (node == item->selected.background
-                               || node->parent == item->selected.background) {
-                       /* We are on an already selected item */
-                       return;
-               }
-               if (node == item->normal.background
-                               || node->parent == item->normal.background) {
-                       /* We are on an item that has new mouse-focus */
-                       menu_set_selection(menu, item);
-                       if (menu->selection.menu) {
-                               /* Close old submenu tree */
-                               menu_close(menu->selection.menu);
-                       }
-                       if (item->submenu) {
-                               /* And open the new one */
-                               wlr_scene_node_set_enabled(
-                                       &item->submenu->scene_tree->node, true);
-                       }
-                       menu->selection.menu = item->submenu;
-                       return;
-               }
-               if (item->submenu && item->submenu == menu->selection.menu) {
-                       menu_process_cursor_motion(item->submenu, node);
-               }
+       if (item->submenu) {
+               /* And open the new one */
+               wlr_scene_node_set_enabled(
+                       &item->submenu->scene_tree->node, true);
        }
+       item->parent->selection.menu = item->submenu;
 }
 
 
 bool
-menu_call_actions(struct menu *menu, struct wlr_scene_node *node)
+menu_call_actions(struct wlr_scene_node *node)
 {
-       /* TODO: this would be much easier if we could use node->data */
+       assert(node && node->data);
+       struct menuitem *item = node_menuitem_from_node(node);
 
-       if (!menu->selection.item) {
-               /* No item selected in current menu */
-               wlr_log(WLR_ERROR, "No item on menu_action_selected");
+       if (item->submenu) {
+               /* We received a click on an item that just opens a submenu */
                return false;
        }
-       struct wlr_scene_node *menu_node =
-               menu->selection.item->selected.background;
-       if (node == menu_node || node->parent == menu_node) {
-               /* We found the correct menu item */
-               if (menu->selection.item->submenu) {
-                       /* ..but it just opens a submenu */
-                       return false;
-               }
-               actions_run(NULL, menu->server, &menu->selection.item->actions, 0);
-               menu_close(menu->server->menu_current);
-               menu->server->menu_current = NULL;
-               return true;
-       }
-       if (menu->selection.menu) {
-               return menu_call_actions(menu->selection.menu, node);
-       }
-       wlr_log(WLR_ERROR, "No match on menu_action_selected");
-       return false;
+
+       actions_run(NULL, item->parent->server, &item->actions, 0);
+       menu_close(item->parent->server->menu_current);
+       item->parent->server->menu_current = NULL;
+       return true;
 }
 
 void
index c189358a6a839b4a55ca304d0cbae80c4223c52f..f667d82a7dd6bc79fab033b118fc53446a417872 100644 (file)
@@ -64,3 +64,12 @@ node_layer_popup_from_node(struct wlr_scene_node *wlr_scene_node)
        assert(node_descriptor->type == LAB_NODE_DESC_LAYER_POPUP);
        return (struct lab_layer_popup *)node_descriptor->data;
 }
+
+struct menuitem *
+node_menuitem_from_node(struct wlr_scene_node *wlr_scene_node)
+{
+       assert(wlr_scene_node->data);
+       struct node_descriptor *node_descriptor = wlr_scene_node->data;
+       assert(node_descriptor->type == LAB_NODE_DESC_MENUITEM);
+       return (struct menuitem *)node_descriptor->data;
+}