spawn: move sn hooks to signals

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-07-31 16:28:17 +02:00
parent ada6056c89
commit 84182466e0
6 changed files with 111 additions and 50 deletions

15
hooks.c
View File

@ -163,20 +163,6 @@ luaA_hooks_property(lua_State *L)
HANDLE_HOOK(L, globalconf.hooks.property);
}
/** Set the function called on each startup-notification events
* This function is called with a table and various fields set to describe the
* vents.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A function to call on each startup-notification event.
*/
static int
luaA_hooks_startup_notification(lua_State *L)
{
HANDLE_HOOK(L, globalconf.hooks.startup_notification);
}
/** Set the function to be called every N seconds.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
@ -226,7 +212,6 @@ const struct luaL_reg awesome_hooks_lib[] =
{ "clients", luaA_hooks_clients },
{ "tags", luaA_hooks_tags },
{ "tagged", luaA_hooks_tagged },
{ "startup_notification", luaA_hooks_startup_notification },
{ "timer", luaA_hooks_timer },
{ "exit", luaA_hooks_exit },
{ NULL, NULL }

View File

@ -5,11 +5,11 @@
---------------------------------------------------------------------------
-- Grab environment we need
local hooks = require("awful.hooks")
local ipairs = ipairs
local table = table
local capi =
{
awesome = awesome,
root = root
}
@ -43,16 +43,12 @@ local function register_event(event_id)
update_cursor()
end
local function startup_hook(event)
if event.type == "initiated" then
register_event(event.id)
elseif event.type == "canceled"
or event.type == "completed"
or event.type == "timedout" then
unregister_event(event.id)
end
end
local function unregister_hook(event) unregister_event(event.id) end
local function register_hook(event) register_event(event.id) end
hooks.startup_notification.register(startup_hook)
capi.awesome.add_signal("spawn::initiated", register_hook)
capi.awesome.add_signal("spawn::canceled", unregister_hook)
capi.awesome.add_signal("spawn::completed", unregister_hook)
capi.awesome.add_signal("spawn::timeout", unregister_hook)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

65
luaa.c
View File

@ -619,6 +619,67 @@ luaA_awesome_newindex(lua_State *L)
return 0;
}
/** Add a global signal.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A string with the event name.
* \lparam The function to call.
*/
static int
luaA_awesome_add_signal(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
luaA_checkfunction(L, 2);
signal_add(&global_signals, name, luaA_object_ref(L, 2));
return 0;
}
/** Remove a global signal.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A string with the event name.
* \lparam The function to call.
*/
static int
luaA_awesome_remove_signal(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
luaA_checkfunction(L, 2);
const void *func = lua_topointer(L, 2);
signal_remove(&global_signals, name, func);
luaA_object_unref(L, (void *) func);
return 0;
}
/** Emit a global signal.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A string with the event name.
* \lparam The function to call.
*/
static int
luaA_awesome_emit_signal(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
signal_t *sigfound = signal_array_getbyid(&global_signals,
a_strhash((const unsigned char *) name));
if(sigfound)
{
int nargs = lua_gettop(L) - 1;
foreach(ref, sigfound->sigfuncs)
{
for(int i = 0; i < nargs; i++)
lua_pushvalue(L, - nargs);
luaA_object_push(L, (void *) *ref);
luaA_dofunction(L, nargs, 0);
}
}
return 0;
}
/** Initialize the Lua VM
* \param xdg An xdg handle to use to get XDG basedir.
*/
@ -632,6 +693,9 @@ luaA_init(xdgHandle* xdg)
{ "exec", luaA_exec },
{ "spawn", luaA_spawn },
{ "restart", luaA_restart },
{ "add_signal", luaA_awesome_add_signal },
{ "remove_signal", luaA_awesome_remove_signal },
{ "emit_signal", luaA_awesome_emit_signal },
{ "__index", luaA_awesome_index },
{ "__newindex", luaA_awesome_newindex },
{ NULL, NULL }
@ -715,7 +779,6 @@ luaA_init(xdgHandle* xdg)
globalconf.hooks.tags = LUA_REFNIL;
globalconf.hooks.tagged = LUA_REFNIL;
globalconf.hooks.property = LUA_REFNIL;
globalconf.hooks.startup_notification = LUA_REFNIL;
globalconf.hooks.timer = LUA_REFNIL;
globalconf.hooks.exit = LUA_REFNIL;

3
luaa.h
View File

@ -239,5 +239,8 @@ bool luaA_isloop(lua_State *, int);
} \
} while(0);
/** Global signals */
signal_array_t global_signals;
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

58
spawn.c
View File

@ -67,16 +67,24 @@ spawn_sequence_remove(SnStartupSequence *s)
static void
spawn_monitor_timeout(struct ev_loop *loop, ev_timer *w, int revents)
{
if(spawn_sequence_remove(w->data)
&& globalconf.hooks.startup_notification != LUA_REFNIL)
if(spawn_sequence_remove(w->data))
{
/* send a timeout event to hook function */
lua_createtable(globalconf.L, 0, 2);
lua_pushstring(globalconf.L, sn_startup_sequence_get_id(w->data));
lua_setfield(globalconf.L, -2, "id");
lua_pushliteral(globalconf.L, "timedout");
lua_setfield(globalconf.L, -2, "type");
luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.startup_notification, 1, 0);
signal_t *sig = signal_array_getbyid(&global_signals,
a_strhash((const unsigned char *) "spawn::timeout"));
if(sig)
{
/* send a timeout signal */
lua_createtable(globalconf.L, 0, 2);
lua_pushstring(globalconf.L, sn_startup_sequence_get_id(w->data));
lua_setfield(globalconf.L, -2, "id");
foreach(func, sig->sigfuncs)
{
lua_pushvalue(globalconf.L, -1);
luaA_object_push(globalconf.L, (void *) *func);
luaA_dofunction(globalconf.L, 1, 0);
}
lua_pop(globalconf.L, 1);
}
}
sn_startup_sequence_unref(w->data);
p_delete(&w);
@ -85,9 +93,6 @@ spawn_monitor_timeout(struct ev_loop *loop, ev_timer *w, int revents)
static void
spawn_monitor_event(SnMonitorEvent *event, void *data)
{
if(globalconf.hooks.startup_notification == LUA_REFNIL)
return;
SnStartupSequence *sequence = sn_monitor_event_get_startup_sequence(event);
SnMonitorEventType event_type = sn_monitor_event_get_type(event);
@ -95,14 +100,15 @@ spawn_monitor_event(SnMonitorEvent *event, void *data)
lua_pushstring(globalconf.L, sn_startup_sequence_get_id(sequence));
lua_setfield(globalconf.L, -2, "id");
const char *event_type_str = NULL;
switch(event_type)
{
case SN_MONITOR_EVENT_INITIATED:
/* ref the sequence for the array */
sn_startup_sequence_ref(sequence);
SnStartupSequence_array_append(&sn_waits, sequence);
lua_pushliteral(globalconf.L, "initiated");
lua_setfield(globalconf.L, -2, "type");
event_type_str = "spawn::initiated";
/* Add a timeout function so we do not wait for this event to complete
* for ever */
@ -114,16 +120,13 @@ spawn_monitor_event(SnMonitorEvent *event, void *data)
ev_timer_start(globalconf.loop, ev_timeout);
break;
case SN_MONITOR_EVENT_CHANGED:
lua_pushliteral(globalconf.L, "change");
lua_setfield(globalconf.L, -2, "type");
event_type_str = "spawn::change";
break;
case SN_MONITOR_EVENT_COMPLETED:
lua_pushliteral(globalconf.L, "completed");
lua_setfield(globalconf.L, -2, "type");
event_type_str = "spawn::completed";
break;
case SN_MONITOR_EVENT_CANCELED:
lua_pushliteral(globalconf.L, "canceled");
lua_setfield(globalconf.L, -2, "type");
event_type_str = "spawn::canceled";
break;
}
@ -174,7 +177,20 @@ spawn_monitor_event(SnMonitorEvent *event, void *data)
break;
}
luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.startup_notification, 1, 0);
/* send the signal */
signal_t *sig = signal_array_getbyid(&global_signals,
a_strhash((const unsigned char *) event_type_str));
if(sig)
{
foreach(func, sig->sigfuncs)
{
lua_pushvalue(globalconf.L, -1);
luaA_object_push(globalconf.L, (void *) *func);
luaA_dofunction(globalconf.L, 1, 0);
}
lua_pop(globalconf.L, 1);
}
}
/** Tell the spawn module that an app has been started.

View File

@ -120,8 +120,6 @@ struct awesome_t
int timer;
/** Command to run on awesome exit */
int exit;
/** Startup notification hooks */
int startup_notification;
} hooks;
/** The event loop */
struct ev_loop *loop;