X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=dfd3b72b9524a1c7ae178a19e34a5011c2fda06f;hb=51454959fefd05ba265f10340b1ace2aa232e190;hp=50ff0f4f41c6d7d22c0068add897b7cbdab1305e;hpb=4ecc6d965801b07677c69434172ce18e25b2e58e;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 50ff0f4..dfd3b72 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -182,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 */ @@ -220,7 +220,6 @@ struct workspace { struct layout *cur_layout; /* current layout handlers */ struct ws_win *focus; /* may be NULL */ struct swm_region *r; /* may be NULL */ - struct swm_region *prev_r; /* may be NULL */ struct ws_win_list winlist; /* list of windows in ws */ /* stacker state */ @@ -250,7 +249,6 @@ struct swm_screen { }; struct swm_screen *screens; int num_screens; -Window rootclick = 0; struct ws_win *cur_focus = NULL; @@ -655,23 +653,20 @@ root_to_region(Window root) if (screens[i].root == root) break; - if (rootclick != root && /* if root was just clicked in, use cursor */ - cur_focus && cur_focus->ws->r && cur_focus->s == &screens[i]) - r = cur_focus->ws->r; - else { - if (XQueryPointer(display, screens[i].root, - &rr, &cr, &x, &y, &wx, &wy, &mask) == False) { - r = TAILQ_FIRST(&screens[i].rl); - } else { - TAILQ_FOREACH(r, &screens[i].rl, entry) { - if (x > X(r) && x < X(r) + WIDTH(r) && - y > Y(r) && y < Y(r) + HEIGHT(r)) - break; - } - - if (r == NULL) - r = TAILQ_FIRST(&screens[i].rl); + if (XQueryPointer(display, screens[i].root, + &rr, &cr, &x, &y, &wx, &wy, &mask) == False) { + /* if we can't query the pointer, grab the first region */ + r = TAILQ_FIRST(&screens[i].rl); + } else { + /* otherwise, choose a region based on pointer location */ + TAILQ_FOREACH(r, &screens[i].rl, entry) { + if (x > X(r) && x < X(r) + WIDTH(r) && + y > Y(r) && y < Y(r) + HEIGHT(r)) + break; } + + if (r == NULL) + r = TAILQ_FIRST(&screens[i].rl); } return (r); } @@ -713,36 +708,42 @@ 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; + 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); } @@ -769,33 +770,26 @@ switchws(struct swm_region *r, union arg *args) other_r = new_ws->r; if (!other_r) { - /* - * If the other workspace is hidden and the workspace was - * previously mapped here, just swap switch windows. - * map new window first to prevent ugly blinking - */ - if (new_ws->restack == 0 && new_ws->prev_r == this_r) { - TAILQ_FOREACH(win, &new_ws->winlist, entry) - XMapRaised(display, win->id); + /* if the other workspace is hidden, switch windows */ + /* map new window first to prevent ugly blinking */ + TAILQ_FOREACH(win, &new_ws->winlist, entry) + XMapRaised(display, win->id); + + TAILQ_FOREACH(win, &old_ws->winlist, entry) + XUnmapWindow(display, win->id); - TAILQ_FOREACH(win, &old_ws->winlist, entry) - XUnmapWindow(display, win->id); - } - old_ws->prev_r = old_ws->r; old_ws->r = NULL; + old_ws->restack = 1; } else { other_r->ws = old_ws; old_ws->r = other_r; } this_r->ws = new_ws; - new_ws->prev_r = new_ws->r; new_ws->r = this_r; ignore_enter = 1; /* set focus */ - if (!new_ws->focus) - new_ws->focus = TAILQ_FIRST(&new_ws->winlist); - if (new_ws->focus ) + if (new_ws->focus) focus_win(new_ws->focus); stack(); bar_update(); @@ -1354,6 +1348,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) { @@ -1433,10 +1442,8 @@ buttonpress(XEvent *e) DNPRINTF(SWM_D_EVENT, "buttonpress: window: %lu\n", ev->window); - if (ev->window == ev->root) { - rootclick = ev->root; + if (ev->window == ev->root) return; - } if (ev->window == cur_focus->id) return; #ifdef SWM_CLICKTOFOCUS @@ -1593,11 +1600,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); @@ -1605,22 +1613,14 @@ 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); free(win); - - if (ws->r == NULL) - ws->restack = 1; - else - stack(); } + stack(); } void @@ -1628,27 +1628,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 @@ -1848,9 +1838,6 @@ setup_screens(void) screens[i].idx = i; TAILQ_INIT(&screens[i].rl); screens[i].root = RootWindow(display, i); - XGetWindowAttributes(display, screens[i].root, &wa); - XSelectInput(display, screens[i].root, - ButtonPressMask | wa.your_event_mask); /* set default colors */ screens[i].color_focus = name_to_color("red");