From: Michael Stapelberg Date: Sun, 3 Jan 2010 17:36:50 +0000 (+0100) Subject: ewmh: Don’t push workspaces with width=0 and height=0 (Thanks Atsutane, badboy) X-Git-Tag: 3.e~6^2~176 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=715983024d0dbbbd8a4755441c75ff8b7436b8a9;p=i3%2Fi3 ewmh: Don’t push workspaces with width=0 and height=0 (Thanks Atsutane, badboy) Even though i3 cannot know the width/height of some workspaces as long as they are not initialized (say you used workspace 1 and 3, but not workspace 2), some applications require this information. In this case, it was Firefox which intersects the available workareas (see mozilla/gfx/src/gtk/nsScreenGtk.cpp) and did not position some windows correctly when being confronted with zero-width/height workspaces. --- diff --git a/src/ewmh.c b/src/ewmh.c index 0d1e8a1b..6bfa3096 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -58,14 +58,41 @@ void ewmh_update_active_window(xcb_window_t window) { 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) + 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); + 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,