From 18950eb84438eb0b61e4587591075a6f9549a74e Mon Sep 17 00:00:00 2001 From: Keith Bowes Date: Thu, 30 Jun 2022 18:25:22 -0400 Subject: [PATCH] Backported changes to tinywl --- include/waybox/output.h | 15 ++++++- include/waybox/seat.h | 3 +- protocol/meson.build | 1 - waybox/cursor.c | 44 ++++++++++++++++++-- waybox/layer_shell.c | 68 ++++++++++++++++++++++++++---- waybox/layer_shell.h | 8 ++++ waybox/output.c | 8 ++++ waybox/seat.c | 65 +++++++++++++++++++++++------ waybox/server.c | 15 +++++++ waybox/xdg_shell.c | 91 +++++++++++++++++++++++++++++++++++++++-- 10 files changed, 288 insertions(+), 30 deletions(-) diff --git a/include/waybox/output.h b/include/waybox/output.h index 55807ec..f8f3b7d 100644 --- a/include/waybox/output.h +++ b/include/waybox/output.h @@ -11,11 +11,19 @@ struct wb_output { struct wb_server *server; struct { +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *shell_background; + struct wlr_scene_tree *shell_bottom; + struct wlr_scene_tree *shell_fullscreen; + struct wlr_scene_tree *shell_overlay; + struct wlr_scene_tree *shell_top; +#else struct wlr_scene_node *shell_background; struct wlr_scene_node *shell_bottom; struct wlr_scene_node *shell_fullscreen; struct wlr_scene_node *shell_overlay; struct wlr_scene_node *shell_top; +#endif } layers; struct wlr_scene_rect *background; @@ -31,10 +39,12 @@ struct wb_view { struct wl_list link; struct wb_server *server; struct wlr_xdg_toplevel *xdg_toplevel; -#if !WLR_CHECK_VERSION(0, 16, 0) +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *scene_tree; +#else + struct wlr_scene_node *scene_node; struct wlr_xdg_surface *xdg_surface; #endif - struct wlr_scene_node *scene_node; struct wlr_xdg_toplevel_decoration_v1 *decoration; @@ -42,6 +52,7 @@ struct wb_view { struct wl_listener unmap; struct wl_listener destroy; struct wl_listener new_popup; + struct wl_listener request_fullscreen; struct wl_listener request_maximize; struct wl_listener request_minimize; struct wl_listener request_move; diff --git a/include/waybox/seat.h b/include/waybox/seat.h index 33f2031..a2b1e76 100644 --- a/include/waybox/seat.h +++ b/include/waybox/seat.h @@ -17,7 +17,8 @@ struct wb_seat { struct wb_keyboard { struct wl_list link; struct wb_server *server; - struct wlr_input_device *device; + struct wlr_input_device *device; /* wlroots 0.15.x */ + struct wlr_keyboard *keyboard; struct wl_listener destroy; struct wl_listener modifiers; diff --git a/protocol/meson.build b/protocol/meson.build index 82dcc9d..af83cc3 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -34,7 +34,6 @@ protocols = [ ] client_protocols = [ - [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], 'idle.xml', 'wlr-screencopy-unstable-v1.xml', diff --git a/waybox/cursor.c b/waybox/cursor.c index 7ad8da7..2adf32c 100644 --- a/waybox/cursor.c +++ b/waybox/cursor.c @@ -4,10 +4,18 @@ static void process_cursor_move(struct wb_server *server) { /* Move the grabbed view to the new position. */ struct wb_view *view = server->grabbed_view; +#if WLR_CHECK_VERSION(0, 16, 0) + if (view->scene_tree->node.type == WLR_SCENE_NODE_TREE) { +#else if (view->scene_node->parent->type == WLR_SCENE_NODE_ROOT) { +#endif view->current_position.x = server->cursor->cursor->x - server->grab_x; view->current_position.y = server->cursor->cursor->y - server->grab_y; +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_set_position(&view->scene_tree->node, +#else wlr_scene_node_set_position(view->scene_node, +#endif view->current_position.x, view->current_position.y); } } @@ -48,6 +56,12 @@ static void process_cursor_resize(struct wb_server *server) { wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); view->current_position.x = new_left - geo_box.x; view->current_position.y = new_top - geo_box.y; +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_set_position(&view->scene_tree->node, +#else + wlr_scene_node_set_position(view->scene_node, +#endif + view->current_position.x, view->current_position.y); int new_width = new_right - new_left; int new_height = new_bottom - new_top; @@ -100,16 +114,31 @@ static void process_cursor_motion(struct wb_server *server, uint32_t time) { } static void handle_cursor_motion(struct wl_listener *listener, void *data) { - struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion); + struct wb_cursor *cursor = + wl_container_of(listener, cursor, cursor_motion); +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_pointer_motion_event *event = data; + wlr_cursor_move(cursor->cursor, &event->pointer->base, + event->delta_x, event->delta_y); +#else struct wlr_event_pointer_motion *event = data; wlr_cursor_move(cursor->cursor, event->device, event->delta_x, event->delta_y); +#endif process_cursor_motion(cursor->server, event->time_msec); } static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { - struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion_absolute); + struct wb_cursor *cursor = + wl_container_of(listener, cursor, cursor_motion_absolute); +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_pointer_motion_absolute_event *event = data; + wlr_cursor_warp_absolute(cursor->cursor, &event->pointer->base, + event->x, event->y); +#else struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x, event->y); +#endif process_cursor_motion(cursor->server, event->time_msec); } @@ -118,7 +147,11 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { * event. */ struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_button); +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_pointer_button_event *event = data; +#else struct wlr_event_pointer_button *event = data; +#endif /* Notify the client with pointer focus that a button press has occurred */ wlr_seat_pointer_notify_button(cursor->server->seat->seat, event->time_msec, event->button, event->state); @@ -140,7 +173,11 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { * for example when you move the scroll wheel. */ struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_axis); +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_pointer_axis_event *event = data; +#else struct wlr_event_pointer_axis *event = data; +#endif /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(cursor->server->seat->seat, event->time_msec, event->orientation, event->delta, @@ -180,6 +217,7 @@ static void handle_cursor_request(struct wl_listener *listener, void *data) { struct wb_cursor *wb_cursor_create(struct wb_server *server) { struct wb_cursor *cursor = malloc(sizeof(struct wb_cursor)); cursor->cursor = wlr_cursor_create(); + cursor->cursor_mode = WB_CURSOR_PASSTHROUGH; cursor->server = server; const char *xcursor_size = getenv("XCURSOR_SIZE"); diff --git a/waybox/layer_shell.c b/waybox/layer_shell.c index af7fb10..46579d8 100644 --- a/waybox/layer_shell.c +++ b/waybox/layer_shell.c @@ -46,9 +46,17 @@ void assign_scene_descriptor(struct wlr_scene_node *node, } static void arrange_surface(struct wb_output *output, struct wlr_box *full_area, +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_box *usable_area, struct wlr_scene_tree *scene_tree) { +#else struct wlr_box *usable_area, struct wlr_scene_node *scene_node) { +#endif struct wlr_scene_node *node; +#if WLR_CHECK_VERSION(0, 16, 0) + wl_list_for_each(node, &scene_tree->children, link) { +#else wl_list_for_each(node, &scene_node->state.children, state.link) { +#endif struct wb_scene_descriptor *desc = node->data; if (desc->type == WB_SCENE_DESC_LAYER_SHELL) { @@ -75,7 +83,11 @@ void arrange_layers(struct wb_output *output) { arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay); } +#if WLR_CHECK_VERSION(0, 16, 0) +static struct wlr_scene_tree *wb_layer_get_scene(struct wb_output *output, +#else static struct wlr_scene_node *wb_layer_get_scene(struct wb_output *output, +#endif enum zwlr_layer_shell_v1_layer type) { switch (type) { case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND: @@ -122,11 +134,20 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { uint32_t committed = layer_surface->current.committed; enum zwlr_layer_shell_v1_layer layer_type = layer_surface->current.layer; +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *output_layer = wb_layer_get_scene( + surface->output, layer_type); +#else struct wlr_scene_node *output_layer = wb_layer_get_scene( surface->output, layer_type); +#endif if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) { +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_reparent(&surface->scene->tree->node, output_layer); +#else wlr_scene_node_reparent(surface->scene->node, output_layer); +#endif } if (committed || layer_surface->mapped != surface->mapped) { @@ -139,7 +160,11 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { } if (layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) { +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_raise_to_top(&output_layer->node); +#else wlr_scene_node_raise_to_top(output_layer); +#endif } if (layer_surface == surface->server->seat->focused_layer) { @@ -219,7 +244,11 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { static struct wb_layer_surface *popup_get_layer( struct wb_layer_popup *popup) { +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_node *current = &popup->scene->node; +#else struct wlr_scene_node *current = popup->scene; +#endif while (current) { if (current->data) { struct wb_scene_descriptor *desc = current->data; @@ -228,7 +257,11 @@ static struct wb_layer_surface *popup_get_layer( } } +#if WLR_CHECK_VERSION(0, 16, 0) + current = ¤t->parent->node; +#else current = current->parent; +#endif } return NULL; @@ -244,7 +277,11 @@ static void popup_unconstrain(struct wb_layer_popup *popup) { struct wb_output *output = surface->output; int lx, ly; +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_coords(&popup->scene->node, &lx, &ly); +#else wlr_scene_node_coords(popup->scene, &lx, &ly); +#endif /* The output box expressed in the coordinate system of the toplevel * parent of the popup. */ @@ -261,7 +298,11 @@ static void popup_unconstrain(struct wb_layer_popup *popup) { static void popup_handle_new_popup(struct wl_listener *listener, void *data); static struct wb_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *parent) { +#else struct wlr_scene_node *parent) { +#endif struct wb_layer_popup *popup = calloc(1, sizeof(struct wb_layer_popup)); if (popup == NULL) { @@ -278,7 +319,11 @@ static struct wb_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, return NULL; } +#if WLR_CHECK_VERSION(0, 16, 0) + assign_scene_descriptor(&popup->scene->node, WB_SCENE_DESC_LAYER_SHELL_POPUP, +#else assign_scene_descriptor(popup->scene, WB_SCENE_DESC_LAYER_SHELL_POPUP, +#endif popup); popup->destroy.notify = popup_handle_destroy; @@ -304,7 +349,11 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { wl_container_of(listener, wb_layer_surface, new_popup); struct wlr_xdg_popup *wlr_popup = data; +#if WLR_CHECK_VERSION(0, 16, 0) + create_popup(wlr_popup, wb_layer_surface->scene->tree); +#else create_popup(wlr_popup, wb_layer_surface->scene->node); +#endif } void handle_layer_shell_surface(struct wl_listener *listener, void *data) { @@ -326,9 +375,9 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { enum zwlr_layer_shell_v1_layer layer_type = layer_surface->pending.layer; - struct wlr_scene_node *output_layer = wb_layer_get_scene( - output, layer_type); #if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *output_layer = wb_layer_get_scene( + output, layer_type); struct wlr_scene_layer_surface_v1 *scene_surface = wlr_scene_layer_surface_v1_create(output_layer, layer_surface); if (!scene_surface) { @@ -337,22 +386,27 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { struct wb_layer_surface *surface = wb_layer_surface_create(scene_surface); + + assign_scene_descriptor(&scene_surface->tree->node, + WB_SCENE_DESC_LAYER_SHELL, surface); + if (!scene_surface->tree->node.data) { + wlr_layer_surface_v1_destroy(layer_surface); + return; + } #else + struct wlr_scene_node *output_layer = wb_layer_get_scene( + output, layer_type); struct wb_layer_surface *surface = wb_layer_surface_create(layer_surface); surface->scene = calloc(1, sizeof(*surface->scene)); surface->scene->layer_surface = layer_surface; surface->scene->node = output_layer; -#endif if (!surface) { wlr_layer_surface_v1_destroy(layer_surface); return; } - -#if WLR_CHECK_VERSION(0, 16, 0) - assign_scene_descriptor(scene_surface->node, - WB_SCENE_DESC_LAYER_SHELL, surface); #endif + surface->output = output; surface->server = output->server; diff --git a/waybox/layer_shell.h b/waybox/layer_shell.h index 02fad7a..cbcc86e 100644 --- a/waybox/layer_shell.h +++ b/waybox/layer_shell.h @@ -28,14 +28,22 @@ struct wb_layer_surface { struct wb_layer_popup { struct wlr_xdg_popup *wlr_popup; +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *scene; +#else struct wlr_scene_node *scene; +#endif struct wl_listener destroy; struct wl_listener new_popup; }; struct wb_layer_subsurface { +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *scene; +#else struct wlr_scene_node *scene; +#endif struct wl_listener destroy; }; diff --git a/waybox/output.c b/waybox/output.c index 8cc5aa3..d3decdc 100644 --- a/waybox/output.c +++ b/waybox/output.c @@ -76,14 +76,22 @@ void new_output_notify(struct wl_listener *listener, void *data) { /* Set the background color */ float color[4] = {0.1875, 0.1875, 0.1875, 1.0}; +#if WLR_CHECK_VERSION(0, 16, 0) + output->background = wlr_scene_rect_create(&server->scene->tree, 0, 0, color); +#else output->background = wlr_scene_rect_create(&server->scene->node, 0, 0, color); +#endif wlr_scene_node_lower_to_bottom(&output->background->node); /* Initializes the layers */ size_t num_layers = sizeof(output->layers) / sizeof(struct wlr_scene_node *); for (size_t i = 0; i < num_layers; i++) { ((struct wlr_scene_node **) &output->layers)[i] = +#if WLR_CHECK_VERSION(0, 16, 0) + &wlr_scene_tree_create(&server->scene->tree)->node; +#else &wlr_scene_tree_create(&server->scene->node)->node; +#endif } wl_list_insert(&server->outputs, &output->link); diff --git a/waybox/seat.c b/waybox/seat.c index 8fc7f3b..f91a2c3 100644 --- a/waybox/seat.c +++ b/waybox/seat.c @@ -81,13 +81,14 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 if (key_binding->action & ACTION_CLOSE) { struct wb_view *current_view = wl_container_of( server->views.next, current_view, link); - if (current_view->scene_node->state.enabled) #if WLR_CHECK_VERSION(0, 16, 0) + if (current_view->scene_tree->node.enabled) wlr_xdg_toplevel_send_close(current_view->xdg_toplevel); #else + if (current_view->scene_node->state.enabled) wlr_xdg_toplevel_send_close(current_view->xdg_surface); #endif - } + } if (key_binding->action & ACTION_EXECUTE) { if (fork() == 0) { execl("/bin/sh", "/bin/sh", "-c", key_binding->cmd, (char *) NULL); @@ -95,19 +96,31 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 } if (key_binding->action & ACTION_TOGGLE_MAXIMIZE) { struct wb_view *view = wl_container_of(server->views.next, view, link); +#if WLR_CHECK_VERSION(0, 16, 0) + if (view->scene_tree->node.enabled) +#else if (view->scene_node->state.enabled) +#endif wl_signal_emit(&view->xdg_toplevel->events.request_maximize, NULL); } if (key_binding->action & ACTION_ICONIFY) { struct wb_view *view = wl_container_of(server->views.next, view, link); +#if WLR_CHECK_VERSION(0, 16, 0) + if (view->scene_tree->node.enabled) { +#else if (view->scene_node->state.enabled) { +#endif view->xdg_toplevel->requested.minimized = true; wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL); } } if (key_binding->action & ACTION_SHADE) { struct wb_view *view = wl_container_of(server->views.next, view, link); +#if WLR_CHECK_VERSION(0, 16, 0) + if (view->scene_tree->node.enabled) { +#else if (view->scene_node->state.enabled) { +#endif struct wlr_box geo_box; wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); int decoration_height = MAX(geo_box.y - view->current_position.y, TITLEBAR_HEIGHT); @@ -124,11 +137,12 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32 } if (key_binding->action & ACTION_UNSHADE) { struct wb_view *view = wl_container_of(server->views.next, view, link); - if (view->scene_node->state.enabled) { #if WLR_CHECK_VERSION(0, 16, 0) + if (view->scene_tree->node.enabled) { wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->previous_position.width, view->previous_position.height); #else + if (view->scene_node->state.enabled) { wlr_xdg_toplevel_set_size(view->xdg_surface, view->previous_position.width, view->previous_position.height); #endif @@ -171,10 +185,14 @@ static void keyboard_handle_modifiers( * same seat. You can swap out the underlying wlr_keyboard like this and * wlr_seat handles this transparently. */ +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_seat_set_keyboard(keyboard->server->seat->seat, keyboard->keyboard); +#else wlr_seat_set_keyboard(keyboard->server->seat->seat, keyboard->device); +#endif /* Send modifiers to the client. */ wlr_seat_keyboard_notify_modifiers(keyboard->server->seat->seat, - &keyboard->device->keyboard->modifiers); + &keyboard->keyboard->modifiers); } static void keyboard_handle_key( @@ -183,7 +201,11 @@ static void keyboard_handle_key( struct wb_keyboard *keyboard = wl_container_of(listener, keyboard, key); struct wb_server *server = keyboard->server; +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_keyboard_key_event *event = data; +#else struct wlr_event_keyboard_key *event = data; +#endif struct wlr_seat *seat = server->seat->seat; /* Translate libinput keycode -> xkbcommon */ @@ -191,10 +213,10 @@ static void keyboard_handle_key( /* Get a list of keysyms based on the keymap for this keyboard */ const xkb_keysym_t *syms; int nsyms = xkb_state_key_get_syms( - keyboard->device->keyboard->xkb_state, keycode, &syms); + keyboard->keyboard->xkb_state, keycode, &syms); bool handled = false; - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->keyboard); if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { for (int i = 0; i < nsyms; i++) { handled = handle_keybinding(server, syms[i], modifiers); @@ -203,7 +225,11 @@ static void keyboard_handle_key( if (!handled) { /* Otherwise, we pass it along to the client. */ +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_seat_set_keyboard(seat, keyboard->keyboard); +#else wlr_seat_set_keyboard(seat, keyboard->device); +#endif wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, event->state); } @@ -214,7 +240,12 @@ static void handle_new_keyboard(struct wb_server *server, struct wb_keyboard *keyboard = calloc(1, sizeof(struct wb_keyboard)); keyboard->server = server; +#if WLR_CHECK_VERSION(0, 16, 0) + keyboard->keyboard = wlr_keyboard_from_input_device(device); +#else keyboard->device = device; + keyboard->keyboard = device->keyboard; +#endif /* We need to prepare an XKB keymap and assign it to the keyboard. */ struct xkb_rule_names *rules = malloc(sizeof(struct xkb_rule_names)); @@ -241,8 +272,8 @@ static void handle_new_keyboard(struct wb_server *server, XKB_KEYMAP_COMPILE_NO_FLAGS); if (keymap != NULL) { - wlr_keyboard_set_keymap(device->keyboard, keymap); - wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); + wlr_keyboard_set_keymap(keyboard->keyboard, keymap); + wlr_keyboard_set_repeat_info(keyboard->keyboard, 25, 600); } free(rules); xkb_keymap_unref(keymap); @@ -252,11 +283,15 @@ static void handle_new_keyboard(struct wb_server *server, keyboard->destroy.notify = keyboard_handle_destroy; wl_signal_add(&device->events.destroy, &keyboard->destroy); keyboard->modifiers.notify = keyboard_handle_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); + wl_signal_add(&keyboard->keyboard->events.modifiers, &keyboard->modifiers); keyboard->key.notify = keyboard_handle_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); + wl_signal_add(&keyboard->keyboard->events.key, &keyboard->key); - wlr_seat_set_keyboard(server->seat->seat, device); +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_seat_set_keyboard(server->seat->seat, keyboard->keyboard); +#else + wlr_seat_set_keyboard(server->seat->seat, keyboard->device); +#endif /* And add the keyboard to our list of keyboards */ wl_list_insert(&server->seat->keyboards, &keyboard->link); @@ -293,8 +328,10 @@ void seat_focus_surface(struct wb_seat *seat, struct wlr_surface *surface) { } struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat->seat); - wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes, - kb->num_keycodes, &kb->modifiers); + if (kb != NULL) { + wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes, + kb->num_keycodes, &kb->modifiers); + } } void seat_set_focus_layer(struct wb_seat *seat, struct wlr_layer_surface_v1 *layer) { @@ -348,6 +385,8 @@ void wb_seat_destroy(struct wb_seat *seat) { wl_list_remove(&seat->keyboards); wl_list_remove(&seat->request_set_primary_selection.link); wl_list_remove(&seat->request_set_selection.link); +#if !WLR_CHECK_VERSION(0, 16, 0) wlr_seat_destroy(seat->seat); +#endif free(seat); } diff --git a/waybox/server.c b/waybox/server.c index 7e2a3c5..623b2f7 100644 --- a/waybox/server.c +++ b/waybox/server.c @@ -16,6 +16,7 @@ bool wb_create_backend(struct wb_server* server) { * if an X11 server is running. */ server->backend = wlr_backend_autocreate(server->wl_display); if (server->backend == NULL) { + wlr_log(WLR_ERROR, "%s", _("Failed to create wlr_backend")); return false; } @@ -24,6 +25,11 @@ bool wb_create_backend(struct wb_server* server) { * The renderer is responsible for defining the various pixel formats it * supports for shared memory, this configures that for clients. */ server->renderer = wlr_renderer_autocreate(server->backend); + if (server->renderer == NULL) { + wlr_log(WLR_ERROR, "%s", _("Failed to create wlr_renderer")); + return false; + } + wlr_renderer_init_wl_display(server->renderer, server->wl_display); /* Autocreates an allocator for us. @@ -31,6 +37,10 @@ bool wb_create_backend(struct wb_server* server) { * handles the buffer creation, allowing wlroots to render onto the * screen */ server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); + if (server->allocator == NULL) { + wlr_log(WLR_ERROR, "%s", _("Failed to create wlr_allocator")); + return false; + } server->compositor = wlr_compositor_create(server->wl_display, server->renderer); @@ -102,10 +112,15 @@ bool wb_start_server(struct wb_server* server) { bool wb_terminate(struct wb_server* server) { wb_cursor_destroy(server->cursor); wl_list_remove(&server->new_xdg_decoration.link); /* wb_decoration_destroy */ +#if !WLR_CHECK_VERSION(0, 16, 0) wb_seat_destroy(server->seat); +#endif deinit_config(server->config); wl_display_destroy_clients(server->wl_display); wl_display_destroy(server->wl_display); +#if WLR_CHECK_VERSION(0, 16, 0) + wb_seat_destroy(server->seat); +#endif wlr_output_layout_destroy(server->output_layout); wlr_log(WLR_INFO, "%s", _("Display destroyed")); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 220943d..1acbc59 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -6,18 +6,43 @@ struct wb_view *get_view_at( /* This returns the topmost node in the scene at the given layout coords. * we only care about surface nodes as we are specifically looking for a * surface in the surface tree of a wb_view. */ +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_node *node = + wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy); + if (node == NULL || node->type != WLR_SCENE_NODE_BUFFER) { +#else struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->node, lx, ly, sx, sy); if (node == NULL || node->type != WLR_SCENE_NODE_SURFACE) { +#endif return NULL; } +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_from_buffer(scene_buffer); + if (!scene_surface) { + return NULL; + } + + *surface = scene_surface->surface; +#else *surface = wlr_scene_surface_from_node(node)->surface; - /* Find the node corresponding to the tinywl_view at the root of this +#endif + /* Find the node corresponding to the wb_view at the root of this * surface tree, it is the only one for which we set the data field. */ +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *tree = node->parent; + while (tree != NULL && tree->node.data == NULL) { + tree = tree->node.parent; + } + return tree->node.data; +#else while (node != NULL && node->data == NULL) { node = node->parent; } return node->data; +#endif } void focus_view(struct wb_view *view, struct wlr_surface *surface) { @@ -54,7 +79,11 @@ void focus_view(struct wb_view *view, struct wlr_surface *surface) { } /* Move the view to the front */ if (!server->seat->focused_layer) { +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_raise_to_top(&view->scene_tree->node); +#else wlr_scene_node_raise_to_top(view->scene_node); +#endif } wl_list_remove(&view->link); wl_list_insert(&server->views, &view->link); @@ -128,7 +157,11 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data) { focus_view(view, view->xdg_toplevel->base->surface); } +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_set_position(&view->scene_tree->node, +#else wlr_scene_node_set_position(view->scene_node, +#endif view->current_position.x, view->current_position.y); } @@ -140,7 +173,11 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) { /* Focus the next view, if any. */ struct wb_view *next_view = wl_container_of(view->link.next, next_view, link); +#if WLR_CHECK_VERSION(0, 16, 0) + if (next_view && next_view->scene_tree && next_view->scene_tree->node.enabled) { +#else if (next_view && next_view->scene_node && next_view->scene_node->state.enabled) { +#endif wlr_log(WLR_INFO, "%s: %s", _("Focusing next view"), next_view->xdg_toplevel->app_id); focus_view(next_view, next_view->xdg_toplevel->base->surface); @@ -157,6 +194,7 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&view->new_popup.link); if (view->xdg_toplevel->base->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + wl_list_remove(&view->request_fullscreen.link); wl_list_remove(&view->request_minimize.link); wl_list_remove(&view->request_maximize.link); wl_list_remove(&view->request_move.link); @@ -167,7 +205,23 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) { free(view); } +static void xdg_toplevel_request_fullscreen( + struct wl_listener *listener, void *data) { + /* This event is raised when a client would like to set itself to + * fullscreen. waybox currently doesn't support fullscreen, but to + * conform to xdg-shell protocol we still must send a configure. + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. + */ + struct wb_view *view = + wl_container_of(listener, view, request_fullscreen); + wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base); +} + static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) { + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. + */ struct wb_view *view = wl_container_of(listener, view, request_maximize); struct wlr_box usable_area = get_usable_area(view); @@ -192,12 +246,14 @@ static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *da #if WLR_CHECK_VERSION(0, 16, 0) wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable_area.width, usable_area.height); wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, !is_maximized); + wlr_scene_node_set_position(&view->scene_tree->node, + view->current_position.x, view->current_position.y); #else wlr_xdg_toplevel_set_size(view->xdg_surface, usable_area.width, usable_area.height); wlr_xdg_toplevel_set_maximized(view->xdg_surface, !is_maximized); -#endif wlr_scene_node_set_position(view->scene_node, view->current_position.x, view->current_position.y); +#endif } static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data) { @@ -213,7 +269,11 @@ static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *da struct wb_view *parent_view = wl_container_of(view->link.prev, parent_view, link); struct wb_view *previous_view = wl_container_of(parent_view->link.prev, previous_view, link); focus_view(previous_view, previous_view->xdg_toplevel->base->surface); +#if WLR_CHECK_VERSION(0, 16, 0) + wlr_scene_node_set_position(&view->scene_tree->node, +#else wlr_scene_node_set_position(view->scene_node, +#endif view->current_position.x, view->current_position.y); } @@ -279,8 +339,13 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = wlr_output_layout_output_at( view->server->output_layout, +#if WLR_CHECK_VERSION(0, 16, 0) + view->current_position.x + popup->current.geometry.x, + view->current_position.y + popup->current.geometry.y); +#else view->current_position.x + popup->geometry.x, view->current_position.y + popup->geometry.y); +#endif if (!wlr_output) return; struct wb_output *output = wlr_output->data; @@ -311,9 +376,15 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { if (wlr_surface_is_xdg_surface(xdg_surface->popup->parent)) { struct wlr_xdg_surface *parent = wlr_xdg_surface_from_wlr_surface( xdg_surface->popup->parent); - struct wlr_scene_node *parent_node = parent->data; +#if WLR_CHECK_VERSION(0, 16, 0) + struct wlr_scene_tree *parent_tree = parent->data; + xdg_surface->data = wlr_scene_xdg_surface_create( + parent_tree, xdg_surface); +#else + struct wlr_scene_node *parent_node = parent->data; xdg_surface->data = wlr_scene_xdg_surface_create( parent_node, xdg_surface); +#endif } /* The scene graph doesn't currently unconstrain popups, so keep going */ /* return; */ @@ -341,12 +412,21 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup); if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +#if WLR_CHECK_VERSION(0, 16, 0) + view->scene_tree = wlr_scene_xdg_surface_create( + &view->server->scene->tree, view->xdg_toplevel->base); + view->scene_tree->node.data = view; + xdg_surface->data = view->scene_tree; +#else view->scene_node = wlr_scene_xdg_surface_create( &view->server->scene->node, view->xdg_toplevel->base); view->scene_node->data = view; xdg_surface->data = view->scene_node; +#endif struct wlr_xdg_toplevel *toplevel = view->xdg_toplevel; + view->request_fullscreen.notify = xdg_toplevel_request_fullscreen; + wl_signal_add(&toplevel->events.request_fullscreen, &view->request_fullscreen); view->request_maximize.notify = xdg_toplevel_request_maximize; wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize); view->request_minimize.notify = xdg_toplevel_request_minimize; @@ -361,7 +441,12 @@ static void handle_new_xdg_surface(struct wl_listener *listener, void *data) { } void init_xdg_shell(struct wb_server *server) { +#if WLR_CHECK_VERSION(0, 16, 0) + /* xdg-shell version 3 */ + server->xdg_shell = wlr_xdg_shell_create(server->wl_display, 3); +#else server->xdg_shell = wlr_xdg_shell_create(server->wl_display); +#endif server->new_xdg_surface.notify = handle_new_xdg_surface; wl_signal_add(&server->xdg_shell->events.new_surface, &server->new_xdg_surface); }