client: Make startup_id writable (#2275)

And document how to use it on Linux to fix broken startup_id
This commit is contained in:
Emmanuel Lepage Vallée 2018-07-23 04:04:07 -04:00 committed by GitHub
parent 94d3918d14
commit 7e17bcd026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 58 additions and 2 deletions

View File

@ -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,