From b909262f5a03b711c7934855a0899b14294d3f01 Mon Sep 17 00:00:00 2001 From: Charlotte Meyer Date: Fri, 17 Jan 2020 19:51:56 +0000 Subject: [PATCH] Add interactive move and rudamentary resize --- include/desktop/view.h | 4 +++ include/input/cursor.h | 18 ++++++++++++ kiwmi/desktop/view.c | 54 +++++++++++++++++++++++++++++++++++ kiwmi/desktop/xdg_shell.c | 29 +++++++++++++++++++ kiwmi/input/cursor.c | 56 ++++++++++++++++++++++++++++++++++++- kiwmi/input/keyboard.c | 3 +- kiwmi/luak/kiwmi_keyboard.c | 6 ++-- 7 files changed, 165 insertions(+), 5 deletions(-) diff --git a/include/desktop/view.h b/include/desktop/view.h index 3ddf345..5ba362f 100644 --- a/include/desktop/view.h +++ b/include/desktop/view.h @@ -36,6 +36,8 @@ struct kiwmi_view { struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; + struct wl_listener request_move; + struct wl_listener request_resize; double x; double y; @@ -91,6 +93,8 @@ struct kiwmi_view *view_at( struct wlr_surface **surface, double *sx, double *sy); +void view_move(struct kiwmi_view *view); +void view_resize(struct kiwmi_view *view, uint32_t edges); struct kiwmi_view *view_create( struct kiwmi_desktop *desktop, enum kiwmi_view_type type, diff --git a/include/input/cursor.h b/include/input/cursor.h index 88cc49f..1c67f78 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -11,11 +11,29 @@ #include #include +#include "desktop/view.h" + +enum kiwmi_cursor_mode { + KIWMI_CURSOR_PASSTHROUGH, + KIWMI_CURSOR_MOVE, + KIWMI_CURSOR_RESIZE, +}; + struct kiwmi_cursor { struct kiwmi_server *server; struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager; + enum kiwmi_cursor_mode cursor_mode; + + struct { + struct kiwmi_view *view; + int orig_x; + int orig_y; + struct wlr_box orig_geom; + uint32_t resize_edges; + } grabbed; + struct wl_listener cursor_motion; struct wl_listener cursor_motion_absolute; struct wl_listener cursor_button; diff --git a/kiwmi/desktop/view.c b/kiwmi/desktop/view.c index cbd2715..220f0e0 100644 --- a/kiwmi/desktop/view.c +++ b/kiwmi/desktop/view.c @@ -7,9 +7,11 @@ #include "desktop/view.h" +#include #include #include "desktop/output.h" +#include "input/cursor.h" #include "server.h" void @@ -74,6 +76,7 @@ view_surface_at( if (view->impl->surface_at) { return view->impl->surface_at(view, sx, sy, sub_x, sub_y); } + return NULL; } @@ -161,6 +164,57 @@ view_at( return NULL; } +static void +view_begin_interactive( + struct kiwmi_view *view, + enum kiwmi_cursor_mode mode, + uint32_t edges) +{ + struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_cursor *cursor = server->input.cursor; + struct wlr_surface *focused_surface = + server->input.seat->pointer_state.focused_surface; + struct wlr_surface *wlr_surface = view->wlr_surface; + + if (wlr_surface != focused_surface) { + return; + } + + uint32_t width; + uint32_t height; + view_get_size(view, &width, &height); + + cursor->cursor_mode = mode; + cursor->grabbed.view = view; + + if (mode == KIWMI_CURSOR_MOVE) { + cursor->grabbed.orig_x = cursor->cursor->x - view->x; + cursor->grabbed.orig_y = cursor->cursor->y - view->y; + } else { + cursor->grabbed.orig_x = cursor->cursor->x; + cursor->grabbed.orig_y = cursor->cursor->y; + cursor->grabbed.resize_edges = edges; + } + + cursor->grabbed.orig_geom.x = view->x; + cursor->grabbed.orig_geom.y = view->y; + cursor->grabbed.orig_geom.width = width; + cursor->grabbed.orig_geom.height = height; +} + +void +view_move(struct kiwmi_view *view) +{ + view_begin_interactive(view, KIWMI_CURSOR_MOVE, 0); +} + +void +view_resize(struct kiwmi_view *view, uint32_t edges) +{ + view_begin_interactive(view, KIWMI_CURSOR_RESIZE, edges); +} + struct kiwmi_view * view_create( struct kiwmi_desktop *desktop, diff --git a/kiwmi/desktop/xdg_shell.c b/kiwmi/desktop/xdg_shell.c index 6ca8aea..70ba796 100644 --- a/kiwmi/desktop/xdg_shell.c +++ b/kiwmi/desktop/xdg_shell.c @@ -47,10 +47,31 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) wl_list_remove(&view->map.link); wl_list_remove(&view->unmap.link); wl_list_remove(&view->destroy.link); + wl_list_remove(&view->request_move.link); + wl_list_remove(&view->request_resize.link); free(view); } +static void +xdg_toplevel_request_move_notify( + struct wl_listener *listener, + void *UNUSED(data)) +{ + struct kiwmi_view *view = wl_container_of(listener, view, request_move); + + view_move(view); +} + +static void +xdg_toplevel_request_resize_notify(struct wl_listener *listener, void *data) +{ + struct kiwmi_view *view = wl_container_of(listener, view, request_resize); + struct wlr_xdg_toplevel_resize_event *event = data; + + view_resize(view, event->edges); +} + static void xdg_shell_view_close(struct kiwmi_view *view) { @@ -162,5 +183,13 @@ xdg_shell_new_surface_notify(struct wl_listener *listener, void *data) view->destroy.notify = xdg_surface_destroy_notify; wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + view->request_move.notify = xdg_toplevel_request_move_notify; + wl_signal_add( + &xdg_surface->toplevel->events.request_move, &view->request_move); + + view->request_resize.notify = xdg_toplevel_request_resize_notify; + wl_signal_add( + &xdg_surface->toplevel->events.request_resize, &view->request_resize); + wl_list_insert(&desktop->views, &view->link); } diff --git a/kiwmi/input/cursor.c b/kiwmi/input/cursor.c index 145b75a..21a40b3 100644 --- a/kiwmi/input/cursor.c +++ b/kiwmi/input/cursor.c @@ -20,6 +20,7 @@ #include "desktop/desktop.h" #include "desktop/view.h" #include "server.h" +#include "wlr/util/edges.h" static void process_cursor_motion(struct kiwmi_server *server, uint32_t time) @@ -29,6 +30,56 @@ process_cursor_motion(struct kiwmi_server *server, uint32_t time) struct kiwmi_cursor *cursor = input->cursor; struct wlr_seat *seat = input->seat; + switch (cursor->cursor_mode) { + case KIWMI_CURSOR_MOVE: { + struct kiwmi_view *view = cursor->grabbed.view; + view->x = cursor->cursor->x - cursor->grabbed.orig_x; + view->y = cursor->cursor->y - cursor->grabbed.orig_y; + return; + } + case KIWMI_CURSOR_RESIZE: { + struct kiwmi_view *view = cursor->grabbed.view; + double dx = cursor->cursor->x - cursor->grabbed.orig_x; + double dy = cursor->cursor->y - cursor->grabbed.orig_y; + + struct wlr_box new_geom = { + .x = view->x, + .y = view->y, + .width = cursor->grabbed.orig_geom.width, + .height = cursor->grabbed.orig_geom.height, + }; + + if (cursor->grabbed.resize_edges & WLR_EDGE_TOP) { + new_geom.y = cursor->grabbed.orig_y + dy; + new_geom.height -= dy; + if (new_geom.height < 1) { + new_geom.y += new_geom.height; + } + } else if (cursor->grabbed.resize_edges & WLR_EDGE_BOTTOM) { + new_geom.height += dy; + } + + if (cursor->grabbed.resize_edges & WLR_EDGE_LEFT) { + new_geom.x = cursor->grabbed.orig_geom.x + dx; + new_geom.width -= dx; + if (new_geom.width < 1) { + new_geom.x += new_geom.width; + } + } else if (cursor->grabbed.resize_edges & WLR_EDGE_RIGHT) { + new_geom.width += dx; + } + + view->x = new_geom.x; + view->y = new_geom.y; + view_set_size(view, new_geom.width, new_geom.height); + + return; + } + default: + // EMPTY + break; + } + struct wlr_surface *surface = NULL; double sx; double sy; @@ -125,6 +176,8 @@ cursor_button_notify(struct wl_listener *listener, void *data) wlr_seat_pointer_notify_button( input->seat, event->time_msec, event->button, event->state); } + + cursor->cursor_mode = KIWMI_CURSOR_PASSTHROUGH; } static void @@ -194,7 +247,8 @@ cursor_create( return NULL; } - cursor->server = server; + cursor->server = server; + cursor->cursor_mode = KIWMI_CURSOR_PASSTHROUGH; cursor->cursor = wlr_cursor_create(); if (!cursor->cursor) { diff --git a/kiwmi/input/keyboard.c b/kiwmi/input/keyboard.c index 1b56cc9..fdc8ac9 100644 --- a/kiwmi/input/keyboard.c +++ b/kiwmi/input/keyboard.c @@ -96,7 +96,8 @@ keyboard_key_notify(struct wl_listener *listener, void *data) static void keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) { - struct kiwmi_keyboard *keyboard = wl_container_of(listener, keyboard, device_destroy); + struct kiwmi_keyboard *keyboard = + wl_container_of(listener, keyboard, device_destroy); wl_list_remove(&keyboard->link); wl_list_remove(&keyboard->modifiers.link); diff --git a/kiwmi/luak/kiwmi_keyboard.c b/kiwmi/luak/kiwmi_keyboard.c index 1b63be1..d7c9298 100644 --- a/kiwmi/luak/kiwmi_keyboard.c +++ b/kiwmi/luak/kiwmi_keyboard.c @@ -62,9 +62,9 @@ static const luaL_Reg kiwmi_keyboard_methods[] = { static void kiwmi_keyboard_on_destroy_notify(struct wl_listener *listener, void *data) { - struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener); - struct kiwmi_server *server = lc->server; - lua_State *L = server->lua->L; + struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener); + struct kiwmi_server *server = lc->server; + lua_State *L = server->lua->L; struct kiwmi_keyboard *keyboard = data; lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);