X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=b5e2ffb2ec79aa9747f4dace990741853690a74e;hb=166a233babe7d2adf2d07a8fc2602d9f7ae424c6;hp=4885e6a4c9afc5d6fd58f97b0fa406d2ce0ede9a;hpb=5171f26a513245b291498e8bdeef3ce0aa4d124f;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 4885e6a..b5e2ffb 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -132,6 +132,9 @@ int ignore_enter = 0; unsigned int numlockmask = 0; Display *display; +int cycle_empty = 0; +int cycle_visible = 0; + /* dialog windows */ double dialog_ratio = .6; /* status bar */ @@ -179,7 +182,7 @@ struct ws_win { TAILQ_ENTRY(ws_win) entry; Window id; struct swm_geometry g; - int focus; + int got_focus; int floating; int transient; struct workspace *ws; /* always valid */ @@ -265,6 +268,8 @@ union arg { #define SWM_ARG_ID_MASTERDEL (9) #define SWM_ARG_ID_STACKRESET (10) #define SWM_ARG_ID_STACKINIT (11) +#define SWM_ARG_ID_CYCLEWS_UP (12) +#define SWM_ARG_ID_CYCLEWS_DOWN (13) char **argv; }; @@ -418,6 +423,10 @@ conf_load(char *filename) name_to_color(val); else goto badidx; + else if (!strncmp(var, "cycle_empty", strlen("cycle_empty"))) + cycle_visible = atoi(val); + else if (!strncmp(var, "cycle_visible", strlen("cycle_visible"))) + cycle_visible = atoi(val); else goto bad; break; @@ -564,7 +573,8 @@ bar_refresh(void) TAILQ_FOREACH(r, &screens[i].rl, entry) { wa.border_pixel = screens[i].bar_border; wa.background_pixel = screens[i].bar_color; - XChangeWindowAttributes(display, r->bar_window, CWBackPixel | CWBorderPixel, &wa); + XChangeWindowAttributes(display, r->bar_window, + CWBackPixel | CWBorderPixel, &wa); } bar_update(); } @@ -702,36 +712,43 @@ spawn(struct swm_region *r, union arg *args) } void -unfocus_win(struct ws_win *win) +unfocus_all(void) { - DNPRINTF(SWM_D_FOCUS, "unfocus_win: id: %lu\n", win->id); - if (win->ws->r && win->focus) - XSetWindowBorder(display, win->id, - win->ws->r->s->color_unfocus); - win->focus = 0; - if (win->ws->focus == win) - win->ws->focus = NULL; - if (cur_focus == win) - cur_focus = NULL; -} + struct ws_win *win; + int i, j; + + DNPRINTF(SWM_D_FOCUS, "unfocus_all:\n"); + for (i = 0; i < ScreenCount(display); i++) + for (j = 0; j < SWM_WS_MAX; j++) + TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) { + if (win->ws->r == NULL) + continue; + XSetWindowBorder(display, win->id, + win->ws->r->s->color_unfocus); + win->got_focus = 0; + win->ws->focus = NULL; + cur_focus = NULL; + } +} void focus_win(struct ws_win *win) { - DNPRINTF(SWM_D_FOCUS, "focus_win: id: %lu\n", win->id); + DNPRINTF(SWM_D_FOCUS, "focus_win: id: %lu\n", win ? win->id : 0); - rootclick = 0; + if (win == NULL) + return; + rootclick = 0; + unfocus_all(); win->ws->focus = win; if (win->ws->r != NULL) { - if (cur_focus && cur_focus != win) - unfocus_win(cur_focus); cur_focus = win; - if (!win->focus) + if (!win->got_focus) XSetWindowBorder(display, win->id, win->ws->r->s->color_focus); - win->focus = 1; + win->got_focus = 1; XSetInputFocus(display, win->id, RevertToPointerRoot, CurrentTime); } @@ -784,6 +801,45 @@ switchws(struct swm_region *r, union arg *args) } void +cyclews(struct swm_region *r, union arg *args) +{ + union arg a; + struct swm_screen *s = r->s; + + DNPRINTF(SWM_D_WS, "cyclews id %d " + "in screen %d region %dx%d+%d+%d ws %d\n", args->id, + r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx); + + a.id = r->ws->idx; + + do { + switch (args->id) { + case SWM_ARG_ID_CYCLEWS_UP: + if (a.id < SWM_WS_MAX - 1) + a.id++; + else + a.id = 0; + break; + case SWM_ARG_ID_CYCLEWS_DOWN: + if (a.id > 0) + a.id--; + else + a.id = SWM_WS_MAX - 1; + break; + default: + return; + }; + + if (cycle_empty == 0 && TAILQ_EMPTY(&s->ws[a.id].winlist)) + continue; + if (cycle_visible == 0 && s->ws[a.id].r != NULL) + continue; + + switchws(r, &a); + } while (a.id != r->ws->idx); +} + +void swapwin(struct swm_region *r, union arg *args) { struct ws_win *target; @@ -1280,6 +1336,8 @@ struct key { { 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_1, send_to_ws, {.id = 0} }, { MODKEY | ShiftMask, XK_2, send_to_ws, {.id = 1} }, { MODKEY | ShiftMask, XK_3, send_to_ws, {.id = 2} }, @@ -1295,6 +1353,21 @@ struct key { { MODKEY | ShiftMask, XK_Tab, focus, {.id = SWM_ARG_ID_FOCUSPREV} }, }; +#if 0 +/* mouse */ +enum { client_click, root_click }; +struct button { + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(struct swm_region *r, union arg *); + union arg args; +} buttons[] = { + /* action key mouse button func args */ + { client_click, MODKEY, Button2, NULL, {0} }, +}; +#endif + void updatenumlockmask(void) { @@ -1534,11 +1607,12 @@ destroynotify(XEvent *e) { struct ws_win *win; XDestroyWindowEvent *ev = &e->xdestroywindow; + struct workspace *ws; DNPRINTF(SWM_D_EVENT, "destroynotify: window %lu\n", ev->window); if ((win = find_window(ev->window)) != NULL) { - struct workspace *ws = win->ws; + ws = win->ws; /* find a window to focus */ if (ws->focus == win) ws->focus = TAILQ_PREV(win, ws_win_list, entry); @@ -1546,12 +1620,8 @@ destroynotify(XEvent *e) ws->focus = TAILQ_FIRST(&ws->winlist); if (ws->focus == win) ws->focus = NULL; - if (cur_focus == win) { - if (ws->focus == NULL) - unfocus_win(win); /* XXX focus another ws? */ - else - focus_win(ws->focus); - } + if (cur_focus == win) + focus_win(ws->focus); TAILQ_REMOVE(&ws->winlist, win, entry); set_win_state(win, WithdrawnState); @@ -1565,27 +1635,17 @@ enternotify(XEvent *e) { XCrossingEvent *ev = &e->xcrossing; struct ws_win *win; - int i, j; DNPRINTF(SWM_D_EVENT, "enternotify: window: %lu\n", ev->window); - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && - ev->window != ev->root) - return; if (ignore_enter) { /* eat event(r) to prevent autofocus */ ignore_enter--; return; } - /* brute force for now */ - for (i = 0; i < ScreenCount(display); i++) { - for (j = 0; j < SWM_WS_MAX; j++) { - TAILQ_FOREACH(win, &screens[i].ws[j].winlist , entry) { - if (win->id == ev->window) - focus_win(win); - } - } - } + + if ((win = find_window(ev->window)) != NULL) + focus_win(win); } void @@ -1787,7 +1847,7 @@ setup_screens(void) screens[i].root = RootWindow(display, i); XGetWindowAttributes(display, screens[i].root, &wa); XSelectInput(display, screens[i].root, - ButtonPressMask | wa.your_event_mask); + EnterWindowMask | ButtonPressMask | wa.your_event_mask); /* set default colors */ screens[i].color_focus = name_to_color("red");