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); 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. /** Set the function to be called every N seconds.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
@ -226,7 +212,6 @@ const struct luaL_reg awesome_hooks_lib[] =
{ "clients", luaA_hooks_clients }, { "clients", luaA_hooks_clients },
{ "tags", luaA_hooks_tags }, { "tags", luaA_hooks_tags },
{ "tagged", luaA_hooks_tagged }, { "tagged", luaA_hooks_tagged },
{ "startup_notification", luaA_hooks_startup_notification },
{ "timer", luaA_hooks_timer }, { "timer", luaA_hooks_timer },
{ "exit", luaA_hooks_exit }, { "exit", luaA_hooks_exit },
{ NULL, NULL } { NULL, NULL }

View File

@ -5,11 +5,11 @@
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Grab environment we need -- Grab environment we need
local hooks = require("awful.hooks")
local ipairs = ipairs local ipairs = ipairs
local table = table local table = table
local capi = local capi =
{ {
awesome = awesome,
root = root root = root
} }
@ -43,16 +43,12 @@ local function register_event(event_id)
update_cursor() update_cursor()
end end
local function startup_hook(event) local function unregister_hook(event) unregister_event(event.id) end
if event.type == "initiated" then local function register_hook(event) register_event(event.id) end
register_event(event.id)
elseif event.type == "canceled"
or event.type == "completed"
or event.type == "timedout" then
unregister_event(event.id)
end
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 -- 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; 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 /** Initialize the Lua VM
* \param xdg An xdg handle to use to get XDG basedir. * \param xdg An xdg handle to use to get XDG basedir.
*/ */
@ -632,6 +693,9 @@ luaA_init(xdgHandle* xdg)
{ "exec", luaA_exec }, { "exec", luaA_exec },
{ "spawn", luaA_spawn }, { "spawn", luaA_spawn },
{ "restart", luaA_restart }, { "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 }, { "__index", luaA_awesome_index },
{ "__newindex", luaA_awesome_newindex }, { "__newindex", luaA_awesome_newindex },
{ NULL, NULL } { NULL, NULL }
@ -715,7 +779,6 @@ luaA_init(xdgHandle* xdg)
globalconf.hooks.tags = LUA_REFNIL; globalconf.hooks.tags = LUA_REFNIL;
globalconf.hooks.tagged = LUA_REFNIL; globalconf.hooks.tagged = LUA_REFNIL;
globalconf.hooks.property = LUA_REFNIL; globalconf.hooks.property = LUA_REFNIL;
globalconf.hooks.startup_notification = LUA_REFNIL;
globalconf.hooks.timer = LUA_REFNIL; globalconf.hooks.timer = LUA_REFNIL;
globalconf.hooks.exit = LUA_REFNIL; globalconf.hooks.exit = LUA_REFNIL;

3
luaa.h
View File

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

52
spawn.c
View File

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

View File

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