client: Make startup_id writable (#2275)
And document how to use it on Linux to fix broken startup_id
This commit is contained in:
parent
94d3918d14
commit
7e17bcd026
|
@ -723,12 +723,59 @@
|
||||||
* identifier remain the same. This allow to match a spawn event to an actual
|
* identifier remain the same. This allow to match a spawn event to an actual
|
||||||
* client.
|
* client.
|
||||||
*
|
*
|
||||||
|
* This is used to display a different mouse cursor when the application is
|
||||||
|
* loading and also to attach some properties to the newly created client (like
|
||||||
|
* a `tag` or `floating` state).
|
||||||
|
*
|
||||||
|
* Some applications, like `xterm`, don't support startup notification. While
|
||||||
|
* not perfect, the addition the following code to `rc.lua` will mitigate the
|
||||||
|
* issue. Please note that this code is Linux specific.
|
||||||
|
*
|
||||||
|
* local blacklisted_snid = setmetatable({}, {__mode = "v" })
|
||||||
|
*
|
||||||
|
* --- Make startup notification work for some clients like XTerm. This is ugly
|
||||||
|
* -- but works often enough to be useful.
|
||||||
|
* local function fix_startup_id(c)
|
||||||
|
* -- Prevent "broken" sub processes created by `c` to inherit its SNID
|
||||||
|
* if c.startup_id then
|
||||||
|
* blacklisted_snid[c.startup_id] = blacklisted_snid[c.startup_id] or c
|
||||||
|
* return
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* if not c.pid then return end
|
||||||
|
*
|
||||||
|
* -- Read the process environment variables
|
||||||
|
* local f = io.open("/proc/"..c.pid.."/environ", "rb")
|
||||||
|
*
|
||||||
|
* -- It will only work on Linux, that's already 99% of the userbase.
|
||||||
|
* if not f then return end
|
||||||
|
*
|
||||||
|
* local value = _VERSION <= "Lua 5.1" and "([^\z]*)\0" or "([^\0]*)\0"
|
||||||
|
* local snid = f:read("*all"):match("STARTUP_ID=" .. value)
|
||||||
|
* f:close()
|
||||||
|
*
|
||||||
|
* -- If there is already a client using this SNID, it means it's either a
|
||||||
|
* -- subprocess or another window for the same process. While it makes sense
|
||||||
|
* -- in some case to apply the same rules, it is not always the case, so
|
||||||
|
* -- better doing nothing rather than something stupid.
|
||||||
|
* if blacklisted_snid[snid] then return end
|
||||||
|
*
|
||||||
|
* c.startup_id = snid
|
||||||
|
*
|
||||||
|
* blacklisted_snid[snid] = c
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* awful.rules.add_rule_source(
|
||||||
|
* "snid", fix_startup_id, {}, {"awful.spawn", "awful.rules"}
|
||||||
|
* )
|
||||||
|
*
|
||||||
* **Signal:**
|
* **Signal:**
|
||||||
*
|
*
|
||||||
* * *property::startup\_id*
|
* * *property::startup\_id*
|
||||||
*
|
*
|
||||||
* @property startup_id
|
* @property startup_id
|
||||||
* @param string
|
* @param string
|
||||||
|
* @see awful.spawn
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -906,6 +953,7 @@ DO_CLIENT_SET_STRING_PROPERTY(name)
|
||||||
DO_CLIENT_SET_STRING_PROPERTY2(alt_name, name)
|
DO_CLIENT_SET_STRING_PROPERTY2(alt_name, name)
|
||||||
DO_CLIENT_SET_STRING_PROPERTY(icon_name)
|
DO_CLIENT_SET_STRING_PROPERTY(icon_name)
|
||||||
DO_CLIENT_SET_STRING_PROPERTY2(alt_icon_name, icon_name)
|
DO_CLIENT_SET_STRING_PROPERTY2(alt_icon_name, icon_name)
|
||||||
|
DO_CLIENT_SET_STRING_PROPERTY2(startup_id, startup_id)
|
||||||
DO_CLIENT_SET_STRING_PROPERTY(role)
|
DO_CLIENT_SET_STRING_PROPERTY(role)
|
||||||
DO_CLIENT_SET_STRING_PROPERTY(machine)
|
DO_CLIENT_SET_STRING_PROPERTY(machine)
|
||||||
#undef DO_CLIENT_SET_STRING_PROPERTY
|
#undef DO_CLIENT_SET_STRING_PROPERTY
|
||||||
|
@ -3057,6 +3105,14 @@ luaA_client_get_icon_name(lua_State *L, client_t *c)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
luaA_client_set_startup_id(lua_State *L, client_t *c)
|
||||||
|
{
|
||||||
|
const char *startup_id = luaL_checkstring(L, -1);
|
||||||
|
client_set_startup_id(L, 1, a_strdup(startup_id));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LUA_OBJECT_EXPORT_OPTIONAL_PROPERTY(client, client_t, screen, luaA_object_push, NULL)
|
LUA_OBJECT_EXPORT_OPTIONAL_PROPERTY(client, client_t, screen, luaA_object_push, NULL)
|
||||||
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, class, lua_pushstring)
|
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, class, lua_pushstring)
|
||||||
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, instance, lua_pushstring)
|
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, instance, lua_pushstring)
|
||||||
|
@ -3717,9 +3773,9 @@ client_class_setup(lua_State *L)
|
||||||
(lua_class_propfunc_t) luaA_client_get_shape_input,
|
(lua_class_propfunc_t) luaA_client_get_shape_input,
|
||||||
(lua_class_propfunc_t) luaA_client_set_shape_input);
|
(lua_class_propfunc_t) luaA_client_set_shape_input);
|
||||||
luaA_class_add_property(&client_class, "startup_id",
|
luaA_class_add_property(&client_class, "startup_id",
|
||||||
NULL,
|
(lua_class_propfunc_t) luaA_client_set_startup_id,
|
||||||
(lua_class_propfunc_t) luaA_client_get_startup_id,
|
(lua_class_propfunc_t) luaA_client_get_startup_id,
|
||||||
NULL);
|
(lua_class_propfunc_t) luaA_client_set_startup_id);
|
||||||
luaA_class_add_property(&client_class, "client_shape_bounding",
|
luaA_class_add_property(&client_class, "client_shape_bounding",
|
||||||
NULL,
|
NULL,
|
||||||
(lua_class_propfunc_t) luaA_client_get_client_shape_bounding,
|
(lua_class_propfunc_t) luaA_client_get_client_shape_bounding,
|
||||||
|
|
Loading…
Reference in New Issue