~sircmpwn/wio

Resize windows by dragging their corner borders v1 PROPOSED

Leonid Bobrov
Leonid Bobrov: 1
 Resize windows by dragging their corner borders

 5 files changed, 232 insertions(+), 36 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/wio/patches/11194/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] Resize windows by dragging their corner borders Export this patch

Leonid Bobrov
---
 include/server.h |   6 +-
 include/view.h   |   6 +-
 input.c          | 166 +++++++++++++++++++++++++++++++++++++++++++----
 output.c         |  36 +++++++++-
 view.c           |  54 +++++++++------
 5 files changed, 232 insertions(+), 36 deletions(-)

diff --git a/include/server.h b/include/server.h
index 60842e1..f49b2dd 100644
--- a/include/server.h
+++ b/include/server.h
@@ -26,9 +26,13 @@ enum wio_input_state {
	INPUT_STATE_RESIZE_SELECT,
	INPUT_STATE_RESIZE_START,
	INPUT_STATE_RESIZE_END,
	INPUT_STATE_BORDER_DRAG_TOP_RIGHT,
	INPUT_STATE_BORDER_DRAG_TOP_LEFT,
	INPUT_STATE_BORDER_DRAG_TOP,
	INPUT_STATE_BORDER_DRAG_RIGHT,
	INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT,
	INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT,
	INPUT_STATE_BORDER_DRAG_BOTTOM,
	INPUT_STATE_BORDER_DRAG_RIGHT,
	INPUT_STATE_BORDER_DRAG_LEFT,
	INPUT_STATE_DELETE_SELECT,
	INPUT_STATE_HIDE_SELECT,
diff --git a/include/view.h b/include/view.h
index 36303fa..5623393 100644
--- a/include/view.h
+++ b/include/view.h
@@ -16,9 +16,13 @@ struct wio_view {

enum wio_view_area {
	VIEW_AREA_SURFACE = 0,
	VIEW_AREA_BORDER_TOP_RIGHT,
	VIEW_AREA_BORDER_TOP_LEFT,
	VIEW_AREA_BORDER_TOP,
	VIEW_AREA_BORDER_RIGHT,
	VIEW_AREA_BORDER_BOTTOM_RIGHT,
	VIEW_AREA_BORDER_BOTTOM_LEFT,
	VIEW_AREA_BORDER_BOTTOM,
	VIEW_AREA_BORDER_RIGHT,
	VIEW_AREA_BORDER_LEFT,
};

diff --git a/input.c b/input.c
index e4e4fbf..29121fd 100644
--- a/input.c
+++ b/input.c
@@ -131,8 +131,13 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) {
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"grabbing", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_right_corner", server->cursor);
			break;
		case INPUT_STATE_RESIZE_START:
		case INPUT_STATE_NEW_START:
		case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_left_corner", server->cursor);
			break;
@@ -140,22 +145,27 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) {
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_side", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_RIGHT:
		case INPUT_STATE_RESIZE_END:
		case INPUT_STATE_NEW_END:
		case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"right_side", server->cursor);
					"bottom_right_corner", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"bottom_left_corner", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_BOTTOM:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"bottom_side", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_LEFT:
		case INPUT_STATE_BORDER_DRAG_RIGHT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"left_side", server->cursor);
					"right_side", server->cursor);
			break;
		case INPUT_STATE_RESIZE_END:
		case INPUT_STATE_NEW_END:
		case INPUT_STATE_BORDER_DRAG_LEFT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"bottom_right_corner", server->cursor);
					"left_side", server->cursor);
			break;
		default:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
@@ -378,6 +388,63 @@ static void handle_button_internal(
			server->input_state = INPUT_STATE_RESIZE_END;
		}
		break;
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		y1 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		y2 = server->cursor->y;
		x1 = server->interactive.view->x, x2 = server->cursor->x;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		}
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		}
		if (height < 100) {
			height = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		y1 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		y2 = server->cursor->y;
		x1 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		x2 = server->cursor->x;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		}
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		}
		if (height < 100) {
			height = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_TOP:
		y1 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		y2 = server->cursor->y;
@@ -398,22 +465,59 @@ static void handle_button_internal(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_LEFT:
	case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
		x1 = server->interactive.view->x, x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		}
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		}
		if (height < 100) {
			height = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		x1 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		}
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1;
		height = server->interactive.view->xdg_surface->surface->current.height;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		}
		if (height < 100) {
			height = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
@@ -430,8 +534,8 @@ static void handle_button_internal(
				x1, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		if (height < 100) {
			height = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
@@ -456,6 +560,26 @@ static void handle_button_internal(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		x1 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1;
		height = server->interactive.view->xdg_surface->surface->current.height;
		if (width < 100) {
			width = 100;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_RESIZE_END:
		x1 = server->interactive.sx, x2 = server->cursor->x;
		y1 = server->interactive.sy, y2 = server->cursor->y;
@@ -541,18 +665,34 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
			wlr_seat_pointer_notify_button(server->seat,
					event->time_msec, event->button, event->state);
			break;
		case VIEW_AREA_BORDER_TOP_RIGHT:
			view_begin_interactive(view, surface, view->x, view->y,
					"top_right_corner", INPUT_STATE_BORDER_DRAG_TOP_RIGHT);
			break;
		case VIEW_AREA_BORDER_TOP_LEFT:
			view_begin_interactive(view, surface, view->x, view->y,
					"top_left_corner", INPUT_STATE_BORDER_DRAG_TOP_LEFT);
			break;
		case VIEW_AREA_BORDER_TOP:
			view_begin_interactive(view, surface, view->x, view->y,
					"top_side", INPUT_STATE_BORDER_DRAG_TOP);
			break;
		case VIEW_AREA_BORDER_RIGHT:
		case VIEW_AREA_BORDER_BOTTOM_RIGHT:
			view_begin_interactive(view, surface, view->x, view->y,
					"right_side", INPUT_STATE_BORDER_DRAG_RIGHT);
					"bottom_right_corner", INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT);
			break;
		case VIEW_AREA_BORDER_BOTTOM_LEFT:
			view_begin_interactive(view, surface, view->x, view->y,
					"bottom_left_corner", INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT);
			break;
		case VIEW_AREA_BORDER_BOTTOM:
			view_begin_interactive(view, surface, view->x, view->y,
					"bottom_side", INPUT_STATE_BORDER_DRAG_BOTTOM);
			break;
		case VIEW_AREA_BORDER_RIGHT:
			view_begin_interactive(view, surface, view->x, view->y,
					"right_side", INPUT_STATE_BORDER_DRAG_RIGHT);
			break;
		case VIEW_AREA_BORDER_LEFT:
			view_begin_interactive(view, surface, view->x, view->y,
					"left_side", INPUT_STATE_BORDER_DRAG_LEFT);
diff --git a/output.c b/output.c
index 6a059f5..20156f9 100644
--- a/output.c
+++ b/output.c
@@ -308,6 +308,22 @@ static void output_frame(struct wl_listener *listener, void *data) {
	}
	view = server->interactive.view;
	switch (server->input_state) {
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		render_view_border(renderer, output, view,
			view->x,
			server->cursor->y,
			server->cursor->x - server->interactive.sx,
			view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy),
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		render_view_border(renderer, output, view,
			server->cursor->x,
			server->cursor->y,
			view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx),
			view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy),
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_TOP:
		render_view_border(renderer, output, view,
			view->x,
@@ -316,12 +332,20 @@ static void output_frame(struct wl_listener *listener, void *data) {
			view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy),
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_LEFT:
	case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
		render_view_border(renderer, output, view,
			view->x,
			view->y,
			server->cursor->x - server->interactive.sx,
			server->cursor->y - server->interactive.sy,
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		render_view_border(renderer, output, view,
			server->cursor->x,
			view->y,
			view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx),
			view->xdg_surface->surface->current.height,
			server->cursor->y - server->interactive.sy,
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_BOTTOM:
@@ -340,6 +364,14 @@ static void output_frame(struct wl_listener *listener, void *data) {
			view->xdg_surface->surface->current.height,
			1);
		break;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		render_view_border(renderer, output, view,
			server->cursor->x,
			view->y,
			view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx),
			view->xdg_surface->surface->current.height,
			1);
		break;
	case INPUT_STATE_MOVE:
		render_view_border(renderer, output, view,
			server->cursor->x - server->interactive.sx,
diff --git a/view.c b/view.c
index 37ad734..f57c189 100644
--- a/view.c
+++ b/view.c
@@ -138,41 +138,57 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		}
		// Top border
		border_box.height = window_border;
		border_box.width = view->xdg_surface->surface->current.width;
		border_box.x = view->x;
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		border_box.x = view->x - window_border;
		border_box.y = view->y - window_border;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_TOP;
			return view;
			goto SIDE_BORDER;
		}

		// Bottom border
		border_box.y = view->y + view->xdg_surface->surface->current.height;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_BOTTOM;
		}

		SIDE_BORDER:
		// Right border
		border_box.height = view->xdg_surface->surface->current.height;
		border_box.height = view->xdg_surface->surface->current.height + window_border * 2;
		border_box.width = window_border;
		border_box.x = view->x + view->xdg_surface->surface->current.width;
		border_box.y = view->y;
		border_box.y = view->y - window_border;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_RIGHT;
			switch (*view_area) {
			case VIEW_AREA_BORDER_TOP:
				*view_area = VIEW_AREA_BORDER_TOP_RIGHT;
				break;
			case VIEW_AREA_BORDER_BOTTOM:
				*view_area = VIEW_AREA_BORDER_BOTTOM_RIGHT;
				break;
			default:
				*view_area = VIEW_AREA_BORDER_RIGHT;
			}
			return view;
		}

		// Bottom border
		border_box.height = window_border;
		border_box.width = view->xdg_surface->surface->current.width;
		border_box.x = view->x;
		border_box.y = view->y + view->xdg_surface->surface->current.height;
		// Left border
		border_box.x = view->x - window_border;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_BOTTOM;
			switch (*view_area) {
			case VIEW_AREA_BORDER_TOP:
				*view_area = VIEW_AREA_BORDER_TOP_LEFT;
				break;
			case VIEW_AREA_BORDER_BOTTOM:
				*view_area = VIEW_AREA_BORDER_BOTTOM_LEFT;
				break;
			default:
				*view_area = VIEW_AREA_BORDER_LEFT;
			}
			return view;
		}

		// Left border
		border_box.height = view->xdg_surface->surface->current.height;
		border_box.width = window_border;
		border_box.x = view->x - window_border;
		border_box.y = view->y;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_LEFT;
		if (*view_area == VIEW_AREA_BORDER_TOP || *view_area == VIEW_AREA_BORDER_BOTTOM) {
			return view;
		}
	}
-- 
2.27.0
Please ignore this patch, I want to make it better:
* less duplicate code;
* render borders accurately when reflecting;
* try to match Rio's behavior when reflecting.