Skip to content

Commit

Permalink
Add support for ext-idle-notify-v1
Browse files Browse the repository at this point in the history
  • Loading branch information
emersion committed Oct 13, 2022
1 parent 24243ae commit a63281d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 24 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# swayidle

This is sway's idle management daemon, swayidle. It is compatible with any
Wayland compositor which implements the KDE
Wayland compositor which implements the
[ext-idle-notify](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/ext-idle-notify)
protocol or the KDE
[idle](https://github.com/swaywm/sway/blob/master/protocols/idle.xml) protocol.
See the man page, [swayidle(1)](./swayidle.1.scd), for instructions on configuring swayidle.

Expand Down
81 changes: 61 additions & 20 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <wordexp.h>
#include "config.h"
#include "idle-client-protocol.h"
#include "ext-idle-notify-v1-client-protocol.h"
#include "log.h"
#if HAVE_SYSTEMD
#include <systemd/sd-bus.h>
Expand All @@ -25,7 +26,8 @@
#include <elogind/sd-login.h>
#endif

static struct org_kde_kwin_idle *idle_manager = NULL;
static struct org_kde_kwin_idle *kde_idle_manager = NULL;
static struct ext_idle_notifier_v1 *idle_notifier = NULL;
static struct wl_seat *seat = NULL;

struct swayidle_state {
Expand All @@ -46,7 +48,8 @@ struct swayidle_state {
struct swayidle_timeout_cmd {
struct wl_list link;
int timeout, registered_timeout;
struct org_kde_kwin_idle_timeout *idle_timer;
struct org_kde_kwin_idle_timeout *kde_idle_timer;
struct ext_idle_notification_v1 *idle_notification;
char *idle_cmd;
char *resume_cmd;
bool idlehint;
Expand Down Expand Up @@ -543,8 +546,11 @@ static const struct wl_seat_listener wl_seat_listener = {
static void handle_global(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version) {
if (strcmp(interface, org_kde_kwin_idle_interface.name) == 0) {
idle_manager =
kde_idle_manager =
wl_registry_bind(registry, name, &org_kde_kwin_idle_interface, 1);
} else if (strcmp(interface, ext_idle_notifier_v1_interface.name) == 0) {
idle_notifier =
wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 1);
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
struct seat *s = calloc(1, sizeof(struct seat));
s->proxy = wl_registry_bind(registry, name, &wl_seat_interface, 2);
Expand All @@ -564,13 +570,18 @@ static const struct wl_registry_listener registry_listener = {
.global_remove = handle_global_remove,
};

static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener;
static const struct org_kde_kwin_idle_timeout_listener kde_idle_timer_listener;
static const struct ext_idle_notification_v1_listener idle_notification_listener;

static void destroy_cmd_timer(struct swayidle_timeout_cmd *cmd) {
if (cmd->idle_timer != NULL) {
if (cmd->kde_idle_timer != NULL) {
swayidle_log(LOG_DEBUG, "Release idle timer");
org_kde_kwin_idle_timeout_release(cmd->idle_timer);
cmd->idle_timer = NULL;
org_kde_kwin_idle_timeout_release(cmd->kde_idle_timer);
cmd->kde_idle_timer = NULL;
}
if (cmd->idle_notification != NULL) {
ext_idle_notification_v1_destroy(cmd->idle_notification);
cmd->idle_notification = NULL;
}
}

Expand All @@ -583,10 +594,17 @@ static void register_timeout(struct swayidle_timeout_cmd *cmd,
return;
}
swayidle_log(LOG_DEBUG, "Register with timeout: %d", timeout);
cmd->idle_timer =
org_kde_kwin_idle_get_idle_timeout(idle_manager, seat, timeout);
org_kde_kwin_idle_timeout_add_listener(cmd->idle_timer,
&idle_timer_listener, cmd);
if (idle_notifier != NULL) {
cmd->idle_notification =
ext_idle_notifier_v1_get_idle_notification(idle_notifier, timeout, seat);
ext_idle_notification_v1_add_listener(cmd->idle_notification,
&idle_notification_listener, cmd);
} else {
cmd->kde_idle_timer =
org_kde_kwin_idle_get_idle_timeout(kde_idle_manager, seat, timeout);
org_kde_kwin_idle_timeout_add_listener(cmd->kde_idle_timer,
&kde_idle_timer_listener, cmd);
}
cmd->registered_timeout = timeout;
}

Expand Down Expand Up @@ -627,8 +645,7 @@ static void disable_timeouts(void) {
}
#endif

static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) {
struct swayidle_timeout_cmd *cmd = data;
static void handle_idled(struct swayidle_timeout_cmd *cmd) {
cmd->resume_pending = true;
swayidle_log(LOG_DEBUG, "idle state");
#if HAVE_SYSTEMD || HAVE_ELOGIND
Expand All @@ -641,8 +658,7 @@ static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) {
}
}

static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) {
struct swayidle_timeout_cmd *cmd = data;
static void handle_resumed(struct swayidle_timeout_cmd *cmd) {
cmd->resume_pending = false;
swayidle_log(LOG_DEBUG, "active state");
if (cmd->registered_timeout != cmd->timeout) {
Expand All @@ -658,9 +674,34 @@ static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) {
}
}

static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = {
.idle = handle_idle,
.resumed = handle_resume,
static void kde_handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) {
struct swayidle_timeout_cmd *cmd = data;
handle_idled(cmd);
}

static void kde_handle_resumed(void *data, struct org_kde_kwin_idle_timeout *timer) {
struct swayidle_timeout_cmd *cmd = data;
handle_resumed(cmd);
}

static const struct org_kde_kwin_idle_timeout_listener kde_idle_timer_listener = {
.idle = kde_handle_idle,
.resumed = kde_handle_resumed,
};

static void ext_handle_idled(void *data, struct ext_idle_notification_v1 *notif) {
struct swayidle_timeout_cmd *cmd = data;
handle_idled(cmd);
}

static void ext_handle_resumed(void *data, struct ext_idle_notification_v1 *notif) {
struct swayidle_timeout_cmd *cmd = data;
handle_resumed(cmd);
}

static const struct ext_idle_notification_v1_listener idle_notification_listener = {
.idled = ext_handle_idled,
.resumed = ext_handle_resumed,
};

static char *parse_command(int argc, char **argv) {
Expand Down Expand Up @@ -893,7 +934,7 @@ static int handle_signal(int sig, void *data) {
swayidle_log(LOG_DEBUG, "Got SIGTERM");
wl_list_for_each(cmd, &state.timeout_cmds, link) {
if (cmd->resume_pending) {
handle_resume(cmd, cmd->idle_timer);
handle_resumed(cmd);
}
}
sway_terminate(0);
Expand Down Expand Up @@ -1071,7 +1112,7 @@ int main(int argc, char *argv[]) {
}
}

if (idle_manager == NULL) {
if (kde_idle_manager == NULL && idle_notifier == NULL) {
swayidle_log(LOG_ERROR, "Display doesn't support idle protocol");
swayidle_finish();
return -4;
Expand Down
15 changes: 12 additions & 3 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ add_project_arguments(
language : 'c')

wayland_client = dependency('wayland-client')
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
wayland_protos = dependency('wayland-protocols', version: '>=1.27')
wayland_server = dependency('wayland-server')
bash_comp = dependency('bash-completion', required: false)
fish_comp = dependency('fish', required: false)
Expand Down Expand Up @@ -57,8 +57,17 @@ wayland_scanner_client = generator(
arguments: ['client-header', '@INPUT@', '@OUTPUT@'],
)

client_protos_src = wayland_scanner_code.process('idle.xml')
client_protos_headers = wayland_scanner_client.process('idle.xml')
protos = [
'idle.xml',
wl_protocol_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml',
]

client_protos_src = []
client_protos_headers = []
foreach xml : protos
client_protos_src += wayland_scanner_code.process(xml)
client_protos_headers += wayland_scanner_client.process(xml)
endforeach

lib_client_protos = static_library(
'client_protos',
Expand Down

0 comments on commit a63281d

Please sign in to comment.