int bar_font_legacy = 1;
char *bar_fonts;
XftColor bar_font_color;
+XftColor search_font_color;
struct passwd *pwd;
char *startup_exception;
unsigned int nr_exceptions = 0;
#define SWM_Q_NOFOCUSONMAP (1<<6) /* Don't focus on window when mapped. */
#define SWM_Q_FOCUSONMAP_SINGLE (1<<7) /* Only focus if single win of type. */
#define SWM_Q_OBEYAPPFOCUSREQ (1<<8) /* Focus when applications ask. */
+#define SWM_Q_IGNOREPID (1<<9) /* Ignore PID when determining ws. */
};
TAILQ_HEAD(quirk_list, quirk);
struct quirk_list quirks = TAILQ_HEAD_INITIALIZER(quirks);
DefaultColormap(display, r->s->idx), &color, &bar_font_color))
warn("Xft error: unable to allocate color.");
+ PIXEL_TO_XRENDERCOLOR(r->s->c[SWM_S_COLOR_BAR].pixel, color);
+
+ if (!XftColorAllocValue(display, DefaultVisual(display, r->s->idx),
+ DefaultColormap(display, r->s->idx), &color, &search_font_color))
+ warn("Xft error: unable to allocate color.");
+
bar_height = bar_font->height + 2 * bar_border_width;
if (bar_height < 1)
XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL
| XCB_CW_EVENT_MASK, wa);
+ /* Stack bar window above region window to start. */
+ wa[0] = r->id;
+ wa[1] = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window(conn, r->bar->id, XCB_CONFIG_WINDOW_SIBLING |
+ XCB_CONFIG_WINDOW_STACK_MODE, wa);
+
r->bar->buffer = xcb_generate_id(conn);
xcb_create_pixmap(conn, screen->root_depth, r->bar->buffer, r->bar->id,
WIDTH(r->bar), HEIGHT(r->bar));
void
focus_win(struct ws_win *win)
{
- struct ws_win *cfw = NULL, *parent = NULL, *w;
+ struct ws_win *cfw = NULL, *parent = NULL, *w, *tmpw;
struct workspace *ws;
xcb_get_input_focus_reply_t *gifr;
map_window(parent);
/* Map siblings next. */
- TAILQ_FOREACH(w, &ws->winlist, entry)
+ TAILQ_FOREACH_SAFE(w, &ws->stack, stack_entry,
+ tmpw)
if (w != win && !ICONIC(w) &&
- win->transient == parent->id)
+ w->transient == parent->id) {
+ raise_window(w);
map_window(w);
+ }
}
/* Map focused window. */
raise_window(win);
map_window(win);
- /* Finally, map children of focus window. */
- TAILQ_FOREACH(w, &ws->winlist, entry)
- if (w->transient == win->id && !ICONIC(w))
+ /* Stack any children of focus window. */
+ TAILQ_FOREACH_SAFE(w, &ws->stack, stack_entry, tmpw)
+ if (w->transient == win->id && !ICONIC(w)) {
+ raise_window(w);
map_window(w);
+ }
} else if (tile_gap < 0 && !ABOVE(win)) {
/*
* Windows overlap in the layout.
if (!(r && r->ws))
goto out;
- DNPRINTF(SWM_D_FOCUS, "focus: id: %d\n", args->id);
-
cur_focus = r->ws->focus;
ws = r->ws;
wl = &ws->winlist;
+ DNPRINTF(SWM_D_FOCUS, "focus: id: %d, cur_focus: %#x\n", args->id,
+ WINID(cur_focus));
+
/* Make sure an uniconified window has focus, if one exists. */
if (cur_focus == NULL) {
cur_focus = TAILQ_FIRST(wl);
while (cur_focus != NULL && ICONIC(cur_focus))
cur_focus = TAILQ_NEXT(cur_focus, entry);
+
+ DNPRINTF(SWM_D_FOCUS, "focus: new cur_focus: %#x\n",
+ WINID(cur_focus));
}
switch (args->id) {
winfocus = TAILQ_LAST(wl, ws_win_list);
if (winfocus == cur_focus)
break;
- } while (winfocus != NULL &&
- (ICONIC(winfocus) || winfocus->id == cur_focus->transient));
+ } while (winfocus && (ICONIC(winfocus) ||
+ winfocus->id == cur_focus->transient ||
+ (cur_focus->transient != XCB_WINDOW_NONE &&
+ winfocus->transient == cur_focus->transient)));
break;
case SWM_ARG_ID_FOCUSNEXT:
if (cur_focus == NULL)
winfocus = TAILQ_FIRST(wl);
if (winfocus == cur_focus)
break;
- } while (winfocus != NULL &&
- (ICONIC(winfocus) || winfocus->id == cur_focus->transient));
+ } while (winfocus && (ICONIC(winfocus) ||
+ winfocus->id == cur_focus->transient ||
+ (cur_focus->transient != XCB_WINDOW_NONE &&
+ winfocus->transient == cur_focus->transient)));
break;
case SWM_ARG_ID_FOCUSMAIN:
if (cur_focus == NULL)
DNPRINTF(SWM_D_MISC, "update_floater: win %#x\n", win->id);
+ win->bordered = 1;
+
if (FULLSCREEN(win)) {
/* _NET_WM_FULLSCREEN: fullscreen without border. */
if (!win->g_floatvalid)
win->g = r->g;
if (bar_enabled && ws->bar_enabled) {
- win->bordered = 1;
if (!bar_at_bottom)
Y(win) += bar_height;
HEIGHT(win) -= bar_height;
} else if (disable_border) {
win->bordered = 0;
- } else {
- win->bordered = 1;
}
if (win->bordered) {
max_stack(struct workspace *ws, struct swm_geometry *g)
{
struct swm_geometry gg = *g;
- struct ws_win *w, *win = NULL, *parent = NULL;
+ struct ws_win *w, *win = NULL, *parent = NULL, *tmpw;
int winno;
DNPRINTF(SWM_D_STACK, "max_stack: workspace: %d\n", ws->idx);
}
}
- if (TRANS(win)) {
- parent = find_window(win->transient);
+ /* If transient, stack parent and its children. */
+ if (TRANS(win) && (parent = find_window(win->transient))) {
raise_window(parent);
- TAILQ_FOREACH(w, &ws->stack, stack_entry)
+ TAILQ_FOREACH_SAFE(w, &ws->stack, stack_entry, tmpw)
if (w->transient == parent->id)
raise_window(w);
}
+ /* Make sure focus window is on top. */
raise_window(win);
- TAILQ_FOREACH(w, &ws->stack, stack_entry)
+ /* Stack any children of focus window. */
+ TAILQ_FOREACH_SAFE(w, &ws->stack, stack_entry, tmpw)
if (w->transient == win->id)
raise_window(w);
struct ws_win *win = NULL;
struct search_window *sw = NULL;
xcb_window_t w;
- uint32_t wa[2];
+ uint32_t wa[3];
+ xcb_screen_t *screen;
int i, width, height;
char s[8];
FILE *lfile;
if ((lfile = fdopen(select_list_pipe[1], "w")) == NULL)
return;
+ if ((screen = get_screen(r->s->idx)) == NULL)
+ errx(1, "ERROR: can't get screen %d.", r->s->idx);
+
TAILQ_INIT(&search_wl);
i = 1;
w = xcb_generate_id(conn);
wa[0] = r->s->c[SWM_S_COLOR_FOCUS].pixel;
wa[1] = r->s->c[SWM_S_COLOR_UNFOCUS].pixel;
+ wa[2] = screen->default_colormap;
if (bar_font_legacy) {
XmbTextExtents(bar_fs, s, len, &l_ibox, &l_lbox);
height = bar_font->height + 4;
}
- xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, win->id, 0, 0,
+ xcb_create_window(conn, screen->root_depth, w, win->id, 0, 0,
width, height, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT,
- XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL |
- XCB_CW_BORDER_PIXEL, wa);
+ screen->root_visual, XCB_CW_BACK_PIXEL |
+ XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP, wa);
xcb_map_window(conn, w);
DefaultVisual(display, r->s->idx),
DefaultColormap(display, r->s->idx));
- XftDrawStringUtf8(draw, &bar_font_color, bar_font, 2,
+ XftDrawStringUtf8(draw, &search_font_color, bar_font, 2,
(HEIGHT(r->bar) + bar_font->height) / 2 -
bar_font->descent, (FcChar8 *)s, len);
"NOFOCUSONMAP",
"FOCUSONMAP_SINGLE",
"OBEYAPPFOCUSREQ",
+ "IGNOREPID",
};
/* SWM_Q_WS: retain '|' for back compat for now (2009-08-11) */
ws[ws_id].cur_layout->l_config(&ws[ws_id],
mg >= 0 ? SWM_ARG_ID_MASTERGROW :
SWM_ARG_ID_MASTERSHRINK);
- stack();
}
/* master add */
for (x = 0; x < abs(ma); x++) {
ws[ws_id].cur_layout->l_config(&ws[ws_id],
ma >= 0 ? SWM_ARG_ID_MASTERADD :
SWM_ARG_ID_MASTERDEL);
- stack();
}
/* stack inc */
for (x = 0; x < abs(si); x++) {
ws[ws_id].cur_layout->l_config(&ws[ws_id],
si >= 0 ? SWM_ARG_ID_STACKINC :
SWM_ARG_ID_STACKDEC);
- stack();
}
/* Apply flip */
if (f) {
ws[ws_id].cur_layout->l_config(&ws[ws_id],
SWM_ARG_ID_FLIPLAYOUT);
- stack();
}
}
- focus_flush();
-
return (0);
}
/* Get WM_PROTOCOLS. */
get_wm_protocols(win);
- /* Figure out which workspace the window belongs to. */
- if ((p = find_pid(window_get_pid(win->id))) != NULL) {
- win->ws = &r->s->ws[p->ws];
- TAILQ_REMOVE(&pidlist, p, entry);
- free(p);
- p = NULL;
- } else if ((ws_idx = get_ws_idx(win->id)) != -1 &&
- !TRANS(win)) {
- /* _SWM_WS is set; use that. */
- win->ws = &r->s->ws[ws_idx];
- } else if (trans && (ww = find_window(trans)) != NULL) {
- /* Launch transients in the same ws as parent. */
- win->ws = ww->ws;
- } else {
- win->ws = r->ws;
- }
-
- /* Set the _NET_WM_DESKTOP atom. */
- DNPRINTF(SWM_D_PROP, "manage_window: set _NET_WM_DESKTOP: %d\n",
- win->ws->idx);
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
- ewmh[_NET_WM_DESKTOP].atom, XCB_ATOM_CARDINAL, 32, 1, &win->ws->idx);
-
- /* WS must already be set for this to work. */
- store_float_geom(win);
-
/* Set initial quirks based on EWMH. */
ewmh_autoquirk(win);
fake_keypress(win, XK_KP_Add, XCB_MOD_MASK_SHIFT);
}
+ /* Figure out which workspace the window belongs to. */
+ if (!(win->quirks & SWM_Q_IGNOREPID) &&
+ (p = find_pid(window_get_pid(win->id))) != NULL) {
+ win->ws = &r->s->ws[p->ws];
+ TAILQ_REMOVE(&pidlist, p, entry);
+ free(p);
+ p = NULL;
+ } else if ((ws_idx = get_ws_idx(win->id)) != -1 &&
+ !TRANS(win)) {
+ /* _SWM_WS is set; use that. */
+ win->ws = &r->s->ws[ws_idx];
+ } else if (trans && (ww = find_window(trans)) != NULL) {
+ /* Launch transients in the same ws as parent. */
+ win->ws = ww->ws;
+ } else {
+ win->ws = r->ws;
+ }
+
+ /* Set the _NET_WM_DESKTOP atom. */
+ DNPRINTF(SWM_D_PROP, "manage_window: set _NET_WM_DESKTOP: %d\n",
+ win->ws->idx);
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
+ ewmh[_NET_WM_DESKTOP].atom, XCB_ATOM_CARDINAL, 32, 1, &win->ws->idx);
+
+ /* WS must already be set for this to work. */
+ store_float_geom(win);
+
/* Make sure window is positioned inside its region, if its active. */
if (win->ws->r) {
region_containment(win, r, SWM_CW_ALLSIDES |
return;
}
} else {
+ if (e->mode == XCB_NOTIFY_MODE_NORMAL &&
+ e->detail == XCB_NOTIFY_DETAIL_INFERIOR) {
+ DNPRINTF(SWM_D_EVENT, "enternotify: entering from "
+ "inferior; ignoring\n");
+ return;
+ }
+
focus_win(get_focus_magic(win));
}
if (screens[i].bar_gc != XCB_NONE)
xcb_free_gc(conn, screens[i].bar_gc);
- if (!bar_font_legacy)
+ if (!bar_font_legacy) {
XftColorFree(display, DefaultVisual(display, i),
DefaultColormap(display, i), &bar_font_color);
+ XftColorFree(display, DefaultVisual(display, i),
+ DefaultColormap(display, i), &search_font_color);
+ }
}
if (bar_font_legacy)