X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=7c076489365cda6a5b8ea14de22b4f7dcfb01e08;hb=de65c2a567bd5b9b4274d7ac5bed3cb833c409a5;hp=ba800275ec5a9495749559f00530783ca473085c;hpb=134554a0430cd9470f4a3d5d8325c1b7a569527a;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index ba80027..7c07648 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -48,7 +48,9 @@ * DEALINGS IN THE SOFTWARE. */ -#define SWM_VERSION "0.5" +static const char *cvstag = "$scrotwm$"; + +#define SWM_VERSION "0.6" #include #include @@ -102,7 +104,7 @@ #define SWM_D_STACK 0x0020 #define SWM_D_MOUSE 0x0040 #define SWM_D_PROP 0x0080 - +#define SWM_D_CLASS 0x0100 u_int32_t swm_debug = 0 | SWM_D_MISC @@ -111,7 +113,9 @@ u_int32_t swm_debug = 0 | SWM_D_FOCUS | SWM_D_MOVE | SWM_D_STACK + | SWM_D_MOUSE | SWM_D_PROP + | SWM_D_CLASS ; #else #define DPRINTF(x...) @@ -122,18 +126,16 @@ u_int32_t swm_debug = 0 #define MODKEY Mod1Mask #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) - -#define X(r) (r)->g.x -#define Y(r) (r)->g.y -#define WIDTH(r) (r)->g.w -#define HEIGHT(r) (r)->g.h +#define SWM_PROPLEN (16) +#define X(r) (r)->g.x +#define Y(r) (r)->g.y +#define WIDTH(r) (r)->g.w +#define HEIGHT(r) (r)->g.h #ifndef SWM_LIB -#define SWM_LIB "/usr/X11R6/lib/swmhack.so" +#define SWM_LIB "/usr/X11R6/lib/swmhack.so" #endif -#define SWM_PROPLEN (16) - char **start_argv; Atom astate; int (*xerrorxlib)(Display *, XErrorEvent *); @@ -176,8 +178,8 @@ char *bar_fonts[] = { /* terminal + args */ char *spawn_term[] = { "xterm", NULL }; char *spawn_screenshot[] = { "screenshot.sh", NULL, NULL }; -char *spawn_menu[] = { "dmenu_run", "-fn", NULL, - "-nb", NULL, "-nf", NULL, "-sb", NULL, "-sf", NULL, NULL }; +char *spawn_menu[] = { "dmenu_run", "-fn", NULL, "-nb", NULL, + "-nf", NULL, "-sb", NULL, "-sf", NULL, NULL }; #define SWM_MENU_FN (2) #define SWM_MENU_NB (4) @@ -309,6 +311,17 @@ union arg { char **argv; }; +struct quirk { + char *class; + char *name; + unsigned long quirk; +#define SWM_Q_FLOAT (1<<0) +} quirks[] = { + { "MPlayer", "xv", SWM_Q_FLOAT }, + { "OpenOffice.org 2.4", "VCLSalFrame", SWM_Q_FLOAT }, + { NULL, NULL, 0}, +}; + unsigned long name_to_color(char *colorname) { @@ -804,6 +817,7 @@ void spawn(struct swm_region *r, union arg *args) { char *ret; + int si; DNPRINTF(SWM_D_MISC, "spawn: %s\n", args->argv[0]); /* @@ -824,6 +838,12 @@ spawn(struct swm_region *r, union arg *args) free(ret); } setsid(); + /* kill stdin, mplayer, ssh-add etc. need that */ + si = open("/dev/null", O_RDONLY, 0); + if (si == -1) + err(1, "open /dev/null"); + if (dup2(si, 0) == -1) + err(1, "dup2 /dev/null"); execvp(args->argv[0], args->argv); fprintf(stderr, "execvp failed\n"); perror(" failed"); @@ -1751,12 +1771,13 @@ manage_window(Window id) struct workspace *ws; struct ws_win *win; XClassHint ch; - int format; + int format, i, ws_idx; unsigned long nitems, bytes; Atom ws_idx_atom = 0, type; unsigned char ws_idx_str[SWM_PROPLEN], *prop = NULL; struct swm_region *r; long mask; + const char *errstr; if ((win = find_window(id)) != NULL) return (win); /* already being managed */ @@ -1773,9 +1794,6 @@ manage_window(Window id) r = root_to_region(win->wa.root); /* If the window was managed before, put it in the same workspace */ if (prop) { - int ws_idx; - const char *errstr; - DNPRINTF(SWM_D_PROP, "got property _SWM_WS=%s\n", prop); ws_idx = strtonum(prop, 0, 9, &errstr); if (errstr) @@ -1790,9 +1808,6 @@ manage_window(Window id) win->s = r->s; /* this never changes */ TAILQ_INSERT_TAIL(&ws->winlist, win, entry); - /* make new win focused */ - focus_win(win); - XGetTransientForHint(display, win->id, &trans); if (trans) { win->transient = trans; @@ -1804,7 +1819,7 @@ manage_window(Window id) win->g.x = win->wa.x; win->g.y = win->wa.y; - XGetWMNormalHints(display, win->id, &win->sh, &mask); + XGetWMNormalHints(display, win->id, &win->sh, &mask); /* XXX function? */ if (ws_idx_atom && prop == NULL && snprintf(ws_idx_str, SWM_PROPLEN, "%d", ws->idx) < SWM_PROPLEN) { @@ -1819,17 +1834,27 @@ manage_window(Window id) fprintf(stderr, "manage window: %d x %d y %d w %d h %d\n", win->id, win->g.x, win->g.y, win->g.w, win->g.h); */ - /* XXX make this a table */ bzero(&ch, sizeof ch); if (XGetClassHint(display, win->id, &ch)) { - /*fprintf(stderr, "class: %s name: %s\n", ch.res_class, ch.res_name); */ - if (!strcmp(ch.res_class, "MPlayer") && !strcmp(ch.res_name, "xv")) { - win->floating = 1; - } + DNPRINTF(SWM_D_CLASS, "class: %s name: %s\n", + ch.res_class, ch.res_name); + for (i = 0; quirks[i].class != NULL && quirks[i].name != NULL && + quirks[i].quirk != 0; i++){ + if (!strcmp(ch.res_class, quirks[i].class) && + !strcmp(ch.res_name, quirks[i].name)) { + DNPRINTF(SWM_D_CLASS, "found: %s name: %s\n", + ch.res_class, ch.res_name); + if (quirks[i].quirk & SWM_Q_FLOAT) + win->floating = 1; + } +#if 0 + /* XXX logic says to do this but get a double free */ if (ch.res_class) XFree(ch.res_class); if (ch.res_name) XFree(ch.res_name); +#endif + } } XSelectInput(display, id, EnterWindowMask | FocusChangeMask | @@ -1837,6 +1862,9 @@ manage_window(Window id) set_win_state(win, NormalState); + /* make new win focused */ + focus_win(win); + return (win); } @@ -1885,15 +1913,16 @@ configurerequest(XEvent *e) win->g.h = ev->height; if (win->ws->r != NULL) { /* this seems to be full screen */ - if (win->g.w > WIDTH(win->ws->r)) { - /* kill border */ - win->g.x -= 1; - win->g.w += 1; + if (win->g.w >= WIDTH(win->ws->r)) { + win->g.x = -1; + win->g.w = WIDTH(win->ws->r); + ev->value_mask |= CWX | CWWidth; } - if (win->g.h > HEIGHT(win->ws->r)) { + if (win->g.h >= HEIGHT(win->ws->r)) { /* kill border */ - win->g.y -= 1; - win->g.h += 1; + win->g.y = -1; + win->g.h = HEIGHT(win->ws->r); + ev->value_mask |= CWY | CWHeight; } } if ((ev->value_mask & (CWX|CWY)) && @@ -1997,8 +2026,36 @@ maprequest(XEvent *e) void propertynotify(XEvent *e) { + struct ws_win *win; + XPropertyEvent *ev = &e->xproperty; + DNPRINTF(SWM_D_EVENT, "propertynotify: window: %lu\n", - e->xproperty.window); + ev->window); + + if (ev->state == PropertyDelete) + return; /* ignore */ + win = find_window(ev->window); + if (win == NULL) + return; + + switch (ev->atom) { + case XA_WM_NORMAL_HINTS: +#if 0 + long mask; + XGetWMNormalHints(display, win->id, &win->sh, &mask); + fprintf(stderr, "normal hints: flag 0x%x\n", win->sh.flags); + if (win->sh.flags & PMinSize) { + win->g.w = win->sh.min_width; + win->g.h = win->sh.min_height; + fprintf(stderr, "min %d %d\n", win->g.w, win->g.h); + } + XMoveResizeWindow(display, win->id, + win->g.x, win->g.y, win->g.w, win->g.h); +#endif + break; + default: + break; + } } void @@ -2264,7 +2321,8 @@ main(int argc, char *argv[]) fd_set rd; start_argv = argv; - fprintf(stderr, "Welcome to scrotwm V%s\n", SWM_VERSION); + fprintf(stderr, "Welcome to scrotwm V%s cvs tag: %s\n", + SWM_VERSION, cvstag); if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) warnx("no locale support");