static const char *cvstag = "$scrotwm$";
-#define SWM_VERSION "0.9.26"
+#define SWM_VERSION "0.9.29"
#include <stdio.h>
#include <stdlib.h>
sig_atomic_t bar_alarm = 0;
int bar_delay = 30;
int bar_enabled = 1;
+int bar_border_width = 1;
int bar_at_bottom = 0;
int bar_extra = 1;
int bar_extra_running = 0;
char *clock_format = NULL;
int title_name_enabled = 0;
int title_class_enabled = 0;
+int window_name_enabled = 0;
int focus_mode = SWM_FOCUS_DEFAULT;
int disable_border = 0;
+int border_width = 1;
pid_t bar_pid;
GC bar_gc;
XGCValues bar_gcv;
if (x < 0 || x > DisplayWidth(display, sidx) ||
y < 0 || y > DisplayHeight(display, sidx) ||
w + x > DisplayWidth(display, sidx) ||
- h + y > DisplayHeight(display, sidx))
- errx(1, "region %ux%u+%u+%u not within screen boundaries "
+ h + y > DisplayHeight(display, sidx)) {
+ 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;
+ }
new_region(&screens[sidx], x, y, w, h);
}
}
void
+bar_window_name(char *s, ssize_t sz, struct ws_win *cur_focus)
+{
+ char *title;
+
+ if (window_name_enabled && cur_focus != NULL) {
+ XFetchName(display, cur_focus->id, &title);
+ if (title) {
+ if (cur_focus->floating)
+ strlcat(s, "(f) ", sz);
+ strlcat(s, title, sz);
+ strlcat(s, " ", sz);
+ XFree(title);
+ }
+ }
+}
+
+void
bar_update(void)
{
time_t tmt;
x = 1;
TAILQ_FOREACH(r, &screens[i].rl, entry) {
strlcpy(cn, "", sizeof cn);
- if (r && r->ws)
+ if (r && r->ws) {
bar_class_name(cn, sizeof cn, r->ws->focus);
+ bar_window_name(cn, sizeof cn, r->ws->focus);
+ }
if (stack_enabled)
stack = r->ws->cur_layout->name;
if (bar_fs == NULL)
errx(1, "couldn't create font structure");
- bar_height = bar_fs->ascent + bar_fs->descent + 3;
+ 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_height - 2,
- 1, r->s->c[SWM_S_COLOR_BAR_BORDER].color,
+ 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);
XSetFont(display, bar_gc, bar_fs->fid);
cr.y = win->g.y;
cr.width = win->g.w;
cr.height = win->g.h;
- cr.border_width = 1;
+ cr.border_width = border_width;
XSendEvent(display, win->id, False, StructureNotifyMask, (XEvent *)&cr);
}
ce.y = win->g.y;
ce.width = win->g.w;
ce.height = win->g.h;
- ce.border_width = 1; /* XXX store this! */
+ ce.border_width = border_width; /* XXX store this! */
ce.above = None;
ce.override_redirect = False;
XSendEvent(display, win->id, False, StructureNotifyMask, (XEvent *)&ce);
unfocus_win(struct ws_win *win)
{
XEvent cne;
- Window none = None;
+ Window none = None;
DNPRINTF(SWM_D_FOCUS, "unfocus_win: id: %lu\n", WINID(win));
return;
if (validate_ws(win->ws))
- abort(); /* XXX replace with return at some point */
+ return; /* XXX this gets hit with thunderbird, needs fixing */
if (win->ws->r == NULL)
return;
return;
if (validate_ws(win->ws))
- abort(); /* XXX replace with return at some point */
+ return; /* XXX this gets hit with thunderbird, needs fixing */
if (validate_win(win)) {
kill_refs(win);
ewmh[_NET_ACTIVE_WINDOW].atom, XA_WINDOW, 32,
PropModeReplace, (unsigned char *)&win->id,1);
}
+
+ if (window_name_enabled)
+ bar_update();
}
void
/* start with screen geometry, adjust for bar */
g = r->g;
- g.w -= 2;
- g.h -= 2;
+ g.w -= 2 * border_width;
+ g.h -= 2 * border_width;
if (bar_enabled) {
if (!bar_at_bottom)
g.y += bar_height;
(win->g.h >= HEIGHT(r)))
wc.border_width = 0;
else
- wc.border_width = 1;
+ wc.border_width = border_width;
if (win->transient && (win->quirks & SWM_Q_TRANSSZ)) {
win->g.w = (double)WIDTH(r) * dialog_ratio;
win->g.h = (double)HEIGHT(r) * dialog_ratio;
* floaters and transients are auto-centred unless moved
* or resized
*/
- win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2;
- win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2;
+ win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2 - border_width;
+ win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2 - border_width;
}
/* win can be outside r if new r smaller than old r */
/* Ensure top left corner inside r (move probs otherwise) */
- if (win->g.x < r->g.x )
- win->g.x = r->g.x;
+ if (win->g.x < r->g.x - border_width)
+ win->g.x = r->g.x - border_width;
if (win->g.x > r->g.x + r->g.w - 1)
win->g.x = (win->g.w > r->g.w) ? r->g.x :
- (r->g.x + r->g.w - win->g.w - 2);
- if (win->g.y < r->g.y )
- win->g.y = r->g.y;
+ (r->g.x + r->g.w - win->g.w - 2 * border_width);
+ if (win->g.y < r->g.y - border_width)
+ win->g.y = r->g.y - border_width;
if (win->g.y > r->g.y + r->g.h - 1)
win->g.y = (win->g.h > r->g.h) ? r->g.y :
- (r->g.y + r->g.h - win->g.h - 2);
+ (r->g.y + r->g.h - win->g.h - 2 * border_width);
wc.x = win->g.x;
wc.y = win->g.y;
} else {
msize = -2;
colno = split = winno / stacks;
- win_g.w = ((r_g.w - (stacks * 2) + 2) / 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.h = hrh - 2;
+ win_g.h = hrh - 2 * border_width;
/* stack all the tiled windows */
i = j = 0, s = stacks;
if (flip)
win_g.x = r_g.x;
else
- win_g.x += win_g.w + 2;
- win_g.w = (r_g.w - msize - (stacks * 2)) / stacks;
+ win_g.x += win_g.w + 2 * border_width;
+ win_g.w = (r_g.w - msize - (stacks * 2 * border_width)) / stacks;
if (s == 1)
- win_g.w += (r_g.w - msize - (stacks * 2)) %
+ win_g.w += (r_g.w - msize - (stacks * 2 * border_width)) %
stacks;
s--;
j = 0;
}
- win_g.h = hrh - 2;
+ win_g.h = hrh - 2 * border_width;
if (rot) {
h_inc = win->sh.width_inc;
h_base = win->sh.base_width;
if (j == 0)
win_g.y = r_g.y;
else
- win_g.y += last_h + 2;
+ win_g.y += last_h + 2 * border_width;
bzero(&wc, sizeof wc);
if (disable_border && bar_enabled == 0 && winno == 1){
wc.border_width = 0;
- win_g.w += 2;
- win_g.h += 2;
+ win_g.w += 2 * border_width;
+ win_g.h += 2 * border_width;
} else
- wc.border_width = 1;
+ wc.border_width = border_width;
reconfigure = 0;
if (rot) {
if (win->g.x != win_g.y || win->g.y != win_g.x ||
win->g.x = wc.x = gg.x;
win->g.y = wc.y = gg.y;
if (bar_enabled){
- wc.border_width = 1;
+ wc.border_width = border_width;
win->g.w = wc.width = gg.w;
win->g.h = wc.height = gg.h;
} else {
wc.border_width = 0;
- win->g.w = wc.width = gg.w + 2;
- win->g.h = wc.height = gg.h + 2;
+ win->g.w = wc.width = gg.w + 2 * border_width;
+ win->g.h = wc.height = gg.h + 2 * border_width;
}
mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
XConfigureWindow(display, win->id, mask, &wc);
struct ws_win *win = r->ws->focus;
union arg a;
+ if (win == NULL)
+ return;
+
ewmh_update_win_state(win, ewmh[_NET_WM_STATE_ABOVE].atom,
_NET_WM_STATE_TOGGLE);
r = root_to_region(win->wa.root);
bzero(&wc, sizeof wc);
mask = CWBorderWidth | CWWidth | CWHeight;
- wc.border_width = 1;
+ wc.border_width = border_width;
wc.width = win->g.w;
wc.height = win->g.h;
if (center == SWM_ARG_ID_CENTER) {
- wc.x = (WIDTH(r) - win->g.w) / 2;
- wc.y = (HEIGHT(r) - win->g.h) / 2;
+ wc.x = (WIDTH(r) - win->g.w) / 2 - border_width;
+ wc.y = (HEIGHT(r) - win->g.h) / 2 - border_width;
mask |= CWX | CWY;
}
/* place pointer at bottom left corner or nearest point inside r */
if ( win->g.x + win->g.w < r->g.x + r->g.w - 1)
- relx = win->g.w;
+ relx = win->g.w - 1;
else
- relx = r->g.x + r->g.w - win->g.x - 2;
+ relx = r->g.x + r->g.w - win->g.x - 1;
if ( win->g.y + win->g.h < r->g.y + r->g.h - 1)
- rely = win->g.h;
+ rely = win->g.h - 1;
else
- rely = r->g.y + r->g.h - win->g.y - 2;
+ rely = r->g.y + r->g.h - win->g.y - 1;
XWarpPointer(display, None, win->id, 0, 0, 0, 0, relx, rely);
do {
ev.xmotion.x = 1;
if (ev.xmotion.y <= 1)
ev.xmotion.y = 1;
- win->g.w = ev.xmotion.x;
- win->g.h = ev.xmotion.y;
+ win->g.w = ev.xmotion.x + 1;
+ win->g.h = ev.xmotion.y + 1;
- /* not free, don't sync more than 60 times / second */
- if ((ev.xmotion.time - time) > (1000 / 60) ) {
+ /* not free, don't sync more than 120 times / second */
+ if ((ev.xmotion.time - time) > (1000 / 120) ) {
time = ev.xmotion.time;
XSync(display, False);
resize_window(win, args->id);
if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
return;
- XWarpPointer(display, None, win->id, 0, 0, 0, 0, -1, -1);
+ XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0);
do {
XMaskEvent(display, MOUSEMASK | ExposureMask |
SubstructureRedirectMask, &ev);
ev.xmotion.y_root > r->g.y + r->g.h - 1)
continue;
- win->g.x = ev.xmotion.x_root;
- win->g.y = ev.xmotion.y_root;
+ win->g.x = ev.xmotion.x_root - border_width;
+ win->g.y = ev.xmotion.y_root - border_width;
- /* not free, don't sync more than 60 times / second */
- if ((ev.xmotion.time - time) > (1000 / 60) ) {
+ /* not free, don't sync more than 120 times / second */
+ if ((ev.xmotion.time - time) > (1000 / 120) ) {
time = ev.xmotion.time;
XSync(display, False);
move_window(win);
/* conf file stuff */
#define SWM_CONF_FILE "scrotwm.conf"
-enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_STACK_ENABLED,
+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_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BAR_FONT,
+ 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
};
case SWM_S_BAR_ENABLED:
bar_enabled = atoi(value);
break;
+ case SWM_S_BAR_BORDER_WIDTH:
+ bar_border_width = atoi(value);
+ break;
case SWM_S_BAR_AT_BOTTOM:
bar_at_bottom = atoi(value);
break;
case SWM_S_TITLE_CLASS_ENABLED:
title_class_enabled = atoi(value);
break;
+ case SWM_S_WINDOW_NAME_ENABLED:
+ window_name_enabled = atoi(value);
+ break;
case SWM_S_TITLE_NAME_ENABLED:
title_name_enabled = atoi(value);
break;
case SWM_S_DISABLE_BORDER:
disable_border = atoi(value);
break;
+ case SWM_S_BORDER_WIDTH:
+ border_width = atoi(value);
+ break;
case SWM_S_BAR_FONT:
free(bar_fonts[0]);
if ((bar_fonts[0] = strdup(value)) == NULL)
{ "bar_enabled", setconfvalue, SWM_S_BAR_ENABLED },
{ "bar_at_bottom", setconfvalue, SWM_S_BAR_AT_BOTTOM },
{ "bar_border", setconfcolor, SWM_S_COLOR_BAR_BORDER },
+ { "bar_border_width", setconfvalue, SWM_S_BAR_BORDER_WIDTH },
{ "bar_color", setconfcolor, SWM_S_COLOR_BAR },
{ "bar_font_color", setconfcolor, SWM_S_COLOR_BAR_FONT },
{ "bar_font", setconfvalue, SWM_S_BAR_FONT },
{ "spawn_term", setconfvalue, SWM_S_SPAWN_TERM },
{ "screenshot_enabled", setconfvalue, SWM_S_SS_ENABLED },
{ "screenshot_app", setconfvalue, SWM_S_SS_APP },
+ { "window_name_enabled", setconfvalue, SWM_S_WINDOW_NAME_ENABLED },
{ "term_width", setconfvalue, SWM_S_TERM_WIDTH },
{ "title_class_enabled", setconfvalue, SWM_S_TITLE_CLASS_ENABLED },
{ "title_name_enabled", setconfvalue, SWM_S_TITLE_NAME_ENABLED },
{ "focus_mode", setconfvalue, SWM_S_FOCUS_MODE },
{ "disable_border", setconfvalue, SWM_S_DISABLE_BORDER },
+ { "border_width", setconfvalue, SWM_S_BORDER_WIDTH },
};
/* border me */
if (border_me) {
bzero(&wc, sizeof wc);
- wc.border_width = 1;
+ wc.border_width = border_width;
mask = CWBorderWidth;
XConfigureWindow(display, win->id, mask, &wc);
configreq_win(win);
parent->child_trans = NULL;
}
- /* work around for mplayer going full screen */
+ /* focus on root just in case */
+ XSetInputFocus(display, PointerRoot, PointerRoot, CurrentTime);
+
if (!win->floating)
focus_prev(win);
XMoveResizeWindow(display, win->id,
win->g.x, win->g.y, win->g.w, win->g.h);
#endif
+ if (window_name_enabled)
+ bar_update();
break;
default:
break;