]> git.sur5r.net Git - i3/i3/commitdiff
ewmh: implement support for _NET_WORKAREA (rdesktop can use that)
authorMichael Stapelberg <michael@stapelberg.de>
Thu, 31 Dec 2009 16:48:41 +0000 (17:48 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Thu, 31 Dec 2009 16:48:41 +0000 (17:48 +0100)
Please note that rdesktop’s -g workarea option will not work on
64-bit systems at the moment because of a bug in rdesktop (see the
rdesktop-devel mailing list).

include/data.h
include/ewmh.h
include/i3.h
include/xcb.h
src/ewmh.c
src/mainx.c
src/workspace.c

index 12c235544bb957a8be4cf9c1ec86e74d2a312704..8c8465378e75b9de73f17be6f48b4d6ea47656b5 100644 (file)
@@ -75,12 +75,16 @@ enum {
 
 /**
  * Stores a rectangle, for example the size of a window, the child window etc.
+ * It needs to be packed so that the compiler will not add any padding bytes.
+ * (it is used in src/ewmh.c for example)
  *
  */
 struct Rect {
-        uint32_t x, y;
-        uint32_t width, height;
-};
+        uint32_t x;
+        uint32_t y;
+        uint32_t width;
+        uint32_t height;
+} __attribute__((packed));
 
 /**
  * Defines a position in the table
index 9ed8527502cd5373046bbbea632698e28bdea83d..c73c4a45cb36addaa7afeb8832b48e9ad5c03715 100644 (file)
@@ -29,4 +29,14 @@ void ewmh_update_current_desktop();
  */
 void ewmh_update_active_window(xcb_window_t window);
 
+/**
+ * Updates the workarea for each desktop.
+ *
+ * EWMH: Contains a geometry for each desktop. These geometries specify an area
+ * that is completely contained within the viewport. Work area SHOULD be used by
+ * desktop applications to place desktop icons appropriately.
+ *
+ */
+void ewmh_update_workarea();
+
 #endif
index abd503f437585075803c837ca587c44df43e8986..ce86e9244e862306016c38e11f8d4556f9b7bf69 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _I3_H
 #define _I3_H
 
-#define NUM_ATOMS 20
+#define NUM_ATOMS 21
 
 extern xcb_connection_t *global_conn;
 extern xcb_key_symbols_t *keysyms;
index 883824dcc04fc672f20eb8dc722f22e93766ac7c..d4ac33a3adbfc0326a9cf31ca3d2dc6ea13a0ae2 100644 (file)
@@ -63,7 +63,8 @@ enum { _NET_SUPPORTED = 0,
         WM_STATE,
         WM_CLIENT_LEADER,
         _NET_CURRENT_DESKTOP,
-        _NET_ACTIVE_WINDOW
+        _NET_ACTIVE_WINDOW,
+        _NET_WORKAREA
 };
 
 extern unsigned int xcb_numlock_mask;
index 2e6e121bcd840bca195d4af9ddd29aea0822cb9d..0d1e8a1ba678acebae67d694c97e14228c11e872 100644 (file)
  *
  */
 #include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
 
 #include "data.h"
 #include "table.h"
 #include "i3.h"
 #include "xcb.h"
+#include "util.h"
+#include "log.h"
 
 /*
  * Updates _NET_CURRENT_DESKTOP with the current desktop number.
@@ -42,3 +46,31 @@ void ewmh_update_active_window(xcb_window_t window) {
         xcb_change_property(global_conn, XCB_PROP_MODE_REPLACE, root,
                             atoms[_NET_ACTIVE_WINDOW], WINDOW, 32, 1, &window);
 }
+
+/*
+ * Updates the workarea for each desktop.
+ *
+ * EWMH: Contains a geometry for each desktop. These geometries specify an area
+ * that is completely contained within the viewport. Work area SHOULD be used by
+ * desktop applications to place desktop icons appropriately.
+ *
+ */
+void ewmh_update_workarea() {
+        Workspace *ws;
+        int num_workspaces = 0, count = 0;
+        /* Get the number of workspaces */
+        TAILQ_FOREACH(ws, workspaces, workspaces)
+                num_workspaces++;
+        DLOG("Got %d workspaces\n", num_workspaces);
+        uint8_t *workarea = smalloc(sizeof(Rect) * num_workspaces);
+        TAILQ_FOREACH(ws, workspaces, workspaces) {
+                DLOG("storing %d: %dx%d with %d x %d\n", count, ws->rect.x, ws->rect.y, ws->rect.width, ws->rect.height);
+                memcpy(workarea + (sizeof(Rect) * count++), &(ws->rect), sizeof(Rect));
+        }
+        xcb_change_property(global_conn, XCB_PROP_MODE_REPLACE, root,
+                            atoms[_NET_WORKAREA], CARDINAL, 32,
+                            num_workspaces * (sizeof(Rect) / sizeof(uint32_t)),
+                            workarea);
+        free(workarea);
+        xcb_flush(global_conn);
+}
index 2a5f0037d2a13d22affaf0b5973bc5fa3f83fc10..1e174644f8e5b80bfa522f48edfca5ab0830e8f0 100644 (file)
@@ -250,6 +250,7 @@ int main(int argc, char *argv[], char *env[]) {
         REQUEST_ATOM(WM_CLIENT_LEADER);
         REQUEST_ATOM(_NET_CURRENT_DESKTOP);
         REQUEST_ATOM(_NET_ACTIVE_WINDOW);
+        REQUEST_ATOM(_NET_WORKAREA);
 
         /* TODO: this has to be more beautiful somewhen */
         int major, minor, error;
@@ -414,6 +415,7 @@ int main(int argc, char *argv[], char *env[]) {
         GET_ATOM(WM_CLIENT_LEADER);
         GET_ATOM(_NET_CURRENT_DESKTOP);
         GET_ATOM(_NET_ACTIVE_WINDOW);
+        GET_ATOM(_NET_WORKAREA);
 
         xcb_property_set_handler(&prophs, atoms[_NET_WM_WINDOW_TYPE], UINT_MAX, handle_window_type, NULL);
         /* TODO: In order to comply with EWMH, we have to watch _NET_WM_STRUT_PARTIAL */
index f8bfcd76f06a60af7b72c2d90d7c19d24fb01d2c..7c29e6f7f8d731fd828f6c03e409acecb7be39e9 100644 (file)
@@ -27,6 +27,7 @@
 #include "workspace.h"
 #include "client.h"
 #include "log.h"
+#include "ewmh.h"
 
 /*
  * Returns a pointer to the workspace with the given number (starting at 0),
@@ -59,6 +60,8 @@ Workspace *workspace_get(int number) {
         }
         DLOG("done\n");
 
+        ewmh_update_workarea();
+
         return ws;
 }
 
@@ -262,6 +265,8 @@ void workspace_assign_to(Workspace *ws, i3Screen *screen) {
         /* Copy the dimensions from the virtual screen */
         memcpy(&(ws->rect), &(ws->screen->rect), sizeof(Rect));
 
+        ewmh_update_workarea();
+
         /* Force reconfiguration for each client on that workspace */
         FOR_TABLE(ws)
                 CIRCLEQ_FOREACH(client, &(ws->table[cols][rows]->clients), clients) {