~sircmpwn/wio

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
12 2

[PATCH 00/11] Behave more like Rio

Details
Message ID
<20200618073954.189606-1-goleo@disroot.org>
DKIM signature
pass
Download raw message
Please take a look at whole diff, I made terrible commits, reviewing by commit is a pain in the eyes.

I keep my fork at https://git.sr.ht/~goleo/wio and https://github.com/goleo108/wio

Leonid Bobrov (11):
  Resize views accurately
  Simplify code for resizing views
  Don't mutate views when input state is active
  Move views by dragging their borders
  Remove obsolete options in contrib/alacritty.yml
  Left and middle mouse buttons stop current action / event
  Remove duplicate code in New, Resize and resize by dragging borders
  Change surface color to grey
  Resize views by dragging their borders like in Rio
  Move and rename which_box and canon_box
  Set cursor image to arrow when hovering over the borders

 contrib/alacritty.yml |   3 -
 include/colors.h      |   4 +
 include/server.h      |   5 +-
 include/view.h        |  17 +-
 input.c               | 395 ++++++++++++++----------------------------
 output.c              |  48 ++---
 view.c                | 150 +++++++++++-----
 7 files changed, 271 insertions(+), 351 deletions(-)

-- 
2.27.0

[PATCH 02/11] Simplify code for resizing views

Details
Message ID
<20200618073954.189606-3-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +210 -379
And it still behaves worse than Rio...

Also I made New and Resize commands behave like in Rio.
---
 include/colors.h |   4 +
 include/server.h |   9 +-
 include/view.h   |  19 ++--
 input.c          | 220 ++++++-----------------------------------------
 output.c         | 149 +++-----------------------------
 view.c           | 188 ++++++++++++++++++++++++++++++++--------
 6 files changed, 210 insertions(+), 379 deletions(-)

diff --git a/include/colors.h b/include/colors.h
index f8d40dc..b1f83d3 100644
--- a/include/colors.h
+++ b/include/colors.h
@@ -29,4 +29,8 @@ static const float menu_border[4] = {
	0x78 / 255.0f, 0xAD / 255.0f, 0x84 / 255.0f, 1.0f,
};

static const float surface[4] = {
	0xFF / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f,
};

#endif
diff --git a/include/server.h b/include/server.h
index f49b2dd..b6eaaa6 100644
--- a/include/server.h
+++ b/include/server.h
@@ -26,14 +26,7 @@ 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_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_BORDER_DRAG,
	INPUT_STATE_DELETE_SELECT,
	INPUT_STATE_HIDE_SELECT,
};
diff --git a/include/view.h b/include/view.h
index e7631de..e1a8bbf 100644
--- a/include/view.h
+++ b/include/view.h
@@ -5,6 +5,9 @@

#define MINWIDTH 100
#define MINHEIGHT 100
// TODO: scale
#define less_swap1(A, B) { if (A < B) { int C = A; A = B + window_border * 2; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C - window_border * 2; } }

struct wio_server;

@@ -19,17 +22,21 @@ struct wio_view {
};

enum wio_view_area {
	VIEW_AREA_NONE = 0,
	VIEW_AREA_SURFACE = 1,
	VIEW_AREA_BORDER_TOP = 2,
	VIEW_AREA_BORDER_BOTTOM = 4,
	VIEW_AREA_BORDER_RIGHT = 8,
	VIEW_AREA_BORDER_LEFT = 16,
	VIEW_AREA_BORDER_TOP_LEFT = 0,
	VIEW_AREA_BORDER_TOP,
	VIEW_AREA_BORDER_TOP_RIGHT,
	VIEW_AREA_BORDER_LEFT,
	VIEW_AREA_SURFACE,
	VIEW_AREA_BORDER_RIGHT,
	VIEW_AREA_BORDER_BOTTOM_LEFT,
	VIEW_AREA_BORDER_BOTTOM,
	VIEW_AREA_BORDER_BOTTOM_RIGHT,
};

void server_new_xdg_surface(struct wl_listener *listener, void *data);

void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wlr_box which_box(struct wio_server *server);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy);
void wio_view_move(struct wio_view *view, int x, int y);
diff --git a/input.c b/input.c
index 84c16b0..8f7b31e 100644
--- a/input.c
+++ b/input.c
@@ -14,9 +14,12 @@
#include "server.h"
#include "view.h"

// TODO: scale
#define less_swap1(A, B) { if (A < B) { int C = A; A = B + window_border * 2; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C - window_border * 2; } }
static char *corners[9] = {
	"top_left_corner", "top_side", "top_right_corner",
	"left_side", NULL, "right_side",
	"bottom_left_corner", "bottom_side", "bottom_right_corner",
};
static char *corner = NULL;

static void keyboard_handle_modifiers(
		struct wl_listener *listener, void *data) {
@@ -118,8 +121,10 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) {
	double sx, sy;
	struct wlr_seat *seat = server->seat;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	struct wio_view *view = NULL;
	if (server->input_state != INPUT_STATE_BORDER_DRAG) {
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	}
	if (!view) {
		switch (server->input_state) {
		case INPUT_STATE_MOVE_SELECT:
@@ -133,42 +138,20 @@ 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:
		case INPUT_STATE_BORDER_DRAG:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_right_corner", server->cursor);
					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;
		case INPUT_STATE_BORDER_DRAG_TOP:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_side", server->cursor);
			break;
		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,
					"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_RIGHT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"right_side", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_LEFT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"left_side", server->cursor);
			break;
		default:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"left_ptr", server->cursor);
@@ -260,19 +243,10 @@ static void new_view(struct wio_server *server) {
	less_swap2(x2, x1);
	less_swap2(y2, y1);
	int width = x2 - x1, height = y2 - y1;
	struct wio_new_view *view = calloc(1, sizeof(struct wio_new_view));
	if (width < MINWIDTH && (x1 - server->interactive.sx) < 0) {
		x1 -= MINWIDTH - width;
	}
	if (height < MINHEIGHT && (y1 - server->interactive.sy) < 0) {
		y1 -= MINHEIGHT - height;
	}
	if (width < MINWIDTH) {
		width = MINWIDTH;
	}
	if (height < MINHEIGHT) {
		height = MINHEIGHT;
	if (width < MINWIDTH || height < MINHEIGHT) {
		return;
	}
	struct wio_new_view *view = calloc(1, sizeof(struct wio_new_view));
	view->box.x = x1;
	view->box.y = y1;
	view->box.width = width;
@@ -333,6 +307,7 @@ static void handle_button_internal(
		.x = server->menu.x, .y = server->menu.y,
		.width = server->menu.width, .height = server->menu.height,
	};
	struct wlr_box box;
	int x1, x2, y1, y2;
	uint32_t width, height;
	switch (server->input_state) {
@@ -387,119 +362,9 @@ static void handle_button_internal(
			server->input_state = INPUT_STATE_RESIZE_END;
		}
		break;
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		less_swap1(y2, y1);
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		less_swap1(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	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;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap1(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM:
		x1 = server->interactive.view->x;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap2(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_RIGHT:
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		x1 = box.x, y1 = box.y, width = box.width, height = box.height;
		goto Done;
	case INPUT_STATE_RESIZE_END:
		x1 = server->interactive.sx, x2 = server->cursor->x;
@@ -507,22 +372,14 @@ static void handle_button_internal(
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.sx) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.sy) < 0) {
			y1 -= MINHEIGHT - height;
		if (width < MINWIDTH || height < MINHEIGHT) {
			view_end_interactive(server);
			break;
		}
	Done:
		wio_view_move(server->interactive.view,
				x1, y1);
		if (width < MINWIDTH) {
			width = MINWIDTH;
		}
		if (height < MINHEIGHT) {
			height = MINHEIGHT;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
@@ -580,37 +437,10 @@ 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|VIEW_AREA_BORDER_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|VIEW_AREA_BORDER_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_BOTTOM|VIEW_AREA_BORDER_RIGHT:
			view_begin_interactive(view, surface, view->x, view->y,
					"bottom_right_corner", INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT);
			break;
		case VIEW_AREA_BORDER_BOTTOM|VIEW_AREA_BORDER_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:
		default:
			corner = corners[view->area];
			view_begin_interactive(view, surface, view->x, view->y,
					"left_side", INPUT_STATE_BORDER_DRAG_LEFT);
					corner, INPUT_STATE_BORDER_DRAG);
			break;
		}
	} else {
diff --git a/output.c b/output.c
index 88f827b..3ec64a8 100644
--- a/output.c
+++ b/output.c
@@ -272,7 +272,9 @@ static void output_frame(struct wl_listener *listener, void *data) {
	struct wio_output *output = wl_container_of(listener, output, frame);
	struct wio_server *server = output->server;
	struct wlr_renderer *renderer = server->renderer;
	int x, y, width, height, scale;
	struct wlr_box box;
	int x, y, width, height;
	float color[4];

	struct timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
@@ -308,134 +310,11 @@ static void output_frame(struct wl_listener *listener, void *data) {
				render_surface, &rdata);
	}
	view = server->interactive.view;
	scale = output->wlr_output->scale;
	switch (server->input_state) {
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		x = view->x;
		y = server->cursor->y;
		width = server->cursor->x - server->interactive.sx;
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		x = server->cursor->x;
		y = server->cursor->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP:
		x = view->x;
		y = server->cursor->y;
		width = view->xdg_surface->surface->current.width;
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
		x = view->x;
		y = view->y;
		width = server->cursor->x - server->interactive.sx;
		height = server->cursor->y - server->interactive.sy;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		x = server->cursor->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = server->cursor->y - server->interactive.sy;
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM:
		x = view->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width;
		height = server->cursor->y - server->interactive.sy;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_RIGHT:
		x = view->x;
		y = view->y;
		width = server->cursor->x - server->interactive.sx;
		height = view->xdg_surface->surface->current.height;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		x = server->cursor->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = view->xdg_surface->surface->current.height;
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		render_view_border(renderer, output, NULL, box.x, box.y, box.width, box.height, 1);
		break;
	case INPUT_STATE_MOVE:
		render_view_border(renderer, output, view,
			server->cursor->x - server->interactive.sx,
@@ -450,20 +329,18 @@ static void output_frame(struct wl_listener *listener, void *data) {
		y = server->interactive.sy;
		width = server->cursor->x - server->interactive.sx;
		height = server->cursor->y - server->interactive.sy;
	Done:
		if (width < 0) {
			width *= -1;
			x -= ((width < MINWIDTH) ? MINWIDTH : width) + window_border * 2 * scale;
			x -= width + window_border * 2;
		}
		if (height < 0) {
			height *= -1;
			y -= ((height < MINHEIGHT) ? MINHEIGHT : height) + window_border * 2 * scale;
		}
		if (width < MINWIDTH) {
			width = MINWIDTH;
			y -= height + window_border * 2;
		}
		if (height < MINHEIGHT) {
			height = MINHEIGHT;
		if (width > 0 && height > 0) {
			box.x = x, box.y = y, box.width = width, box.height = height;
			memcpy(color, surface, sizeof(color));
			wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix);
		}
		render_view_border(renderer, output, NULL, x, y, width, height, 1);
		break;
diff --git a/view.c b/view.c
index 259a7b1..1e93a13 100644
--- a/view.c
+++ b/view.c
@@ -122,6 +122,157 @@ static bool view_at(struct wio_view *view,
	return false;
}

static int portion(int x, int lo, int width) {
	x -= lo;
	if (x < 20) {
		return 0;
	}
	if (x > width-20) {
		return 2;
	}
	return 1;
}

static int which_corner(struct wlr_box *box, int x, int y) {
	int i, j;

	i = portion(x, box->x, box->width);
	j = portion(y, box->y, box->height);
	return 3*j+i;
}

struct wlr_box which_box(struct wio_server *server) {
	struct wlr_box box;
	int x1, x2, y1, y2, width, height;
	switch (server->interactive.view->area) {
	case VIEW_AREA_BORDER_TOP_LEFT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		less_swap1(y2, y1);
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_TOP:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		less_swap1(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_TOP_RIGHT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		break;
	case VIEW_AREA_BORDER_RIGHT:
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		break;
	case VIEW_AREA_BORDER_BOTTOM_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap1(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_BOTTOM:
		x1 = server->interactive.view->x;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap2(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_BOTTOM_RIGHT:
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		break;
	}
	if (width < MINWIDTH) {
		width = MINWIDTH;
	}
	if (height < MINHEIGHT) {
		height = MINHEIGHT;
	}
	box.x = x1;
	box.y = y1;
	box.width = width;
	box.height = height;
	return box;
}

struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy) {
	struct wlr_box border_box = {
@@ -130,49 +281,18 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
	};
	struct wio_view *view;
	wl_list_for_each(view, &server->views, link) {
		view->area = VIEW_AREA_NONE;

		// Surface
		if (view_at(view, lx, ly, surface, sx, sy)) {
			view->area = VIEW_AREA_SURFACE;
			return view;
		}

		// Top border
		border_box.height = window_border;
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		// Border
		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;
			goto SideBorder;
		}

		// 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;
		}

	SideBorder:
		// Right border
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		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 - window_border;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			view->area |= VIEW_AREA_BORDER_RIGHT;
			return view;
		}

		// 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_LEFT;
			return view;
		}

		if (view->area != VIEW_AREA_NONE) {
			view->area = which_corner(&border_box, server->cursor->x, server->cursor->y);
			return view;
		}
	}
-- 
2.27.0

[PATCH 03/11] Don't mutate views when input state is active

Details
Message ID
<20200618073954.189606-4-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +53 -49
---
 input.c | 102 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 53 insertions(+), 49 deletions(-)

diff --git a/input.c b/input.c
index 8f7b31e..c5b25d9 100644
--- a/input.c
+++ b/input.c
@@ -122,42 +122,44 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) {
	struct wlr_seat *seat = server->seat;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = NULL;
	if (server->input_state != INPUT_STATE_BORDER_DRAG) {
	if (server->input_state == INPUT_STATE_NONE) {
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	}
	if (!view) {
		switch (server->input_state) {
		case INPUT_STATE_MOVE_SELECT:
		case INPUT_STATE_RESIZE_SELECT:
		case INPUT_STATE_DELETE_SELECT:
		case INPUT_STATE_HIDE_SELECT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"hand1", server->cursor);
			break;
		case INPUT_STATE_MOVE:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"grabbing", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					corner, server->cursor);
			break;
		case INPUT_STATE_RESIZE_START:
		case INPUT_STATE_NEW_START:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_left_corner", server->cursor);
			break;
		case INPUT_STATE_RESIZE_END:
		case INPUT_STATE_NEW_END:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"bottom_right_corner", server->cursor);
			break;
		default:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"left_ptr", server->cursor);
			break;
		}
	if (view) {
		goto End;
	}
	switch (server->input_state) {
	case INPUT_STATE_MOVE_SELECT:
	case INPUT_STATE_RESIZE_SELECT:
	case INPUT_STATE_DELETE_SELECT:
	case INPUT_STATE_HIDE_SELECT:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"hand1", server->cursor);
		break;
	case INPUT_STATE_MOVE:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"grabbing", server->cursor);
		break;
	case INPUT_STATE_BORDER_DRAG:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				corner, server->cursor);
		break;
	case INPUT_STATE_RESIZE_START:
	case INPUT_STATE_NEW_START:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"top_left_corner", server->cursor);
		break;
	case INPUT_STATE_RESIZE_END:
	case INPUT_STATE_NEW_END:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"bottom_right_corner", server->cursor);
		break;
	default:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"left_ptr", server->cursor);
		break;
	}
End:
	if (surface) {
		bool focus_changed = seat->pointer_state.focused_surface != surface;
		wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
@@ -428,23 +430,25 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
	struct wlr_event_pointer_button *event = data;
	double sx, sy;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	if (server->input_state == INPUT_STATE_NONE && view) {
		wio_view_focus(view, surface);
		switch (view->area) {
		case VIEW_AREA_SURFACE:
			wlr_seat_pointer_notify_button(server->seat,
					event->time_msec, event->button, event->state);
			break;
		default:
			corner = corners[view->area];
			view_begin_interactive(view, surface, view->x, view->y,
					corner, INPUT_STATE_BORDER_DRAG);
			break;
		}
	} else {
	struct wio_view *view = NULL;
	if (server->input_state == INPUT_STATE_NONE) {
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	}
	if (!view) {
		handle_button_internal(server, event);
		return;
	}
	wio_view_focus(view, surface);
	switch (view->area) {
	case VIEW_AREA_SURFACE:
		wlr_seat_pointer_notify_button(server->seat,
				event->time_msec, event->button, event->state);
		break;
	default:
		corner = corners[view->area];
		view_begin_interactive(view, surface, view->x, view->y,
				corner, INPUT_STATE_BORDER_DRAG);
		break;
	}
}

-- 
2.27.0

[PATCH 01/11] Resize views accurately

Details
Message ID
<20200618073954.189606-2-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +352 -178
As promised, I did:
* avoid some, but not all, duplicate code;
* resize views when dragging corner borders;
* width and height never become negative
  to avoid rendering bugs while reflecting;
* reflection behaves like in Rio;
* minimal size is enforced on red box like in Rio.

TODO: input.c needs int scale
---
 include/server.h |   6 +-
 include/view.h   |  18 +--
 input.c          | 281 ++++++++++++++++++++++++++++-------------------
 output.c         | 179 ++++++++++++++++++++++++------
 view.c           |  46 ++++----
 5 files changed, 352 insertions(+), 178 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..e7631de 100644
--- a/include/view.h
+++ b/include/view.h
@@ -3,10 +3,14 @@
#include <wlr/types/wlr_xdg_shell.h>
#include <wayland-server.h>

#define MINWIDTH 100
#define MINHEIGHT 100

struct wio_server;

struct wio_view {
	int x, y;
	int area;
	struct wlr_xdg_surface *xdg_surface;
	struct wio_server *server;
	struct wl_list link;
@@ -15,19 +19,19 @@ struct wio_view {
};

enum wio_view_area {
	VIEW_AREA_SURFACE = 0,
	VIEW_AREA_BORDER_TOP,
	VIEW_AREA_BORDER_RIGHT,
	VIEW_AREA_BORDER_BOTTOM,
	VIEW_AREA_BORDER_LEFT,
	VIEW_AREA_NONE = 0,
	VIEW_AREA_SURFACE = 1,
	VIEW_AREA_BORDER_TOP = 2,
	VIEW_AREA_BORDER_BOTTOM = 4,
	VIEW_AREA_BORDER_RIGHT = 8,
	VIEW_AREA_BORDER_LEFT = 16,
};

void server_new_xdg_surface(struct wl_listener *listener, void *data);

void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy,
		int *view_area);
		struct wlr_surface **surface, double *sx, double *sy);
void wio_view_move(struct wio_view *view, int x, int y);

#endif
diff --git a/input.c b/input.c
index e4e4fbf..84c16b0 100644
--- a/input.c
+++ b/input.c
@@ -14,6 +14,10 @@
#include "server.h"
#include "view.h"

// TODO: scale
#define less_swap1(A, B) { if (A < B) { int C = A; A = B + window_border * 2; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C - window_border * 2; } }

static void keyboard_handle_modifiers(
		struct wl_listener *listener, void *data) {
	struct wio_keyboard *keyboard =
@@ -112,12 +116,10 @@ void server_new_input(struct wl_listener *listener, void *data) {

static void process_cursor_motion(struct wio_server *server, uint32_t time) {
	double sx, sy;
	int view_area;
	struct wlr_seat *seat = server->seat;
	struct wlr_surface *surface = NULL;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy,
			&view_area);
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	if (!view) {
		switch (server->input_state) {
		case INPUT_STATE_MOVE_SELECT:
@@ -131,8 +133,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 +147,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,
@@ -245,27 +257,26 @@ static void view_end_interactive(struct wio_server *server) {
static void new_view(struct wio_server *server) {
	int x1 = server->interactive.sx, x2 = server->cursor->x;
	int y1 = server->interactive.sy, y2 = server->cursor->y;
	if (x2 < x1) {
		int _ = x1;
		x1 = x2;
		x2 = _;
	less_swap2(x2, x1);
	less_swap2(y2, y1);
	int width = x2 - x1, height = y2 - y1;
	struct wio_new_view *view = calloc(1, sizeof(struct wio_new_view));
	if (width < MINWIDTH && (x1 - server->interactive.sx) < 0) {
		x1 -= MINWIDTH - width;
	}
	if (y2 < y1) {
		int _ = y1;
		y1 = y2;
		y2 = _;
	if (height < MINHEIGHT && (y1 - server->interactive.sy) < 0) {
		y1 -= MINHEIGHT - height;
	}
	struct wio_new_view *view = calloc(1, sizeof(struct wio_new_view));
	view->box.x = x1;
	view->box.y = y1;
	view->box.width = x2 - x1;
	view->box.height = y2 - y1;
	if (view->box.width < 100){
		view->box.width = 100;
	if (width < MINWIDTH) {
		width = MINWIDTH;
	}
	if (view->box.height < 100){
		view->box.height = 100;
	if (height < MINHEIGHT) {
		height = MINHEIGHT;
	}
	view->box.x = x1;
	view->box.y = y1;
	view->box.width = width;
	view->box.height = height;
	int fd[2];
	if (pipe(fd) != 0) {
		wlr_log(WLR_ERROR, "Unable to create pipe for fork");
@@ -358,11 +369,9 @@ static void handle_button_internal(
	case INPUT_STATE_RESIZE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			int view_area;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy,
					&view_area);
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				view_begin_interactive(view, surface, sx, sy,
						"bottom_right_corner", INPUT_STATE_RESIZE_START);
@@ -378,105 +387,141 @@ static void handle_button_internal(
			server->input_state = INPUT_STATE_RESIZE_END;
		}
		break;
	case INPUT_STATE_BORDER_DRAG_TOP:
		y1 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		y2 = server->cursor->y;
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		x2 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		less_swap1(y2, y1);
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		less_swap1(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < 100) {
			height = 100;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		wlr_xdg_toplevel_set_size(
				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;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
		x1 = server->interactive.view->x;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		y2 = server->cursor->y;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap1(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		height = server->interactive.view->xdg_surface->surface->current.height;
		if (width < 100) {
			width = 100;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM:
		x1 = server->interactive.view->x;
		y1 = server->interactive.view->y, y2 = server->cursor->y;
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		y1 = server->interactive.view->y;
		y2 = server->cursor->y;
		less_swap2(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_RIGHT:
		x1 = server->interactive.view->x, x2 = server->cursor->x;
		x1 = server->interactive.view->x;
		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);
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		if (width < 100) {
			width = 100;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
		height = server->interactive.view->xdg_surface->surface->current.height;
		goto Done;
	case INPUT_STATE_RESIZE_END:
		x1 = server->interactive.sx, x2 = server->cursor->x;
		y1 = server->interactive.sy, y2 = server->cursor->y;
		if (x2 < x1) {
			int _ = x1;
			x1 = x2;
			x2 = _;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.sx) < 0) {
			x1 -= MINWIDTH - width;
		}
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.sy) < 0) {
			y1 -= MINHEIGHT - height;
		}
	Done:
		wio_view_move(server->interactive.view,
				x1, y1);
		width = x2 - x1, height = y2 - y1;
		if (width < 100) {
			width = 100;
		if (width < MINWIDTH) {
			width = MINWIDTH;
		}
		if (height < 100) {
			height = 100;
		if (height < MINHEIGHT) {
			height = MINHEIGHT;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
@@ -485,11 +530,9 @@ static void handle_button_internal(
	case INPUT_STATE_MOVE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			int view_area;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy,
					&view_area);
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				view_begin_interactive(view, surface, sx, sy,
						"grabbing", INPUT_STATE_MOVE);
@@ -507,11 +550,9 @@ static void handle_button_internal(
	case INPUT_STATE_DELETE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			int view_area;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy,
					&view_area);
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				wlr_xdg_toplevel_send_close(view->xdg_surface);
			}
@@ -530,29 +571,43 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
	struct wlr_event_pointer_button *event = data;
	double sx, sy;
	struct wlr_surface *surface = NULL;
	int view_area;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy,
			&view_area);
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	if (server->input_state == INPUT_STATE_NONE && view) {
		wio_view_focus(view, surface);
		switch (view_area) {
		switch (view->area) {
		case VIEW_AREA_SURFACE:
			wlr_seat_pointer_notify_button(server->seat,
					event->time_msec, event->button, event->state);
			break;
		case VIEW_AREA_BORDER_TOP|VIEW_AREA_BORDER_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|VIEW_AREA_BORDER_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|VIEW_AREA_BORDER_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|VIEW_AREA_BORDER_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..88f827b 100644
--- a/output.c
+++ b/output.c
@@ -272,6 +272,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
	struct wio_output *output = wl_container_of(listener, output, frame);
	struct wio_server *server = output->server;
	struct wlr_renderer *renderer = server->renderer;
	int x, y, width, height, scale;

	struct timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
@@ -307,39 +308,134 @@ static void output_frame(struct wl_listener *listener, void *data) {
				render_surface, &rdata);
	}
	view = server->interactive.view;
	scale = output->wlr_output->scale;
	switch (server->input_state) {
	case INPUT_STATE_BORDER_DRAG_TOP_RIGHT:
		x = view->x;
		y = server->cursor->y;
		width = server->cursor->x - server->interactive.sx;
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP_LEFT:
		x = server->cursor->x;
		y = server->cursor->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_TOP:
		render_view_border(renderer, output, view,
			view->x,
			server->cursor->y,
			view->xdg_surface->surface->current.width,
			view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy),
			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;
		x = view->x;
		y = server->cursor->y;
		width = view->xdg_surface->surface->current.width;
		height = view->xdg_surface->surface->current.height - (server->cursor->y - server->interactive.sy);
		if (height < MINHEIGHT && height > -MINHEIGHT) {
			if (height < 0) {
				height *= -1;
				y -= height - window_border * 2 * scale;
			} else {
				y -= MINHEIGHT - height;
			}
			height = MINHEIGHT;
		}
		if (height < 0) {
			height *= -1;
			y -= height - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_RIGHT:
		x = view->x;
		y = view->y;
		width = server->cursor->x - server->interactive.sx;
		height = server->cursor->y - server->interactive.sy;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM_LEFT:
		x = server->cursor->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = server->cursor->y - server->interactive.sy;
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_BORDER_DRAG_BOTTOM:
		render_view_border(renderer, output, view,
			view->x,
			view->y,
			view->xdg_surface->surface->current.width,
			server->cursor->y - server->interactive.sy,
			1);
		break;
		x = view->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width;
		height = server->cursor->y - server->interactive.sy;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_RIGHT:
		render_view_border(renderer, output, view,
			view->x,
			view->y,
			server->cursor->x - server->interactive.sx,
			view->xdg_surface->surface->current.height,
			1);
		break;
		x = view->x;
		y = view->y;
		width = server->cursor->x - server->interactive.sx;
		height = view->xdg_surface->surface->current.height;
		goto Done;
	case INPUT_STATE_BORDER_DRAG_LEFT:
		x = server->cursor->x;
		y = view->y;
		width = view->xdg_surface->surface->current.width - (server->cursor->x - server->interactive.sx);
		height = view->xdg_surface->surface->current.height;
		if (width < MINWIDTH && width > -MINWIDTH) {
			if (width < 0) {
				width *= -1;
				x -= width - window_border * 2 * scale;
			} else {
				x -= MINWIDTH - width;
			}
			width = MINWIDTH;
		}
		if (width < 0) {
			width *= -1;
			x -= width - window_border * 2 * scale;
		}
		goto Done;
	case INPUT_STATE_MOVE:
		render_view_border(renderer, output, view,
			server->cursor->x - server->interactive.sx,
@@ -350,11 +446,26 @@ static void output_frame(struct wl_listener *listener, void *data) {
		break;
	case INPUT_STATE_NEW_END:
	case INPUT_STATE_RESIZE_END:
		render_view_border(renderer, output, NULL,
			server->interactive.sx, server->interactive.sy,
			server->cursor->x - server->interactive.sx,
			server->cursor->y - server->interactive.sy,
			1);
		x = server->interactive.sx;
		y = server->interactive.sy;
		width = server->cursor->x - server->interactive.sx;
		height = server->cursor->y - server->interactive.sy;
	Done:
		if (width < 0) {
			width *= -1;
			x -= ((width < MINWIDTH) ? MINWIDTH : width) + window_border * 2 * scale;
		}
		if (height < 0) {
			height *= -1;
			y -= ((height < MINHEIGHT) ? MINHEIGHT : height) + window_border * 2 * scale;
		}
		if (width < MINWIDTH) {
			width = MINWIDTH;
		}
		if (height < MINHEIGHT) {
			height = MINHEIGHT;
		}
		render_view_border(renderer, output, NULL, x, y, width, height, 1);
		break;
	default:
		break;
diff --git a/view.c b/view.c
index 37ad734..259a7b1 100644
--- a/view.c
+++ b/view.c
@@ -123,56 +123,56 @@ static bool view_at(struct wio_view *view,
}

struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy,
		int *view_area) {
		struct wlr_surface **surface, double *sx, double *sy) {
	struct wlr_box border_box = {
		.x = 0, .y = 0,
		.width = 0, .height = 0,
	};
	struct wio_view *view;
	wl_list_for_each(view, &server->views, link) {
		view->area = VIEW_AREA_NONE;

		// Surface
		if (view_at(view, lx, ly, surface, sx, sy)) {
			*view_area = VIEW_AREA_SURFACE;
			view->area = VIEW_AREA_SURFACE;
			return view;
		}

		// 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;
			view->area = VIEW_AREA_BORDER_TOP;
			goto SideBorder;
		}

		// 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;
		}

	SideBorder:
		// 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;
			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;
			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_NONE) {
			return view;
		}
	}
-- 
2.27.0

[PATCH 04/11] Move views dragging their borders

Details
Message ID
<20200618073954.189606-5-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +9 -2
---
 input.c | 5 +++++
 view.c  | 6 ++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/input.c b/input.c
index c5b25d9..bd4389a 100644
--- a/input.c
+++ b/input.c
@@ -445,6 +445,11 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
				event->time_msec, event->button, event->state);
		break;
	default:
		if (event->button == BTN_RIGHT) {
			view_begin_interactive(view, surface, sx, sy,
					"grabbing", INPUT_STATE_MOVE);
			break;
		}
		corner = corners[view->area];
		view_begin_interactive(view, surface, view->x, view->y,
				corner, INPUT_STATE_BORDER_DRAG);
diff --git a/view.c b/view.c
index 1e93a13..31697da 100644
--- a/view.c
+++ b/view.c
@@ -291,8 +291,10 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		border_box.y = view->y - window_border;
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		border_box.height = view->xdg_surface->surface->current.height + window_border * 2;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			view->area = which_corner(&border_box, server->cursor->x, server->cursor->y);
		if (wlr_box_contains_point(&border_box, lx, ly)) {
			view->area = which_corner(&border_box, lx, ly);
			*sx = lx - view->x;
			*sy = ly - view->y;
			return view;
		}
	}
-- 
2.27.0

[PATCH 06/11] Left and middle mouse buttons stop current action / event

Details
Message ID
<20200618073954.189606-7-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +43 -60
Also revert 8ecffded9bf606e80ce8b2ad3d2ed929aea4f374
---
 input.c | 103 +++++++++++++++++++++++---------------------------------
 1 file changed, 43 insertions(+), 60 deletions(-)

diff --git a/input.c b/input.c
index bd4389a..8e79f0e 100644
--- a/input.c
+++ b/input.c
@@ -30,7 +30,6 @@ static void keyboard_handle_modifiers(
		&keyboard->device->keyboard->modifiers);
}

static void view_end_interactive(struct wio_server *server);
static void keyboard_handle_key(
		struct wl_listener *listener, void *data) {
	struct wio_keyboard *keyboard =
@@ -38,25 +37,6 @@ static void keyboard_handle_key(
	struct wio_server *server = keyboard->server;
	struct wlr_event_keyboard_key *event = data;
	struct wlr_seat *seat = server->seat;
	xkb_keycode_t keycode = event->keycode + 8;
	const xkb_keysym_t *syms;
	int nsyms = xkb_state_key_get_syms(
		keyboard->device->keyboard->xkb_state,
		keycode, &syms);

	for (int i = 0; i < nsyms; i++) {
		if (syms[i] == XKB_KEY_Escape) {
			switch (server->input_state) {
			case INPUT_STATE_NONE:
			case INPUT_STATE_MENU:
				break;
			default:
				view_end_interactive(server);
				return;
			}
		}
	}

	wlr_seat_set_keyboard(seat, keyboard->device);
	wlr_seat_keyboard_notify_key(seat, event->time_msec,
		event->keycode, event->state);
@@ -312,9 +292,12 @@ static void handle_button_internal(
	struct wlr_box box;
	int x1, x2, y1, y2;
	uint32_t width, height;
	double sx, sy;
	struct wlr_surface *surface = NULL;
	struct wio_view *view;
	switch (server->input_state) {
	case INPUT_STATE_NONE:
		if (event->state == WLR_BUTTON_PRESSED && event->button == BTN_RIGHT) {
		if (event->state == WLR_BUTTON_PRESSED) {
			// TODO: Open over the last-used menu item
			server->input_state = INPUT_STATE_MENU;
			server->menu.x = server->cursor->x;
@@ -333,36 +316,36 @@ static void handle_button_internal(
		}
		break;
	case INPUT_STATE_NEW_START:
		if (event->state == WLR_BUTTON_PRESSED) {
			server->interactive.sx = server->cursor->x;
			server->interactive.sy = server->cursor->y;
			server->input_state = INPUT_STATE_NEW_END;
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		server->interactive.sx = server->cursor->x;
		server->interactive.sy = server->cursor->y;
		server->input_state = INPUT_STATE_NEW_END;
		break;
	case INPUT_STATE_NEW_END:
		new_view(server);
		view_end_interactive(server);
		break;
	case INPUT_STATE_RESIZE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				view_begin_interactive(view, surface, sx, sy,
						"bottom_right_corner", INPUT_STATE_RESIZE_START);
			} else {
				view_end_interactive(server);
			}
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
		if (view != NULL) {
			view_begin_interactive(view, surface, sx, sy,
					"bottom_right_corner", INPUT_STATE_RESIZE_START);
		} else {
			view_end_interactive(server);
		}
		break;
	case INPUT_STATE_RESIZE_START:
		if (event->state == WLR_BUTTON_PRESSED) {
			server->interactive.sx = server->cursor->x;
			server->interactive.sy = server->cursor->y;
			server->input_state = INPUT_STATE_RESIZE_END;
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		server->interactive.sx = server->cursor->x;
		server->interactive.sy = server->cursor->y;
		server->input_state = INPUT_STATE_RESIZE_END;
		break;
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
@@ -387,17 +370,15 @@ static void handle_button_internal(
		view_end_interactive(server);
		break;
	case INPUT_STATE_MOVE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				view_begin_interactive(view, surface, sx, sy,
						"grabbing", INPUT_STATE_MOVE);
			} else {
				view_end_interactive(server);
			}
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
		if (view != NULL) {
			view_begin_interactive(view, surface, sx, sy,
					"grabbing", INPUT_STATE_MOVE);
		} else {
			view_end_interactive(server);
		}
		break;
	case INPUT_STATE_MOVE:
@@ -407,16 +388,14 @@ static void handle_button_internal(
		view_end_interactive(server);
		break;
	case INPUT_STATE_DELETE_SELECT:
		if (event->state == WLR_BUTTON_PRESSED) {
			double sx, sy;
			struct wlr_surface *surface = NULL;
			struct wio_view *view = wio_view_at(server,
					server->cursor->x, server->cursor->y, &surface, &sx, &sy);
			if (view != NULL) {
				wlr_xdg_toplevel_send_close(view->xdg_surface);
			}
			view_end_interactive(server);
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
		if (view != NULL) {
			wlr_xdg_toplevel_send_close(view->xdg_surface);
		}
		view_end_interactive(server);
		break;
	default:
		// TODO
@@ -435,6 +414,10 @@ void server_cursor_button(struct wl_listener *listener, void *data) {
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
	}
	if (!view) {
		if (event->state == WLR_BUTTON_PRESSED && event->button != BTN_RIGHT) {
			view_end_interactive(server);
			return;
		}
		handle_button_internal(server, event);
		return;
	}
-- 
2.27.0

[PATCH 08/11] Change surface color to grey

Details
Message ID
<20200618073954.189606-9-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +1 -1
---
 include/colors.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/colors.h b/include/colors.h
index b1f83d3..7ab7aff 100644
--- a/include/colors.h
+++ b/include/colors.h
@@ -30,7 +30,7 @@ static const float menu_border[4] = {
};

static const float surface[4] = {
	0xFF / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f,
	0xEE / 255.0f, 0xEE / 255.0f, 0xEE / 255.0f, 1.0f,
};

#endif
-- 
2.27.0

[PATCH 07/11] Remove duplicate code in New, Resize and resize by dragging borders

Details
Message ID
<20200618073954.189606-8-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +75 -127
---
 include/view.h |   4 +-
 input.c        |  34 ++++--------
 output.c       |  20 ++-----
 view.c         | 144 +++++++++++++++++++++----------------------------
 4 files changed, 75 insertions(+), 127 deletions(-)

diff --git a/include/view.h b/include/view.h
index e1a8bbf..0899f9c 100644
--- a/include/view.h
+++ b/include/view.h
@@ -5,9 +5,6 @@

#define MINWIDTH 100
#define MINHEIGHT 100
// TODO: scale
#define less_swap1(A, B) { if (A < B) { int C = A; A = B + window_border * 2; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C - window_border * 2; } }

struct wio_server;

@@ -37,6 +34,7 @@ void server_new_xdg_surface(struct wl_listener *listener, void *data);

void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wlr_box which_box(struct wio_server *server);
struct wlr_box canon_box(struct wio_server *server, struct wlr_box box);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy);
void wio_view_move(struct wio_view *view, int x, int y);
diff --git a/input.c b/input.c
index 8e79f0e..9640b9c 100644
--- a/input.c
+++ b/input.c
@@ -220,19 +220,12 @@ static void view_end_interactive(struct wio_server *server) {
}

static void new_view(struct wio_server *server) {
	int x1 = server->interactive.sx, x2 = server->cursor->x;
	int y1 = server->interactive.sy, y2 = server->cursor->y;
	less_swap2(x2, x1);
	less_swap2(y2, y1);
	int width = x2 - x1, height = y2 - y1;
	if (width < MINWIDTH || height < MINHEIGHT) {
	struct wlr_box box = which_box(server);
	if (box.width < MINWIDTH || box.height < MINHEIGHT) {
		return;
	}
	struct wio_new_view *view = calloc(1, sizeof(struct wio_new_view));
	view->box.x = x1;
	view->box.y = y1;
	view->box.width = width;
	view->box.height = height;
	view->box = box;
	int fd[2];
	if (pipe(fd) != 0) {
		wlr_log(WLR_ERROR, "Unable to create pipe for fork");
@@ -290,8 +283,6 @@ static void handle_button_internal(
		.width = server->menu.width, .height = server->menu.height,
	};
	struct wlr_box box;
	int x1, x2, y1, y2;
	uint32_t width, height;
	double sx, sy;
	struct wlr_surface *surface = NULL;
	struct wio_view *view;
@@ -334,7 +325,7 @@ static void handle_button_internal(
		view = wio_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
		if (view != NULL) {
			view_begin_interactive(view, surface, sx, sy,
					"bottom_right_corner", INPUT_STATE_RESIZE_START);
					"top_left_corner", INPUT_STATE_RESIZE_START);
		} else {
			view_end_interactive(server);
		}
@@ -349,24 +340,17 @@ static void handle_button_internal(
		break;
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		x1 = box.x, y1 = box.y, width = box.width, height = box.height;
		box = canon_box(server, box);
		goto Done;
	case INPUT_STATE_RESIZE_END:
		x1 = server->interactive.sx, x2 = server->cursor->x;
		y1 = server->interactive.sy, y2 = server->cursor->y;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		height = y2 - y1;
		if (width < MINWIDTH || height < MINHEIGHT) {
		box = which_box(server);
		if (box.width < MINWIDTH || box.height < MINHEIGHT) {
			view_end_interactive(server);
			break;
		}
	Done:
		wio_view_move(server->interactive.view,
				x1, y1);
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		wio_view_move(server->interactive.view, box.x, box.y);
		wlr_xdg_toplevel_set_size(server->interactive.view->xdg_surface, box.width, box.height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_MOVE_SELECT:
diff --git a/output.c b/output.c
index 3ec64a8..28efb2f 100644
--- a/output.c
+++ b/output.c
@@ -273,7 +273,6 @@ static void output_frame(struct wl_listener *listener, void *data) {
	struct wio_server *server = output->server;
	struct wlr_renderer *renderer = server->renderer;
	struct wlr_box box;
	int x, y, width, height;
	float color[4];

	struct timespec now;
@@ -313,6 +312,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
	switch (server->input_state) {
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		box = canon_box(server, box);
		render_view_border(renderer, output, NULL, box.x, box.y, box.width, box.height, 1);
		break;
	case INPUT_STATE_MOVE:
@@ -325,24 +325,12 @@ static void output_frame(struct wl_listener *listener, void *data) {
		break;
	case INPUT_STATE_NEW_END:
	case INPUT_STATE_RESIZE_END:
		x = server->interactive.sx;
		y = server->interactive.sy;
		width = server->cursor->x - server->interactive.sx;
		height = server->cursor->y - server->interactive.sy;
		if (width < 0) {
			width *= -1;
			x -= width + window_border * 2;
		}
		if (height < 0) {
			height *= -1;
			y -= height + window_border * 2;
		}
		if (width > 0 && height > 0) {
			box.x = x, box.y = y, box.width = width, box.height = height;
		box = which_box(server);
		if (box.width > 0 && box.height > 0) {
			memcpy(color, surface, sizeof(color));
			wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix);
		}
		render_view_border(renderer, output, NULL, x, y, width, height, 1);
		render_view_border(renderer, output, NULL, box.x, box.y, box.width, box.height, 1);
		break;
	default:
		break;
diff --git a/view.c b/view.c
index 31697da..fc7ccc7 100644
--- a/view.c
+++ b/view.c
@@ -5,6 +5,10 @@
#include "server.h"
#include "view.h"

// TODO: scale
#define less_swap1(A, B) { if (A < B) { int C = A; A = B + window_border * 2; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C - window_border * 2; } }

static void xdg_surface_map(struct wl_listener *listener, void *data) {
	struct wio_view *view = wl_container_of(listener, view, map);
	struct wio_server *server = view->server;
@@ -143,133 +147,107 @@ static int which_corner(struct wlr_box *box, int x, int y) {

struct wlr_box which_box(struct wio_server *server) {
	struct wlr_box box;
	int x1, x2, y1, y2, width, height;
	int x1, x2, y1, y2;

	if (server->interactive.view == NULL) {
		goto End;
	}
	x2 = server->interactive.sx + server->interactive.view->xdg_surface->surface->current.width;
	y2 = server->interactive.sy + server->interactive.view->xdg_surface->surface->current.height;
	switch (server->interactive.view->area) {
	case VIEW_AREA_BORDER_TOP_LEFT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		less_swap1(y2, y1);
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_TOP:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		x1 = server->interactive.sx;
		less_swap1(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_TOP_RIGHT:
		y1 = server->cursor->y;
		y2 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		x1 = server->interactive.view->x;
		x1 = server->interactive.sx;
		x2 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT
			&& (y1 - server->interactive.view->y) < (server->interactive.view->xdg_surface->surface->current.height)) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		y1 = server->interactive.sy;
		less_swap1(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		break;
	case VIEW_AREA_BORDER_RIGHT:
		x1 = server->interactive.view->x;
		x1 = server->interactive.sx;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		y1 = server->interactive.sy;
		less_swap2(x2, x1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = server->interactive.view->xdg_surface->surface->current.height;
		break;
	case VIEW_AREA_BORDER_BOTTOM_LEFT:
		x1 = server->cursor->x;
		x2 = server->interactive.view->x + server->interactive.view->xdg_surface->surface->current.width;
		y1 = server->interactive.view->y;
		y1 = server->interactive.sy;
		y2 = server->cursor->y;
		less_swap1(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH
			&& (x1 - server->interactive.view->x) < (server->interactive.view->xdg_surface->surface->current.width)) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		break;
	case VIEW_AREA_BORDER_BOTTOM:
		x1 = server->interactive.view->x;
		y1 = server->interactive.view->y;
		x1 = server->interactive.sx;
		y1 = server->interactive.sy;
		y2 = server->cursor->y;
		less_swap2(y2, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		box.height = y2 - y1;
		break;
	case VIEW_AREA_BORDER_BOTTOM_RIGHT:
		x1 = server->interactive.view->x;
	End:
		x1 = server->interactive.sx;
		x2 = server->cursor->x;
		y1 = server->interactive.view->y;
		y1 = server->interactive.sy;
		y2 = server->cursor->y;
		less_swap2(x2, x1);
		less_swap2(y2, y1);
		width = x2 - x1;
		if (width < MINWIDTH && (x1 - server->interactive.view->x) < 0) {
			x1 -= MINWIDTH - width;
		}
		height = y2 - y1;
		if (height < MINHEIGHT && (y1 - server->interactive.view->y) < 0) {
			y1 -= MINHEIGHT - height;
		}
		break;
	}
	if (width < MINWIDTH) {
		width = MINWIDTH;
	}
	if (height < MINHEIGHT) {
		height = MINHEIGHT;
	}
	box.x = x1;
	box.y = y1;
	box.width = width;
	box.height = height;
	box.width = x2 - x1;
	box.height = y2 - y1;
	return box;
}

struct wlr_box canon_box(struct wio_server *server, struct wlr_box box) {
	if (box.width < MINWIDTH) {
		switch (server->interactive.view->area) {
		case VIEW_AREA_BORDER_TOP_LEFT:
		case VIEW_AREA_BORDER_LEFT:
		case VIEW_AREA_BORDER_BOTTOM_LEFT:
			if ((box.x - server->interactive.sx) < server->interactive.view->xdg_surface->surface->current.width) {
				box.x -= MINWIDTH - box.width;
			}
			break;
		default:
			if (box.x < server->interactive.sx) {
				box.x -= MINWIDTH - box.width;
			}
		}
		box.width = MINWIDTH;
	}
	if (box.height < MINHEIGHT) {
		switch (server->interactive.view->area) {
		case VIEW_AREA_BORDER_TOP_LEFT:
		case VIEW_AREA_BORDER_TOP:
		case VIEW_AREA_BORDER_TOP_RIGHT:
			if ((box.y - server->interactive.sy) < server->interactive.view->xdg_surface->surface->current.height) {
				box.y -= MINHEIGHT - box.height;
			}
			break;
		default:
			if (box.y < server->interactive.sy) {
				box.y -= MINHEIGHT - box.height;
			}
		}
		box.height = MINHEIGHT;
	}
	return box;
}

-- 
2.27.0

[PATCH 05/11] Remove obsolete options in contrib/alacritty.yml

Details
Message ID
<20200618073954.189606-6-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +0 -3
---
 contrib/alacritty.yml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/contrib/alacritty.yml b/contrib/alacritty.yml
index cef2dcd..0cbc48a 100644
--- a/contrib/alacritty.yml
+++ b/contrib/alacritty.yml
@@ -11,9 +11,6 @@ window:
scrolling:
  history: 10000
  multiplier: 3
  faux_multiplier: 3
  auto_scroll: false
tabspaces: 8
draw_bold_text_with_bright_colors: true
font:
  normal:
-- 
2.27.0

[PATCH 09/11] Resize views by dragging their borders like in Rio

Details
Message ID
<20200618073954.189606-10-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +4 -32
Like a glove!
---
 view.c | 36 ++++--------------------------------
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/view.c b/view.c
index fc7ccc7..c768cc4 100644
--- a/view.c
+++ b/view.c
@@ -216,39 +216,11 @@ struct wlr_box which_box(struct wio_server *server) {
}

struct wlr_box canon_box(struct wio_server *server, struct wlr_box box) {
	if (box.width < MINWIDTH) {
		switch (server->interactive.view->area) {
		case VIEW_AREA_BORDER_TOP_LEFT:
		case VIEW_AREA_BORDER_LEFT:
		case VIEW_AREA_BORDER_BOTTOM_LEFT:
			if ((box.x - server->interactive.sx) < server->interactive.view->xdg_surface->surface->current.width) {
				box.x -= MINWIDTH - box.width;
			}
			break;
		default:
			if (box.x < server->interactive.sx) {
				box.x -= MINWIDTH - box.width;
			}
		}
		box.width = MINWIDTH;
	}
	if (box.height < MINHEIGHT) {
		switch (server->interactive.view->area) {
		case VIEW_AREA_BORDER_TOP_LEFT:
		case VIEW_AREA_BORDER_TOP:
		case VIEW_AREA_BORDER_TOP_RIGHT:
			if ((box.y - server->interactive.sy) < server->interactive.view->xdg_surface->surface->current.height) {
				box.y -= MINHEIGHT - box.height;
			}
			break;
		default:
			if (box.y < server->interactive.sy) {
				box.y -= MINHEIGHT - box.height;
			}
		}
		box.height = MINHEIGHT;
	static struct wlr_box cache;
	if (box.width < MINWIDTH || box.height < MINHEIGHT) {
		return cache;
	}
	return box;
	return cache = box;
}

struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
-- 
2.27.0

[PATCH 10/11] Move and rename which_box and canon_box

Details
Message ID
<20200618073954.189606-11-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +50 -50
---
 include/view.h |  4 +--
 input.c        |  8 ++---
 output.c       |  6 ++--
 view.c         | 82 +++++++++++++++++++++++++-------------------------
 4 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/include/view.h b/include/view.h
index 0899f9c..09f7e1a 100644
--- a/include/view.h
+++ b/include/view.h
@@ -33,10 +33,10 @@ enum wio_view_area {
void server_new_xdg_surface(struct wl_listener *listener, void *data);

void wio_view_focus(struct wio_view *view, struct wlr_surface *surface);
struct wlr_box which_box(struct wio_server *server);
struct wlr_box canon_box(struct wio_server *server, struct wlr_box box);
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy);
void wio_view_move(struct wio_view *view, int x, int y);
struct wlr_box wio_which_box(struct wio_server *server);
struct wlr_box wio_canon_box(struct wio_server *server, struct wlr_box box);

#endif
diff --git a/input.c b/input.c
index 9640b9c..6d76097 100644
--- a/input.c
+++ b/input.c
@@ -220,7 +220,7 @@ static void view_end_interactive(struct wio_server *server) {
}

static void new_view(struct wio_server *server) {
	struct wlr_box box = which_box(server);
	struct wlr_box box = wio_which_box(server);
	if (box.width < MINWIDTH || box.height < MINHEIGHT) {
		return;
	}
@@ -339,11 +339,11 @@ static void handle_button_internal(
		server->input_state = INPUT_STATE_RESIZE_END;
		break;
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		box = canon_box(server, box);
		box = wio_which_box(server);
		box = wio_canon_box(server, box);
		goto Done;
	case INPUT_STATE_RESIZE_END:
		box = which_box(server);
		box = wio_which_box(server);
		if (box.width < MINWIDTH || box.height < MINHEIGHT) {
			view_end_interactive(server);
			break;
diff --git a/output.c b/output.c
index 28efb2f..c6d3f81 100644
--- a/output.c
+++ b/output.c
@@ -311,8 +311,8 @@ static void output_frame(struct wl_listener *listener, void *data) {
	view = server->interactive.view;
	switch (server->input_state) {
	case INPUT_STATE_BORDER_DRAG:
		box = which_box(server);
		box = canon_box(server, box);
		box = wio_which_box(server);
		box = wio_canon_box(server, box);
		render_view_border(renderer, output, NULL, box.x, box.y, box.width, box.height, 1);
		break;
	case INPUT_STATE_MOVE:
@@ -325,7 +325,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
		break;
	case INPUT_STATE_NEW_END:
	case INPUT_STATE_RESIZE_END:
		box = which_box(server);
		box = wio_which_box(server);
		if (box.width > 0 && box.height > 0) {
			memcpy(color, surface, sizeof(color));
			wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix);
diff --git a/view.c b/view.c
index c768cc4..8ed91ee 100644
--- a/view.c
+++ b/view.c
@@ -145,7 +145,46 @@ static int which_corner(struct wlr_box *box, int x, int y) {
	return 3*j+i;
}

struct wlr_box which_box(struct wio_server *server) {
struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy) {
	struct wlr_box border_box = {
		.x = 0, .y = 0,
		.width = 0, .height = 0,
	};
	struct wio_view *view;
	wl_list_for_each(view, &server->views, link) {
		// Surface
		if (view_at(view, lx, ly, surface, sx, sy)) {
			view->area = VIEW_AREA_SURFACE;
			return view;
		}
		// Border
		border_box.x = view->x - window_border;
		border_box.y = view->y - window_border;
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		border_box.height = view->xdg_surface->surface->current.height + window_border * 2;
		if (wlr_box_contains_point(&border_box, lx, ly)) {
			view->area = which_corner(&border_box, lx, ly);
			*sx = lx - view->x;
			*sy = ly - view->y;
			return view;
		}
	}
	return NULL;
}

void wio_view_move(struct wio_view *view, int x, int y) {
	view->x = x;
	view->y = y;

	// Cheating as FUCK because I'm lazy
	struct wio_output *output;
	wl_list_for_each(output, &view->server->outputs, link) {
		wlr_surface_send_enter(view->xdg_surface->surface, output->wlr_output);
	}
}

struct wlr_box wio_which_box(struct wio_server *server) {
	struct wlr_box box;
	int x1, x2, y1, y2;

@@ -215,49 +254,10 @@ struct wlr_box which_box(struct wio_server *server) {
	return box;
}

struct wlr_box canon_box(struct wio_server *server, struct wlr_box box) {
struct wlr_box wio_canon_box(struct wio_server *server, struct wlr_box box) {
	static struct wlr_box cache;
	if (box.width < MINWIDTH || box.height < MINHEIGHT) {
		return cache;
	}
	return cache = box;
}

struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
		struct wlr_surface **surface, double *sx, double *sy) {
	struct wlr_box border_box = {
		.x = 0, .y = 0,
		.width = 0, .height = 0,
	};
	struct wio_view *view;
	wl_list_for_each(view, &server->views, link) {
		// Surface
		if (view_at(view, lx, ly, surface, sx, sy)) {
			view->area = VIEW_AREA_SURFACE;
			return view;
		}
		// Border
		border_box.x = view->x - window_border;
		border_box.y = view->y - window_border;
		border_box.width = view->xdg_surface->surface->current.width + window_border * 2;
		border_box.height = view->xdg_surface->surface->current.height + window_border * 2;
		if (wlr_box_contains_point(&border_box, lx, ly)) {
			view->area = which_corner(&border_box, lx, ly);
			*sx = lx - view->x;
			*sy = ly - view->y;
			return view;
		}
	}
	return NULL;
}

void wio_view_move(struct wio_view *view, int x, int y) {
	view->x = x;
	view->y = y;

	// Cheating as FUCK because I'm lazy
	struct wio_output *output;
	wl_list_for_each(output, &view->server->outputs, link) {
		wlr_surface_send_enter(view->xdg_surface->surface, output->wlr_output);
	}
}
-- 
2.27.0

[PATCH 11/11] Set cursor image to arrow when hovering borders

Details
Message ID
<20200618073954.189606-12-goleo@disroot.org>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
Patch: +4 -0
---
 input.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/input.c b/input.c
index 6d76097..b6118f2 100644
--- a/input.c
+++ b/input.c
@@ -147,6 +147,10 @@ End:
			wlr_seat_pointer_notify_motion(seat, time, sx, sy);
		}
	} else {
		if (view) {
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					corners[view->area], server->cursor);
		}
		wlr_seat_pointer_clear_focus(seat);
	}
}
-- 
2.27.0
Details
Message ID
<C3K968OYQAY4.ZD2C4FPAGQ40@homura>
In-Reply-To
<20200618073954.189606-1-goleo@disroot.org> (view parent)
DKIM signature
pass
Download raw message
On Thu Jun 18, 2020 at 6:39 AM EDT, Leonid Bobrov wrote:
> Please take a look at whole diff, I made terrible commits, reviewing by
> commit is a pain in the eyes.

You'll have to rebase until it's not.

https://git-rebase.io
Review patch Export thread (mbox)