Make client.focusable writable from Lua

It uses an extra boolean to track if `c.focusable` has been set.

It's possible to unset the overriding by setting it to `nil`, i.e.
`client.focus.focusable = nil`.

Fixes https://github.com/awesomeWM/awesome/issues/237.
Closes https://github.com/awesomeWM/awesome/pull/239.
This commit is contained in:
Daniel Hahler 2015-05-21 17:30:51 +02:00
parent 82e62a0fad
commit fd6ffb1458
2 changed files with 39 additions and 3 deletions

View File

@ -946,6 +946,24 @@ client_set_sticky(lua_State *L, int cidx, bool s)
} }
} }
/** Set a client focusable, or not.
* \param L The Lua VM state.
* \param cidx The client index.
* \param s Set or not the client's focusable property.
*/
static void
client_set_focusable(lua_State *L, int cidx, bool s)
{
client_t *c = luaA_checkudata(L, cidx, &client_class);
if(c->focusable != s || !c->focusable_set)
{
c->focusable = s;
c->focusable_set = true;
luaA_object_emit_signal(L, cidx, "property::focusable", 0);
}
}
/** Set a client fullscreen, or not. /** Set a client fullscreen, or not.
* \param L The Lua VM state. * \param L The Lua VM state.
* \param cidx The client index. * \param cidx The client index.
@ -1878,6 +1896,16 @@ luaA_client_set_icon(lua_State *L, client_t *c)
return 0; return 0;
} }
static int
luaA_client_set_focusable(lua_State *L, client_t *c)
{
if(lua_isnil(L, -1))
c->focusable_set = false;
else
client_set_focusable(L, -3, luaA_checkboolean(L, -1));
return 0;
}
static int static int
luaA_client_set_sticky(lua_State *L, client_t *c) luaA_client_set_sticky(lua_State *L, client_t *c)
{ {
@ -2028,8 +2056,11 @@ luaA_client_get_focusable(lua_State *L, client_t *c)
{ {
bool ret; bool ret;
if (c->focusable_set)
ret = c->focusable;
/* A client can be focused if it doesnt have the "nofocus" hint...*/ /* A client can be focused if it doesnt have the "nofocus" hint...*/
if (!c->nofocus) else if (!c->nofocus)
ret = true; ret = true;
else else
/* ...or if it knows the WM_TAKE_FOCUS protocol */ /* ...or if it knows the WM_TAKE_FOCUS protocol */
@ -2499,9 +2530,9 @@ client_class_setup(lua_State *L)
(lua_class_propfunc_t) luaA_client_get_size_hints, (lua_class_propfunc_t) luaA_client_get_size_hints,
NULL); NULL);
luaA_class_add_property(&client_class, "focusable", luaA_class_add_property(&client_class, "focusable",
NULL, (lua_class_propfunc_t) luaA_client_set_focusable,
(lua_class_propfunc_t) luaA_client_get_focusable, (lua_class_propfunc_t) luaA_client_get_focusable,
NULL); (lua_class_propfunc_t) luaA_client_set_focusable);
luaA_class_add_property(&client_class, "shape_bounding", luaA_class_add_property(&client_class, "shape_bounding",
(lua_class_propfunc_t) luaA_client_set_shape_bounding, (lua_class_propfunc_t) luaA_client_set_shape_bounding,
(lua_class_propfunc_t) luaA_client_get_shape_bounding, (lua_class_propfunc_t) luaA_client_get_shape_bounding,
@ -2534,6 +2565,7 @@ client_class_setup(lua_State *L)
signal_add(&client_class.signals, "property::above"); signal_add(&client_class.signals, "property::above");
signal_add(&client_class.signals, "property::below"); signal_add(&client_class.signals, "property::below");
signal_add(&client_class.signals, "property::class"); signal_add(&client_class.signals, "property::class");
signal_add(&client_class.signals, "property::focusable");
signal_add(&client_class.signals, "property::fullscreen"); signal_add(&client_class.signals, "property::fullscreen");
signal_add(&client_class.signals, "property::geometry"); signal_add(&client_class.signals, "property::geometry");
signal_add(&client_class.signals, "property::group_window"); signal_add(&client_class.signals, "property::group_window");

View File

@ -91,6 +91,10 @@ struct client_t
bool skip_taskbar; bool skip_taskbar;
/** True if the client cannot have focus */ /** True if the client cannot have focus */
bool nofocus; bool nofocus;
/** True if the client is focusable. Overrides nofocus, and can be set
* from Lua. */
bool focusable;
bool focusable_set;
/** Window of the group leader */ /** Window of the group leader */
xcb_window_t group_window; xcb_window_t group_window;
/** Window holding command needed to start it (session management related) */ /** Window holding command needed to start it (session management related) */