Add support for ext_idle_notify_v1..

..and combine both idle variants into a standalone manager
This commit is contained in:
Consolatis 2023-07-08 18:27:40 +02:00 committed by Johan Malm
parent e06a8cfc7a
commit 40aba9e542
9 changed files with 134 additions and 51 deletions

11
include/idle.h Normal file
View file

@ -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 */

View file

@ -17,8 +17,6 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.h>
@ -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);

View file

@ -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);

110
src/idle.c Normal file
View file

@ -0,0 +1,110 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <assert.h>
#include <stdlib.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_notify_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#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);
}

View file

@ -3,6 +3,7 @@
#include <wlr/backend/multi.h>
#include <wlr/backend/session.h>
#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);

View file

@ -6,6 +6,7 @@ labwc_sources = files(
'desktop.c',
'dnd.c',
'foreign.c',
'idle.c',
'interactive.c',
'keyboard.c',
'key-state.c',

View file

@ -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,

View file

@ -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(

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <wlr/types/wlr_touch.h>
#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)) {