XFontStruct *bar_fs;
char bar_text[128];
char *bar_fonts[] = {
- "-*-terminus-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-times-medium-r-*-*-*-*-*-*-*-*-*-*",
- NULL
+ "-*-terminus-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-times-medium-r-*-*-*-*-*-*-*-*-*-*",
+ NULL
};
/* terminal + args */
char *spawn_term[] = { "xterm", NULL };
+char *spawn_menu[] = { "dmenu_run", NULL };
struct ws_win {
TAILQ_ENTRY(ws_win) entry;
int y;
int width;
int height;
+ int floating;
+ int transient;
};
TAILQ_HEAD(ws_win_list, ws_win);
int visible; /* workspace visible */
int restack; /* restack on switch */
struct ws_win *focus; /* which win has focus */
- int winno; /* total nr of windows */
struct ws_win_list winlist; /* list of windows in ws */
} ws[SWM_WS_MAX];
int current_ws = 0;
if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
if (feof(config))
break;
-
cp = line;
cp += (long)strspn(cp, SWM_CONF_WS);
if (cp[0] == '\0') {
free(line);
continue;
}
-
if ((var = strsep(&cp, SWM_CONF_WS)) == NULL || cp == NULL)
break;
-
cp += (long)strspn(cp, SWM_CONF_WS);
if ((val = strsep(&cp, SWM_CONF_WS)) == NULL)
break;
default:
goto bad;
}
-
free(line);
}
bar_height - 2, 1, bar_border, bar_color);
bar_gc = XCreateGC(display, bar_window, 0, &bar_gcv);
XSetFont(display, bar_gc, bar_fs->fid);
+ XSelectInput(display, bar_window, VisibilityChangeMask);
if (bar_enabled) {
height -= bar_height; /* correct screen height */
XMapWindow(display, bar_window);
}
+ DNPRINTF(SWM_D_MISC, "bar_setup: bar_window %d\n", (int)bar_window);
if (signal(SIGALRM, bar_signal) == SIG_ERR)
err(1, "could not install bar_signal");
bar_print();
}
+int
+count_win(int wsid, int count_transient)
+{
+ struct ws_win *win;
+ int count = 0;
+
+ TAILQ_FOREACH (win, &ws[wsid].winlist, entry) {
+ if (count_transient == 0 && win->transient)
+ continue;
+ count++;
+ }
+ DNPRINTF(SWM_D_MISC, "count_win: %d\n", count);
+
+ return (count);
+}
void
quit(union arg *args)
{
/* map new window first to prevent ugly blinking */
TAILQ_FOREACH (win, &ws[wsid].winlist, entry)
- XMapWindow(display, win->id);
+ XMapRaised(display, win->id);
ws[wsid].visible = 1;
TAILQ_FOREACH (win, &ws[current_ws].winlist, entry)
struct ws_win *winfocus, *winlostfocus;
DNPRINTF(SWM_D_FOCUS, "focus: id %d\n", args->id);
- if (ws[current_ws].focus == NULL || ws[current_ws].winno == 0)
+ if (ws[current_ws].focus == NULL || count_win(current_ws, 1) == 0)
return;
winlostfocus = ws[current_ws].focus;
{
XWindowChanges wc;
struct ws_win wf, *win, *winfocus = &wf;
- int i, h, w, x, y, hrh;
+ int i, h, w, x, y, hrh, winno;
+ int floater = 0;
+ unsigned int mask;
DNPRINTF(SWM_D_EVENT, "stack: workspace: %d\n", current_ws);
ws[current_ws].restack = 0;
- if (ws[current_ws].winno == 0)
+ winno = count_win(current_ws, 0);
+ if (winno == 0)
return;
- if (ws[current_ws].winno > 1)
+ if (winno > 1)
w = width / 2;
else
w = width;
- if (ws[current_ws].winno > 2)
- hrh = height / (ws[current_ws].winno - 1);
+ if (winno > 2)
+ hrh = height / (winno - 1);
else
hrh = 0;
}
}
+ if (win->transient != 0 || win->floating != 0)
+ floater = 1;
+ else
+ floater = 0;
+
bzero(&wc, sizeof wc);
- win->x = wc.x = x;
- win->y = wc.y = y;
- win->width = wc.width = w;
- win->height = wc.height = h;
wc.border_width = 1;
- XConfigureWindow(display, win->id, CWX | CWY | CWWidth |
- CWHeight | CWBorderWidth, &wc);
+ if (floater == 0) {
+ win->x = wc.x = x;
+ win->y = wc.y = y;
+ win->width = wc.width = w;
+ win->height = wc.height = h;
+ mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
+ } else {
+ win->x = wc.x = width / 2;
+ win->y = wc.y = height / 2;
+ mask = CWX | CWY | CWBorderWidth;
+ }
+ XConfigureWindow(display, win->id, mask, &wc);
+
if (win == ws[current_ws].focus)
winfocus = win;
else
unfocus_win(win);
- XMapWindow(display, win->id);
+ XMapRaised(display, win->id);
i++;
}
ws[current_ws].focus = TAILQ_FIRST(&ws[current_ws].winlist);
TAILQ_REMOVE(&ws[current_ws].winlist, win, entry);
- ws[current_ws].winno--;
TAILQ_INSERT_TAIL(&ws[wsid].winlist, win, entry);
- if (ws[wsid].winno == 0)
+ if (count_win(wsid, 1) == 0)
ws[wsid].focus = win;
- ws[wsid].winno++;
ws[wsid].restack = 1;
stack();
} keys[] = {
/* modifier key function argument */
{ MODKEY, XK_Return, swap_to_main, {0} },
- { MODKEY | ShiftMask, XK_Return, spawn, {.argv = spawn_term } },
+ { MODKEY | ShiftMask, XK_Return, spawn, {.argv = spawn_term} },
+ { MODKEY, XK_p, spawn, {.argv = spawn_menu} },
{ MODKEY | ShiftMask, XK_q, quit, {0} },
{ MODKEY, XK_m, focus, {.id = SWM_ARG_ID_FOCUSMAIN} },
{ MODKEY, XK_1, switchws, {.id = 0} },
configurerequest(XEvent *e)
{
XConfigureRequestEvent *ev = &e->xconfigurerequest;
+ Window trans;
struct ws_win *win;
DNPRINTF(SWM_D_EVENT, "configurerequest: window: %lu\n", ev->window);
+ TAILQ_FOREACH (win, &ws[current_ws].winlist, entry) {
+ if (ev->window == win->id)
+ return;
+ }
+
XSelectInput(display, ev->window, ButtonPressMask | EnterWindowMask |
- FocusChangeMask);
+ FocusChangeMask | ExposureMask);
if ((win = calloc(1, sizeof(struct ws_win))) == NULL)
errx(1, "calloc: failed to allocate memory for new window");
win->id = ev->window;
TAILQ_INSERT_TAIL(&ws[current_ws].winlist, win, entry);
ws[current_ws].focus = win; /* make new win focused */
- ws[current_ws].winno++;
+
+ XGetTransientForHint(display, win->id, &trans);
+ if (trans) {
+ win->transient = trans;
+ DNPRINTF(SWM_D_MISC, "configurerequest: win %u transient %u\n",
+ (unsigned)win->id, win->transient);
+ }
+#if 0
+ XClassHint ch = { 0 };
+ if(XGetClassHint(display, win->id, &ch)) {
+ fprintf(stderr, "class: %s name: %s\n", ch.res_class, ch.res_name);
+ if (!strcmp(ch.res_class, "Gvim") && !strcmp(ch.res_name, "gvim")) {
+ win->floating = 0;
+ }
+ if(ch.res_class)
+ XFree(ch.res_class);
+ if(ch.res_name)
+ XFree(ch.res_name);
+ }
+#endif
stack();
}
TAILQ_REMOVE(&ws[current_ws].winlist, win, entry);
free(win);
- ws[current_ws].winno--;
break;
}
}
DNPRINTF(SWM_D_EVENT, "focusin: window: %lu\n", ev->window);
+ XSync(display, False); /* not sure this helps redrawing graphic apps */
+
if (ev->window == root)
return;
-
/*
* kill grab for now so that we can cut and paste , this screws up
* click to focus
DNPRINTF(SWM_D_EVENT, "unmapnotify: window: %lu\n", e->xunmap.window);
}
+void
+visibilitynotify(XEvent *e)
+{
+ DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: %lu\n", e->xvisibility.window);
+
+ if (e->xvisibility.window == bar_window &&
+ e->xvisibility.state == VisibilityUnobscured)
+ bar_print();
+}
+
void (*handler[LASTEvent])(XEvent *) = {
[Expose] = expose,
[KeyPress] = keypress,
[MapRequest] = maprequest,
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify,
+ [VisibilityNotify] = visibilitynotify,
};
int
width = DisplayWidth(display, screen) - 2;
height = DisplayHeight(display, screen) - 2;
- /* look for local and globale conf file */
+ /* look for local and global conf file */
pwd = getpwuid(getuid());
if (pwd == NULL)
errx(1, "invalid user %d", getuid());
ws[0].visible = 1;
ws[0].restack = 0;
ws[0].focus = NULL;
- ws[0].winno = 0;
TAILQ_INIT(&ws[0].winlist);
for (i = 1; i < SWM_WS_MAX; i++) {
ws[i].visible = 0;
ws[i].restack = 0;
ws[i].focus = NULL;
- ws[i].winno = 0;
TAILQ_INIT(&ws[i].winlist);
}
XSelectInput(display, root, SubstructureRedirectMask |
SubstructureNotifyMask | ButtonPressMask | KeyPressMask |
EnterWindowMask | LeaveWindowMask | StructureNotifyMask |
- FocusChangeMask | PropertyChangeMask);
+ FocusChangeMask | PropertyChangeMask | ExposureMask);
grabkeys();