Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Won't suspend app "closed" to systray #45

Open
haarp opened this issue Dec 19, 2023 · 3 comments
Open

Won't suspend app "closed" to systray #45

haarp opened this issue Dec 19, 2023 · 3 comments
Labels

Comments

@haarp
Copy link

haarp commented Dec 19, 2023

Hi,

( nice tool! fyi, I just made a Gentoo ebuild for it :) )

xsuspender seems to be working so far. However, I noticed that it won't suspend certain apps that are "closed" but really just "minimize" to the systray. In this case, Signal (Electron-based 🙄)

How it's started: firejail signal-desktop --use-tray-icon

Config:

[Default]
suspend_delay = 5
resume_every = 59
resume_for = 5
send_signals = true
only_on_battery = false
auto_suspend_on_battery = true
downclock_on_battery = 0

[Signal]
match_wm_class_contains = signal
suspend_subtree_pattern = .

When the window loses focus: 👍

(xsuspender:2728894): xsuspender-DEBUG: 14:13:14.697: Suspending window in 5s: 0x4a00003 (1207188): Signal
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.823: kill -STOP 1207188
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.824: Exec: pstree 1207188 (.) | kill -STOP
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.824:       kill -STOP 1207188
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.845:       kill -STOP 1207191 1207192 1207354 1207433 1499504
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.863:       kill -STOP 1207347
(xsuspender:2728894): xsuspender-DEBUG: 14:13:19.897:       kill -STOP 1207194

When the window is "closed" to systray: 👎

(xsuspender:2728894): xsuspender-DEBUG: 14:13:56.384: Suspending window in 5s: 0x4a00003 (1207188): Signal
(then...nothing, unsuspended)

Thanks!

edit: Other "closed" windows are affected aswell. Discord, or birdtray'ed Thunderbird. Probably because from xsuspender's perspective, the window simply disappeared?

@kernc
Copy link
Owner

kernc commented Oct 29, 2024

xsuspender/src/xsuspender.c

Lines 150 to 156 in 4cce090

g_debug ("Suspending window in %ds: %#lx (%d): %s",
rule->delay,
wnck_window_get_xid (window),
wnck_window_get_pid (window),
wnck_window_get_name (window));
WindowEntry *entry = xsus_window_entry_new (window, rule);
xsus_window_entry_enqueue (entry, rule->delay);

xsuspender/src/events.c

Lines 115 to 125 in 4cce090

GSList *l = queued_entries;
while (l) {
GSList *next = l->next;
WindowEntry *entry = l->data;
if (now >= entry->suspend_timestamp) {
queued_entries = g_slist_delete_link (queued_entries, l);
// Follow through with suspension only if window is still alive
if (window_entry_get_pid (entry))
xsus_signal_stop (entry);

xsuspender/src/events.c

Lines 104 to 107 in 4cce090

window_entry_get_pid (WindowEntry *entry)
{
WnckWindow *window = wnck_window_get (entry->xid);
return window && wnck_window_get_pid (window) == entry->pid ? entry->pid : 0;

Probably because from xsuspender's perspective, the window simply disappeared?

Indeed! If something can be done about the return statement (in this buggy case, there might be no window while the process is indeed still there 🤔), I'd appreciate a PR.

@kernc kernc added the bug label Oct 29, 2024
@haarp
Copy link
Author

haarp commented Oct 30, 2024

An idea might be to maintain processId<->windowId mappings whenever a new window is found. Then this window can disappear while the process itself will still be tracked. However that might be janky, especially for multi-process applications.

@kernc
Copy link
Owner

kernc commented Oct 30, 2024

I'd be happier with simply removing the whole condition here:

xsuspender/src/events.c

Lines 123 to 125 in 4cce090

// Follow through with suspension only if window is still alive
if (window_entry_get_pid (entry))
xsus_signal_stop (entry);

It passes through to:
xsus_signal_stop (WindowEntry *entry)
{
Rule *rule = entry->rule;
// Run the windows' designated exec_suspend script, if any.
// If the subprocess fails, exit early without stopping the process.
if (xsus_exec_subprocess (rule->exec_suspend, entry) != 0) {
g_debug ("Subprocess failed; not stopping the process.");
return FALSE;
}
// Mark the process as suspended and kill it
g_debug ("kill -STOP %d", entry->pid);
suspended_entries = g_slist_prepend (suspended_entries, entry);
if (rule->send_signals) {
kill (entry->pid, SIGSTOP);
xsus_kill_subtree (entry->pid, SIGSTOP, rule->subtree_pattern);
}
return TRUE;

which seems safe/noop in case the pid were no longer valid.


Be aware, with resume_every = 59, your systray icon might be unresponsive (i.e. no menus) until the next wakeup cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants