Add end to end support for spawning tracking using startup notifications

This allow to spawn something, then apply some properties or rules when
the client show up ("manage").

This commit add:
 * "startup_id" property for all clients object (immutable, can be nil)
 * Second return value to awful.util.spawn() with the startup_id
 * Update the documentation

Example:

  local wait_for_it = {}

  local pid,snid = awful.util.spawn("urxvtc")
  wait_for_it[snid] = {ontop=true,sticky=false,
     tag = awful.tag.gettags(mouse.screen)[1] }

  client.connect_signal("manage", function (c, startup)
     if c.startup_id and wait_for_it[c.startup_id] then
        for k,v in pairs(wait_for_it[c.startup_id]) do
           c[k] = v
        end
        if wait_for_it[c.startup_id].tag then
           c:tags({wait_for_it[c.startup_id].tag})
        end
     end
  end)

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Emmanuel Lepage Vallee 2014-03-15 18:09:33 -04:00 committed by Uli Schlachter
parent ef27189ffe
commit d6e06450d3
5 changed files with 17 additions and 3 deletions

View File

@ -72,7 +72,8 @@ end
--- Spawn a program.
-- @param cmd The command.
-- @param sn Enable startup-notification.
-- @return The awesome.spawn return value.
-- @return The forked PID or an error message
-- @return The startup notification UID, if the spawn was successful
function util.spawn(cmd, sn)
if cmd and cmd ~= "" then
if sn == nil then sn = true end

View File

@ -46,6 +46,7 @@ module("client")
-- @field shape_clip The client's clip shape as set by awesome as a (native) cairo surface.
-- @field shape_client_bounding The client's bounding shape as set by the program as a (native) cairo surface.
-- @field shape_client_clip The client's clip shape as set by the program as a (native) cairo surface.
-- @field startup_id The FreeDesktop StartId.
-- @class table
-- @name client

View File

@ -53,6 +53,7 @@ client_wipe(client_t *c)
p_delete(&c->alt_icon_name);
p_delete(&c->name);
p_delete(&c->alt_name);
p_delete(&c->startup_id);
if(c->icon)
cairo_surface_destroy(c->icon);
}
@ -577,9 +578,9 @@ HANDLE_GEOM(height)
xcb_get_property_reply(globalconf.connection, startup_id_q, NULL);
/* Say spawn that a client has been started, with startup id as argument */
char *startup_id = xutil_get_text_property_from_reply(reply);
c->startup_id = startup_id;
p_delete(&reply);
spawn_start_notify(c, startup_id);
p_delete(&startup_id);
}
luaA_class_emit_signal(globalconf.L, &client_class, "list", 0);
@ -1820,6 +1821,7 @@ LUA_OBJECT_EXPORT_PROPERTY(client, client_t, sticky, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, size_hints_honor, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_horizontal, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_vertical, lua_pushboolean)
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, startup_id, lua_pushstring)
static int
luaA_client_get_maximized(lua_State *L, client_t *c)
@ -2335,6 +2337,10 @@ client_class_setup(lua_State *L)
(lua_class_propfunc_t) luaA_client_set_shape_clip,
(lua_class_propfunc_t) luaA_client_get_shape_clip,
(lua_class_propfunc_t) luaA_client_set_shape_clip);
luaA_class_add_property(&client_class, "startup_id",
NULL,
(lua_class_propfunc_t) luaA_client_get_startup_id,
NULL);
luaA_class_add_property(&client_class, "client_shape_bounding",
NULL,
(lua_class_propfunc_t) luaA_client_get_client_shape_bounding,

View File

@ -64,6 +64,8 @@ struct client_t
char *class, *instance;
/** Window geometry */
area_t geometry;
/** Startup ID */
char *startup_id;
/** True if the client is sticky */
bool sticky;
/** Has urgency hint */

View File

@ -372,7 +372,11 @@ luaA_spawn(lua_State *L)
/* push pid on stack */
lua_pushnumber(L, pid);
return 1;
/* push sn on stack */
if (context)
lua_pushstring(L,sn_launcher_context_get_startup_id(context));
return (context)?2:1;
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80