+ ws = win->ws;
+
+ DNPRINTF(SWM_D_EVENT, "lower_window: win %#x\n", win->id);
+
+ TAILQ_FOREACH(target, &ws->stack, stack_entry) {
+ if (target == win || ICONIC(target))
+ continue;
+ if (ws->cur_layout == &layouts[SWM_MAX_STACK])
+ break;
+ if (TRANS(win)) {
+ if (win->transient == target->transient)
+ continue;
+ if (win->transient == target->id)
+ break;
+ }
+ if (FULLSCREEN(target))
+ continue;
+ if (FULLSCREEN(win))
+ break;
+ if (MAXIMIZED(target))
+ continue;
+ if (MAXIMIZED(win))
+ break;
+ if (ABOVE(target) || TRANS(target))
+ continue;
+ if (ABOVE(win) || TRANS(win))
+ break;
+ }
+
+ /* Change stack position. */
+ TAILQ_REMOVE(&ws->stack, win, stack_entry);
+ if (target)
+ TAILQ_INSERT_BEFORE(target, win, stack_entry);
+ else
+ TAILQ_INSERT_TAIL(&ws->stack, win, stack_entry);
+
+ update_win_stacking(win);
+
+#ifdef SWM_DEBUG
+ if (swm_debug & SWM_D_STACK) {
+ DPRINTF("=== stacking order (top down) === \n");
+ TAILQ_FOREACH(target, &ws->stack, stack_entry) {
+ DPRINTF("win %#x, fs: %s, maximized: %s, above: %s, "
+ "iconic: %s\n", target->id, YESNO(FULLSCREEN(target)),
+ YESNO(MAXIMIZED(target)), YESNO(ABOVE(target)),
+ YESNO(ICONIC(target)));
+ }
+ }
+#endif
+ DNPRINTF(SWM_D_EVENT, "lower_window: done\n");
+}
+
+void
+raise_window(struct ws_win *win)
+{
+ struct ws_win *target = NULL;
+ struct workspace *ws;
+
+ if (win == NULL)
+ return;
+ ws = win->ws;
+
+ DNPRINTF(SWM_D_EVENT, "raise_window: win %#x\n", win->id);
+
+ TAILQ_FOREACH(target, &ws->stack, stack_entry) {
+ if (target == win || ICONIC(target))
+ continue;
+ if (ws->cur_layout == &layouts[SWM_MAX_STACK])
+ break;
+ if (TRANS(win) && (win->transient == target->transient ||
+ win->transient == target->id))
+ break;
+ if (FULLSCREEN(win))
+ break;
+ if (FULLSCREEN(target))
+ continue;
+ if (MAXIMIZED(win))
+ break;
+ if (MAXIMIZED(target))
+ continue;
+ if (ABOVE(win) || TRANS(win) ||
+ (win->ws->focus == win && ws->always_raise))
+ break;
+ if (!ABOVE(target) && !TRANS(target))
+ break;
+ }
+
+ TAILQ_REMOVE(&ws->stack, win, stack_entry);
+ if (target)
+ TAILQ_INSERT_BEFORE(target, win, stack_entry);
+ else
+ TAILQ_INSERT_TAIL(&ws->stack, win, stack_entry);
+
+ update_win_stacking(win);
+
+#ifdef SWM_DEBUG
+ if (swm_debug & SWM_D_STACK) {
+ DPRINTF("=== stacking order (top down) === \n");
+ TAILQ_FOREACH(target, &ws->stack, stack_entry) {
+ DPRINTF("win %#x, fs: %s, maximized: %s, above: %s, "
+ "iconic: %s\n", target->id, YESNO(FULLSCREEN(target)),
+ YESNO(MAXIMIZED(target)), YESNO(ABOVE(target)),
+ YESNO(ICONIC(target)));
+ }
+ }
+#endif
+ DNPRINTF(SWM_D_EVENT, "raise_window: done\n");
+}
+
+void
+update_win_stacking(struct ws_win *win)
+{
+ struct ws_win *sibling;
+ struct swm_region *r;
+ uint32_t val[2];
+
+ if (win == NULL || (r = win->ws->r) == NULL)
+ return;
+
+ sibling = TAILQ_NEXT(win, stack_entry);
+ if (sibling != NULL && (FLOATING(win) == FLOATING(sibling) ||
+ (win->ws->always_raise && win->ws->focus == win)))
+ val[0] = sibling->id;
+ else if (FLOATING(win) || (win->ws->always_raise &&
+ win->ws->focus == win))
+ val[0] = r->bar->id;
+ else
+ val[0] = r->id;
+
+ DNPRINTF(SWM_D_EVENT, "update_win_stacking: %#x, sibling %#x\n",
+ win->id, val[0]);
+
+ val[1] = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window(conn, win->id, XCB_CONFIG_WINDOW_SIBLING |
+ XCB_CONFIG_WINDOW_STACK_MODE, val);
+}
+
+void
+map_window(struct ws_win *win)
+{
+ if (win == NULL)
+ return;