From 0befee6dfa61a0107fe8da6d59a53fb8df78b743 Mon Sep 17 00:00:00 2001 From: Mikhail Schemelev Date: Sun, 15 May 2016 16:31:57 +0300 Subject: [PATCH] Attempt at better handling of NET_CURRENT_DESKTOP property. NET_CURRENT_DESKTOP is now being set to the index of the tag with currently focused client. In case of no focused clients present, first selected tag index is taken, with fallback value being 0. Current desktop is updated on next client signals: focus, unfocus, tagged, untagged. Current desktop is also updated on tag property::selected signal. This should fix drag and drop issues with chrome-based applications on multihead setups --- ewmh.c | 13 ++++++++++--- ewmh.h | 2 +- objects/tag.c | 38 +++++++++++++++++--------------------- objects/tag.h | 19 ++++++++++++++++++- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/ewmh.c b/ewmh.c index 5f9c5b58d..62dd55bfc 100755 --- a/ewmh.c +++ b/ewmh.c @@ -228,6 +228,12 @@ ewmh_init(void) luaA_class_connect_signal(L, &client_class, "property::titlebar_left" , ewmh_client_update_frame_extents); luaA_class_connect_signal(L, &client_class, "property::border_width" , ewmh_client_update_frame_extents); luaA_class_connect_signal(L, &client_class, "manage", ewmh_client_update_frame_extents); + /* NET_CURRENT_DESKTOP handling */ + luaA_class_connect_signal(L, &client_class, "focus", ewmh_update_net_current_desktop); + luaA_class_connect_signal(L, &client_class, "unfocus", ewmh_update_net_current_desktop); + luaA_class_connect_signal(L, &client_class, "tagged", ewmh_update_net_current_desktop); + luaA_class_connect_signal(L, &client_class, "untagged", ewmh_update_net_current_desktop); + luaA_class_connect_signal(L, &tag_class, "property::selected", ewmh_update_net_current_desktop); } /** Set the client list in stacking order, bottom to top. @@ -256,14 +262,15 @@ ewmh_update_net_numbers_of_desktop(void) _NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &count); } -void -ewmh_update_net_current_desktop(void) +int +ewmh_update_net_current_desktop(lua_State *L) { - uint32_t idx = tags_get_first_selected_index(); + uint32_t idx = tags_get_current_or_first_selected_index(); xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, globalconf.screen->root, _NET_CURRENT_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &idx); + return 0; } void diff --git a/ewmh.h b/ewmh.h index 6473687e5..ad11d2070 100644 --- a/ewmh.h +++ b/ewmh.h @@ -31,7 +31,7 @@ typedef struct client_t client_t; void ewmh_init(void); void ewmh_update_net_numbers_of_desktop(void); -void ewmh_update_net_current_desktop(void); +int ewmh_update_net_current_desktop(lua_State *); void ewmh_update_net_desktop_names(void); int ewmh_process_client_message(xcb_client_message_event_t *); void ewmh_update_net_client_list_stacking(void); diff --git a/objects/tag.c b/objects/tag.c index 92396dec4..a0512a4ca 100644 --- a/objects/tag.c +++ b/objects/tag.c @@ -91,23 +91,6 @@ * @function set_newindex_miss_handler */ -/** Tag type */ -struct tag -{ - LUA_OBJECT_HEADER - /** Tag name */ - char *name; - /** true if activated */ - bool activated; - /** true if selected */ - bool selected; - /** clients in this tag */ - client_array_t clients; -}; - -static lua_class_t tag_class; -LUA_OBJECT_FUNCS(tag_class, tag_t, tag) - void tag_unref_simplified(tag_t **tag) @@ -139,7 +122,6 @@ tag_view(lua_State *L, int udx, bool view) { tag->selected = view; banning_need_update(); - ewmh_update_net_current_desktop(); luaA_object_emit_signal(L, udx, "property::selected", 0); } @@ -220,15 +202,29 @@ is_client_tagged(client_t *c, tag_t *t) return false; } -/** Get the index of the first selected tag. - * \return Its index. +/** Get the index of the tag with focused client or first selected + * \return Its index */ int -tags_get_first_selected_index(void) +tags_get_current_or_first_selected_index(void) { + /* Consider "current desktop" a tag, that has focused window, + * basically a tag user actively interacts with. + * If no focused windows are present, fallback to first selected. + */ + if(globalconf.focus.client) + { + foreach(tag, globalconf.tags) + { + if((*tag)->selected && is_client_tagged(globalconf.focus.client, *tag)) + return tag_array_indexof(&globalconf.tags, tag); + } + } foreach(tag, globalconf.tags) + { if((*tag)->selected) return tag_array_indexof(&globalconf.tags, tag); + } return 0; } diff --git a/objects/tag.h b/objects/tag.h index c2aa2370d..d6bb40e0d 100644 --- a/objects/tag.h +++ b/objects/tag.h @@ -24,7 +24,7 @@ #include "client.h" -int tags_get_first_selected_index(void); +int tags_get_current_or_first_selected_index(void); void tag_client(lua_State *, client_t *); void untag_client(client_t *, tag_t *); bool is_client_tagged(client_t *, tag_t *); @@ -32,6 +32,23 @@ void tag_unref_simplified(tag_t **); ARRAY_FUNCS(tag_t *, tag, tag_unref_simplified) +/** Tag type */ +struct tag +{ + LUA_OBJECT_HEADER + /** Tag name */ + char *name; + /** true if activated */ + bool activated; + /** true if selected */ + bool selected; + /** clients in this tag */ + client_array_t clients; +}; + +lua_class_t tag_class; +LUA_OBJECT_FUNCS(tag_class, tag_t, tag) + void tag_class_setup(lua_State *); bool tag_get_selected(tag_t *);