]> git.mdlowis.com Git - proto/labwc.git/commitdiff
mousebind: add support for more contexts and mouse events
authorARDiDo <90479315+ARDiDo@users.noreply.github.com>
Tue, 2 Nov 2021 00:32:14 +0000 (20:32 -0400)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 2 Nov 2021 18:14:50 +0000 (18:14 +0000)
include/config/mousebind.h
src/config/mousebind.c
src/config/rcxml.c
src/cursor.c

index 6244a5072c4810c7e8d4a4b376c2320fd306aae1..cfd25b51f774e8c7752be04760f64cae329b3430 100644 (file)
@@ -7,6 +7,9 @@
 enum mouse_event {
        MOUSE_ACTION_NONE = 0,
        MOUSE_ACTION_DOUBLECLICK,
+       MOUSE_ACTION_CLICK,
+       MOUSE_ACTION_PRESS,
+       MOUSE_ACTION_RELEASE,
 };
 
 struct mousebind {
@@ -21,6 +24,7 @@ struct mousebind {
        const char *command;
 
        struct wl_list link; /* rcxml::mousebinds */
+       bool pressed_in_context; /* used in click events */
 };
 
 enum mouse_event mousebind_event_from_str(const char *str);
index 3a9804032863d064f450cf1440749d0e2f981a38..f12a11311e68a9d8d4a740ecba423a0432310ce6 100644 (file)
@@ -27,8 +27,14 @@ enum mouse_event
 mousebind_event_from_str(const char *str)
 {
        assert(str);
-       if (strcasecmp(str, "doubleclick") == 0) {
+       if (!strcasecmp(str, "doubleclick")) {
                return MOUSE_ACTION_DOUBLECLICK;
+       } else if (!strcasecmp(str, "click")) {
+               return MOUSE_ACTION_CLICK;
+       } else if (!strcasecmp(str, "press")) {
+               return MOUSE_ACTION_PRESS;
+       } else if (!strcasecmp(str, "release")) {
+               return MOUSE_ACTION_RELEASE;
        }
        wlr_log(WLR_ERROR, "unknown mouse action (%s)", str);
        return MOUSE_ACTION_NONE;
@@ -39,6 +45,12 @@ context_from_str(const char *str)
 {
        if (!strcasecmp(str, "Titlebar")) {
                return LAB_SSD_PART_TITLEBAR;
+       } else if (!strcasecmp(str, "Close")) {
+               return LAB_SSD_BUTTON_CLOSE;
+       } else if (!strcasecmp(str, "Maximize")) {
+               return LAB_SSD_BUTTON_MAXIMIZE;
+       } else if (!strcasecmp(str, "Iconify")) {
+               return LAB_SSD_BUTTON_ICONIFY;
        }
        wlr_log(WLR_ERROR, "unknown mouse context (%s)", str);
        return LAB_SSD_NONE;
index f9781f8b4952687a152a98ba10fae7fb9e6cc8d8..c70fd2fc09081b61525c828c3da5fddd681039c9 100644 (file)
@@ -466,6 +466,9 @@ static struct {
        const char *context, *button, *event, *action, *command;
 } mouse_combos[] = {
        { "TitleBar", "Left", "DoubleClick", "ToggleMaximize", NULL },
+       { "Close", "Left", "Click", "Close", NULL },
+       { "Iconify", "Left", "Click", "Iconify", NULL},
+       { "Maximize", "Left", "Click", "ToggleMaximize", NULL},
        { NULL, NULL, NULL, NULL, NULL },
 };
 
index 63b0f2e742ea8c3b7301af95f7e4cace868f8958..13107c7a68e09fee34c902c8d2447a6ecd8842e5 100644 (file)
@@ -420,6 +420,27 @@ handle_cursor_button_with_meta_key(struct view *view, uint32_t button,
        interactive_begin(view, LAB_INPUT_STATE_RESIZE, edges);
 }
 
+static void
+handle_release_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area)
+{
+       struct mousebind *mousebind;
+       wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
+               if (mousebind->context == view_area
+                               && mousebind->button == button) {
+                       if (mousebind->mouse_event
+                                       == MOUSE_ACTION_RELEASE) {
+                               action(server, mousebind->action,
+                                       mousebind->command);
+                       }
+                       if (mousebind->pressed_in_context) {
+                               mousebind->pressed_in_context = false;
+                               action(server, mousebind->action,
+                                       mousebind->command);
+                       }
+               }
+       }
+}
+
 static bool
 is_double_click(long double_click_speed)
 {
@@ -433,6 +454,37 @@ is_double_click(long double_click_speed)
        return ms < double_click_speed && ms >= 0;
 }
 
+static bool
+handle_press_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area)
+{
+       struct mousebind *mousebind;
+       bool double_click = is_double_click(rc.doubleclick_time);
+       bool bound;
+
+       wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
+               if (mousebind->context == view_area
+                               && mousebind->button == button) {
+                       if (mousebind->mouse_event
+                                       == MOUSE_ACTION_PRESS) {
+                               bound = true;
+                               action(server, mousebind->action,
+                                       mousebind->command);
+                       } else if (mousebind->mouse_event
+                                       == MOUSE_ACTION_CLICK) {
+                               bound = true;
+                               mousebind->pressed_in_context = true;
+                       } else if (double_click
+                                       && mousebind->mouse_event
+                                       == MOUSE_ACTION_DOUBLECLICK) {
+                               bound = true;
+                               action(server, mousebind->action,
+                                               mousebind->command);
+                       }
+               }
+       }
+       return bound;
+}
+
 void
 cursor_button(struct wl_listener *listener, void *data)
 {
@@ -471,10 +523,13 @@ cursor_button(struct wl_listener *listener, void *data)
                if (server->input_mode == LAB_INPUT_STATE_MENU) {
                        return;
                }
-               /* Exit interactive move/resize/menu mode. */
-               server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
                damage_all_outputs(server);
-               return;
+               if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
+                       /* Exit interactive move/resize/menu mode. */
+                       server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
+                       return;
+               }
+               goto mousebindings;
        }
 
        if (server->input_mode == LAB_INPUT_STATE_MENU) {
@@ -507,39 +562,24 @@ cursor_button(struct wl_listener *listener, void *data)
        desktop_raise_view(view);
        damage_all_outputs(server);
 
-       if (is_double_click(rc.doubleclick_time)
-                       && view_area == LAB_SSD_PART_TITLEBAR) {
-               struct mousebind *mousebind;
-               wl_list_for_each_reverse (mousebind, &rc.mousebinds, link) {
-                       /* TODO: make this more generic */
-                       if ((mousebind->context == LAB_SSD_PART_TITLEBAR) &&
-                               (mousebind->mouse_event == MOUSE_ACTION_DOUBLECLICK) &&
-                               (mousebind->button == event->button)) {
-                               action(server, mousebind->action, mousebind->command);
-                       }
-               }
-               return;
-       }
-
        resize_edges = ssd_resize_edges(view_area);
        if (resize_edges) {
                interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
                return;
        }
 
-       switch (view_area) {
-       case LAB_SSD_BUTTON_CLOSE:
-               view->impl->close(view);
-               break;
-       case LAB_SSD_BUTTON_ICONIFY:
-               view_minimize(view, true);
-               break;
-       case LAB_SSD_PART_TITLEBAR:
+mousebindings:
+       if (event->state == WLR_BUTTON_RELEASED) {
+               handle_release_mousebinding(server, event->button, view_area);
+               return;
+       } else if (event->state == WLR_BUTTON_PRESSED) {
+               if (handle_press_mousebinding(server, event->button, view_area)) {
+                       return;
+               }
+       }
+
+       if (view_area == LAB_SSD_PART_TITLEBAR) {
                interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
-               break;
-       case LAB_SSD_BUTTON_MAXIMIZE:
-               view_toggle_maximize(view);
-               break;
        }
 }