Freeze problem
Let’s say we have a text widget which displays output of some script (get unread emails for instance). And sometimes execution of this script takes some time. Since lua is not multi-threaded you’ll have a ‘freeze’ - you won’t be able to interact with Awesome (switch tags, open Awesome menu, etc.) because Awesome will wait for the response.
I will demonstrate it on a simple example. Let’s say I have a python script which sleeps for 5 seconds and then returns some string, sleep.py:
#!/usr/bin/python
import time
time.sleep(5)
print 'wow'
Pread example
By using awful.util.pread
Awesome will just wait until execution of a script is finished. To check it let’s create a text widget in a separate lus file:
local wibox = require("wibox")
local awful = require("awful")
sleepMessage = wibox.widget.textbox()
-- Pread (Awesome freezes while waiting for response)
sleepMessageTimer = timer({ timeout = 10 })
sleepMessageTimer:connect_signal("timeout",
function()
sleepMessage:set_text(awful.util.pread("python ~/HomeDev/temp/sleep.py"))
end)
sleepMessageTimer:start()
And put it in rc.lua:
require("sleep")
...
right_layout:add(sleepMessage)
After restart of Awesome after 5 seconds Awesome will freeze for 5 seconds and then message will be displayed on a widget. This is exactly what happens when execution of some scripts takes time.
Now let’s have on a solution of this problem: using DBus to transfer messages between scripts and Awesome.
DBus example
To use DBus for this example change implementation of sleep.py
local wibox = require("wibox")
local awful = require("awful")
sleepMessage = wibox.widget.textbox()
-- DBus (Command are sent to DBus, which prevents Awesome from freezing)
sleepTimerDbus = timer ({timeout = 5})
sleepTimerDbus:connect_signal ("timeout",
function ()
awful.util.spawn_with_shell("dbus-send --session --dest=org.naquadah.awesome.awful /com/console/sleep com.console.sleep.sleepMessage string:$(python ~/HomeDev/temp/sleep.py)" )
end)
sleepTimerDbus:start()
dbus.request_name("session", "com.console.sleep")
dbus.add_match("session", "interface='com.console.sleep', member='sleepMessage' " )
dbus.connect_signal("com.console.sleep",
function (...)
local data = {...}
local dbustext = data[2]
sleepMessage:set_text(dbustext)
end)
With this implementation Awesome will not freeze. Here instead of reading output of a script we send it to DBus:
dbus-send --session --dest=org.naquadah.awesome.awful /com/console/sleep com.console.sleep.sleepMessage string:$(python ~/HomeDev/temp/sleep.py)
And when execution has finished we take it and display:
dbus.request_name("session", "com.console.sleep")
dbus.add_match("session", "interface='com.console.sleep', member='sleepMessage' " )
dbus.connect_signal("com.console.sleep",
function (...)
local data = {...}
local dbustext = data[2]
sleepMessage:set_text(dbustext)
end)
Conclusion
For widgets, which uses scripts which could take some time to run, like calling some service use DBus :)