X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fewmh.c;h=6bfa3096ef25c777bf5f8b6d22961d8768022037;hb=b93413ca49c59638e3d0c4854665ca4907a8a15c;hp=2e6e121bcd840bca195d4af9ddd29aea0822cb9d;hpb=e7e9e8e49d3df01c3f534a17e810242b9621058c;p=i3%2Fi3 diff --git a/src/ewmh.c b/src/ewmh.c index 2e6e121b..6bfa3096 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,58 @@ 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; + Rect last_rect = {0, 0, 0, 0}; + + /* Get the number of workspaces */ + TAILQ_FOREACH(ws, workspaces, workspaces) { + /* Check if we need to initialize last_rect. The case that the + * first workspace is all-zero may happen when the user + * assigned workspace 2 for his first screen, for example. Thus + * we need an initialized last_rect in the very first run of + * the following loop. */ + if (last_rect.width == 0 && last_rect.height == 0 && + ws->rect.width != 0 && ws->rect.height != 0) { + memcpy(&last_rect, &(ws->rect), sizeof(Rect)); + } + 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); + /* If a workspace is not yet initialized and thus its + * dimensions are zero, we will instead put the dimensions + * of the last workspace in the list. For example firefox + * intersects all workspaces and does not cope so well with + * an all-zero workspace. */ + if (ws->rect.width == 0 || ws->rect.height == 0) { + DLOG("re-using last_rect (%dx%d, %d, %d)\n", + last_rect.x, last_rect.y, last_rect.width, + last_rect.height); + memcpy(workarea + (sizeof(Rect) * count++), &last_rect, sizeof(Rect)); + continue; + } + memcpy(workarea + (sizeof(Rect) * count++), &(ws->rect), sizeof(Rect)); + memcpy(&last_rect, &(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); +}