From 40aba9e5427b4c1ca6c5f623d1231501c1fa68f5 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 8 Jul 2023 18:27:40 +0200 Subject: [PATCH] Add support for ext_idle_notify_v1.. ..and combine both idle variants into a standalone manager --- include/idle.h | 11 +++++ include/labwc.h | 11 ----- src/cursor.c | 9 ++-- src/idle.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ src/keyboard.c | 3 +- src/meson.build | 1 + src/seat.c | 34 --------------- src/server.c | 3 ++ src/touch.c | 3 +- 9 files changed, 134 insertions(+), 51 deletions(-) create mode 100644 include/idle.h create mode 100644 src/idle.c diff --git a/include/idle.h b/include/idle.h new file mode 100644 index 00000000..50a660c2 --- /dev/null +++ b/include/idle.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_IDLE_H +#define LABWC_IDLE_H + +struct wl_display; +struct wlr_seat; + +void idle_manager_create(struct wl_display *display, struct wlr_seat *wlr_seat); +void idle_manager_notify_activity(struct wlr_seat *seat); + +#endif /* LABWC_IDLE_H */ diff --git a/include/labwc.h b/include/labwc.h index dffb4595..efe694dc 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include #include @@ -117,8 +115,6 @@ struct seat { } smooth_scroll_offset; struct wlr_pointer_constraint_v1 *current_constraint; - struct wlr_idle *wlr_idle; - struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_manager; /* In support for ToggleKeybinds */ uint32_t nr_inhibited_keybind_views; @@ -194,7 +190,6 @@ struct seat { struct wl_listener touch_frame; struct wl_listener constraint_commit; - struct wl_listener idle_inhibitor_create; struct wl_listener pressed_surface_destroy; struct wlr_virtual_pointer_manager_v1 *virtual_pointer; @@ -352,12 +347,6 @@ struct constraint { struct wl_listener destroy; }; -struct idle_inhibitor { - struct seat *seat; - struct wlr_idle_inhibitor_v1 *wlr_inhibitor; - struct wl_listener destroy; -}; - void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup); void xdg_activation_handle_request(struct wl_listener *listener, void *data); diff --git a/src/cursor.c b/src/cursor.c index 8746e2c2..90a67cf5 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -11,6 +11,7 @@ #include "common/scene-helpers.h" #include "config/mousebind.h" #include "dnd.h" +#include "idle.h" #include "labwc.h" #include "menu/menu.h" #include "regions.h" @@ -709,7 +710,7 @@ cursor_motion(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, cursor_motion); struct server *server = seat->server; struct wlr_pointer_motion_event *event = data; - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); wlr_relative_pointer_manager_v1_send_relative_motion( server->relative_pointer_manager, @@ -735,7 +736,7 @@ cursor_motion_absolute(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of( listener, seat, cursor_motion_absolute); struct wlr_pointer_motion_absolute_event *event = data; - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); double lx, ly; wlr_cursor_absolute_to_layout_coords(seat->cursor, @@ -988,7 +989,7 @@ cursor_button(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, cursor_button); struct wlr_pointer_button_event *event = data; - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); switch (event->state) { case WLR_BUTTON_PRESSED: @@ -1089,7 +1090,7 @@ cursor_axis(struct wl_listener *listener, void *data) struct wlr_pointer_axis_event *event = data; struct server *server = seat->server; struct cursor_context ctx = get_cursor_context(server); - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); /* Bindings swallow mouse events if activated */ bool handled = handle_cursor_axis(server, &ctx, event); diff --git a/src/idle.c b/src/idle.c new file mode 100644 index 00000000..0edaf0a5 --- /dev/null +++ b/src/idle.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include "common/mem.h" +#include "idle.h" + +struct lab_idle_inhibitor { + struct wlr_idle_inhibitor_v1 *wlr_inhibitor; + struct wl_listener on_destroy; +}; + +struct lab_idle_manager { + struct wlr_idle *kde; + struct wlr_idle_notifier_v1 *ext; + struct { + struct wlr_idle_inhibit_manager_v1 *manager; + struct wl_listener on_new_inhibitor; + } inhibitor; + struct wlr_seat *wlr_seat; + struct wl_listener on_display_destroy; +}; + +static struct lab_idle_manager *manager; + +static void +handle_idle_inhibitor_destroy(struct wl_listener *listener, void *data) +{ + struct lab_idle_inhibitor *idle_inhibitor = wl_container_of(listener, + idle_inhibitor, on_destroy); + + if (manager) { + /* + * The display destroy event might have been triggered + * already and thus the manager would be NULL. + */ + bool still_inhibited = + wl_list_length(&manager->inhibitor.manager->inhibitors) > 1; + wlr_idle_notifier_v1_set_inhibited(manager->ext, still_inhibited); + wlr_idle_set_enabled(manager->kde, manager->wlr_seat, !still_inhibited); + } + + wl_list_remove(&idle_inhibitor->on_destroy.link); + free(idle_inhibitor); +} + +static void +handle_idle_inhibitor_new(struct wl_listener *listener, void *data) +{ + assert(manager); + struct wlr_idle_inhibitor_v1 *wlr_inhibitor = data; + + struct lab_idle_inhibitor *inhibitor = znew(*inhibitor); + inhibitor->wlr_inhibitor = wlr_inhibitor; + inhibitor->on_destroy.notify = handle_idle_inhibitor_destroy; + wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->on_destroy); + + wlr_idle_notifier_v1_set_inhibited(manager->ext, true); + wlr_idle_set_enabled(manager->kde, manager->wlr_seat, false); +} + +static void +handle_display_destroy(struct wl_listener *listener, void *data) +{ + /* + * All the managers will react to the display + * destroy signal as well and thus clean up. + */ + wl_list_remove(&manager->on_display_destroy.link); + zfree(manager); +} + +void +idle_manager_create(struct wl_display *display, struct wlr_seat *wlr_seat) +{ + assert(!manager); + manager = znew(*manager); + manager->wlr_seat = wlr_seat; + + manager->kde = wlr_idle_create(display); + manager->ext = wlr_idle_notifier_v1_create(display); + + manager->inhibitor.manager = wlr_idle_inhibit_v1_create(display); + manager->inhibitor.on_new_inhibitor.notify = handle_idle_inhibitor_new; + wl_signal_add(&manager->inhibitor.manager->events.new_inhibitor, + &manager->inhibitor.on_new_inhibitor); + + manager->on_display_destroy.notify = handle_display_destroy; + wl_display_add_destroy_listener(display, &manager->on_display_destroy); +} + +void +idle_manager_notify_activity(struct wlr_seat *seat) +{ + /* + * The display destroy event might have been triggered + * already and thus the manager would be NULL. Due to + * future code changes we might also get called before + * the manager has been created. + */ + if (!manager) { + return; + } + + wlr_idle_notify_activity(manager->kde, seat); + wlr_idle_notifier_v1_notify_activity(manager->ext, seat); +} diff --git a/src/keyboard.c b/src/keyboard.c index f7b3629d..012344b2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -3,6 +3,7 @@ #include #include #include "action.h" +#include "idle.h" #include "key-state.h" #include "labwc.h" #include "regions.h" @@ -305,7 +306,7 @@ keyboard_key_notify(struct wl_listener *listener, void *data) struct wlr_keyboard_key_event *event = data; struct wlr_seat *wlr_seat = seat->seat; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); /* any new press/release cancels current keybind repeat */ keyboard_cancel_keybind_repeat(keyboard); diff --git a/src/meson.build b/src/meson.build index 5aab9a62..391e9cdc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -6,6 +6,7 @@ labwc_sources = files( 'desktop.c', 'dnd.c', 'foreign.c', + 'idle.c', 'interactive.c', 'keyboard.c', 'key-state.c', diff --git a/src/seat.c b/src/seat.c index 4d35809b..ce308867 100644 --- a/src/seat.c +++ b/src/seat.c @@ -288,33 +288,6 @@ new_input_notify(struct wl_listener *listener, void *data) seat_add_device(seat, input); } -static void -destroy_idle_inhibitor(struct wl_listener *listener, void *data) -{ - struct idle_inhibitor *idle_inhibitor = wl_container_of(listener, - idle_inhibitor, destroy); - struct seat *seat = idle_inhibitor->seat; - wl_list_remove(&idle_inhibitor->destroy.link); - wlr_idle_set_enabled(seat->wlr_idle, seat->seat, wl_list_length( - &seat->wlr_idle_inhibit_manager->inhibitors) <= 1); - free(idle_inhibitor); -} - -static void -new_idle_inhibitor(struct wl_listener *listener, void *data) -{ - struct wlr_idle_inhibitor_v1 *wlr_inhibitor = data; - struct seat *seat = wl_container_of(listener, seat, - idle_inhibitor_create); - - struct idle_inhibitor *inhibitor = znew(*inhibitor); - inhibitor->seat = seat; - inhibitor->wlr_inhibitor = wlr_inhibitor; - inhibitor->destroy.notify = destroy_idle_inhibitor; - wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy); - wlr_idle_set_enabled(seat->wlr_idle, seat->seat, 0); -} - static void new_virtual_pointer(struct wl_listener *listener, void *data) { @@ -361,13 +334,6 @@ seat_init(struct server *server) seat->new_input.notify = new_input_notify; wl_signal_add(&server->backend->events.new_input, &seat->new_input); - seat->wlr_idle = wlr_idle_create(server->wl_display); - seat->wlr_idle_inhibit_manager = wlr_idle_inhibit_v1_create( - server->wl_display); - wl_signal_add(&seat->wlr_idle_inhibit_manager->events.new_inhibitor, - &seat->idle_inhibitor_create); - seat->idle_inhibitor_create.notify = new_idle_inhibitor; - seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create( server->wl_display); wl_signal_add(&seat->virtual_pointer->events.new_virtual_pointer, diff --git a/src/server.c b/src/server.c index 4e3c3d69..c781f53d 100644 --- a/src/server.c +++ b/src/server.c @@ -19,6 +19,7 @@ #include "config/rcxml.h" #include "config/session.h" #include "decorations.h" +#include "idle.h" #include "labwc.h" #include "layers.h" #include "menu/menu.h" @@ -394,6 +395,8 @@ server_init(struct server *server) wlr_viewporter_create(server->wl_display); wlr_single_pixel_buffer_manager_v1_create(server->wl_display); + idle_manager_create(server->wl_display, server->seat.seat); + server->relative_pointer_manager = wlr_relative_pointer_manager_v1_create( server->wl_display); server->constraints = wlr_pointer_constraints_v1_create( diff --git a/src/touch.c b/src/touch.c index 0023068d..d87e02f0 100644 --- a/src/touch.c +++ b/src/touch.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include "idle.h" #include "labwc.h" #include "common/scene-helpers.h" @@ -29,7 +30,7 @@ touch_motion(struct wl_listener *listener, void *data) { struct seat *seat = wl_container_of(listener, seat, touch_motion); struct wlr_touch_motion_event *event = data; - wlr_idle_notify_activity(seat->wlr_idle, seat->seat); + idle_manager_notify_activity(seat->seat); double sx, sy; if (touch_get_coords(seat, event->touch, event->x, event->y, &sx, &sy)) {