gimp but for windows: a wayland compositor
git clone https://github.com/m-col/wimp
Files | Refs | Readme

Commit 881484955c2a528e79832f6360c6ab1658c1327f
Parent: bd719e46da3325a43e514432438dbd781e2194c1
Author: mcol <mcol@posteo.net>
Date: 2021-02-13 12:10:34 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-02-13 12:10:34 +0000

Rendering corner areas and drag on them to resize windows

src/types.h Modified

@@ -19,6 +19,8 @@
 #define is_readable(p) (access(p, R_OK) != -1)
 #define is_executable(p) (access(p, R_OK | X_OK) != -1)
 
+#define CORNER 24
+
 enum cursor_mode {
     CURSOR_PASSTHROUGH,
     CURSOR_MOD,
@@ -215,7 +217,7 @@
 };
 
 enum direction {
-    NONE = 0,
+    NO_DIRECTION = 0,
     UP = 1 << 0,
     RIGHT = 1 << 1,
     DOWN = 1 << 2,

src/output.c Modified

@@ -61,15 +61,15 @@
 	    struct wlr_box corners = {
 		.x = borders.x,
 		.y = borders.y,
-		.width = 24,
-		.height = 24,
+		.width = CORNER,
+		.height = CORNER,
 	    };
 	    float *corner = rdata->is_focussed ?
 		wimp.current_desk->corner_focus : wimp.current_desk->corner_normal;
 	    wlr_render_rect(rdata->renderer, &corners, corner, output->transform_matrix);
-	    corners.x = borders.x + borders.width - 24;
+	    corners.x = borders.x + borders.width - CORNER;
 	    wlr_render_rect(rdata->renderer, &corners, corner, output->transform_matrix);
-	    corners.y = borders.y + borders.height - 24;
+	    corners.y = borders.y + borders.height - CORNER;
 	    wlr_render_rect(rdata->renderer, &corners, corner, output->transform_matrix);
 	    corners.x = borders.x;
 	    wlr_render_rect(rdata->renderer, &corners, corner, output->transform_matrix);

src/cursor.c Modified

@@ -168,6 +168,67 @@
 }
 
 
+static enum wlr_edges pointer_in_view_corner(struct view *view) {
+    /* It is assumed that the pointer is above the view. */
+    double x = wimp.cursor->x;
+    double y = wimp.cursor->y;
+    double zoom = wimp.current_desk->zoom;
+    int border_width = wimp.current_desk->border_width;
+    enum wlr_edges edges = WLR_EDGE_NONE;
+
+    struct wlr_box inner = {
+	.x = view->x * zoom,
+	.y = view->y * zoom,
+	.width = view->surface->geometry.width * zoom,
+	.height = view->surface->geometry.height * zoom,
+    };
+    struct wlr_box outer = {
+	.x = inner.x - border_width * zoom,
+	.y = inner.y - border_width * zoom,
+	.width = inner.width + border_width * 2 * zoom,
+	.height = inner.height + border_width * 2 * zoom,
+    };
+
+    if (x <= inner.x) {
+	edges |= WLR_EDGE_LEFT;
+	if (y <= outer.y + CORNER) {
+	    edges |= WLR_EDGE_TOP;
+	} else if (outer.y + outer.height - CORNER <= y) {
+	    edges |= WLR_EDGE_BOTTOM;
+	}
+	return edges;
+    }
+    if (inner.x + inner.width <= x) {
+	edges |= WLR_EDGE_RIGHT;
+	if (y <= outer.y + CORNER) {
+	    edges |= WLR_EDGE_TOP;
+	} else if (outer.y + outer.height - CORNER <= y) {
+	    edges |= WLR_EDGE_BOTTOM;
+	}
+	return edges;
+    }
+    if (y <= inner.y) {
+	edges |= WLR_EDGE_TOP;
+	if (x <= outer.x + CORNER) {
+	    edges |= WLR_EDGE_LEFT;
+	} else if (outer.x + outer.width - CORNER <= x) {
+	    edges |= WLR_EDGE_RIGHT;
+	}
+	return edges;
+    }
+    if (inner.y + inner.height <= y) {
+	edges |= WLR_EDGE_BOTTOM;
+	if (x <= outer.x + CORNER) {
+	    edges |= WLR_EDGE_LEFT;
+	} else if (outer.x + outer.width - CORNER <= x) {
+	    edges |= WLR_EDGE_RIGHT;
+	}
+	return edges;
+    }
+    return edges;
+}
+
+
 static void process_cursor_motion(uint32_t time, double dx, double dy) {
     double sx, sy;
     struct wlr_seat *seat;
@@ -280,7 +341,23 @@
     else {
 	struct view *view = under_pointer(&surface, &sx, &sy, &is_layer);
 	if (!is_layer) {
-	    focus_view(view, surface);
+	    if (view) {
+		enum wlr_edges edges = pointer_in_view_corner(view);
+		if (edges) {
+		    wimp.grabbed_view = view;
+		    wimp.resize_edges = edges;
+		    wimp.grab_x = wimp.cursor->x - view->x * wimp.current_desk->zoom;
+		    wimp.grab_y = wimp.cursor->y - view->y * wimp.current_desk->zoom;
+		    wlr_xdg_surface_get_geometry(view->surface, &wimp.grab_geobox);
+		    wimp.grab_geobox.x = view->x;
+		    wimp.grab_geobox.y = view->y;
+		    wimp.cursor_mode = CURSOR_RESIZE;
+		} else {
+		    focus_view(view, surface);
+		}
+	    } else {
+		focus_view(view, surface);
+	    }
 	}
     }
 }

src/action.c Modified

@@ -388,7 +388,7 @@
 	    width = output->width;
 	    height = output->height / 2;
 	    break;
-	case NONE:
+	case NO_DIRECTION:
 	    return;
     }