]> git.lizzy.rs Git - bspwm.git/blobdiff - ewmh.c
Fix initial tagging of windows
[bspwm.git] / ewmh.c
diff --git a/ewmh.c b/ewmh.c
index e948d431505e554aa4ad0184c2df3a65d9f050ac..25d86d391408691d56722d04c506039b4e163333 100644 (file)
--- a/ewmh.c
+++ b/ewmh.c
+/* * Copyright (c) 2012-2013 Bastien Dejean
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include <string.h>
-#include <xcb/xcb_ewmh.h>
-#include "types.h"
+#include <unistd.h>
 #include "bspwm.h"
 #include "settings.h"
+#include "tree.h"
 #include "ewmh.h"
 
 void ewmh_init(void)
 {
-    xcb_intern_atom_cookie_t *ewmh_cookies;
-    ewmh_cookies = xcb_ewmh_init_atoms(dpy, &ewmh);
-    xcb_ewmh_init_atoms_replies(&ewmh, ewmh_cookies, NULL);
+    ewmh = malloc(sizeof(xcb_ewmh_connection_t));
+    if (xcb_ewmh_init_atoms_replies(ewmh, xcb_ewmh_init_atoms(dpy, ewmh), NULL) == 0)
+        err("Can't initialize EWMH atoms.\n");
+}
+
+void ewmh_update_active_window(void)
+{
+    xcb_window_t win = (mon->desk->focus == NULL ? XCB_NONE : mon->desk->focus->client->window);
+    xcb_ewmh_set_active_window(ewmh, default_screen, win);
+}
+
+void ewmh_update_number_of_desktops(void)
+{
+    xcb_ewmh_set_number_of_desktops(ewmh, default_screen, num_desktops);
+}
+
+uint32_t ewmh_get_desktop_index(desktop_t *d)
+{
+    uint32_t i = 0;
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next, i++)
+            if (d == cd)
+                return i;
+    return 0;
+}
+
+bool ewmh_locate_desktop(uint32_t i, coordinates_t *loc)
+{
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        for (desktop_t *d = m->desk_head; d != NULL; d = d->next, i--)
+            if (i == 0) {
+                loc->monitor = m;
+                loc->desktop = d;
+                loc->node = NULL;
+                return true;
+            }
+    return false;
+}
+
+void ewmh_update_current_desktop(void)
+{
+    uint32_t i = ewmh_get_desktop_index(mon->desk);
+    xcb_ewmh_set_current_desktop(ewmh, default_screen, i);
+}
+
+void ewmh_set_wm_desktop(node_t *n, desktop_t *d)
+{
+    uint32_t i = ewmh_get_desktop_index(d);
+    xcb_ewmh_set_wm_desktop(ewmh, n->client->window, i);
+}
+
+void ewmh_update_wm_desktops(void)
+{
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
+            uint32_t i = ewmh_get_desktop_index(d);
+            for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+                xcb_ewmh_set_wm_desktop(ewmh, n->client->window, i);
+        }
+}
+
+void ewmh_update_desktop_names(void)
+{
+    char names[MAXLEN];
+    unsigned int i, j;
+    uint32_t names_len;
+    i = 0;
+
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
+            for (j = 0; d->name[j] != '\0' && (i + j) < sizeof(names); j++)
+                names[i + j] = d->name[j];
+            i += j;
+            if (i < sizeof(names))
+                names[i++] = '\0';
+        }
+
+    if (i < 1)
+        return;
+
+    names_len = i - 1;
+    xcb_ewmh_set_desktop_names(ewmh, default_screen, names_len, names);
+}
+
+void ewmh_update_client_list(void)
+{
+    if (num_clients == 0) {
+        xcb_ewmh_set_client_list(ewmh, default_screen, 0, NULL);
+        xcb_ewmh_set_client_list_stacking(ewmh, default_screen, 0, NULL);
+        return;
+    }
+
+    xcb_window_t wins[num_clients];
+    unsigned int i = 0;
+
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
+            for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+                wins[i++] = n->client->window;
+
+    xcb_ewmh_set_client_list(ewmh, default_screen, num_clients, wins);
+    xcb_ewmh_set_client_list_stacking(ewmh, default_screen, num_clients, wins);
+}
+
+bool ewmh_wm_state_add(client_t *c, xcb_atom_t state)
+{
+    if (c->num_states >= MAX_STATE)
+        return false;
+    for (int i = 0; i < c->num_states; i++)
+        if (c->wm_state[i] == state)
+            return false;
+    c->wm_state[c->num_states] = state;
+    c->num_states++;
+    xcb_ewmh_set_wm_state(ewmh, c->window, c->num_states, c->wm_state);
+    return true;
+}
+
+bool ewmh_wm_state_remove(client_t *c, xcb_atom_t state)
+{
+    for (int i = 0; i < c->num_states; i++)
+        if (c->wm_state[i] == state)
+        {
+            for (int j = i; j < (c->num_states - 1); j++)
+                c->wm_state[j] = c->wm_state[j + 1];
+            c->num_states--;
+            xcb_ewmh_set_wm_state(ewmh, c->window, c->num_states, c->wm_state);
+            return true;
+        }
+    return false;
 }
 
-void ewmh_update_wm_name(void)
+void ewmh_set_supporting(xcb_window_t win)
 {
-    if (wm_name != NULL)
-        xcb_ewmh_set_wm_name(&ewmh, screen->root, strlen(wm_name), wm_name);
+    pid_t wm_pid = getpid();
+    xcb_ewmh_set_supporting_wm_check(ewmh, root, win);
+    xcb_ewmh_set_supporting_wm_check(ewmh, win, win);
+    xcb_ewmh_set_wm_name(ewmh, win, strlen(WM_NAME), WM_NAME);
+    xcb_ewmh_set_wm_pid(ewmh, win, wm_pid);
 }