8#define _POSIX_C_SOURCE 200112L
9#include <linux/input-event-codes.h>
11#include "protocols/idle.h"
13#ifdef HAVE_WL_CURSOR_SHAPE
14#include "protocols/cursor-shape-v1.h"
15#include "protocols/tablet-unstable-v2.h"
18#ifdef HAVE_WL_EXT_IDLE_NOTIFY
19#include "protocols/ext-idle-notify-v1.h"
29static void touch_handle_motion(
void *data,
struct wl_touch *wl_touch,
30 uint32_t time, int32_t
id,
31 wl_fixed_t surface_x, wl_fixed_t surface_y) {
34 if (
id >= MAX_TOUCHPOINTS) {
37 seat->touch.pts[id].x = wl_fixed_to_int(surface_x);
38 seat->touch.pts[id].y = wl_fixed_to_int(surface_y);
41static void touch_handle_down(
void *data,
struct wl_touch *wl_touch,
42 uint32_t serial, uint32_t time,
struct wl_surface *sfc, int32_t
id,
43 wl_fixed_t surface_x, wl_fixed_t surface_y) {
46 if (
id >= MAX_TOUCHPOINTS) {
49 seat->touch.pts[id].x = wl_fixed_to_int(surface_x);
50 seat->touch.pts[id].y = wl_fixed_to_int(surface_y);
53static void touch_handle_up(
void *data,
struct wl_touch *wl_touch,
54 uint32_t serial, uint32_t time, int32_t
id) {
57 if (
id >= MAX_TOUCHPOINTS) {
61 seat->touch.pts[
id].x, seat->touch.pts[
id].y);
65static void touch_handle_frame(
void *data,
struct wl_touch *wl_touch) {
68static void touch_handle_cancel(
void *data,
struct wl_touch *wl_touch) {
71static const struct wl_touch_listener touch_listener = {
72 .down = touch_handle_down,
73 .up = touch_handle_up,
74 .motion = touch_handle_motion,
75 .frame = touch_handle_frame,
76 .cancel = touch_handle_cancel,
79static void pointer_handle_enter(
void *data,
struct wl_pointer *wl_pointer,
80 uint32_t serial,
struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) {
87#ifdef HAVE_WL_CURSOR_SHAPE
88 if (ctx.cursor_shape_manager != NULL) {
89 struct wp_cursor_shape_device_v1 *device =
90 wp_cursor_shape_manager_v1_get_pointer(ctx.cursor_shape_manager, wl_pointer);
91 wp_cursor_shape_device_v1_set_shape(device, serial,
92 WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
93 wp_cursor_shape_device_v1_destroy(device);
97 if (ctx.cursor_theme != NULL) {
98 wl_pointer_set_cursor(wl_pointer, serial, ctx.cursor_surface, ctx.cursor_image->hotspot_x, ctx.cursor_image->hotspot_y);
102static void pointer_handle_motion(
void *data,
struct wl_pointer *wl_pointer,
103 uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
106 seat->pointer.x = wl_fixed_to_int(surface_x);
107 seat->pointer.y = wl_fixed_to_int(surface_y);
110static void pointer_handle_button(
void *data,
struct wl_pointer *wl_pointer,
111 uint32_t serial, uint32_t time, uint32_t button,
112 uint32_t button_state) {
118static void pointer_handle_leave(
void *data,
struct wl_pointer *wl_pointer,
119 uint32_t serial,
struct wl_surface *surface) {
126static void pointer_handle_axis(
void *data,
struct wl_pointer *wl_pointer,
127 uint32_t time, uint32_t axis, wl_fixed_t value) {
130static const struct wl_pointer_listener pointer_listener = {
131 .enter = pointer_handle_enter,
132 .leave = pointer_handle_leave,
133 .motion = pointer_handle_motion,
134 .button = pointer_handle_button,
135 .axis = pointer_handle_axis,
138static void destroy_seat_pointer(
struct dunst_seat *seat) {
139 wl_pointer_release(seat->pointer.wl_pointer);
140 seat->pointer.wl_pointer = NULL;
143static void destroy_seat_touch(
struct dunst_seat *seat) {
144 wl_touch_release(seat->touch.wl_touch);
145 seat->touch.wl_touch = NULL;
153 if (seat->pointer.wl_pointer != NULL) {
154 destroy_seat_pointer(seat);
157 if (seat->touch.wl_touch != NULL) {
158 destroy_seat_touch(seat);
161 if (seat->idle_timeout != NULL) {
162 org_kde_kwin_idle_timeout_release(seat->idle_timeout);
163 seat->idle_timeout = NULL;
166#ifdef HAVE_WL_EXT_IDLE_NOTIFY
167 if (seat->ext_idle_notification != NULL) {
168 ext_idle_notification_v1_destroy(seat->ext_idle_notification);
169 seat->ext_idle_notification = NULL;
173 wl_list_remove(&seat->link);
175#ifdef WL_SEAT_RELEASE_SINCE_VERSION
176 if (wl_seat_get_version(seat->wl_seat) >= WL_SEAT_RELEASE_SINCE_VERSION) {
177 wl_seat_release(seat->wl_seat);
181 wl_seat_destroy(seat->wl_seat);
183 seat->wl_seat = NULL;
191static void seat_handle_capabilities(
void *data,
struct wl_seat *wl_seat,
192 uint32_t capabilities) {
195 if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
196 if (seat->pointer.wl_pointer == NULL) {
197 seat->pointer.wl_pointer = wl_seat_get_pointer(wl_seat);
198 wl_pointer_add_listener(seat->pointer.wl_pointer,
199 &pointer_listener, seat);
201 }
else if (seat->pointer.wl_pointer != NULL) {
202 destroy_seat_pointer(seat);
205 if (capabilities & WL_SEAT_CAPABILITY_TOUCH) {
206 if (seat->touch.wl_touch == NULL) {
207 seat->touch.wl_touch = wl_seat_get_touch(wl_seat);
208 wl_touch_add_listener(seat->touch.wl_touch,
209 &touch_listener, seat);
211 }
else if (seat->touch.wl_touch != NULL) {
212 destroy_seat_touch(seat);
216static void seat_handle_name(
void *data,
struct wl_seat *wl_seat,
const char *name) {
219 seat->name = g_strdup(name);
220 LOG_I(
"New seat found - id %" PRIu32
" name %s", seat->global_name, seat->name);
223static const struct wl_seat_listener seat_listener = {
224 .capabilities = seat_handle_capabilities,
225 .name = seat_handle_name,
229static void idle_start (
void *data,
struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) {
232 seat->is_idle =
true;
233 LOG_D(
"User went idle on seat \"%s\"", seat->name);
235static void idle_stop (
void *data,
struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) {
238 seat->is_idle =
false;
239 LOG_D(
"User isn't idle anymore on seat \"%s\"", seat->name);
242static const struct org_kde_kwin_idle_timeout_listener idle_timeout_listener = {
244 .resumed = idle_stop,
247#ifdef HAVE_WL_EXT_IDLE_NOTIFY
248static void ext_idle_notification_handle_idled(
void *data,
struct ext_idle_notification_v1 *
notification) {
251 seat->is_idle =
true;
252 LOG_D(
"User went idle on seat \"%s\"", seat->name);
255static void ext_idle_notification_handle_resumed(
void *data,
struct ext_idle_notification_v1 *
notification) {
258 seat->is_idle =
false;
259 LOG_D(
"User isn't idle anymore on seat \"%s\"", seat->name);
262static const struct ext_idle_notification_v1_listener ext_idle_notification_listener = {
263 .idled = ext_idle_notification_handle_idled,
264 .resumed = ext_idle_notification_handle_resumed,
268void add_seat_to_idle_handler(
struct dunst_seat *seat) {
272 uint32_t timeout_ms =
settings.idle_threshold/1000;
274#ifdef HAVE_WL_EXT_IDLE_NOTIFY
275 if (ctx.ext_idle_notifier != NULL) {
276 if (seat->ext_idle_notification == NULL) {
277 seat->ext_idle_notification =
278 ext_idle_notifier_v1_get_idle_notification(ctx.ext_idle_notifier,
279 timeout_ms, seat->wl_seat);
280 ext_idle_notification_v1_add_listener(seat->ext_idle_notification,
281 &ext_idle_notification_listener, seat);
284 if (seat->idle_timeout != NULL) {
285 org_kde_kwin_idle_timeout_release(seat->idle_timeout);
286 seat->idle_timeout = NULL;
291 if (ctx.idle_handler != NULL && seat->idle_timeout == NULL) {
292 seat->idle_timeout = org_kde_kwin_idle_get_idle_timeout(ctx.idle_handler, seat->wl_seat, timeout_ms);
293 org_kde_kwin_idle_timeout_add_listener(seat->idle_timeout, &idle_timeout_listener, seat);
297void create_seat(
struct wl_registry *registry, uint32_t global_name, uint32_t version) {
300 LOG_E(
"allocation failed");
303 seat->global_name = global_name;
304 seat->wl_seat = wl_registry_bind(registry, global_name, &wl_seat_interface, 3);
305 wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
306 add_seat_to_idle_handler(seat);
307 wl_list_insert(&ctx.seats, &seat->link);
void dunst_status(const enum dunst_status_field field, bool value)
Modify the current status of dunst.
Logging subsystem and helpers.
#define LOG_E
Prefix message with "[<source path>:<function name>:<line number>] ".
Type definitions for settings.
Wayland context tracking.