Xsuspender does not register focus/unfocus events
dbedrenko opened this issue · comments
Hello, firstly, thank you very much for this program! It's just what I need for a few pesky applications that take up CPU even when not being used.
Specs
OS: ArchLinux
Xsuspender version: Latest as-of today (4cce090)
Window Manager: AwesomeWM v4.3
Xorg-server version: 21.1.8
Steps to reproduce
- Have this config:
[Default]
suspend_delay = 5
resume_every = 0
resume_for = 0
send_signals = true
only_on_battery = false
auto_suspend_on_battery = true
downclock_on_battery = 0
# Suspend all processes.
suspend_subtree_pattern = .
[Pavucontrol]
match_wm_class_group_contains = Pavucontrol
- Open
pavucontrol
(I tried Chromium and other apps too, any app will do) - Run
G_MESSAGES_DEBUG=xsuspender xsuspender
in a terminal - Focus Pavucontrol and notice that it's responding to mouse events.
- Wait 5 seconds
- Pavucontrol stops responding to mouse/keyboard events. No amount of clicking or minimising and re-maximising resumes the process.
- Terminate
xsuspender
to have Pavucontrol resume running.
Here's the output of that:
$ G_MESSAGES_DEBUG=xsuspender xsuspender
(xsuspender:110132): xsuspender-DEBUG: 21:24:53.280: Initializing.
(xsuspender:110132): xsuspender-DEBUG: 21:24:53.282:
needle_wm_class = (null)
needle_wm_class_group = Pavucontrol
needle_wm_name = (null)
delay = 5
resume_every = 0
resume_for = 1
only_on_battery = 0
send_signals = 1
subtree_pattern = .
downclock_on_battery = 0
exec_suspend = (null)
exec_resume = (null)
(xsuspender:110132): xsuspender-DEBUG: 21:25:03.244: AC power = 0; State changed. Suspending/resuming windows.
(xsuspender:110132): xsuspender-DEBUG: 21:25:04.244: kill -STOP 104986
(xsuspender:110132): xsuspender-DEBUG: 21:25:04.244: Exec: pstree 104986 (.) | kill -STOP
(xsuspender:110132): xsuspender-DEBUG: 21:25:04.244: kill -STOP 104986
^C(xsuspender:110132): xsuspender-DEBUG: 21:25:12.548: Exiting ...
(xsuspender:110132): xsuspender-DEBUG: 21:25:12.549: kill -CONT 104986
(xsuspender:110132): xsuspender-DEBUG: 21:25:12.549: Exec: pstree 104986 (.) | kill -CONT
(xsuspender:110132): xsuspender-DEBUG: 21:25:12.549: kill -CONT 104986
(xsuspender:110132): xsuspender-DEBUG: 21:25:12.558: Bye.
It seems that whatever mechanism xsuspender
uses to listen to the focus/unfocus events isn't working? Can I provide any more info or experiments to help debug this issue?
Thanks for replying so quickly!
I added some debug prints and reran the program. It seems that on_active_window_changed()
only gets entered once at the start of the program--and that's even without changing the active window (why is that?). Clicking around windows, minimising and maximising windows and switching virtual desktops back and forth did not trigger this function again.
$ G_MESSAGES_DEBUG=all ./src/xsuspender
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.244: Initializing@@@@@@@@.
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.246:
needle_wm_class = (null)
needle_wm_class_group = Pavucontrol
needle_wm_name = (null)
delay = 5
resume_every = 0
resume_for = 1
only_on_battery = 0
send_signals = 1
subtree_pattern = .
downclock_on_battery = 0
exec_suspend = (null)
exec_resume = (null)
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.246: 8888888 wnck_screen_get_default():
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.246: s+\xe8\xf7U
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.246: s+\xe8\xf7U
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.246: @@@@@@ screen 0 found
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.309: 1111 entered on_active_window_changed()
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.309: 55555 entered windows_are_same_process()
(xsuspender:128842): xsuspender-DEBUG: 22:29:07.309: 222222 windows_are_same_process() evaluated to true
(xsuspender:128842): xsuspender-DEBUG: 22:29:17.144: AC power = 0; State changed. Suspending/resuming windows.
(xsuspender:128842): xsuspender-DEBUG: 22:29:18.144: kill -STOP 104986
(xsuspender:128842): xsuspender-DEBUG: 22:29:18.144: Exec: pstree 104986 (.) | kill -STOP
(xsuspender:128842): xsuspender-DEBUG: 22:29:18.145: kill -STOP 104986
^C(xsuspender:128842): xsuspender-DEBUG: 22:29:24.653: Exiting ...
(xsuspender:128842): xsuspender-DEBUG: 22:29:24.655: kill -CONT 104986
(xsuspender:128842): xsuspender-DEBUG: 22:29:24.656: Exec: pstree 104986 (.) | kill -CONT
(xsuspender:128842): xsuspender-DEBUG: 22:29:24.656: kill -CONT 104986
(xsuspender:128842): xsuspender-DEBUG: 22:29:24.666: Bye.
I thought that maybe this line could be the cause:
WnckScreen *screen = wnck_screen_get_default ();
because I have 2 screens, so I thought maybe it's connecting to the other screen than the one I am using. But I disabled 1 screen (via xrandr), and verified with the debug prints that only 1 screen is detected in xsuspender, yet the bug still manifested with the same behaviour.
Any ideas what else I could try? I see 2 issues:
- Signal doesn't trigger
on_active_window_changed()
when I click around different windows - Why the heck is
on_active_window_changed()
executing that one time? It shouldn't because I have a terminal window open where I type inxsuspender
and don't switch to another window. This is mighty suspicious. Just a mereg_signal_connect()
call should not trigger the callback: only a signal can.
Make sure the platform is X11 and not Wayland.
If it works with another WM, such as flwm or Xfce, you might ask @awesomeWM guys.
I tested with Openbox and Xfce, but unfortunately it's the same behaviour. The application just seems to fail to listen to window events.
I am definitely not in Wayland:
$ echo $XDG_SESSION_TYPE
x11
For anyone else encountering this issue, you can recreate the suspend functionality in AwesomeWM, just paste this into your rc.lua
:
-- Suspend these when not in focus
local classes_to_suspend = {
["starter.exe"] = true,
["Pavucontrol"] = true,
}
client.connect_signal("focus",
function(c)
if classes_to_suspend[c.class] and c.pid then
awful.util.spawn_with_shell("kill -s SIGCONT " .. c.pid)
end
end)
client.connect_signal("unfocus",
function(c)
if classes_to_suspend[c.class] and c.pid then
awful.util.spawn_with_shell("kill -s SIGSTOP " .. c.pid)
end
end)