Leonid Bobrov: 1 Resize views accurately 6 files changed, 210 insertions(+), 379 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~sircmpwn/wio/patches/11232/mbox | git am -3Learn more about email & git
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