From: Johan Malm Date: Mon, 25 May 2020 12:42:40 +0000 (+0100) Subject: Support xwayland view resize (LAB_DECO_PART_LEFT) X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=e716a92c00753860c96e170158c3789879fb8cd0;p=proto%2Flabwc.git Support xwayland view resize (LAB_DECO_PART_LEFT) --- diff --git a/.clang-format b/.clang-format index 7ac923e8..0a012ef9 100644 --- a/.clang-format +++ b/.clang-format @@ -145,6 +145,7 @@ Cpp11BracedListStyle: false ForEachMacros: - 'wl_list_for_each' - 'wl_list_for_each_reverse' + - 'wl_list_for_each_safe' # The maximum number of consecutive empty lines to keep. MaxEmptyLinesToKeep: 1 diff --git a/deco.c b/deco.c index 5623df5a..f5029688 100644 --- a/deco.c +++ b/deco.c @@ -39,9 +39,11 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part) enum deco_part deco_at(struct view *view, double lx, double ly) { - struct wlr_box box; - box = deco_box(view, LAB_DECO_PART_TOP); - if (wlr_box_contains_point(&box, lx, ly)) - return LAB_DECO_PART_TOP; + enum deco_part deco_part; + for (deco_part = 0; deco_part < LAB_DECO_NONE; ++deco_part) { + struct wlr_box box = deco_box(view, deco_part); + if (wlr_box_contains_point(&box, lx, ly)) + return deco_part; + } return LAB_DECO_NONE; } diff --git a/labwc.h b/labwc.h index 46be920a..26f7bcf8 100644 --- a/labwc.h +++ b/labwc.h @@ -34,7 +34,7 @@ #define XCURSOR_MOVE "grabbing" #define XWL_TITLEBAR_HEIGHT (10) #define XWL_WINDOW_BORDER (3) -#define LAB_DISABLE_CSD (1) +#define LAB_DISABLE_CSD (0) enum cursor_mode { TINYWL_CURSOR_PASSTHROUGH, @@ -79,6 +79,9 @@ struct server { struct wlr_output_layout *output_layout; struct wl_list outputs; struct wl_listener new_output; + + /* For use in cycle (alt-tab) mode */ + struct view *cycle_view; }; struct output { @@ -90,7 +93,8 @@ struct output { enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW }; -enum deco_part { LAB_DECO_NONE, LAB_DECO_PART_TOP, LAB_DECO_PART_LEFT }; +/* Keep LAB_DECO_NONE last for the purpose of iterating */ +enum deco_part { LAB_DECO_PART_TOP = 0, LAB_DECO_PART_LEFT, LAB_DECO_NONE }; struct view { enum view_type type; diff --git a/main.c b/main.c index b62afd66..692684c1 100644 --- a/main.c +++ b/main.c @@ -134,8 +134,8 @@ int main(int argc, char *argv[]) wlr_cursor_attach_output_layout(server.cursor, server.output_layout); // This is done below - //server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE); - //if (!server.cursor_mgr) { + // server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE); + // if (!server.cursor_mgr) { // wlr_log(WLR_ERROR, "cannot create xcursor manager"); // return 1; //} @@ -279,10 +279,10 @@ int main(int argc, char *argv[]) wl_list_remove(&_output->link); free(_output); } - struct output *_keyboard, *_keyboard_tmp; - wl_list_for_each_safe (_keyboard, _keyboard_tmp, &server.keyboards, link) { - wl_list_remove(&_keyboard->link); - free(_keyboard); + struct output *k, *k_tmp; + wl_list_for_each_safe (k, k_tmp, &server.keyboards, link) { + wl_list_remove(&k->link); + free(k); } wlr_cursor_destroy(server.cursor); wlr_output_layout_destroy(server.output_layout); diff --git a/output.c b/output.c index ba9ffcee..8cd684bb 100644 --- a/output.c +++ b/output.c @@ -7,6 +7,47 @@ struct render_data { struct timespec *when; }; +static void render_grab(struct output *output) +{ + if (output->server->cursor_mode == TINYWL_CURSOR_PASSTHROUGH) + return; + + if (output->server->cursor_mode == TINYWL_CURSOR_RESIZE) { + float grab_box_color[] = { 0.0, 1.0, 0.0, 0.3 }; + wlr_render_rect(output->server->renderer, + &output->server->grab_box, grab_box_color, + output->wlr_output->transform_matrix); + } + + float grab_point_color[] = { 1.0, 0.0, 1.0, 1.0 }; + struct wlr_box point = { .x = output->server->grab_x + + output->server->grabbed_view->x - 1, + .y = output->server->grab_y + + output->server->grabbed_view->y - 1, + .width = 3, + .height = 3 }; + fprintf(stderr, "XX grab_x=%f; grab_y=%f\n", output->server->grab_x, + output->server->grab_y); + wlr_render_rect(output->server->renderer, &point, grab_point_color, + output->wlr_output->transform_matrix); +} + +static void render_cycle_box(struct output *output) +{ + if (!output->server->cycle_view) + return; + struct view *view; + wl_list_for_each_reverse (view, &output->server->views, link) { + if (view != output->server->cycle_view) + continue; + struct wlr_box box = deco_max_extents(view); + float cycle_color[] = { 0.0, 0.0, 0.0, 0.2 }; + wlr_render_rect(output->server->renderer, &box, cycle_color, + output->wlr_output->transform_matrix); + return; + } +} + static void render_decorations(struct wlr_output *output, struct view *view) { if (!view_want_deco(view)) @@ -144,6 +185,10 @@ void output_frame(struct wl_listener *listener, void *data) } } + /* If in cycle (alt-tab) mode, highlight selected view */ + render_cycle_box(output); + render_grab(output); + /* Hardware cursors are rendered by the GPU on a separate plane, and can * be moved around without re-rendering what's beneath them - which is * more efficient. However, not all hardware supports hardware cursors. diff --git a/server.c b/server.c index 6368e94b..52b89ee2 100644 --- a/server.c +++ b/server.c @@ -1,10 +1,21 @@ #include "labwc.h" -static bool in_alt_tab_mode; -static struct view *alt_tab_view; +static struct wlr_box view_geometry(struct view *view) +{ + struct wlr_box box = { 0 }; + switch (view->type) { + case LAB_XDG_SHELL_VIEW: + wlr_xdg_surface_get_geometry(view->xdg_surface, &box); + break; + case LAB_XWAYLAND_VIEW: + box.width = view->xwayland_surface->width; + box.height = view->xwayland_surface->height; + break; + } + return box; +} -void begin_interactive(struct view *view, enum cursor_mode mode, - uint32_t edges) +void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges) { /* This function sets up an interactive move or resize operation, where * the compositor stops propegating pointer events to clients and @@ -13,24 +24,13 @@ void begin_interactive(struct view *view, enum cursor_mode mode, server->grabbed_view = view; server->cursor_mode = mode; - if (mode == TINYWL_CURSOR_MOVE) { + switch (mode) { + case TINYWL_CURSOR_MOVE: server->grab_x = server->cursor->x - view->x; server->grab_y = server->cursor->y - view->y; - } else { - struct wlr_box geo_box; - switch (view->type) { - case LAB_XDG_SHELL_VIEW: - wlr_xdg_surface_get_geometry(view->xdg_surface, - &geo_box); - break; - case LAB_XWAYLAND_VIEW: - geo_box.x = view->xwayland_surface->x; - geo_box.y = view->xwayland_surface->y; - geo_box.width = view->xwayland_surface->width; - geo_box.height = view->xwayland_surface->height; - break; - } - + break; + case TINYWL_CURSOR_RESIZE: { + struct wlr_box geo_box = view_geometry(view); double border_x = (view->x + geo_box.x) + ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0); @@ -43,6 +43,9 @@ void begin_interactive(struct view *view, enum cursor_mode mode, server->grab_box.x += view->x; server->grab_box.y += view->y; server->resize_edges = edges; + } break; + default: + break; } } @@ -79,9 +82,8 @@ static bool handle_keybinding(struct server *server, xkb_keysym_t sym) break; case XKB_KEY_F1: case XKB_KEY_F2: - in_alt_tab_mode = true; - alt_tab_view = next_toplevel(view_front_toplevel(server)); - fprintf(stderr, "alt_tab_view=%p\n", (void *)alt_tab_view); + server->cycle_view = next_toplevel(view_front_toplevel(server)); + fprintf(stderr, "cycle_view=%p\n", (void *)server->cycle_view); break; case XKB_KEY_F3: if (fork() == 0) { @@ -120,17 +122,17 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data) uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if (in_alt_tab_mode) { + if (server->cycle_view) { if ((syms[0] == XKB_KEY_Alt_L) && event->state == WLR_KEY_RELEASED) { /* end cycle */ - in_alt_tab_mode = false; - view_focus(alt_tab_view); + view_focus(server->cycle_view); + server->cycle_view = NULL; } else if (event->state == WLR_KEY_PRESSED) { /* cycle to next */ - alt_tab_view = next_toplevel(alt_tab_view); - fprintf(stderr, "alt_tab_view=%p\n", - (void *)alt_tab_view); + server->cycle_view = next_toplevel(server->cycle_view); + fprintf(stderr, "cycle_view=%p\n", + (void *)server->cycle_view); return; } } @@ -268,11 +270,6 @@ static void process_cursor_move(struct server *server, uint32_t time) static void process_cursor_resize(struct server *server, uint32_t time) { /* - * Resizing the grabbed view can be a little bit complicated, because we - * could be resizing from any corner or edge. This not only resizes the - * view on one or two axes, but can also move the view if you resize - * from the top or left edges (or top-left corner). - * * TODO: Wait for the client to prepare a buffer at the new size, then * commit any movement that was prepared. */ @@ -303,14 +300,22 @@ static void process_cursor_resize(struct server *server, uint32_t time) new_right = new_left + 1; } - struct wlr_box geo_box; - wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box); + struct wlr_box geo_box = view_geometry(view); view->x = new_left - geo_box.x; view->y = new_top - geo_box.y; int new_width = new_right - new_left; int new_height = new_bottom - new_top; - wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, new_height); + switch (view->type) { + case LAB_XDG_SHELL_VIEW: + wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, + new_height); + break; + case LAB_XWAYLAND_VIEW: + wlr_xwayland_surface_configure(view->xwayland_surface, view->x, + view->y, new_width, new_height); + break; + } } static void process_cursor_motion(struct server *server, uint32_t time) @@ -345,6 +350,10 @@ static void process_cursor_motion(struct server *server, uint32_t time) wlr_xcursor_manager_set_cursor_image( server->cursor_mgr, "left_ptr", server->cursor); break; + case LAB_DECO_PART_LEFT: + wlr_xcursor_manager_set_cursor_image( + server->cursor_mgr, "left_side", server->cursor); + break; } if (surface) { bool focus_changed = seat->pointer_state.focused_surface != @@ -431,6 +440,10 @@ void server_cursor_button(struct wl_listener *listener, void *data) case LAB_DECO_PART_TOP: begin_interactive(view, TINYWL_CURSOR_MOVE, 0); break; + case LAB_DECO_PART_LEFT: + begin_interactive(view, TINYWL_CURSOR_RESIZE, + WLR_EDGE_LEFT); + break; } } } diff --git a/view.c b/view.c index 8d8912a5..ea0b33c2 100644 --- a/view.c +++ b/view.c @@ -165,6 +165,10 @@ struct view *view_at(struct server *server, double lx, double ly, *view_area = LAB_DECO_PART_TOP; return view; } + if (deco_at(view, lx, ly) == LAB_DECO_PART_LEFT) { + *view_area = LAB_DECO_PART_LEFT; + return view; + } } return NULL; }