~sircmpwn/wio

2

[PATCH 1/4] Resize like in Rio

Details
Message ID
<20200618193050.265932-1-goleo@disroot.org>
DKIM signature
pass
Download raw message
Patch: +264 -329
Summary:
* remove duplicate code;
* resize views when dragging corner borders;
* width and height never become negative to avoid rendering bugs while reflecting,
  also recently wlroots crashes when width/height is <= 0;
* reflection behaves like in Rio;
* minimal size is enforced on red box like in Rio;
* change cursor for New and Resize;
* New and Resize do nothing if size is less than minimal like in Rio;
* New and Resize draw a grey surface in red box like in Rio;
* it's not accurate because it assumes scale is always 1.
---
 include/colors.h |   4 +
 include/server.h |   5 +-
 include/view.h   |  17 ++-
 input.c          | 369 ++++++++++++++++-------------------------------
 output.c         |  48 ++----
 view.c           | 150 ++++++++++++++-----
 6 files changed, 264 insertions(+), 329 deletions(-)

diff --git a/include/colors.h b/include/colors.h
index f8d40dc..7ab7aff 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] = {
	0xEE / 255.0f, 0xEE / 255.0f, 0xEE / 255.0f, 1.0f,
};

#endif
diff --git a/include/server.h b/include/server.h
index 60842e1..b6eaaa6 100644
--- a/include/server.h
+++ b/include/server.h
@@ -26,10 +26,7 @@ enum wio_input_state {
	INPUT_STATE_RESIZE_SELECT,
	INPUT_STATE_RESIZE_START,
	INPUT_STATE_RESIZE_END,
	INPUT_STATE_BORDER_DRAG_TOP,
	INPUT_STATE_BORDER_DRAG_RIGHT,
	INPUT_STATE_BORDER_DRAG_BOTTOM,
	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 36303fa..09f7e1a 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,24 @@ struct wio_view {
};

enum wio_view_area {
	VIEW_AREA_SURFACE = 0,
	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_LEFT,
	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 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);
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 e4e4fbf..b7be393 100644
--- a/input.c
+++ b/input.c
@@ -14,6 +14,13 @@
#include "server.h"
#include "view.h"

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) {
	struct wio_keyboard *keyboard =
@@ -112,57 +119,47 @@ 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);
	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_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_BORDER_DRAG_TOP:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"top_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_BOTTOM:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"bottom_side", server->cursor);
			break;
		case INPUT_STATE_BORDER_DRAG_LEFT:
			wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
					"left_side", 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;
		}
	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) {
		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,
				"grabbing", server->cursor);
		break;
	case INPUT_STATE_RESIZE_END:
	case INPUT_STATE_NEW_END:
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"grabbing", 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);
@@ -170,6 +167,10 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) {
			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);
	}
}
@@ -199,7 +200,7 @@ static void menu_handle_button(
	case 0:
		server->input_state = INPUT_STATE_NEW_START;
		wlr_xcursor_manager_set_cursor_image(server->cursor_mgr,
				"top_left_corner", server->cursor);
				"grabbing", server->cursor);
		break;
	case 1:
		server->input_state = INPUT_STATE_RESIZE_SELECT;
@@ -243,29 +244,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;
	if (x2 < x1) {
		int _ = x1;
		x1 = x2;
		x2 = _;
	}
	if (y2 < y1) {
		int _ = y1;
		y1 = y2;
		y2 = _;
	struct wlr_box box = wio_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 = x2 - x1;
	view->box.height = y2 - y1;
	if (view->box.width < 100){
		view->box.width = 100;
	}
	if (view->box.height < 100){
		view->box.height = 100;
	}
	view->box = box;
	int fd[2];
	if (pipe(fd) != 0) {
		wlr_log(WLR_ERROR, "Unable to create pipe for fork");
@@ -322,8 +306,10 @@ static void handle_button_internal(
		.x = server->menu.x, .y = server->menu.y,
		.width = server->menu.width, .height = server->menu.height,
	};
	int x1, x2, y1, y2;
	uint32_t width, height;
	struct wlr_box box;
	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) {
@@ -345,157 +331,63 @@ 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;
			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);
			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;
		}
		break;
	case INPUT_STATE_BORDER_DRAG_TOP:
		y1 = server->interactive.view->y + server->interactive.view->xdg_surface->surface->current.height;
		y2 = server->cursor->y;
		x1 = server->interactive.view->x;
		if (y2 < y1) {
			int _ = y1;
			y1 = y2;
			y2 = _;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		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_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_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 = _;
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		wio_view_move(server->interactive.view,
				x1, y1);
		width = server->interactive.view->xdg_surface->surface->current.width;
		height = y2 - y1;
		if (width < 100) {
			width = 100;
		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_RESIZE_START);
		} else {
			view_end_interactive(server);
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		break;
	case INPUT_STATE_BORDER_DRAG_RIGHT:
		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);
		width = x2 - x1;
		height = server->interactive.view->xdg_surface->surface->current.height;
		if (width < 100) {
			width = 100;
	case INPUT_STATE_RESIZE_START:
		if (event->state != WLR_BUTTON_PRESSED) {
			break;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
		view_end_interactive(server);
		server->interactive.sx = server->cursor->x;
		server->interactive.sy = server->cursor->y;
		server->interactive.view->area = VIEW_AREA_BORDER_BOTTOM_RIGHT;
		server->input_state = INPUT_STATE_RESIZE_END;
		break;
	case INPUT_STATE_BORDER_DRAG:
		box = wio_which_box(server);
		box = wio_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;
		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;
		box = wio_which_box(server);
		if (box.width < MINWIDTH || box.height < MINHEIGHT) {
			view_end_interactive(server);
			break;
		}
		wlr_xdg_toplevel_set_size(
				server->interactive.view->xdg_surface, width, height);
	Done:
		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:
		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);
			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:
@@ -505,18 +397,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;
			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);
			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
@@ -530,36 +418,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;
	int view_area;
	struct wio_view *view = wio_view_at(
			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy,
			&view_area);
	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;
		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:
			view_begin_interactive(view, surface, view->x, view->y,
					"right_side", INPUT_STATE_BORDER_DRAG_RIGHT);
			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_LEFT:
			view_begin_interactive(view, surface, view->x, view->y,
					"left_side", INPUT_STATE_BORDER_DRAG_LEFT);
			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;
	}
}

diff --git a/output.c b/output.c
index 6a059f5..c6d3f81 100644
--- a/output.c
+++ b/output.c
@@ -272,6 +272,8 @@ 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;
	struct wlr_box box;
	float color[4];

	struct timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
@@ -308,37 +310,10 @@ static void output_frame(struct wl_listener *listener, void *data) {
	}
	view = server->interactive.view;
	switch (server->input_state) {
	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;
	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;
	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);
	case INPUT_STATE_BORDER_DRAG:
		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:
		render_view_border(renderer, output, view,
@@ -350,11 +325,12 @@ 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);
		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);
		}
		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 37ad734..3b1e38d 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; B = C + window_border * 2; } }
#define less_swap2(A, B) { if (A < B) { int C = A; A = B - window_border * 2; B = C; } }

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;
@@ -122,9 +126,27 @@ 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 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,
@@ -133,46 +155,18 @@ struct wio_view *wio_view_at(struct wio_server *server, double lx, double ly,
	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;
		}
		// Top 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 - window_border;
		if (wlr_box_contains_point(&border_box, server->cursor->x, server->cursor->y)) {
			*view_area = VIEW_AREA_BORDER_TOP;
			return view;
		}

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

		// Left border
		border_box.height = view->xdg_surface->surface->current.height;
		border_box.width = window_border;
		// 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;
		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;
		}
	}
@@ -189,3 +183,81 @@ void wio_view_move(struct wio_view *view, int x, int y) {
		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;

	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;
		x1 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap1(x2, x1);
		break;
	case VIEW_AREA_BORDER_TOP:
		y1 = server->cursor->y;
		x1 = server->interactive.sx;
		less_swap1(y2, y1);
		break;
	case VIEW_AREA_BORDER_TOP_RIGHT:
		y1 = server->cursor->y;
		x1 = server->interactive.sx;
		x2 = server->cursor->x;
		less_swap1(y2, y1);
		less_swap2(x2, x1);
		break;
	case VIEW_AREA_BORDER_LEFT:
		x1 = server->cursor->x;
		y1 = server->interactive.sy;
		less_swap1(x2, x1);
		break;
	case VIEW_AREA_BORDER_RIGHT:
		x1 = server->interactive.sx;
		x2 = server->cursor->x;
		y1 = server->interactive.sy;
		less_swap2(x2, x1);
		break;
	case VIEW_AREA_BORDER_BOTTOM_LEFT:
		x1 = server->cursor->x;
		y1 = server->interactive.sy;
		y2 = server->cursor->y;
		less_swap1(x2, x1);
		less_swap2(y2, y1);
		break;
	case VIEW_AREA_BORDER_BOTTOM:
		x1 = server->interactive.sx;
		y1 = server->interactive.sy;
		y2 = server->cursor->y;
		less_swap2(y2, y1);
		box.height = y2 - y1;
		break;
	case VIEW_AREA_BORDER_BOTTOM_RIGHT:
	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);
		break;
	}
	box.x = x1;
	box.y = y1;
	box.width = x2 - x1;
	box.height = y2 - y1;
	return 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;
}
-- 
2.27.0

[PATCH 3/4] Left and middle mouse buttons stop current action / event

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

diff --git a/input.c b/input.c
index 3b177fa..c2b78f9 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,7 +292,7 @@ static void handle_button_internal(
	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;
@@ -423,6 +403,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 4/4] Remove obsolete options in contrib/alacritty.yml

Details
Message ID
<20200618193050.265932-4-goleo@disroot.org>
In-Reply-To
<20200618193050.265932-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
Export thread (mbox)