Skip to content

Commit 31bcca3

Browse files
committed
Wait for user activity before notification timeout starts counting
1 parent a34d3c0 commit 31bcca3

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ executable(
2626
'src/Confirmation.vala',
2727
'src/DBus.vala',
2828
'src/FdoActionGroup.vala',
29+
'src/IdleMonitor.vala',
2930
'src/Notification.vala',
3031
'src/Widgets/MaskedImage.vala',
3132
css_gresource,

src/AbstractBubble.vala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ public class Notifications.AbstractBubble : Gtk.Window {
128128

129129
transparency_settings.changed["use-transparency"].connect (update_transparency);
130130
update_transparency ();
131+
132+
IdleMonitor.get_default ().notify["is-idle"].connect (check_idle_status);
131133
}
132134

133135
private void update_transparency () requires (transparency_settings != null) {
@@ -146,11 +148,17 @@ public class Notifications.AbstractBubble : Gtk.Window {
146148

147149
base.present ();
148150

149-
if (timeout != 0) {
151+
if (!IdleMonitor.get_default ().is_idle) {
150152
timeout_id = Timeout.add (timeout, timeout_expired);
151153
}
152154
}
153155

156+
private void check_idle_status () {
157+
if (!IdleMonitor.get_default ().is_idle && timeout_id == 0) {
158+
Timeout.add (timeout, timeout_expired);
159+
}
160+
}
161+
154162
private void pointer_enter () {
155163
close_revealer.reveal_child = true;
156164

@@ -163,7 +171,7 @@ public class Notifications.AbstractBubble : Gtk.Window {
163171
private void pointer_leave () {
164172
close_revealer.reveal_child = false;
165173

166-
if (timeout != 0) {
174+
if (timeout == 0) {
167175
timeout_id = Timeout.add (timeout, timeout_expired);
168176
}
169177
}

src/Application.vala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class Notifications.Application : Gtk.Application {
3333
try {
3434
new Notifications.Server (connection);
3535
} catch (Error e) {
36-
Error.prefix_literal (out e, "Registring notification server failed: ");
36+
Error.prefix_literal (out e, "Registering notification server failed: ");
3737
throw e;
3838
}
3939

@@ -76,6 +76,8 @@ public class Notifications.Application : Gtk.Application {
7676
name_lost ();
7777
}
7878
);
79+
80+
IdleMonitor.get_default (); // Start listening to MutterIdleMonitor
7981
}
8082

8183
public static int main (string[] args) {

src/IdleMonitor.vala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SPDX-License-Identifier: GPL-3.0-or-later
3+
* SPDX-FileCopyrightText: Copyright 2025 elementary, Inc. (https://elementary.io)
4+
*/
5+
6+
public class Notifications.IdleMonitor : Object {
7+
[DBus (name = "org.gnome.Mutter.IdleMonitor")]
8+
private interface MutterIdleMonitor : Object {
9+
public signal void watch_fired (uint32 id);
10+
public abstract uint32 add_idle_watch (uint64 interval) throws Error;
11+
}
12+
13+
private static GLib.Once<IdleMonitor> instance;
14+
public static unowned IdleMonitor get_default () {
15+
return instance.once (() => new IdleMonitor ());
16+
}
17+
18+
private MutterIdleMonitor? idle_monitor;
19+
private uint32 idle_id = 0;
20+
private uint32 active_id = 0;
21+
22+
public bool is_idle { get; private set; default = false; }
23+
24+
construct {
25+
Bus.get_proxy.begin<MutterIdleMonitor> (
26+
SESSION, "org.gnome.Mutter.IdleMonitor", "/org/gnome/Mutter/IdleMonitor/Core", NONE, null,
27+
(obj, res) => {
28+
try {
29+
idle_monitor = Bus.get_proxy.end<MutterIdleMonitor> (res);
30+
idle_id = idle_monitor.add_idle_watch (30000);
31+
active_id = idle_monitor.add_idle_watch (100);
32+
idle_monitor.watch_fired.connect ((id) => {
33+
if (id == idle_id) {
34+
is_idle = true;
35+
} else if (id == active_id && is_idle) {
36+
is_idle = false;
37+
}
38+
});
39+
} catch (Error e) {
40+
warning ("Couldn't connect to idle monitor: %s", e.message);
41+
}
42+
}
43+
);
44+
}
45+
}

0 commit comments

Comments
 (0)