~sircmpwn/wio

Bug-Fix: Can no longer select borders hidden under views v1 PROPOSED

Leon Plickat: 1
 Bug-Fix: Can no longer select borders hidden under views

 3 files changed, 94 insertions(+), 75 deletions(-)
Export patchset (mbox)
How do I use this?

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

curl -s https://lists.sr.ht/~sircmpwn/wio/patches/7324/mbox | git am -3
Learn more about email & git

[PATCH] Bug-Fix: Can no longer select borders hidden under views Export this patch

This fixes the bug where clicking on a border would enable border
dragging even if the border was hidden under a view.

Letting wio_view_at() report where the given coordinates are on a view
enables us to check for views and borders of views in the same loop,
easily solving this problem.

Additionally this makes the border dragging code cleaner and enables
other functions as well to see where on a view was clicked.
---
 include/view.h |  11 ++++-
 input.c        | 110 +++++++++++++++++--------------------------------
 view.c         |  48 ++++++++++++++++++++-
 3 files changed, 94 insertions(+), 75 deletions(-)

diff --git a/include/view.h b/include/view.h
index e3c47f0..36303fa 100644
--- a/include/view.h
+++ b/include/view.h
@@ -14,11 +14,20 @@ struct wio_view {
 	struct wl_listener destroy;
 };
 
+enum wio_view_area {
+	VIEW_AREA_SURFACE = 0,
+	VIEW_AREA_BORDER_TOP,
+	VIEW_AREA_BORDER_RIGHT,
+	VIEW_AREA_BORDER_BOTTOM,
+	VIEW_AREA_BORDER_LEFT,
+};
+
 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);
+		struct wlr_surface **surface, double *sx, double *sy,
+		int *view_area);
 void wio_view_move(struct wio_view *view, int x, int y);
 
 #endif
diff --git a/input.c b/input.c
index eda7f44..e4e4fbf 100644
--- a/input.c
+++ b/input.c
@@ -112,10 +112,12 @@ 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);
+			server, server->cursor->x, server->cursor->y, &surface, &sx, &sy,
+			&view_area);
 	if (!view) {
 		switch (server->input_state) {
 		case INPUT_STATE_MOVE_SELECT:
@@ -312,69 +314,6 @@ static void new_view(struct wio_server *server) {
 	}
 }
 
-bool wio_border_drag(
-		struct wio_server *server, struct wlr_event_pointer_button *event) {
-	if (event->button != BTN_RIGHT) {
-		return false;
-	}
-	struct wlr_box border_box = {
-		.x = 0, .y = 0,
-		.width = 0, .height = 0,
-	};
-	struct wio_view *view;
-	struct wlr_surface *surface = NULL;
-	wl_list_for_each(view, &server->views, link) {
-		// 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_begin_interactive(view, surface, view->x, view->y,
-					"top_side", INPUT_STATE_BORDER_DRAG_TOP);
-			return true;
-		}
-
-		// 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_begin_interactive(view, surface, view->x, view->y,
-					"right_side", INPUT_STATE_BORDER_DRAG_RIGHT);
-			return true;
-		}
-
-		// 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_begin_interactive(view, surface, view->x, view->y,
-					"bottom_side", INPUT_STATE_BORDER_DRAG_BOTTOM);
-			return true;
-		}
-
-		// 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_begin_interactive(view, surface, view->x, view->y,
-					"left_side", INPUT_STATE_BORDER_DRAG_LEFT);
-			return true;
-		}
-	}
-	return false;
-}
-
 static void handle_button_internal(
 		struct wio_server *server, struct wlr_event_pointer_button *event) {
 	// TODO: open menu if the client doesn't handle the button press
@@ -419,9 +358,11 @@ 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);
+					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);
@@ -544,9 +485,11 @@ 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);
+					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);
@@ -564,9 +507,11 @@ 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);
+					server->cursor->x, server->cursor->y, &surface, &sx, &sy,
+					&view_area);
 			if (view != NULL) {
 				wlr_xdg_toplevel_send_close(view->xdg_surface);
 			}
@@ -585,15 +530,34 @@ 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);
-	if (wio_border_drag(server, event)) {
-		return;
-	}
+			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);
-		wlr_seat_pointer_notify_button(server->seat,
-				event->time_msec, event->button, event->state);
+		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 {
 		handle_button_internal(server, event);
 	}
diff --git a/view.c b/view.c
index 0144f09..1273b2c 100644
--- a/view.c
+++ b/view.c
@@ -123,10 +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) {
+		struct wlr_surface **surface, double *sx, double *sy,
+		int *view_area) {
+	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;
+		}
+		// 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;
+			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_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;
 			return view;
 		}
 	}
-- 
2.22.0
Thanks!

To git.sr.ht:~sircmpwn/wio
   65176f9..ec6567e  master -> master
View this thread in the archives