* DEALINGS IN THE SOFTWARE.
*/
-static const char *cvstag = "$scrotwm$";
+static const char *cvstag =
+ "$scrotwm$";
#define SWM_VERSION "0.9.30"
XWindowAttributes wa;
XSizeHints sh;
XClassHint ch;
+ XWMHints *hints;
};
TAILQ_HEAD(ws_win_list, ws_win);
{ vertical_stack, vertical_config, 0, "[|]" },
{ horizontal_stack, horizontal_config, 0, "[-]" },
{ max_stack, NULL,
- SWM_L_MAPONFOCUS | SWM_L_FOCUSPREV, "[ ]"},
- { NULL, NULL, 0, NULL },
+ SWM_L_MAPONFOCUS | SWM_L_FOCUSPREV, "[ ]" },
+ { NULL, NULL, 0, NULL },
};
/* position of max_stack mode in the layouts array */
#define SWM_Q_ANYWHERE (1<<2) /* don't position this window */
#define SWM_Q_XTERM_FONTADJ (1<<3) /* adjust xterm fonts when resizing */
#define SWM_Q_FULLSCREEN (1<<4) /* remove border */
+#define SWM_Q_FOCUSPREV (1<<5) /* focus on caller */
};
int quirks_size = 0, quirks_length = 0;
struct quirk *quirks = NULL;
/* Report supported atoms */
XDeleteProperty(display, screens[i].root, sup_list);
for (j = 0; j < LENGTH(ewmh); j++)
- XChangeProperty(display, screens[i].root, sup_list, XA_ATOM, 32,
+ XChangeProperty(display, screens[i].root,
+ sup_list, XA_ATOM, 32,
PropModeAppend, (unsigned char *)&ewmh[j].atom,1);
}
}
win->manual = (win->ewmh_flags & SWM_F_MANUAL) != 0;
if (state == ewmh[_NET_WM_STATE_FULLSCREEN].atom)
if (changed)
- if (!ewmh_set_win_fullscreen(win, win->ewmh_flags & EWMH_F_FULLSCREEN))
+ if (!ewmh_set_win_fullscreen(win,
+ win->ewmh_flags & EWMH_F_FULLSCREEN))
win->ewmh_flags = orig_flags; /* revert */
XDeleteProperty(display, win->id, ewmh[_NET_WM_STATE].atom);
if (win->manual)
win->ewmh_flags |= SWM_F_MANUAL;
- success = get_property(win->id, ewmh[_NET_WM_STATE].atom, (~0L), XA_ATOM,
- &n, (unsigned char **)&states);
+ success = get_property(win->id, ewmh[_NET_WM_STATE].atom,
+ (~0L), XA_ATOM, &n, (unsigned char **)&states);
if (!success)
return;
y < 0 || y > DisplayHeight(display, sidx) ||
w + x > DisplayWidth(display, sidx) ||
h + y > DisplayHeight(display, sidx)) {
- fprintf(stderr, "ignoring region %ux%u+%u+%u - not within screen boundaries "
+ fprintf(stderr, "ignoring region %ux%u+%u+%u "
+ "- not within screen boundaries "
"(%ux%u)\n", w, h, x, y,
DisplayWidth(display, sidx), DisplayHeight(display, sidx));
return;
if (bar_fs == NULL)
errx(1, "couldn't create font structure");
- bar_height = bar_fs->ascent + bar_fs->descent + 1 + 2 * bar_border_width;
+ bar_height = bar_fs->ascent + bar_fs->descent + 1 +
+ 2 * bar_border_width;
x = X(r);
y = bar_at_bottom ? (Y(r) + HEIGHT(r) - bar_height) : Y(r);
r->bar_window = XCreateSimpleWindow(display,
- r->s->root, x, y, WIDTH(r) - 2 * bar_border_width, bar_height - 2 * bar_border_width,
+ r->s->root, x, y, WIDTH(r) - 2 * bar_border_width,
+ bar_height - 2 * bar_border_width,
bar_border_width, r->s->c[SWM_S_COLOR_BAR_BORDER].color,
r->s->c[SWM_S_COLOR_BAR].color);
bar_gc = XCreateGC(display, r->bar_window, 0, &bar_gcv);
return;
if (ev == NULL) {
- DNPRINTF(SWM_D_MISC, "config_win: win %lu x %d y %d w %d h %d\n",
+ DNPRINTF(SWM_D_MISC,
+ "config_win: win %lu x %d y %d w %d h %d\n",
win->id, win->g.x, win->g.y, win->g.w, win->g.h);
ce.type = ConfigureNotify;
ce.above = None;
ce.override_redirect = False;
} else {
- DNPRINTF(SWM_D_MISC, "config_win: ev win %lu x %d y %d w %d h %d\n",
+ DNPRINTF(SWM_D_MISC,
+ "config_win: ev win %lu x %d y %d w %d h %d\n",
ev->window, ev->x, ev->y, ev->width, ev->height);
ce.type = ConfigureNotify;
ce.display = ev->display;
int i, x, foundit = 0;
if (testwin == NULL)
- return(0);
+ return (0);
for (i = 0, foundit = 0; i < ScreenCount(display); i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
XGetInputFocus(display, &cur_focus, &rr);
if ((cfw = find_window(cur_focus)) != NULL)
unfocus_win(cfw);
+ else {
+ /* use larger hammer since the window was killed somehow */
+ TAILQ_FOREACH(cfw, &win->ws->winlist, entry)
+ XSetWindowBorder(display, cfw->id,
+ cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);
+ }
win->ws->focus = win;
this_r->ws = new_ws;
new_ws->r = this_r;
+ /* this is needed so that we can click on a window after a restart */
+ unfocus_all();
+
stack();
a.id = SWM_ARG_ID_FOCUSCUR;
focus(new_ws->r, &a);
source = source->ws->focus_prev;
else
return;
- }
+ }
if (target == NULL || source == NULL)
return;
source->ws->focus_prev = target;
}
/* if in max_stack try harder */
- if (ws->cur_layout->flags & SWM_L_FOCUSPREV) {
+ if ((win->quirks & SWM_Q_FOCUSPREV) ||
+ (ws->cur_layout->flags & SWM_L_FOCUSPREV)) {
if (cur_focus != ws->focus_prev)
winfocus = ws->focus_prev;
else if (cur_focus != ws->focus)
ws->cur_layout = &layouts[0];
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
a.id = SWM_ARG_ID_FOCUSCUR;
focus(r, &a);
bar_update();
* floaters and transients are auto-centred unless moved
* or resized
*/
- win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2 - wc.border_width;
- win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2 - wc.border_width;
+ win->g.x = r->g.x + (WIDTH(r) - win->g.w) /
+ 2 - wc.border_width;
+ win->g.y = r->g.y + (HEIGHT(r) - win->g.h) /
+ 2 - wc.border_width;
}
/* win can be outside r if new r smaller than old r */
return;
TAILQ_FOREACH(win, &ws->winlist, entry)
- if (win->transient == 0 && win->floating == 0 && win->iconic == 0)
+ if (win->transient == 0 && win->floating == 0
+ && win->iconic == 0)
break;
if (win == NULL)
} else {
msize = -2;
colno = split = winno / stacks;
- win_g.w = ((r_g.w - (stacks * 2 * border_width) + 2 * border_width) / stacks);
+ win_g.w = ((r_g.w - (stacks * 2 * border_width) +
+ 2 * border_width) / stacks);
}
hrh = r_g.h / colno;
extra = r_g.h - (colno * hrh);
win_g.x = r_g.x;
else
win_g.x += win_g.w + 2 * border_width;
- win_g.w = (r_g.w - msize - (stacks * 2 * border_width)) / stacks;
+ win_g.w = (r_g.w - msize -
+ (stacks * 2 * border_width)) / stacks;
if (s == 1)
- win_g.w += (r_g.w - msize - (stacks * 2 * border_width)) %
- stacks;
+ win_g.w += (r_g.w - msize -
+ (stacks * 2 * border_width)) % stacks;
s--;
j = 0;
}
unmap_window(r->ws->focus);
update_iconic(r->ws->focus, 1);
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
r->ws->focus = NULL;
a.id = SWM_ARG_ID_FOCUSCUR;
focus(r, &a);
_NET_WM_STATE_TOGGLE);
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
if (win == win->ws->focus) {
a.id = SWM_ARG_ID_FOCUSCUR;
Time time = 0;
struct swm_region *r = win->ws->r;
int relx, rely;
- union arg a;
DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %lu\n",
win->manual = 1;
ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom,
_NET_WM_STATE_ADD);
- /* raise the window = move to last in window list */
- a.id = SWM_ARG_ID_MOVELAST;
- swapwin(r, &a);
+
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
do {
XMaskEvent(display, MOUSEMASK | ExposureMask |
SubstructureRedirectMask, &ev);
- switch(ev.type) {
+ switch (ev.type) {
case ConfigureRequest:
case Expose:
case MapRequest:
XEvent ev;
Time time = 0;
struct swm_region *r = win->ws->r;
- union arg a;
DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %lu\n",
win->id, win->floating, win->transient);
win->manual = 1;
if (win->floating == 0 && !win->transient) {
- win->floating = 1;
ewmh_update_win_state(win, ewmh[_NET_WM_STATE_ABOVE].atom,
_NET_WM_STATE_ADD);
}
ewmh_update_win_state(win, ewmh[_SWM_WM_STATE_MANUAL].atom,
_NET_WM_STATE_ADD);
- /* raise the window = move to last in window list */
- a.id = SWM_ARG_ID_MOVELAST;
- swapwin(r, &a);
stack();
if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
do {
XMaskEvent(display, MOUSEMASK | ExposureMask |
SubstructureRedirectMask, &ev);
- switch(ev.type) {
+ switch (ev.type) {
case ConfigureRequest:
case Expose:
case MapRequest:
}
void
-setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name)
+setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid,
+ char *spawn_name)
{
int i, j;
DNPRINTF(SWM_D_KEY, "setkeybinding: enter %s [%s]\n",
for (i = 0; i < 8; i++)
for (j = 0; j < modmap->max_keypermod; j++)
if (modmap->modifiermap[i * modmap->max_keypermod + j]
- == XKeysymToKeycode(display, XK_Num_Lock))
+ == XKeysymToKeycode(display, XK_Num_Lock))
numlockmask = (1 << i);
XFreeModifiermap(modmap);
"ANYWHERE",
"XTERM_FONTADJ",
"FULLSCREEN",
+ "FOCUSPREV",
};
/* SWM_Q_WS: retain '|' for back compat for now (2009-08-11) */
cp += (long)strspn(cp, SWM_Q_WS);
for (i = 0; i < LENGTH(quirkname); i++) {
if (!strncasecmp(name, quirkname[i], SWM_QUIRK_LEN)) {
- DNPRINTF(SWM_D_QUIRK, "parsequirks: %s\n", name);
+ DNPRINTF(SWM_D_QUIRK,
+ "parsequirks: %s\n", name);
if (i == 0) {
*quirk = 0;
return (0);
} else if (quirks_length == quirks_size) {
quirks_size *= 2;
DNPRINTF(SWM_D_QUIRK, "setquirk: grow list %d\n", quirks_size);
- quirks = realloc(quirks, (size_t)quirks_size * sizeof(struct quirk));
+ quirks = realloc(quirks,
+ (size_t)quirks_size * sizeof(struct quirk));
if (!quirks) {
fprintf(stderr, "setquirk: realloc failed\n");
perror(" failed");
void
setup_quirks(void)
{
- setquirk("MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN);
+ setquirk("MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV);
setquirk("OpenOffice.org 3.2", "VCLSalFrame", SWM_Q_FLOAT);
setquirk("Firefox-bin", "firefox-bin", SWM_Q_TRANSSZ);
setquirk("Firefox", "Dialog", SWM_Q_FLOAT);
/* conf file stuff */
#define SWM_CONF_FILE "scrotwm.conf"
-enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_BAR_BORDER_WIDTH, SWM_S_STACK_ENABLED,
- SWM_S_CLOCK_ENABLED, SWM_S_CLOCK_FORMAT, SWM_S_CYCLE_EMPTY,
- SWM_S_CYCLE_VISIBLE, SWM_S_SS_ENABLED, SWM_S_TERM_WIDTH,
- SWM_S_TITLE_CLASS_ENABLED, SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED,
- SWM_S_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, SWM_S_BAR_FONT,
- SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_SS_APP, SWM_S_DIALOG_RATIO,
- SWM_S_BAR_AT_BOTTOM
+enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_BAR_BORDER_WIDTH,
+ SWM_S_STACK_ENABLED, SWM_S_CLOCK_ENABLED, SWM_S_CLOCK_FORMAT,
+ SWM_S_CYCLE_EMPTY, SWM_S_CYCLE_VISIBLE, SWM_S_SS_ENABLED,
+ SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED,
+ SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED,
+ SWM_S_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH,
+ SWM_S_BAR_FONT, SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM,
+ SWM_S_SS_APP, SWM_S_DIALOG_RATIO, SWM_S_BAR_AT_BOTTOM
};
int
}
void
-set_child_transient(struct ws_win *win)
+set_child_transient(struct ws_win *win, Window *trans)
{
- struct ws_win *parent;
+ struct ws_win *parent, *w;
+ XWMHints *wmh = NULL;
+ struct swm_region *r;
+ struct workspace *ws;
parent = find_window(win->transient);
if (parent)
parent->child_trans = win;
+ else {
+ DNPRINTF(SWM_D_MISC, "set_child_transient: parent doesn't exist"
+ " for %lu trans %lu\n", win->id, win->transient);
+
+ if (win->hints == NULL) {
+ fprintf(stderr, "no hints for %lu\n", win->id);
+ return;
+ }
+
+ r = root_to_region(win->wa.root);
+ ws = r->ws;
+ /* parent doen't exist in our window list */
+ TAILQ_FOREACH(w, &ws->winlist, entry) {
+ if (wmh)
+ XFree(wmh);
+
+ if ((wmh = XGetWMHints(display, w->id)) == NULL) {
+ fprintf(stderr, "can't get hints for %lu\n",
+ w->id);
+ continue;
+ }
+
+ if (win->hints->window_group != wmh->window_group)
+ continue;
+
+ w->child_trans = win;
+ win->transient = w->id;
+ *trans = w->id;
+ DNPRINTF(SWM_D_MISC, "set_child_transient: asjusting "
+ "transient to %lu\n", win->transient);
+ break;
+ }
+ }
+
+ if (wmh)
+ XFree(wmh);
}
struct ws_win *
DNPRINTF(SWM_D_MISC, "manage previously unmanaged window "
"%lu\n", win->id);
TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry);
- if (win->transient)
- set_child_transient(win);
- if (trans && (ww = find_window(trans)))
+ if (win->transient) {
+ set_child_transient(win, &trans);
+ } if (trans && (ww = find_window(trans)))
TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry);
else
TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry);
False, XA_STRING, &type, &format, &nitems, &bytes, &prop);
XGetWindowAttributes(display, id, &win->wa);
XGetWMNormalHints(display, id, &win->sh, &mask);
+ win->hints = XGetWMHints(display, id);
XGetTransientForHint(display, id, &trans);
if (trans) {
win->transient = trans;
- set_child_transient(win);
+ set_child_transient(win, &trans);
DNPRINTF(SWM_D_MISC, "manage_window: win %lu transient %lu\n",
win->id, win->transient);
}
keysym = XKeycodeToKeysym(display, (KeyCode)ev->keycode, 0);
for (i = 0; i < keys_length; i++)
if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keyfuncs[keys[i].funcid].func) {
+ && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
+ && keyfuncs[keys[i].funcid].func) {
if (keys[i].funcid == kf_spawn_custom)
spawn_custom(
root_to_region(ev->root),
adjust_font(win);
if (font_adjusted)
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
}
}
unmanage_window(win);
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
free_window(win);
}
/* resend unmap because we ated it */
XUnmapWindow(display, e->xunmap.window);
}
+
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
}
void
XKillClient(display, win->id);
}
if (ev->message_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) {
- DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_MOVERESIZE_WINDOW \n");
+ DNPRINTF(SWM_D_EVENT,
+ "clientmessage: _NET_MOVERESIZE_WINDOW \n");
if (win->floating) {
if (ev->data.l[0] & (1<<8)) /* x */
win->g.x = ev->data.l[1];
DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_WM_STATE \n");
ewmh_update_win_state(win, ev->data.l[1], ev->data.l[0]);
if (ev->data.l[2])
- ewmh_update_win_state(win, ev->data.l[2], ev->data.l[0]);
+ ewmh_update_win_state(win, ev->data.l[2],
+ ev->data.l[0]);
stack();
}
TAILQ_FOREACH(r, &screens[i].rl, entry)
bar_setup(r);
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
}
void
grabkeys();
stack();
+ if (focus_mode == SWM_FOCUS_DEFAULT)
+ drain_enter_notify();
xfd = ConnectionNumber(display);
while (running) {