diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba7406cf..2308e80b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,6 +95,7 @@ jobs: apt-get install -y git gcc clang gdb xwayland apt-get build-dep -y labwc apt-get build-dep -y libwlroots-0.19-dev + apt-get build-dep -y libxkbcommon-dev - name: Install FreeBSD dependencies if: matrix.name == 'FreeBSD' @@ -121,7 +122,7 @@ jobs: xbps-install -y git meson gcc clang pkg-config scdoc \ cairo-devel glib-devel libpng-devel librsvg-devel libxml2-devel \ pango-devel wlroots0.19-devel gdb bash xorg-server-xwayland \ - dejavu-fonts-ttf libsfdo-devel foot + dejavu-fonts-ttf libsfdo-devel foot hwids # These builds are executed on all runners - name: Build with gcc diff --git a/include/labwc.h b/include/labwc.h index 7ffcb45a..88860de2 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -372,6 +372,7 @@ void desktop_focus_topmost_view(struct server *server); void seat_init(struct server *server); void seat_finish(struct server *server); void seat_reconfigure(struct server *server); +void seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface); void seat_focus_surface(struct seat *seat, struct wlr_surface *surface); void seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface); diff --git a/include/layers.h b/include/layers.h index da1bdb86..0ea00669 100644 --- a/include/layers.h +++ b/include/layers.h @@ -30,6 +30,7 @@ struct lab_layer_popup { struct wlr_xdg_popup *wlr_popup; struct wlr_scene_tree *scene_tree; struct server *server; + struct lab_layer_surface *lab_layer_surface; /* To simplify moving popup nodes from the bottom to the top layer */ struct wlr_box output_toplevel_sx_box; @@ -38,6 +39,7 @@ struct lab_layer_popup { struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener reposition; + struct wl_listener grab; }; void layers_init(struct server *server); diff --git a/include/xwayland.h b/include/xwayland.h index bbb9fa1c..cee15302 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -75,8 +75,6 @@ void xwayland_adjust_usable_area(struct view *view, void xwayland_update_workarea(struct server *server); -void xwayland_reset_cursor(struct server *server); - void xwayland_flush(struct server *server); #endif /* HAVE_XWAYLAND */ diff --git a/meson.build b/meson.build index 62925ddb..5a18d5a3 100644 --- a/meson.build +++ b/meson.build @@ -51,9 +51,9 @@ endif add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( - 'wlroots-0.19', + 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.19.0', '<0.20.0'], + version: ['>=0.20.0', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/src/input/cursor.c b/src/input/cursor.c index 98679565..808e910b 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -1614,9 +1614,6 @@ void cursor_reload(struct seat *seat) { cursor_load(seat); -#if HAVE_XWAYLAND - xwayland_reset_cursor(seat->server); -#endif cursor_update_image(seat); } diff --git a/src/input/ime.c b/src/input/ime.c index 92d88ffe..efbe54d6 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -309,7 +309,8 @@ handle_keyboard_grab_destroy(struct wl_listener *listener, void *data) { struct input_method_relay *relay = wl_container_of(listener, relay, keyboard_grab_destroy); - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = + relay->input_method->keyboard_grab; assert(keyboard_grab); wl_list_remove(&relay->keyboard_grab_destroy.link); @@ -583,11 +584,11 @@ input_method_relay_create(struct seat *seat) relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&seat->server->text_input_manager->events.text_input, + wl_signal_add(&seat->server->text_input_manager->events.new_text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&seat->server->input_method_manager->events.input_method, + wl_signal_add(&seat->server->input_method_manager->events.new_input_method, &relay->new_input_method); relay->focused_surface_destroy.notify = handle_focused_surface_destroy; diff --git a/src/layers.c b/src/layers.c index 7feb026d..4db966ea 100644 --- a/src/layers.c +++ b/src/layers.c @@ -441,6 +441,7 @@ handle_popup_destroy(struct wl_listener *listener, void *data) wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->reposition.link); + wl_list_remove(&popup->grab.link); /* Usually already removed unless there was no commit at all */ if (popup->commit.notify) { @@ -468,6 +469,19 @@ handle_popup_commit(struct wl_listener *listener, void *data) } } +static void +handle_popup_grab(struct wl_listener *listener, void *data) +{ + struct lab_layer_popup *popup = wl_container_of(listener, popup, grab); + wlr_log(WLR_ERROR, "grab layer-shell popup"); + struct seat *seat = &popup->server->seat; + //seat_force_focus_surface(seat, popup->wlr_popup->base->surface); + + struct wlr_surface *wlr_surface = + popup->lab_layer_surface->layer_surface->surface; + seat_force_focus_surface(seat, wlr_surface); +} + static void handle_popup_reposition(struct wl_listener *listener, void *data) { @@ -508,6 +522,9 @@ create_popup(struct server *server, struct wlr_xdg_popup *wlr_popup, popup->commit.notify = handle_popup_commit; wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit); + popup->grab.notify = handle_popup_grab; + wl_signal_add(&wlr_popup->events.grab, &popup->grab); + popup->reposition.notify = handle_popup_reposition; wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); @@ -533,6 +550,7 @@ handle_popup_new_popup(struct wl_listener *listener, void *data) new_popup->output_toplevel_sx_box = lab_layer_popup->output_toplevel_sx_box; + new_popup->lab_layer_surface = lab_layer_popup->lab_layer_surface; } /* @@ -598,6 +616,7 @@ handle_new_popup(struct wl_listener *listener, void *data) } popup->output_toplevel_sx_box = output_toplevel_sx_box; + popup->lab_layer_surface = toplevel; if (surface->layer_surface->current.layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) { diff --git a/src/seat.c b/src/seat.c index b19ff88a..ef0bcb55 100644 --- a/src/seat.c +++ b/src/seat.c @@ -759,6 +759,17 @@ seat_reconfigure(struct server *server) } } +void +seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface) +{ + uint32_t *pressed_sent_keycodes = key_state_pressed_sent_keycodes(); + int nr_pressed_sent_keycodes = key_state_nr_pressed_sent_keycodes(); + struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; + + wlr_seat_keyboard_enter(seat->seat, surface, + pressed_sent_keycodes, nr_pressed_sent_keycodes, &kb->modifiers); +} + static void seat_focus(struct seat *seat, struct wlr_surface *surface, bool replace_exclusive_layer, bool is_lock_surface) diff --git a/src/server.c b/src/server.c index bc515b08..aeb770eb 100644 --- a/src/server.c +++ b/src/server.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -256,6 +257,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "wl_data_device_manager", /* would be great if we could drop this one */ "wl_seat", "xdg_wm_base", + "wl_fixes", /* enhanced */ "wl_output", "wl_drm", @@ -436,6 +438,8 @@ server_init(struct server *server) server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + wlr_fixes_create(server->wl_display, 1); + /* Catch signals */ server->sighup_source = wl_event_loop_add_signal( server->wl_event_loop, SIGHUP, handle_sighup, server); diff --git a/src/xwayland.c b/src/xwayland.c index 9bb1cf39..a95338ae 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1209,60 +1209,11 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor) server->seat.xcursor_manager, XCURSOR_DEFAULT, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->xwayland, image->buffer, - image->width * 4, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - } -} - -void -xwayland_reset_cursor(struct server *server) -{ - /* - * As xwayland caches the pixel data when not yet started up - * due to the delayed lazy startup approach, we do have to - * re-set the xwayland cursor image. Otherwise the first X11 - * client connected will cause the xwayland server to use - * the cached (and potentially destroyed) pixel data. - * - * Calling this function after reloading the cursor theme - * ensures that the cached pixel data keeps being valid. - * - * To reproduce: - * - Compile with b_sanitize=address,undefined - * - Start labwc (nothing in autostart that could create - * a X11 connection, e.g. no GTK or X11 application) - * - Reconfigure - * - Start some X11 client - */ - - if (!server->xwayland) { - return; - } - - struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( - server->seat.xcursor_manager, XCURSOR_DEFAULT, 1); - - if (xcursor && !server->xwayland->xwm) { - /* Prevents setting the cursor on an active xwayland server */ - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->xwayland, image->buffer, - image->width * 4, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - return; - } - - if (server->xwayland->cursor) { - /* - * The previous configured theme has set the - * default cursor or the xwayland server is - * currently running but still has a cached - * xcursor set that will be used on the next - * xwayland destroy -> lazy startup cycle. - */ - zfree(server->xwayland->cursor); + struct wlr_buffer *cursor_buffer = wlr_xcursor_image_get_buffer(image); + if (cursor_buffer) { + wlr_xwayland_set_cursor(server->xwayland, cursor_buffer, + image->hotspot_x, image->hotspot_y); + } } } diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 25a947ed..4352289b 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,7 +1,7 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 0.19 +revision = master [provide] -dependency_names = wlroots-0.19 -wlroots-0.19=wlroots +dependency_names = wlroots-0.20 +wlroots-0.20=wlroots