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 c54aeba29cc945d4fb4e2f5b35c509244be263d8
parent 8442dc236f4d5b2e230c9cdf2e13278c6325a15e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 25 Apr 2019 12:42:48 -0400

Implement interactive resize

Diffstat:
Minclude/server.h | 5++++-
Minput.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mmain.c | 2+-
Moutput.c | 60++++++++++++++++++++++++++++++++++++++----------------------
4 files changed, 132 insertions(+), 36 deletions(-)

diff --git a/include/server.h b/include/server.h @@ -12,6 +12,8 @@ #include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xdg_shell.h> +static const int window_border = 5; + enum wio_input_state { INPUT_STATE_NONE = 0, INPUT_STATE_MENU, @@ -20,7 +22,8 @@ enum wio_input_state { INPUT_STATE_MOVE_SELECT, INPUT_STATE_MOVE, INPUT_STATE_RESIZE_SELECT, - INPUT_STATE_RESIZE, + INPUT_STATE_RESIZE_START, + INPUT_STATE_RESIZE_END, INPUT_STATE_DELETE_SELECT, INPUT_STATE_HIDE_SELECT, }; diff --git a/input.c b/input.c @@ -99,6 +99,14 @@ 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_RESIZE_START: + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, + "top_left_corner", server->cursor); + break; + case INPUT_STATE_RESIZE_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); @@ -138,6 +146,11 @@ static void menu_handle_button( struct wio_server *server, struct wlr_event_pointer_button *event) { server->menu.x = server->menu.y = -1; switch (server->menu.selected) { + case 1: + server->input_state = INPUT_STATE_RESIZE_SELECT; + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, + "hand1", server->cursor); + break; case 2: server->input_state = INPUT_STATE_MOVE_SELECT; wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, @@ -149,6 +162,30 @@ static void menu_handle_button( } } +static void view_begin_interactive(struct wio_view *view, + struct wlr_surface *surface, double sx, double sy, + const char *cursor, enum wio_input_state state) { + wio_view_focus(view, surface); + view->server->interactive.view = view; + view->server->interactive.sx = (int)sx; + view->server->interactive.sy = (int)sy; + view->server->input_state = state; + wlr_xcursor_manager_set_cursor_image(view->server->cursor_mgr, + "grabbing", view->server->cursor); +} + +static void view_end_interactive(struct wio_server *server) { + server->input_state = INPUT_STATE_NONE; + server->interactive.view = NULL; + if (server->interactive.cursor) { + wlr_cursor_set_surface(server->cursor, server->interactive.cursor, + server->interactive.hotspot_x, server->interactive.hotspot_y); + } else { + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, + "left_ptr", server->cursor); + } +} + 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 @@ -157,6 +194,7 @@ 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; switch (server->input_state) { case INPUT_STATE_NONE: if (event->state == WLR_BUTTON_PRESSED && event->button == BTN_RIGHT) { @@ -177,20 +215,15 @@ static void handle_button_internal( } } break; - case INPUT_STATE_MOVE_SELECT: + 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) { - wio_view_focus(view, surface); - server->interactive.view = view; - server->interactive.sx = (int)sx; - server->interactive.sy = (int)sy; - server->input_state = INPUT_STATE_MOVE; - wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, - "grabbing", server->cursor); + view_begin_interactive(view, surface, sx, sy, + "bottom_right_corner", INPUT_STATE_RESIZE_START); } else { server->input_state = INPUT_STATE_NONE; wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, @@ -198,15 +231,59 @@ static void handle_button_internal( } } 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_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 = _; + } + server->interactive.view->x = x1 + window_border; + server->interactive.view->y = y1 + window_border; + uint32_t width = x2 - x1, height = y2 - y1; + if (width < 100) { + width = 100; + } + 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_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); + } + } + break; case INPUT_STATE_MOVE: server->interactive.view->x = server->cursor->x - server->interactive.sx; server->interactive.view->y = server->cursor->y - server->interactive.sy; - server->input_state = INPUT_STATE_NONE; - server->interactive.view = NULL; - wlr_cursor_set_surface(server->cursor, server->interactive.cursor, - server->interactive.hotspot_x, server->interactive.hotspot_y); + view_end_interactive(server); break; default: // TODO diff --git a/main.c b/main.c @@ -72,7 +72,7 @@ static void gen_menu_textures(struct wio_server *server) { } int main(int argc, char **argv) { - struct wio_server server; + struct wio_server server = { 0 }; wlr_log_init(WLR_DEBUG, NULL); diff --git a/output.c b/output.c @@ -134,8 +134,8 @@ static void render_menu(struct wio_output *output) { } static void render_view_border(struct wlr_renderer *renderer, - struct wio_output *output, struct wio_view *view, int x, int y) { - const int border = 5; + struct wio_output *output, struct wio_view *view, + int x, int y, int width, int height) { float color[4]; if (view->xdg_surface->toplevel->current.activated) { memcpy(color, active_border, sizeof(color)); @@ -144,31 +144,31 @@ static void render_view_border(struct wlr_renderer *renderer, } struct wlr_box borders; // Top - borders.x = x - border; - borders.y = y - border; - borders.width = view->xdg_surface->surface->current.width + border * 2; - borders.height = border; + borders.x = x - window_border; + borders.y = y - window_border; + borders.width = width + window_border * 2; + borders.height = window_border; wlr_render_rect(renderer, &borders, color, output->wlr_output->transform_matrix); // Right - borders.x = x + view->xdg_surface->surface->current.width; - borders.y = y - border; - borders.width = border; - borders.height = view->xdg_surface->surface->current.height + border * 2; + borders.x = x + width; + borders.y = y - window_border; + borders.width = window_border; + borders.height = height + window_border * 2; wlr_render_rect(renderer, &borders, color, output->wlr_output->transform_matrix); // Bottom - borders.x = x - border; - borders.y = y + view->xdg_surface->surface->current.height; - borders.width = view->xdg_surface->surface->current.width + border * 2; - borders.height = border; + borders.x = x - window_border; + borders.y = y + height; + borders.width = width + window_border * 2; + borders.height = window_border; wlr_render_rect(renderer, &borders, color, output->wlr_output->transform_matrix); // Left - borders.x = x - border; - borders.y = y - border; - borders.width = border; - borders.height = view->xdg_surface->surface->current.height + border * 2; + borders.x = x - window_border; + borders.y = y - window_border; + borders.width = window_border; + borders.height = height + window_border * 2; wlr_render_rect(renderer, &borders, color, output->wlr_output->transform_matrix); } @@ -203,13 +203,29 @@ static void output_frame(struct wl_listener *listener, void *data) { .when = &now, }; - render_view_border(renderer, output, view, view->x, view->y); + render_view_border(renderer, output, view, view->x, view->y, + view->xdg_surface->surface->current.width, + view->xdg_surface->surface->current.height); wlr_xdg_surface_for_each_surface(view->xdg_surface, render_surface, &rdata); if (server->interactive.view == view) { - render_view_border(renderer, output, view, - server->cursor->x - server->interactive.sx, - server->cursor->y - server->interactive.sy); + switch (server->input_state) { + case INPUT_STATE_MOVE: + render_view_border(renderer, output, view, + server->cursor->x - server->interactive.sx, + server->cursor->y - server->interactive.sy, + view->xdg_surface->surface->current.width, + view->xdg_surface->surface->current.height); + break; + case INPUT_STATE_RESIZE_END: + render_view_border(renderer, output, view, + server->interactive.sx, server->interactive.sy, + server->cursor->x - server->interactive.sx, + server->cursor->y - server->interactive.sy); + break; + default: + break; + } } }