]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Resize via dragging corners
authorWenhua Zhao <whzhao@gmail.com>
Sun, 29 Nov 2020 01:20:01 +0000 (01:20 +0000)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sun, 29 Nov 2020 08:03:44 +0000 (08:03 +0000)
src/cursor.c

index abfdc11d425f458c99ecdbc0f8fb09128b836d9a..749275127f2db70ffa3eee52afbca60d38515e89 100644 (file)
@@ -1,6 +1,33 @@
 #include "labwc.h"
 #include "menu/menu.h"
 
+#define RESIZE_BORDER_WIDTH 4
+
+static uint32_t
+get_resize_edges(struct view *view, double x, double y)
+{
+       uint32_t edges = 0;
+       int top, right, bottom, left;
+
+       top = view->y - view->margin.top;
+       left = view->x - view->margin.left;
+       bottom = top + view->h + view->margin.top + view->margin.bottom;
+       right = left + view->w + view->margin.left + view->margin.right;
+
+       if (top <= y && y < top + RESIZE_BORDER_WIDTH) {
+               edges |= WLR_EDGE_TOP;
+       } else if (bottom - RESIZE_BORDER_WIDTH <= y && y < bottom) {
+               edges |= WLR_EDGE_BOTTOM;
+       }
+       if (left <= x && x < left + RESIZE_BORDER_WIDTH) {
+               edges |= WLR_EDGE_LEFT;
+       } else if (right - RESIZE_BORDER_WIDTH <= x && x < right) {
+               edges |= WLR_EDGE_RIGHT;
+       }
+
+       return edges;
+}
+
 static void
 request_cursor_notify(struct wl_listener *listener, void *data)
 {
@@ -121,6 +148,7 @@ process_cursor_motion(struct server *server, uint32_t time)
        struct wlr_seat *wlr_seat = server->seat.seat;
        struct wlr_surface *surface = NULL;
        int view_area;
+       char *cursor_name = NULL;
        struct view *view =
                desktop_view_at(server, server->seat.cursor->x, server->seat.cursor->y,
                                &surface, &sx, &sy, &view_area);
@@ -130,35 +158,45 @@ process_cursor_motion(struct server *server, uint32_t time)
                 * a default. This is what makes the cursor image appear when
                 * you move it around the screen, not over any views.
                 */
-               wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, XCURSOR_DEFAULT, server->seat.cursor);
+               cursor_name = XCURSOR_DEFAULT;
+       } else {
+               uint32_t resize_edges = get_resize_edges(
+                       view, server->seat.cursor->x, server->seat.cursor->y);
+               switch (resize_edges) {
+               case WLR_EDGE_TOP:
+                       cursor_name = "top_side";
+                       break;
+               case WLR_EDGE_RIGHT:
+                       cursor_name = "right_side";
+                       break;
+               case WLR_EDGE_BOTTOM:
+                       cursor_name = "bottom_side";
+                       break;
+               case WLR_EDGE_LEFT:
+                       cursor_name = "left_side";
+                       break;
+               case WLR_EDGE_TOP | WLR_EDGE_LEFT:
+                       cursor_name = "top_left_corner";
+                       break;
+               case WLR_EDGE_TOP | WLR_EDGE_RIGHT:
+                       cursor_name = "top_right_corner";
+                       break;
+               case WLR_EDGE_BOTTOM | WLR_EDGE_LEFT:
+                       cursor_name = "bottom_left_corner";
+                       break;
+               case WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT:
+                       cursor_name = "bottom_right_corner";
+                       break;
+               case 0:
+                       cursor_name = view_area == LAB_DECO_NONE ? NULL: XCURSOR_DEFAULT;
+                       break;
+               }
        }
-
-       /* TODO: Could we use wlr_xcursor_get_resize_name() here?? */
-       switch (view_area) {
-       case LAB_DECO_NONE:
-               break;
-       case LAB_DECO_PART_TOP:
-               wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, "top_side", server->seat.cursor);
-               break;
-       case LAB_DECO_PART_RIGHT:
+       if (cursor_name) {
                wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, "right_side", server->seat.cursor);
-               break;
-       case LAB_DECO_PART_BOTTOM:
-               wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, "bottom_side", server->seat.cursor);
-               break;
-       case LAB_DECO_PART_LEFT:
-               wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, "left_side", server->seat.cursor);
-               break;
-       default:
-               wlr_xcursor_manager_set_cursor_image(
-                       server->seat.xcursor_manager, XCURSOR_DEFAULT, server->seat.cursor);
-               break;
+                       server->seat.xcursor_manager, cursor_name, server->seat.cursor);
        }
+
        if (surface) {
                bool focus_changed =
                        wlr_seat->pointer_state.focused_surface != surface;
@@ -245,6 +283,7 @@ cursor_button(struct wl_listener *listener, void *data)
        double sx, sy;
        struct wlr_surface *surface;
        int view_area;
+       uint32_t resize_edges;
        struct view *view = desktop_view_at(server, server->seat.cursor->x,
                server->seat.cursor->y, &surface, &sx, &sy, &view_area);
 
@@ -273,6 +312,13 @@ cursor_button(struct wl_listener *listener, void *data)
 
        /* Handle _press_ on view */
        desktop_focus_view(&server->seat, view);
+
+       resize_edges = get_resize_edges(view, server->seat.cursor->x, server->seat.cursor->y);
+       if (resize_edges != 0) {
+               interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
+               return;
+       }
+
        switch (view_area) {
        case LAB_DECO_BUTTON_CLOSE:
                view->impl->close(view);
@@ -283,22 +329,6 @@ cursor_button(struct wl_listener *listener, void *data)
        case LAB_DECO_PART_TITLE:
                interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
                break;
-       case LAB_DECO_PART_TOP:
-               interactive_begin(view, LAB_INPUT_STATE_RESIZE,
-                                 WLR_EDGE_TOP);
-               break;
-       case LAB_DECO_PART_RIGHT:
-               interactive_begin(view, LAB_INPUT_STATE_RESIZE,
-                                 WLR_EDGE_RIGHT);
-               break;
-       case LAB_DECO_PART_BOTTOM:
-               interactive_begin(view, LAB_INPUT_STATE_RESIZE,
-                                 WLR_EDGE_BOTTOM);
-               break;
-       case LAB_DECO_PART_LEFT:
-               interactive_begin(view, LAB_INPUT_STATE_RESIZE,
-                                 WLR_EDGE_LEFT);
-               break;
        }
 }