Add support for motif wm hints
This makes motif wm hints available on clients as c.motif_wm_hints. Actually interpreting all the values is up to Lua. The definition of the necessary properties is taken from motif. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
15a508f022
commit
d76143f97b
|
@ -64,3 +64,4 @@ XSEL_DATA
|
|||
WM_TAKE_FOCUS
|
||||
AWESOME_CLIENT_ORDER
|
||||
_XKB_RULES_NAMES
|
||||
_MOTIF_WM_HINTS
|
||||
|
|
126
objects/client.c
126
objects/client.c
|
@ -646,6 +646,43 @@
|
|||
* @see size_hints_honor
|
||||
*/
|
||||
|
||||
/**
|
||||
* The motif WM hints of the client.
|
||||
*
|
||||
* This is nil if the client has no motif hints. Otherwise, this is a table that
|
||||
* contains the present properties. Note that awesome provides these properties
|
||||
* as-is and does not interpret them for you. For example, if the function table
|
||||
* only has "resize" set to true, this means that the window requests to be only
|
||||
* resizable, but asks for the other functions not to be able. If however both
|
||||
* "resize" and "all" are set, this means that all but the resize function
|
||||
* should be enabled.
|
||||
*
|
||||
* **Signal:**
|
||||
*
|
||||
* * *property::motif\_wm\_hints*
|
||||
*
|
||||
* @property motif_wm_hints
|
||||
* @param table
|
||||
* @tfield[opt] table table.functions
|
||||
* @tfield[opt] boolean table.functions.all
|
||||
* @tfield[opt] boolean table.functions.resize
|
||||
* @tfield[opt] boolean table.functions.move
|
||||
* @tfield[opt] boolean table.functions.minimize
|
||||
* @tfield[opt] boolean table.functions.maximize
|
||||
* @tfield[opt] boolean table.functions.close
|
||||
* @tfield[opt] table table.decorations
|
||||
* @tfield[opt] boolean table.decorations.all
|
||||
* @tfield[opt] boolean table.decorations.border
|
||||
* @tfield[opt] boolean table.decorations.resizeh
|
||||
* @tfield[opt] boolean table.decorations.title
|
||||
* @tfield[opt] boolean table.decorations.menu
|
||||
* @tfield[opt] boolean table.decorations.minimize
|
||||
* @tfield[opt] boolean table.decorations.maximize
|
||||
* @tfield[opt] string table.input_mode
|
||||
* @tfield[opt] table table.status
|
||||
* @tfield[opt] boolean table.status.tearoff_window
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the client sticky, i.e. available on all tags.
|
||||
*
|
||||
|
@ -978,6 +1015,17 @@ DO_CLIENT_SET_STRING_PROPERTY(role)
|
|||
DO_CLIENT_SET_STRING_PROPERTY(machine)
|
||||
#undef DO_CLIENT_SET_STRING_PROPERTY
|
||||
|
||||
void
|
||||
client_set_motif_wm_hints(lua_State *L, int cidx, motif_wm_hints_t hints)
|
||||
{
|
||||
client_t *c = luaA_checkudata(L, cidx, &client_class);
|
||||
if (memcmp(&c->motif_wm_hints, &hints, sizeof(c->motif_wm_hints)) == 0)
|
||||
return;
|
||||
|
||||
memcpy(&c->motif_wm_hints, &hints, sizeof(c->motif_wm_hints));
|
||||
luaA_object_emit_signal(L, cidx, "property::motif_wm_hints", 0);
|
||||
}
|
||||
|
||||
void
|
||||
client_find_transient_for(client_t *c)
|
||||
{
|
||||
|
@ -1416,6 +1464,7 @@ client_update_properties(lua_State *L, int cidx, client_t *c)
|
|||
xcb_get_property_cookie_t net_wm_icon_name = property_get_net_wm_icon_name(c);
|
||||
xcb_get_property_cookie_t wm_class = property_get_wm_class(c);
|
||||
xcb_get_property_cookie_t wm_protocols = property_get_wm_protocols(c);
|
||||
xcb_get_property_cookie_t motif_wm_hints = property_get_motif_wm_hints(c);
|
||||
xcb_get_property_cookie_t opacity = xwindow_get_opacity_unchecked(c->window);
|
||||
|
||||
/* update strut */
|
||||
|
@ -1436,6 +1485,7 @@ client_update_properties(lua_State *L, int cidx, client_t *c)
|
|||
property_update_net_wm_icon_name(c, net_wm_icon_name);
|
||||
property_update_wm_class(c, wm_class);
|
||||
property_update_wm_protocols(c, wm_protocols);
|
||||
property_update_motif_wm_hints(c, motif_wm_hints);
|
||||
window_set_opacity(L, cidx, xwindow_get_opacity_from_cookie(opacity));
|
||||
}
|
||||
|
||||
|
@ -3156,6 +3206,78 @@ LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_vertical, lua_pushboolean
|
|||
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized, lua_pushboolean)
|
||||
LUA_OBJECT_EXPORT_PROPERTY(client, client_t, startup_id, lua_pushstring)
|
||||
|
||||
static int
|
||||
luaA_client_get_motif_wm_hints(lua_State *L, client_t *c)
|
||||
{
|
||||
if (!(c->motif_wm_hints.hints & MWM_HINTS_AWESOME_SET))
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
#define HANDLE_BIT(field, flag, name) do { \
|
||||
lua_pushboolean(L, c->motif_wm_hints.field & flag); \
|
||||
lua_setfield(L, -2, name); \
|
||||
} while (0)
|
||||
|
||||
if (c->motif_wm_hints.hints & MWM_HINTS_FUNCTIONS)
|
||||
{
|
||||
lua_newtable(L);
|
||||
HANDLE_BIT(functions, MWM_FUNC_ALL, "all");
|
||||
HANDLE_BIT(functions, MWM_FUNC_RESIZE, "resize");
|
||||
HANDLE_BIT(functions, MWM_FUNC_MOVE, "move");
|
||||
HANDLE_BIT(functions, MWM_FUNC_MINIMIZE, "minimize");
|
||||
HANDLE_BIT(functions, MWM_FUNC_MAXIMIZE, "maximize");
|
||||
HANDLE_BIT(functions, MWM_FUNC_CLOSE, "close");
|
||||
lua_setfield(L, -2, "functions");
|
||||
}
|
||||
|
||||
if (c->motif_wm_hints.hints & MWM_HINTS_DECORATIONS)
|
||||
{
|
||||
lua_newtable(L);
|
||||
HANDLE_BIT(decorations, MWM_DECOR_ALL, "all");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_BORDER, "border");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_RESIZEH, "resizeh");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_TITLE, "title");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_MENU, "menu");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_MINIMIZE, "minimize");
|
||||
HANDLE_BIT(decorations, MWM_DECOR_MAXIMIZE, "maximize");
|
||||
lua_setfield(L, -2, "decorations");
|
||||
}
|
||||
|
||||
if (c->motif_wm_hints.hints & MWM_HINTS_INPUT_MODE)
|
||||
{
|
||||
switch (c->motif_wm_hints.input_mode) {
|
||||
case MWM_INPUT_MODELESS:
|
||||
lua_pushliteral(L, "modeless");
|
||||
break;
|
||||
case MWM_INPUT_PRIMARY_APPLICATION_MODAL:
|
||||
lua_pushliteral(L, "primary_application_modal");
|
||||
break;
|
||||
case MWM_INPUT_SYSTEM_MODAL:
|
||||
lua_pushliteral(L, "system_modal");
|
||||
break;
|
||||
case MWM_INPUT_FULL_APPLICATION_MODAL:
|
||||
lua_pushliteral(L, "full_application_modal");
|
||||
break;
|
||||
default:
|
||||
lua_pushfstring(L, "unknown (%d)", (int) c->motif_wm_hints.input_mode);
|
||||
break;
|
||||
}
|
||||
lua_setfield(L, -2, "input_mode");
|
||||
}
|
||||
|
||||
if (c->motif_wm_hints.hints & MWM_HINTS_STATUS)
|
||||
{
|
||||
lua_newtable(L);
|
||||
HANDLE_BIT(status, MWM_TEAROFF_WINDOW, "tearoff_window");
|
||||
lua_setfield(L, -2, "status");
|
||||
}
|
||||
|
||||
#undef HANDLE_BIT
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaA_client_get_content(lua_State *L, client_t *c)
|
||||
{
|
||||
|
@ -3721,6 +3843,10 @@ client_class_setup(lua_State *L)
|
|||
(lua_class_propfunc_t) luaA_client_set_modal,
|
||||
(lua_class_propfunc_t) luaA_client_get_modal,
|
||||
(lua_class_propfunc_t) luaA_client_set_modal);
|
||||
luaA_class_add_property(&client_class, "motif_wm_hints",
|
||||
NULL,
|
||||
(lua_class_propfunc_t) luaA_client_get_motif_wm_hints,
|
||||
NULL);
|
||||
luaA_class_add_property(&client_class, "group_window",
|
||||
NULL,
|
||||
(lua_class_propfunc_t) luaA_client_get_group_window,
|
||||
|
|
|
@ -47,6 +47,48 @@ typedef enum {
|
|||
CLIENT_TITLEBAR_COUNT = 4
|
||||
} client_titlebar_t;
|
||||
|
||||
/* Special bit we invented to "fake" unset hints */
|
||||
#define MWM_HINTS_AWESOME_SET (1L << 15)
|
||||
|
||||
/* The following is taken from MwmUtil.h and slightly adapted, which is
|
||||
* copyright (c) 1987-2012, The Open Group.
|
||||
* It is licensed under GPLv2 or later.
|
||||
*/
|
||||
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||
#define MWM_HINTS_STATUS (1L << 3)
|
||||
|
||||
#define MWM_FUNC_ALL (1L << 0)
|
||||
#define MWM_FUNC_RESIZE (1L << 1)
|
||||
#define MWM_FUNC_MOVE (1L << 2)
|
||||
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||
#define MWM_FUNC_CLOSE (1L << 5)
|
||||
|
||||
#define MWM_DECOR_ALL (1L << 0)
|
||||
#define MWM_DECOR_BORDER (1L << 1)
|
||||
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||
#define MWM_DECOR_TITLE (1L << 3)
|
||||
#define MWM_DECOR_MENU (1L << 4)
|
||||
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||
|
||||
#define MWM_INPUT_MODELESS 0
|
||||
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
||||
#define MWM_INPUT_SYSTEM_MODAL 2
|
||||
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
||||
|
||||
#define MWM_TEAROFF_WINDOW (1L<<0)
|
||||
|
||||
typedef struct {
|
||||
uint32_t hints;
|
||||
uint32_t functions;
|
||||
uint32_t decorations;
|
||||
int32_t input_mode;
|
||||
uint32_t status;
|
||||
} motif_wm_hints_t;
|
||||
|
||||
/** client_t type */
|
||||
struct client_t
|
||||
{
|
||||
|
@ -143,6 +185,8 @@ struct client_t
|
|||
/** The drawable for this bar. */
|
||||
drawable_t *drawable;
|
||||
} titlebar[CLIENT_TITLEBAR_COUNT];
|
||||
/** Motif WM hints, with an additional MWM_HINTS_AWESOME_SET bit */
|
||||
motif_wm_hints_t motif_wm_hints;
|
||||
};
|
||||
|
||||
ARRAY_FUNCS(client_t *, client, DO_NOTHING)
|
||||
|
@ -190,6 +234,7 @@ void client_set_group_window(lua_State *, int, xcb_window_t);
|
|||
void client_set_icons(client_t *, cairo_surface_array_t);
|
||||
void client_set_icon_from_pixmaps(client_t *, xcb_pixmap_t, xcb_pixmap_t);
|
||||
void client_set_skip_taskbar(lua_State *, int, bool);
|
||||
void client_set_motif_wm_hints(lua_State *, int, motif_wm_hints_t);
|
||||
void client_focus(client_t *);
|
||||
bool client_focus_update(client_t *);
|
||||
bool client_hasproto(client_t *, xcb_atom_t);
|
||||
|
|
39
property.c
39
property.c
|
@ -91,6 +91,7 @@ HANDLE_PROPERTY(wm_hints)
|
|||
HANDLE_PROPERTY(wm_class)
|
||||
HANDLE_PROPERTY(net_wm_icon)
|
||||
HANDLE_PROPERTY(net_wm_pid)
|
||||
HANDLE_PROPERTY(motif_wm_hints)
|
||||
|
||||
#undef HANDLE_PROPERTY
|
||||
|
||||
|
@ -304,6 +305,41 @@ property_update_net_wm_pid(client_t *c, xcb_get_property_cookie_t cookie)
|
|||
p_delete(&reply);
|
||||
}
|
||||
|
||||
xcb_get_property_cookie_t
|
||||
property_get_motif_wm_hints(client_t *c)
|
||||
{
|
||||
return xcb_get_property_unchecked(globalconf.connection, false, c->window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 0L, 5L);
|
||||
}
|
||||
|
||||
void
|
||||
property_update_motif_wm_hints(client_t *c, xcb_get_property_cookie_t cookie)
|
||||
{
|
||||
motif_wm_hints_t hints;
|
||||
xcb_get_property_reply_t *reply;
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
|
||||
/* Clear the hints */
|
||||
p_clear(&hints, 1);
|
||||
|
||||
reply = xcb_get_property_reply(globalconf.connection, cookie, NULL);
|
||||
|
||||
if(reply && reply->value_len == 5)
|
||||
{
|
||||
uint32_t *rdata = xcb_get_property_value(reply);
|
||||
if(rdata)
|
||||
{
|
||||
memcpy(&hints, rdata, sizeof(hints));
|
||||
hints.hints |= MWM_HINTS_AWESOME_SET;
|
||||
}
|
||||
}
|
||||
|
||||
p_delete(&reply);
|
||||
|
||||
luaA_object_push(L, c);
|
||||
client_set_motif_wm_hints(L, -1, hints);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
xcb_get_property_cookie_t
|
||||
property_get_wm_protocols(client_t *c)
|
||||
{
|
||||
|
@ -478,6 +514,9 @@ property_handle_propertynotify(xcb_property_notify_event_t *ev)
|
|||
HANDLE(_NET_WM_PID, property_handle_net_wm_pid)
|
||||
HANDLE(_NET_WM_WINDOW_OPACITY, property_handle_net_wm_opacity)
|
||||
|
||||
/* MOTIF hints */
|
||||
HANDLE(_MOTIF_WM_HINTS, property_handle_motif_wm_hints)
|
||||
|
||||
/* background change */
|
||||
HANDLE(_XROOTPMAP_ID, property_handle_xrootpmap_id)
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ PROPERTY(wm_class);
|
|||
PROPERTY(wm_protocols);
|
||||
PROPERTY(net_wm_pid);
|
||||
PROPERTY(net_wm_icon);
|
||||
PROPERTY(motif_wm_hints);
|
||||
|
||||
#undef PROPERTY
|
||||
|
||||
|
|
Loading…
Reference in New Issue