+ ws->focus = TAILQ_PREV(win, ws_win_list, entry);
+ if (ws->focus == NULL)
+ ws->focus = TAILQ_FIRST(&ws->winlist);
+ if (ws->focus == win)
+ ws->focus = NULL;
+
+ TAILQ_REMOVE(&ws->winlist, win, entry);
+
+ TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
+ win->ws = nws;
+
+ /* Try to update the window's workspace property */
+ ws_idx_atom = XInternAtom(display, "_SWM_WS", False);
+ if (ws_idx_atom &&
+ snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
+ DNPRINTF(SWM_D_PROP, "setting property _SWM_WS to %s\n",
+ ws_idx_str);
+ XChangeProperty(display, win->id, ws_idx_atom, XA_STRING, 8,
+ PropModeReplace, ws_idx_str, SWM_PROPLEN);
+ }
+
+ if (count_win(nws, 1) == 1)
+ nws->focus = win;
+ ws->restack = 1;
+ nws->restack = 1;
+
+ stack();
+}
+
+void
+wkill(struct swm_region *r, union arg *args)
+{
+ DNPRINTF(SWM_D_MISC, "wkill %d\n", args->id);
+
+ if(r->ws->focus == NULL)
+ return;
+
+ if (args->id == SWM_ARG_ID_KILLWINDOW)
+ XKillClient(display, r->ws->focus->id);
+ else
+ if (r->ws->focus->can_delete)
+ client_msg(r->ws->focus, adelete);
+}
+
+void
+screenshot(struct swm_region *r, union arg *args)
+{
+ union arg a;
+
+ DNPRINTF(SWM_D_MISC, "screenshot\n");
+
+ if (ss_enabled == 0)
+ return;
+
+ switch (args->id) {
+ case SWM_ARG_ID_SS_ALL:
+ spawn_screenshot[1] = "full";
+ break;
+ case SWM_ARG_ID_SS_WINDOW:
+ spawn_screenshot[1] = "window";
+ break;
+ default:
+ return;
+ }
+ a.argv = spawn_screenshot;
+ spawn(r, &a);
+}
+
+void
+floating_toggle(struct swm_region *r, union arg *args)
+{
+ struct ws_win *win = cur_focus;
+
+ if (win == NULL)
+ return;
+
+ win->floating = !win->floating;
+ win->manual = 0;
+ stack();
+ focus_win(win);
+}
+
+/* key definitions */
+struct key {
+ unsigned int mod;
+ KeySym keysym;
+ void (*func)(struct swm_region *r, union arg *);
+ union arg args;
+} keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_space, cycle_layout, {0} },
+ { MODKEY | ShiftMask, XK_space, stack_config, {.id = SWM_ARG_ID_STACKRESET} },
+ { MODKEY, XK_h, stack_config, {.id = SWM_ARG_ID_MASTERSHRINK} },
+ { MODKEY, XK_l, stack_config, {.id = SWM_ARG_ID_MASTERGROW} },
+ { MODKEY, XK_comma, stack_config, {.id = SWM_ARG_ID_MASTERADD} },
+ { MODKEY, XK_period, stack_config, {.id = SWM_ARG_ID_MASTERDEL} },
+ { MODKEY | ShiftMask, XK_comma, stack_config, {.id = SWM_ARG_ID_STACKINC} },
+ { MODKEY | ShiftMask, XK_period, stack_config, {.id = SWM_ARG_ID_STACKDEC} },
+ { MODKEY, XK_Return, swapwin, {.id = SWM_ARG_ID_SWAPMAIN} },
+ { MODKEY, XK_j, focus, {.id = SWM_ARG_ID_FOCUSNEXT} },
+ { MODKEY, XK_k, focus, {.id = SWM_ARG_ID_FOCUSPREV} },
+ { MODKEY | ShiftMask, XK_j, swapwin, {.id = SWM_ARG_ID_SWAPNEXT} },
+ { MODKEY | ShiftMask, XK_k, swapwin, {.id = SWM_ARG_ID_SWAPPREV} },
+ { MODKEY | ShiftMask, XK_Return, spawnterm, {.argv = spawn_term} },
+ { MODKEY, XK_p, spawnmenu, {.argv = spawn_menu} },
+ { MODKEY | ShiftMask, XK_q, quit, {0} },
+ { MODKEY, XK_q, restart, {0} },
+ { MODKEY, XK_m, focus, {.id = SWM_ARG_ID_FOCUSMAIN} },
+ { MODKEY, XK_1, switchws, {.id = 0} },
+ { MODKEY, XK_2, switchws, {.id = 1} },
+ { MODKEY, XK_3, switchws, {.id = 2} },
+ { MODKEY, XK_4, switchws, {.id = 3} },
+ { MODKEY, XK_5, switchws, {.id = 4} },
+ { MODKEY, XK_6, switchws, {.id = 5} },
+ { MODKEY, XK_7, switchws, {.id = 6} },
+ { MODKEY, XK_8, switchws, {.id = 7} },
+ { MODKEY, XK_9, switchws, {.id = 8} },
+ { MODKEY, XK_0, switchws, {.id = 9} },
+ { MODKEY, XK_Right, cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP} },
+ { MODKEY, XK_Left, cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN} },
+ { MODKEY | ShiftMask, XK_Right, cyclescr, {.id = SWM_ARG_ID_CYCLESC_UP} },
+ { MODKEY | ShiftMask, XK_Left, cyclescr, {.id = SWM_ARG_ID_CYCLESC_DOWN} },
+ { MODKEY | ShiftMask, XK_1, send_to_ws, {.id = 0} },
+ { MODKEY | ShiftMask, XK_2, send_to_ws, {.id = 1} },
+ { MODKEY | ShiftMask, XK_3, send_to_ws, {.id = 2} },
+ { MODKEY | ShiftMask, XK_4, send_to_ws, {.id = 3} },
+ { MODKEY | ShiftMask, XK_5, send_to_ws, {.id = 4} },
+ { MODKEY | ShiftMask, XK_6, send_to_ws, {.id = 5} },
+ { MODKEY | ShiftMask, XK_7, send_to_ws, {.id = 6} },
+ { MODKEY | ShiftMask, XK_8, send_to_ws, {.id = 7} },
+ { MODKEY | ShiftMask, XK_9, send_to_ws, {.id = 8} },
+ { MODKEY | ShiftMask, XK_0, send_to_ws, {.id = 9} },
+ { MODKEY, XK_b, bar_toggle, {0} },
+ { MODKEY, XK_Tab, focus, {.id = SWM_ARG_ID_FOCUSNEXT} },
+ { MODKEY | ShiftMask, XK_Tab, focus, {.id = SWM_ARG_ID_FOCUSPREV} },
+ { MODKEY | ShiftMask, XK_x, wkill, {.id = SWM_ARG_ID_KILLWINDOW} },
+ { MODKEY, XK_x, wkill, {.id = SWM_ARG_ID_DELETEWINDOW} },
+ { MODKEY, XK_s, screenshot, {.id = SWM_ARG_ID_SS_ALL} },
+ { MODKEY | ShiftMask, XK_s, screenshot, {.id = SWM_ARG_ID_SS_WINDOW} },
+ { MODKEY, XK_t, floating_toggle,{0} },
+ { MODKEY | ShiftMask, XK_v, version, {0} },
+ { MODKEY | ShiftMask, XK_Delete, spawn, {.argv = spawn_lock} },
+ { MODKEY | ShiftMask, XK_i, spawn, {.argv = spawn_initscr} },
+};
+
+void
+resize_window(struct ws_win *win, int center)
+{
+ unsigned int mask;
+ XWindowChanges wc;
+ struct swm_region *r;
+
+ r = root_to_region(win->wa.root);
+ bzero(&wc, sizeof wc);
+ mask = CWBorderWidth | CWWidth | CWHeight;
+ wc.border_width = 1;
+ wc.width = win->g.w;
+ wc.height = win->g.h;
+ if (center == SWM_ARG_ID_CENTER) {
+ wc.x = (WIDTH(r) - win->g.w) / 2;
+ wc.y = (HEIGHT(r) - win->g.h) / 2;
+ mask |= CWX | CWY;
+ }
+
+ DNPRINTF(SWM_D_STACK, "resize_window: win %lu x %d y %d w %d h %d\n",
+ win->id, wc.x, wc.y, wc.width, wc.height);
+
+ XConfigureWindow(display, win->id, mask, &wc);
+ config_win(win);
+}
+
+void
+resize(struct ws_win *win, union arg *args)
+{
+ XEvent ev;
+ Time time = 0;