textclock: should update immediately after suspending more than 1 minute
I've noticed that the textclock is not being updated immediately after resuming from suspend, although the maximum of 59 seconds for the timer have passed.
It seems like the glib timer does not use absolute time, but is relative? Can we do something about this?
I think the relative behavior is good in general, but not for the textclock widget.
Daniel Hahler wrote:
I've noticed that the textclock is not being updated immediately after resuming from suspend, although the maximum of 59 seconds for the timer have passed.
It seems like the glib timer does not use absolute time, but is relative? Can we do something about this? Yes ;) Catch the resume and do the update. For systemd (and consolekit?) it should be simply connecting to a dbus signal. Triggering a signal would be really great because it would simplify updating other widgets. I personally would like to get current battery state directly after resume.
I think the relative behavior is good in general, but not for the textclock widget.
Reply to this email directly or view it on GitHub: https://github.com/awesomeWM/awesome/issues/344
@ff2000
Sounds like a plan: awesome would connect to the D-Bus signal(s) and then emit one itself internally, e.g. resume (according to the already existing startup).
Do you feel like creating a PR for this?
On Fri, 24 Jul 2015 06:43:07 -0700, Daniel Hahler [email protected] wrote:
@ff2000 Sounds like a plan: awesome would connect to the D-Bus signal(s) and then emit one itself internally, e.g.
resume(according to the already existingstartup).Do you feel like creating a PR for this? Sorry for the late reply... My lua is still bad as hell (my dbus is even worse), so it would be great if you could do that.
I just had the idea of a complete "system" module, that would encapsulate system calls like "reboot" or "hibernate" and add signals for system actions like "resumed" or "about-to-shutdown" and so on. (that's when I remembered this issue...)
Do you think that's doable?
Reply to this email directly or view it on GitHub: https://github.com/awesomeWM/awesome/issues/344#issuecomment-124525215Non-text part: text/html
I guess it's more on the C side, which would "just" need to hook into dbus and then emit the signal.
The "system module" would be just a particular set of signals then, e.g. system::resumed.
I've came across xss-lock, which provides calling a screenlocker when the system gets resumed. That code might be relevant: https://bitbucket.org/raymonad/xss-lock/src/1e158fb20108058dbd62bd51d8e8c003c0a48717/src/xss-lock.c?at=master.
Do we really want systemd-specific code in awesome? :-( Also, I think it would be better to implement that in lua. Sadly, as far as I know, no one found good lua dbus bindings so far (or gdbus bindings).
Oh. Systemd's dbus API likely can't be used from lua. It requires FD passing (at least for some things?).
Edit: Two more hints about possible DBus APIs: http://askubuntu.com/questions/183516/how-do-i-detect-when-my-system-wakes-up-from-suspend-via-dbus-or-similar-in-a-py
For reference: https://www.freedesktop.org/wiki/Software/systemd/logind/
@blueyed Could you test if the following program does what I think it should be doing? (Great description, right? :-) )
local lgi = require("lgi")
local Gio = lgi.require("Gio")
local function listen_to_signals()
local bus = lgi.Gio.bus_get_sync(Gio.BusType.SYSTEM)
local sender = "org.freedesktop.login1"
local interface = "org.freedesktop.login1.Manager"
local object = "/org/freedesktop/login1"
local member = "PrepareForSleep"
bus:signal_subscribe(sender, interface, member, object, nil, Gio.DBusSignalFlags.NONE, function(bus, sender, object, interface, signal, params)
-- "signals are sent right before (with the argument True) and
-- after (with the argument False) the system goes down for
-- reboot/poweroff, resp. suspend/hibernate."
if not params[1] then
print(os.date("%c"), "We are after suspend!")
else
print(os.date("%c"), "We are BEFORE suspend (this case should not be interesting)")
end
end)
end
listen_to_signals()
lgi.GLib.MainLoop():run()
@psychon Yes, it works as expected!
I could see the "before" message just before suspending, and the other then after/when resuming.
@blueyed Together with #2034 and the default config, the following (untested) code should work for you. Should this be added to the FAQ, the recipes, or something like that?
local lgi = require("lgi")
local Gio = lgi.require("Gio")
local function listen_to_signals()
local bus = lgi.Gio.bus_get_sync(Gio.BusType.SYSTEM)
local sender = "org.freedesktop.login1"
local interface = "org.freedesktop.login1.Manager"
local object = "/org/freedesktop/login1"
local member = "PrepareForSleep"
bus:signal_subscribe(sender, interface, member, object, nil, Gio.DBusSignalFlags.NONE,
function(bus, sender, object, interface, signal, params)
-- "signals are sent right before (with the argument True) and
-- after (with the argument False) the system goes down for
-- reboot/poweroff, resp. suspend/hibernate."
if not params[1] then
require("gears.timer").start_new(2, function()
mytextclock:force_update()
end)
end
end)
end
listen_to_signals()
Edit: Of course, no idea if the delay of two seconds is needed. Feel free to try without.
So, what's the plan here? Do we really want this in awesome, or is it enough somewhere in the docs/recipes? If in awesome, you suggested adding an abstraction layer around it. So, gears.system that provides a singleton object on which various signals are emitted? Would it just abstract over logind/systemd, or are there other implementations that could be written?
I am not sure, but I think having this functionality (the textclock updating it after resuming) in awesome by default makes sense.
@blueyed Together with #2034 and the default config, the following (untested) code should work for you. Should this be added to the FAQ, the recipes, or something like that?
local lgi = require("lgi") local Gio = lgi.require("Gio") local function listen_to_signals() local bus = lgi.Gio.bus_get_sync(Gio.BusType.SYSTEM) local sender = "org.freedesktop.login1" local interface = "org.freedesktop.login1.Manager" local object = "/org/freedesktop/login1" local member = "PrepareForSleep" bus:signal_subscribe(sender, interface, member, object, nil, Gio.DBusSignalFlags.NONE, function(bus, sender, object, interface, signal, params) -- "signals are sent right before (with the argument True) and -- after (with the argument False) the system goes down for -- reboot/poweroff, resp. suspend/hibernate." if not params[1] then require("gears.timer").start_new(2, function() mytextclock:force_update() end) end end) end listen_to_signals()Edit: Of course, no idea if the delay of two seconds is needed. Feel free to try without.
Was searching for how could this problem be solved and came across this, unfortunately this doesn't seem to work as intended, as despite subscribing to the signal being successful. It never ends up firing after resuming from suspend.
There's also some old-ish commit in one of my experimental branch here
https://github.com/Elv13/awesome-1/commits/experimental2
Those commits extend the gears.timer API and use the internal event loop ticks to detect wake-ups. This branch is missing a bunch of things and most of the API it adds have bugs in some corner case. It's pretty low in my priority list and honestly I just have too little time these days to ever get to work on things like that. If someone want to cherry pick those commits and get them to the finish line, it would be appreciated.
The goal of those commits was/is to fix the clock and have alarm clock level features built in the API. This has use cases like "change color theme based on time of day" or "have a calendar popup with basic iCal features". It also has the stuff a actually align the clock correctly to :00 or whatever granularity it needs.
@SteelT1 I modified psychon example to work although I used the dbus_proxy library instead of Gio directly so you will need that installed.
suspend_hook.lua
local p = require('dbus_proxy')
local proxy = p.Proxy:new {
bus = p.Bus.SYSTEM,
name = 'org.freedesktop.login1',
interface = 'org.freedesktop.login1.Manager',
path = '/org/freedesktop/login1'
}
local suspend_hook = {
before = {},
after = {},
}
local function suspend_resume(_, suspend)
if suspend then
for _, callback in ipairs(suspend_hook.before) do
callback()
end
else -- Resume
for _, callback in ipairs(suspend_hook.after) do
callback()
end
end
end
proxy:connect_signal(suspend_resume, 'PrepareForSleep', nil)
function suspend_hook:add(when, callback)
table.insert(self[when], callback)
end
return suspend_hook
clock_update_fix.lua
local suspend_hook = require('module.suspend_hook')
-- Clocks can take up to 59 seconds to update when resuming from suspend
-- This fixes that by forcing an update
-- https://github.com/awesomeWM/awesome/issues/344#issuecomment-328354719
local clocks = {}
local clock_fix = {}
function clock_fix.add(clock)
table.insert(clocks, clock)
end
suspend_hook:add('after', function()
for _, clock in ipairs(clocks) do
clock:force_update()
end
end)
return clock_fix
Lastly add your textclock widgets to the list:
clock.lua
...
local clock_update_fix = require('module.clock_update_fix')
local widget = wibox.widget {
format = '%H:%M',
widget = wibox.widget.textclock
}
clock_update_fix.add(widget)
...
@SteelT1 I modified psychon example to work although I used the dbus_proxy library instead of Gio directly so you will need that installed.
suspend_hook.lualocal p = require('dbus_proxy') local proxy = p.Proxy:new { bus = p.Bus.SYSTEM, name = 'org.freedesktop.login1', interface = 'org.freedesktop.login1.Manager', path = '/org/freedesktop/login1' } local suspend_hook = { before = {}, after = {}, } local function suspend_resume(_, suspend) if suspend then for _, callback in ipairs(suspend_hook.before) do callback() end else -- Resume for _, callback in ipairs(suspend_hook.after) do callback() end end end proxy:connect_signal(suspend_resume, 'PrepareForSleep', nil) function suspend_hook:add(when, callback) table.insert(self[when], callback) end return suspend_hook
clock_update_fix.lualocal suspend_hook = require('module.suspend_hook') -- Clocks can take up to 59 seconds to update when resuming from suspend -- This fixes that by forcing an update -- https://github.com/awesomeWM/awesome/issues/344#issuecomment-328354719 local clocks = {} local clock_fix = {} function clock_fix.add(clock) table.insert(clocks, clock) end suspend_hook:add('after', function() for _, clock in ipairs(clocks) do clock:force_update() end end) return clock_fixLastly add your textclock widgets to the list:
clock.lua... local clock_update_fix = require('module.clock_update_fix') local widget = wibox.widget { format = '%H:%M', widget = wibox.widget.textclock } clock_update_fix.add(widget) ...
This works very nicely, thank you!