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 */
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 */
}
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);
}
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();
{ 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)
{
{
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);
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
{
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
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");