X-Git-Url: https://git.sur5r.net/?p=i3%2Fi3;a=blobdiff_plain;f=src%2Fewmh.c;h=e5dcafcb012a6572e336e23594fae26301bd3a95;hp=c4ae844ea0a1a523b54057ab248818636759f0eb;hb=HEAD;hpb=fdbbae56b2b5f8049380b9456c01c3966b3b18f2 diff --git a/src/ewmh.c b/src/ewmh.c index c4ae844e..e5dcafcb 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -1,5 +1,3 @@ -#undef I3__FILE__ -#define I3__FILE__ "ewmh.c" /* * vim:ts=4:sw=4:expandtab * @@ -124,11 +122,13 @@ void ewmh_update_desktop_viewport(void) { } static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop) { - /* Recursively call this to descend through the entire subtree. */ Con *child; + + /* Recursively call this to descend through the entire subtree. */ TAILQ_FOREACH(child, &(con->nodes_head), nodes) { ewmh_update_wm_desktop_recursively(child, desktop); } + /* If con is a workspace, we also need to go through the floating windows on it. */ if (con->type == CT_WORKSPACE) { TAILQ_FOREACH(child, &(con->floating_head), floating_windows) { @@ -139,8 +139,6 @@ static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop) if (!con_has_managed_window(con)) return; - const xcb_window_t window = con->window->id; - uint32_t wm_desktop = desktop; /* Sticky windows are only actually sticky when they are floating or inside * a floating container. This is technically still slightly wrong, since @@ -151,11 +149,20 @@ static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop) wm_desktop = NET_WM_DESKTOP_ALL; } + /* If the window is on the scratchpad we assign the sticky value to it + * since showing it works on any workspace. We cannot remove the property + * as per specification. */ + Con *ws = con_get_workspace(con); + if (ws != NULL && con_is_internal(ws)) { + wm_desktop = NET_WM_DESKTOP_ALL; + } + /* If this is the cached value, we don't need to do anything. */ if (con->window->wm_desktop == wm_desktop) return; con->window->wm_desktop = wm_desktop; + const xcb_window_t window = con->window->id; if (wm_desktop != NET_WM_DESKTOP_NONE) { DLOG("Setting _NET_WM_DESKTOP = %d for window 0x%08x.\n", wm_desktop, window); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, A__NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &wm_desktop); @@ -179,11 +186,11 @@ void ewmh_update_wm_desktop(void) { TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { Con *workspace; TAILQ_FOREACH(workspace, &(output_get_content(output)->nodes_head), nodes) { - if (con_is_internal(workspace)) - continue; - ewmh_update_wm_desktop_recursively(workspace, desktop); - ++desktop; + + if (!con_is_internal(workspace)) { + ++desktop; + } } } } @@ -215,9 +222,9 @@ void ewmh_update_visible_name(xcb_window_t window, const char *name) { /* * i3 currently does not support _NET_WORKAREA, because it does not correspond * to i3’s concept of workspaces. See also: - * http://bugs.i3wm.org/539 - * http://bugs.i3wm.org/301 - * http://bugs.i3wm.org/1038 + * https://bugs.i3wm.org/539 + * https://bugs.i3wm.org/301 + * https://bugs.i3wm.org/1038 * * We need to actively delete this property because some display managers (e.g. * LightDM) set it. @@ -277,6 +284,20 @@ void ewmh_update_sticky(xcb_window_t window, bool sticky) { } } +/* + * Set or remove _NEW_WM_STATE_FOCUSED on the window. + * + */ +void ewmh_update_focused(xcb_window_t window, bool is_focused) { + if (is_focused) { + DLOG("Setting _NET_WM_STATE_FOCUSED for window = %d.\n", window); + xcb_add_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_FOCUSED); + } else { + DLOG("Removing _NET_WM_STATE_FOCUSED for window = %d.\n", window); + xcb_remove_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_FOCUSED); + } +} + /* * Set up the EWMH hints on the root window. *