]> git.lizzy.rs Git - bspwm.git/blobdiff - ewmh.c
Fix typo
[bspwm.git] / ewmh.c
diff --git a/ewmh.c b/ewmh.c
index f4014b03c11a13cb8554c68a534b6aa248929605..b53faad85dc7a4ef65094935b149238aed9c7fbd 100644 (file)
--- a/ewmh.c
+++ b/ewmh.c
@@ -1,7 +1,31 @@
-#include <stdio.h>
+/* Copyright (c) 2012, 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ * 2. 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 OWNER 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 <stdlib.h>
+#include <sys/types.h>
 #include <string.h>
-#include <xcb/xcb_ewmh.h>
-#include "types.h"
+#include <unistd.h>
 #include "bspwm.h"
 #include "settings.h"
 #include "tree.h"
 
 void ewmh_init(void)
 {
-    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_wm_name(void)
-{
-    if (wm_name != NULL)
-        xcb_ewmh_set_wm_name(ewmh, root, strlen(wm_name), wm_name);
+       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);
+       xcb_window_t win = ((mon->desk->focus == NULL || mon->desk->focus->client == NULL) ? XCB_NONE : mon->desk->focus->id);
+       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 desktops_count = 0;
+
+       for (monitor_t *m = mon_head; m != NULL; m = m->next) {
+               for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
+                       desktops_count++;
+               }
+       }
+
+       xcb_ewmh_set_number_of_desktops(ewmh, default_screen, desktops_count);
 }
 
 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;
+       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, desktop_location_t *loc)
+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;
-                return true;
-            }
-
-    return false;
+       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);
+       if (mon == NULL) {
+               return;
+       }
+       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);
+       uint32_t i = ewmh_get_desktop_index(d);
+       for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
+               if (f->client == NULL) {
+                       continue;
+               }
+               xcb_ewmh_set_wm_desktop(ewmh, f->id, i);
+       }
 }
 
-void ewmh_update_desktop_names(void)
+void ewmh_update_wm_desktops(void)
 {
-    char names[MAXLEN];
-    monitor_t *m = mon_head;
-    unsigned int pos, i;
-    pos = i = 0;
-
-    while (m != NULL) {
-        desktop_t *d = m->desk_head;
-
-        while (d != NULL && i < num_desktops) {
-            for (unsigned int j = 0; j < strlen(d->name); j++)
-                names[pos + j] = d->name[j];
-            pos += strlen(d->name);
-            names[pos] = '\0';
-            pos++;
-            d = d->next;
-            i++;
-        }
-
-        m = m->next;
-    }
-
-    if (i != num_desktops)
-        return;
-
-    pos--;
-
-    xcb_ewmh_set_desktop_names(ewmh, default_screen, pos, names);
+       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)) {
+                               if (n->client == NULL) {
+                                       continue;
+                               }
+                               xcb_ewmh_set_wm_desktop(ewmh, n->id, i);
+                       }
+               }
+       }
 }
 
-void ewmh_update_client_list(void)
+void ewmh_update_desktop_names(void)
 {
-    if (num_clients == 0) {
-        xcb_ewmh_set_client_list(ewmh, default_screen, 0, NULL);
-        return;
-    }
-
-    xcb_window_t wins[num_clients];
-    unsigned int i = 0;
+       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) {
+               xcb_ewmh_set_desktop_names(ewmh, default_screen, 0, NULL);
+               return;
+       }
+
+       names_len = i - 1;
+       xcb_ewmh_set_desktop_names(ewmh, default_screen, names_len, names);
+}
 
-    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))
-                wins[i++] = n->client->window;
+void ewmh_update_client_list(bool stacking)
+{
+       if (clients_count == 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[clients_count];
+       unsigned int i = 0;
+
+       if (stacking) {
+               for (stacking_list_t *s = stack_head; s != NULL; s = s->next) {
+                       wins[i++] = s->node->id;
+               }
+               xcb_ewmh_set_client_list_stacking(ewmh, default_screen, clients_count, wins);
+       } else {
+               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)) {
+                                       if (n->client == NULL) {
+                                               continue;
+                                       }
+                                       wins[i++] = n->id;
+                               }
+                       }
+               }
+               xcb_ewmh_set_client_list(ewmh, default_screen, clients_count, wins);
+       }
+}
 
-    if (i != num_clients)
-        return;
+void ewmh_wm_state_update(node_t *n)
+{
+       client_t *c = n->client;
+       size_t count = 0;
+       uint32_t values[12];
+#define HANDLE_WM_STATE(s)  \
+       if (WM_FLAG_##s & c->wm_flags) { \
+               values[count++] = ewmh->_NET_WM_STATE_##s; \
+       }
+       HANDLE_WM_STATE(MODAL)
+       HANDLE_WM_STATE(STICKY)
+       HANDLE_WM_STATE(MAXIMIZED_VERT)
+       HANDLE_WM_STATE(MAXIMIZED_HORZ)
+       HANDLE_WM_STATE(SHADED)
+       HANDLE_WM_STATE(SKIP_TASKBAR)
+       HANDLE_WM_STATE(SKIP_PAGER)
+       HANDLE_WM_STATE(HIDDEN)
+       HANDLE_WM_STATE(FULLSCREEN)
+       HANDLE_WM_STATE(ABOVE)
+       HANDLE_WM_STATE(BELOW)
+       HANDLE_WM_STATE(DEMANDS_ATTENTION)
+#undef HANDLE_WM_STATE
+       xcb_ewmh_set_wm_state(ewmh, n->id, count, values);
+}
 
-    xcb_ewmh_set_client_list(ewmh, default_screen, num_clients, wins);
+void ewmh_set_supporting(xcb_window_t win)
+{
+       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);
 }