From 97679b8e12a5e508a51d7cb83b3c039b99e9901d Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 30 Sep 2017 10:39:06 +0200 Subject: [PATCH 1/5] React to xdg shell resize requests --- include/rootston/input.h | 2 ++ rootston/cursor.c | 12 ++++++++++++ rootston/wl_shell.c | 4 ++-- rootston/xdg_shell_v6.c | 21 +++++++++++++++++++++ rootston/xwayland.c | 4 ++-- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index aeab9c0d..b4d6de65 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -110,5 +110,7 @@ const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial); void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view); +void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, + struct roots_view *view); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 2742e7cd..d5f1f7f5 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -29,6 +29,14 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, wlr_seat_pointer_clear_focus(input->wl_seat); } +void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, + struct roots_view *view) { + input->mode = ROOTS_CURSOR_RESIZE; + input->offs_x = cursor->x - view->x; + input->offs_y = cursor->y - view->y; + wlr_seat_pointer_clear_focus(input->wl_seat); +} + void cursor_update_position(struct roots_input *input, uint32_t time) { struct roots_desktop *desktop = input->server->desktop; struct roots_view *view; @@ -53,6 +61,10 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { } break; case ROOTS_CURSOR_RESIZE: + // TODO: this is just for testing + if (input->active_view && input->active_view->type == ROOTS_XDG_SHELL_V6_VIEW) { + wlr_xdg_toplevel_v6_set_size(input->active_view->xdg_surface_v6, input->cursor->x - input->offs_x, input->cursor->y - input->offs_y); + } break; case ROOTS_CURSOR_ROTATE: break; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 4189e910..d70f59f2 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -10,7 +10,7 @@ #include "rootston/server.h" #include "rootston/input.h" -static void handle_move(struct wl_listener *listener, void *data) { +static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); struct roots_view *view = roots_surface->view; @@ -53,7 +53,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&surface->events.destroy, &roots_surface->destroy); wl_list_init(&roots_surface->ping_timeout.link); wl_list_init(&roots_surface->request_move.link); - roots_surface->request_move.notify = handle_move; + roots_surface->request_move.notify = handle_request_move; wl_signal_add(&surface->events.request_move, &roots_surface->request_move); wl_list_init(&roots_surface->request_resize.link); wl_list_init(&roots_surface->request_set_fullscreen.link); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index e8edaa8f..814c5642 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -14,6 +14,11 @@ static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; memcpy(box, surf->geometry, sizeof(struct wlr_box)); + // TODO: real input bounds + box->x -= 10; + box->y -= 10; + box->width += 20; + box->height += 20; } static void activate(struct roots_view *view, bool active) { @@ -37,6 +42,19 @@ static void handle_request_move(struct wl_listener *listener, void *data) { view_begin_move(input, event->cursor, view); } +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, request_resize); + struct roots_view *view = roots_xdg_surface->view; + struct roots_input *input = view->desktop->server->input; + struct wlr_xdg_toplevel_v6_resize_event *e = data; + const struct roots_input_event *event = get_input_event(input, e->serial); + if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + return; + } + view_begin_resize(input, event->cursor, view); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, destroy); @@ -71,6 +89,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { roots_surface->request_move.notify = handle_request_move; wl_signal_add(&surface->events.request_move, &roots_surface->request_move); wl_list_init(&roots_surface->request_resize.link); + roots_surface->request_resize.notify = handle_request_resize; + wl_signal_add(&surface->events.request_resize, + &roots_surface->request_resize); wl_list_init(&roots_surface->request_show_window_menu.link); struct roots_view *view = calloc(1, sizeof(struct roots_view)); diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 181b959d..4e42a925 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -17,7 +17,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { free(roots_surface); } -static void handle_configure(struct wl_listener *listener, void *data) { +static void handle_request_configure(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_configure); struct wlr_xwayland_surface *xwayland_surface = @@ -58,7 +58,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); wl_list_init(&roots_surface->request_configure.link); - roots_surface->request_configure.notify = handle_configure; + roots_surface->request_configure.notify = handle_request_configure; wl_signal_add(&surface->events.request_configure, &roots_surface->request_configure); From 33a97576ca3169b7771a0bd574383f5cf502f583 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 30 Sep 2017 11:57:39 +0200 Subject: [PATCH 2/5] Add view_resize --- include/rootston/input.h | 3 ++- include/rootston/view.h | 2 ++ rootston/cursor.c | 16 ++++++++++------ rootston/desktop.c | 6 ++++++ rootston/xdg_shell_v6.c | 11 ++++++++++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index b4d6de65..cf4513e5 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -71,6 +71,7 @@ struct roots_input { enum roots_cursor_mode mode; struct roots_view *active_view; int offs_x, offs_y; + uint32_t resize_edges; // Ring buffer of input events that could trigger move/resize/rotate int input_events_idx; @@ -111,6 +112,6 @@ const struct roots_input_event *get_input_event(struct roots_input *input, void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view); void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view); + struct roots_view *view, uint32_t edges); #endif diff --git a/include/rootston/view.h b/include/rootston/view.h index 2bd71104..d690fd48 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -63,9 +63,11 @@ struct roots_view { // elsewhere void (*get_input_bounds)(struct roots_view *view, struct wlr_box *box); void (*activate)(struct roots_view *view, bool active); + void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); }; void view_get_input_bounds(struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); +void view_resize(struct roots_view *view, uint32_t width, uint32_t height); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index d5f1f7f5..c57bff52 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -30,10 +30,12 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, } void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view) { + struct roots_view *view, uint32_t edges) { input->mode = ROOTS_CURSOR_RESIZE; - input->offs_x = cursor->x - view->x; - input->offs_y = cursor->y - view->y; + wlr_log(L_DEBUG, "begin resize"); + input->offs_x = cursor->x - (double)view->wlr_surface->current.width - view->x; + input->offs_y = cursor->y - (double)view->wlr_surface->current.height - view->y; + input->resize_edges = edges; wlr_seat_pointer_clear_focus(input->wl_seat); } @@ -61,9 +63,11 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { } break; case ROOTS_CURSOR_RESIZE: - // TODO: this is just for testing - if (input->active_view && input->active_view->type == ROOTS_XDG_SHELL_V6_VIEW) { - wlr_xdg_toplevel_v6_set_size(input->active_view->xdg_surface_v6, input->cursor->x - input->offs_x, input->cursor->y - input->offs_y); + if (input->active_view) { + // TODO: edges + uint32_t width = input->cursor->x - input->offs_x; + uint32_t height = input->cursor->y - input->offs_y; + view_resize(input->active_view, width, height); } break; case ROOTS_CURSOR_ROTATE: diff --git a/rootston/desktop.c b/rootston/desktop.c index cd417755..00657bc6 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -41,6 +41,12 @@ void view_activate(struct roots_view *view, bool activate) { } } +void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { + if (view->resize) { + view->resize(view, width, height); + } +} + struct roots_view *view_at(struct roots_desktop *desktop, int x, int y) { for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *view = desktop->views->items[i]; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 814c5642..a18aa501 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -29,6 +29,14 @@ static void activate(struct roots_view *view, bool active) { } } +static void resize(struct roots_view *view, uint32_t width, uint32_t height) { + assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); + struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; + if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + wlr_xdg_toplevel_v6_set_size(surf, width, height); + } +} + static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, request_move); @@ -52,7 +60,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view); + view_begin_resize(input, event->cursor, view, e->edges); } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -102,6 +110,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->wlr_surface = surface->surface; view->get_input_bounds = get_input_bounds; view->activate = activate; + view->resize = resize; view->desktop = desktop; roots_surface->view = view; list_add(desktop->views, view); From 28d4b475dc74302653882e5f5f58506c5c16bcb6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 30 Sep 2017 13:22:42 +0200 Subject: [PATCH 3/5] Add edges support, remove get_input_bounds --- include/rootston/input.h | 8 ++++++++ rootston/cursor.c | 27 ++++++++++++++++++++++----- rootston/xdg_shell_v6.c | 12 ++++-------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index cf4513e5..c2e0ff75 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -53,6 +53,13 @@ enum roots_cursor_mode { ROOTS_CURSOR_ROTATE = 3, }; +enum roots_cursor_resize_edge { + ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, + ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, +}; + struct roots_input_event { uint32_t serial; struct wlr_cursor *cursor; @@ -71,6 +78,7 @@ struct roots_input { enum roots_cursor_mode mode; struct roots_view *active_view; int offs_x, offs_y; + int view_width, view_height; uint32_t resize_edges; // Ring buffer of input events that could trigger move/resize/rotate diff --git a/rootston/cursor.c b/rootston/cursor.c index c57bff52..ac6b1dc3 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -33,8 +33,10 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { input->mode = ROOTS_CURSOR_RESIZE; wlr_log(L_DEBUG, "begin resize"); - input->offs_x = cursor->x - (double)view->wlr_surface->current.width - view->x; - input->offs_y = cursor->y - (double)view->wlr_surface->current.height - view->y; + input->offs_x = cursor->x - view->x; + input->offs_y = cursor->y - view->y; + input->view_width = view->wlr_surface->current.width; + input->view_height = view->wlr_surface->current.height; input->resize_edges = edges; wlr_seat_pointer_clear_focus(input->wl_seat); } @@ -64,9 +66,24 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { break; case ROOTS_CURSOR_RESIZE: if (input->active_view) { - // TODO: edges - uint32_t width = input->cursor->x - input->offs_x; - uint32_t height = input->cursor->y - input->offs_y; + int dx = input->cursor->x - input->offs_x; + int dy = input->cursor->y - input->offs_y; + int width = input->view_width; + int height = input->view_height; + if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + input->active_view->y = dy; + height -= dy; + } + if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + height += dy; + } + if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + input->active_view->x = dx; + width -= dx; + } + if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + width += dx; + } view_resize(input->active_view, width, height); } break; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index a18aa501..8f5b405c 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -10,16 +10,12 @@ #include "rootston/server.h" #include "rootston/input.h" -static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { +/*static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; + // TODO: surf->geometry can be NULL memcpy(box, surf->geometry, sizeof(struct wlr_box)); - // TODO: real input bounds - box->x -= 10; - box->y -= 10; - box->width += 20; - box->height += 20; -} +}*/ static void activate(struct roots_view *view, bool active) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); @@ -108,7 +104,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->xdg_surface_v6 = surface; view->roots_xdg_surface_v6 = roots_surface; view->wlr_surface = surface->surface; - view->get_input_bounds = get_input_bounds; + //view->get_input_bounds = get_input_bounds; view->activate = activate; view->resize = resize; view->desktop = desktop; From 77d28183b53a9fc85efe4788f3a53f3077084f6b Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 30 Sep 2017 13:54:51 +0200 Subject: [PATCH 4/5] Partially fix resize offset --- include/rootston/input.h | 2 +- rootston/cursor.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index c2e0ff75..1fae07d7 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -78,7 +78,7 @@ struct roots_input { enum roots_cursor_mode mode; struct roots_view *active_view; int offs_x, offs_y; - int view_width, view_height; + int view_x, view_y, view_width, view_height; uint32_t resize_edges; // Ring buffer of input events that could trigger move/resize/rotate diff --git a/rootston/cursor.c b/rootston/cursor.c index ac6b1dc3..bef30746 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -33,8 +33,10 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { input->mode = ROOTS_CURSOR_RESIZE; wlr_log(L_DEBUG, "begin resize"); - input->offs_x = cursor->x - view->x; - input->offs_y = cursor->y - view->y; + input->offs_x = cursor->x; + input->offs_y = cursor->y; + input->view_x = view->x; + input->view_y = view->y; input->view_width = view->wlr_surface->current.width; input->view_height = view->wlr_surface->current.height; input->resize_edges = edges; @@ -71,14 +73,14 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { int width = input->view_width; int height = input->view_height; if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - input->active_view->y = dy; + input->active_view->y = input->view_y + dy; height -= dy; } if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { height += dy; } if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - input->active_view->x = dx; + input->active_view->x = input->view_x + dx; width -= dx; } if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { From 74f2d0cd63131ab782c309270241bcbf0e47db12 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 30 Sep 2017 14:02:09 +0200 Subject: [PATCH 5/5] Completely fix resize offset --- include/rootston/view.h | 2 ++ rootston/cursor.c | 6 ++++-- rootston/desktop.c | 10 ++++++++++ rootston/xdg_shell_v6.c | 6 +++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index d690fd48..39ff80db 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -61,11 +61,13 @@ struct roots_view { // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use // elsewhere + void (*get_size)(struct roots_view *view, struct wlr_box *box); void (*get_input_bounds)(struct roots_view *view, struct wlr_box *box); void (*activate)(struct roots_view *view, bool active); void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); }; +void view_get_size(struct roots_view *view, struct wlr_box *box); void view_get_input_bounds(struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); diff --git a/rootston/cursor.c b/rootston/cursor.c index bef30746..bd8f91d2 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -37,8 +37,10 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, input->offs_y = cursor->y; input->view_x = view->x; input->view_y = view->y; - input->view_width = view->wlr_surface->current.width; - input->view_height = view->wlr_surface->current.height; + struct wlr_box size; + view_get_size(view, &size); + input->view_width = size.width; + input->view_height = size.height; input->resize_edges = edges; wlr_seat_pointer_clear_focus(input->wl_seat); } diff --git a/rootston/desktop.c b/rootston/desktop.c index 00657bc6..8ddd9444 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -25,6 +25,16 @@ void view_destroy(struct roots_view *view) { free(view); } +void view_get_size(struct roots_view *view, struct wlr_box *box) { + if (view->get_size) { + view->get_size(view, box); + return; + } + box->x = box->y = 0; + box->width = view->wlr_surface->current.width; + box->height = view->wlr_surface->current.height; +} + void view_get_input_bounds(struct roots_view *view, struct wlr_box *box) { if (view->get_input_bounds) { view->get_input_bounds(view, box); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 8f5b405c..ab34f52a 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -10,12 +10,12 @@ #include "rootston/server.h" #include "rootston/input.h" -/*static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { +static void get_size(struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; // TODO: surf->geometry can be NULL memcpy(box, surf->geometry, sizeof(struct wlr_box)); -}*/ +} static void activate(struct roots_view *view, bool active) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); @@ -104,7 +104,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->xdg_surface_v6 = surface; view->roots_xdg_surface_v6 = roots_surface; view->wlr_surface = surface->surface; - //view->get_input_bounds = get_input_bounds; + view->get_size = get_size; view->activate = activate; view->resize = resize; view->desktop = desktop;