diff --git a/include/data.h b/include/data.h index 12c23554..8c846537 100644 --- a/include/data.h +++ b/include/data.h @@ -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 diff --git a/include/ewmh.h b/include/ewmh.h index 9ed85275..c73c4a45 100644 --- a/include/ewmh.h +++ b/include/ewmh.h @@ -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 diff --git a/include/i3.h b/include/i3.h index abd503f4..ce86e924 100644 --- a/include/i3.h +++ b/include/i3.h @@ -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; diff --git a/include/xcb.h b/include/xcb.h index 883824dc..d4ac33a3 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -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; diff --git a/src/ewmh.c b/src/ewmh.c index 2e6e121b..0d1e8a1b 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -11,11 +11,15 @@ * */ #include +#include +#include #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); +} diff --git a/src/mainx.c b/src/mainx.c index 2a5f0037..1e174644 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -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 */ diff --git a/src/workspace.c b/src/workspace.c index f8bfcd76..7c29e6f7 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -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) {