wio

a wayland wm stylised after plan9 rio - forked from git.sr.ht/~srcmpwn/wio
git clone git://src.gearsix.net/wio
Log | Files | Refs | Atom | Submodules | README | LICENSE

commit 65176f9e2fe203a8e5d10b907bb9821e899be8ca
parent 30c2643a28f795a0b441dd834ea9580b0002c587
Author: Leon Plickat <leonhenrik.plickat@stud.uni-goettingen.de>
Date:   Fri,  2 Aug 2019 18:18:17 +0200

Resize views by dragging their borders

This matches Rios behaviour, with the small exception that wios resizing
is smooth while Rios snaps to a grid.

Diffstat:
Minclude/server.h | 4++++
Minput.c | 163++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Moutput.c | 36++++++++++++++++++++++++++++++++++--
3 files changed, 200 insertions(+), 3 deletions(-)

diff --git a/include/server.h b/include/server.h @@ -26,6 +26,10 @@ 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_DELETE_SELECT, INPUT_STATE_HIDE_SELECT, }; diff --git a/input.c b/input.c @@ -134,6 +134,22 @@ static void process_cursor_motion(struct wio_server *server, uint32_t time) { 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, @@ -296,6 +312,69 @@ 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 @@ -305,6 +384,7 @@ static void handle_button_internal( .width = server->menu.width, .height = server->menu.height, }; int x1, x2, y1, y2; + uint32_t width, height; switch (server->input_state) { case INPUT_STATE_NONE: if (event->state == WLR_BUTTON_PRESSED && event->button == BTN_RIGHT) { @@ -357,6 +437,84 @@ 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; + 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 = _; + } + 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; + } + 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; + } + wlr_xdg_toplevel_set_size( + server->interactive.view->xdg_surface, width, height); + view_end_interactive(server); + break; case INPUT_STATE_RESIZE_END: x1 = server->interactive.sx, x2 = server->cursor->x; y1 = server->interactive.sy, y2 = server->cursor->y; @@ -372,7 +530,7 @@ static void handle_button_internal( } wio_view_move(server->interactive.view, x1, y1); - uint32_t width = x2 - x1, height = y2 - y1; + width = x2 - x1, height = y2 - y1; if (width < 100) { width = 100; } @@ -429,6 +587,9 @@ void server_cursor_button(struct wl_listener *listener, void *data) { struct wlr_surface *surface = NULL; struct wio_view *view = wio_view_at( server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + if (wio_border_drag(server, event)) { + return; + } if (server->input_state == INPUT_STATE_NONE && view) { wio_view_focus(view, surface); wlr_seat_pointer_notify_button(server->seat, diff --git a/output.c b/output.c @@ -306,9 +306,41 @@ static void output_frame(struct wl_listener *listener, void *data) { wlr_xdg_surface_for_each_surface(view->xdg_surface, render_surface, &rdata); } + view = server->interactive.view; switch (server->input_state) { - case INPUT_STATE_MOVE:; - struct wio_view *view = server->interactive.view; + 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); + break; + case INPUT_STATE_MOVE: render_view_border(renderer, output, view, server->cursor->x - server->interactive.sx, server->cursor->y - server->interactive.sy,