diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 43312c3d..6c14e976 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -144,6 +144,7 @@ Configuration must be wrapped in a root-node. - Release: Releasing the specified button in the context. - Click: Pressing and then releasing inside of the the context. - DoubleClick: Two presses within the doubleClickTime. + - Drag: Pressing the button within the contex, then moving the cursor # LIBINPUT diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 0dfb6d41..8f4fc1a8 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -108,7 +108,7 @@ @@ -116,12 +116,12 @@ 500 - + - + @@ -129,48 +129,48 @@ - + - + - + - + - + - + - + - + - + diff --git a/include/config/mousebind.h b/include/config/mousebind.h index da43594c..e2da203c 100644 --- a/include/config/mousebind.h +++ b/include/config/mousebind.h @@ -11,6 +11,7 @@ enum mouse_event { MOUSE_ACTION_CLICK, MOUSE_ACTION_PRESS, MOUSE_ACTION_RELEASE, + MOUSE_ACTION_DRAG, }; struct mousebind { diff --git a/src/config/mousebind.c b/src/config/mousebind.c index 091e5824..fdbd34d0 100644 --- a/src/config/mousebind.c +++ b/src/config/mousebind.c @@ -49,6 +49,8 @@ mousebind_event_from_str(const char *str) return MOUSE_ACTION_PRESS; } else if (!strcasecmp(str, "release")) { return MOUSE_ACTION_RELEASE; + } else if (!strcasecmp(str, "drag")) { + return MOUSE_ACTION_DRAG; } wlr_log(WLR_ERROR, "unknown mouse action (%s)", str); return MOUSE_ACTION_NONE; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 8cb84312..fd1ec15c 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -520,23 +520,23 @@ load_default_key_bindings(void) static struct { const char *context, *button, *event, *action, *command; } mouse_combos[] = { - { "Left", "Left", "Press", "Resize", NULL}, - { "Top", "Left", "Press", "Resize", NULL}, - { "Bottom", "Left", "Press", "Resize", NULL}, - { "Right", "Left", "Press", "Resize", NULL}, - { "TLCorner", "Left", "Press", "Resize", NULL}, - { "TRCorner", "Left", "Press", "Resize", NULL}, - { "BRCorner", "Left", "Press", "Resize", NULL}, - { "BLCorner", "Left", "Press", "Resize", NULL}, - { "Frame", "A-Left", "Press", "Focus", NULL}, - { "Frame", "A-Left", "Press", "Raise", NULL}, - { "Frame", "A-Left", "Press", "Move", NULL}, - { "Frame", "A-Right", "Press", "Focus", NULL}, - { "Frame", "A-Right", "Press", "Raise", NULL}, - { "Frame", "A-Right", "Press", "Resize", NULL}, - { "Titlebar", "Left", "Press", "Focus", NULL}, - { "Titlebar", "Left", "Press", "Raise", NULL}, - { "TitleBar", "Left", "Press", "Move", NULL }, + { "Left", "Left", "Drag", "Resize", NULL}, + { "Top", "Left", "Drag", "Resize", NULL}, + { "Bottom", "Left", "Drag", "Resize", NULL}, + { "Right", "Left", "Drag", "Resize", NULL}, + { "TLCorner", "Left", "Drag", "Resize", NULL}, + { "TRCorner", "Left", "Drag", "Resize", NULL}, + { "BRCorner", "Left", "Drag", "Resize", NULL}, + { "BLCorner", "Left", "Drag", "Resize", NULL}, + { "Frame", "A-Left", "Drag", "Focus", NULL}, + { "Frame", "A-Left", "Drag", "Raise", NULL}, + { "Frame", "A-Left", "Drag", "Move", NULL}, + { "Frame", "A-Right", "Drag", "Focus", NULL}, + { "Frame", "A-Right", "Drag", "Raise", NULL}, + { "Frame", "A-Right", "Drag", "Resize", NULL}, + { "Titlebar", "Left", "Drag", "Focus", NULL}, + { "Titlebar", "Left", "Drag", "Raise", NULL}, + { "TitleBar", "Left", "Drag", "Move", NULL }, { "TitleBar", "Left", "DoubleClick", "ToggleMaximize", NULL }, { "Close", "Left", "Click", "Close", NULL }, { "Iconify", "Left", "Click", "Iconify", NULL}, diff --git a/src/cursor.c b/src/cursor.c index 03208736..1253a6f6 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -198,13 +198,14 @@ process_cursor_motion(struct server *server, uint32_t time) server->seat.cursor->x, server->seat.cursor->y, &surface, &sx, &sy, &view_area); + /* resize handles */ + uint32_t resize_edges = ssd_resize_edges(view_area); + /* Set cursor */ if (!view) { /* root, etc. */ cursor_set(&server->seat, XCURSOR_DEFAULT); } else { - /* resize handles */ - uint32_t resize_edges = ssd_resize_edges(view_area); if (resize_edges) { cursor_name_set_by_server = true; cursor_set(&server->seat, @@ -228,6 +229,25 @@ process_cursor_motion(struct server *server, uint32_t time) } } + struct mousebind *mousebind; + wl_list_for_each(mousebind, &rc.mousebinds, link) { + if (mousebind->mouse_event == MOUSE_ACTION_DRAG + && mousebind->pressed_in_context) { + /* Find closest resize edges in case action is Resize */ + if (view) { + resize_edges |= server->seat.cursor->x + < view->x + view->w / 2 ? WLR_EDGE_LEFT + : WLR_EDGE_RIGHT; + resize_edges |= server->seat.cursor->y + < view->y + view->h / 2 ? WLR_EDGE_TOP + : WLR_EDGE_BOTTOM; + } + + mousebind->pressed_in_context = false; + action(NULL, server, &mousebind->actions, resize_edges); + } + } + /* Required for iconify/maximize/close button mouse-over deco */ damage_all_outputs(server); @@ -473,6 +493,8 @@ handle_release_mousebinding(struct view *view, struct server *server, activated_any_frame |= mousebind->context == LAB_SSD_FRAME; action(view, server, &mousebind->actions, resize_edges); } + /* For the drag events */ + mousebind->pressed_in_context = false; } return activated_any && activated_any_frame; } @@ -518,6 +540,7 @@ handle_press_mousebinding(struct view *view, struct server *server, && mousebind->button == button && modifiers == mousebind->modifiers) { switch (mousebind->mouse_event) { + case MOUSE_ACTION_DRAG: /* FALLTHROUGH */ case MOUSE_ACTION_CLICK: mousebind->pressed_in_context = true; continue;