X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=634e08b27d142c7589a71681197c5831cab6a4b2;hb=0266c3c6c39b5f188424ee41d6df07a53b53a7da;hp=29290d5d60a4922f8c1acf8f889d7fcc8147abc7;hpb=a1d2fb7ac3944d438cec8635ce113177c25b085b;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 29290d5..634e08b 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -50,7 +50,7 @@ static const char *cvstag = "$scrotwm$"; -#define SWM_VERSION "0.8" +#define SWM_VERSION "0.9" #include #include @@ -140,6 +140,8 @@ u_int32_t swm_debug = 0 char **start_argv; Atom astate; +Atom aprot; +Atom adelete; int (*xerrorxlib)(Display *, XErrorEvent *); int other_wm; int running = 1; @@ -158,7 +160,7 @@ int font_adjusted = 0; /* dialog windows */ double dialog_ratio = .6; /* status bar */ -#define SWM_BAR_MAX (128) +#define SWM_BAR_MAX (256) char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; char bar_ext[SWM_BAR_MAX]; @@ -228,6 +230,7 @@ struct ws_win { int font_size_boundary[SWM_MAX_FONT_STEPS]; int font_steps; int last_inc; + int can_delete; unsigned long quirks; struct workspace *ws; /* always valid */ struct swm_screen *s; /* always valid, never changes */ @@ -246,6 +249,7 @@ void horizontal_stack(struct workspace *, struct swm_geometry *); void max_stack(struct workspace *, struct swm_geometry *); void grabbuttons(struct ws_win *, int); +void new_region(struct swm_screen *, int, int, int, int); struct layout { void (*l_stack)(struct workspace *, struct swm_geometry *); @@ -330,6 +334,8 @@ union arg { #define SWM_ARG_ID_SS_WINDOW (1) #define SWM_ARG_ID_DONTCENTER (0) #define SWM_ARG_ID_CENTER (1) +#define SWM_ARG_ID_KILLWINDOW (0) +#define SWM_ARG_ID_DELETEWINDOW (1) char **argv; }; @@ -342,13 +348,20 @@ struct quirk { #define SWM_Q_TRANSSZ (1<<1) /* transiend window size too small */ #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 */ } quirks[] = { - { "MPlayer", "xv", SWM_Q_FLOAT }, + { "MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN }, { "OpenOffice.org 2.4", "VCLSalFrame", SWM_Q_FLOAT }, { "OpenOffice.org 3.0", "VCLSalFrame", SWM_Q_FLOAT }, - { "Firefox-bin", "firefox-bin", SWM_Q_TRANSSZ}, - { "Gimp", "gimp", SWM_Q_FLOAT | SWM_Q_ANYWHERE}, - { "XTerm", "xterm", SWM_Q_XTERM_FONTADJ}, + { "Firefox-bin", "firefox-bin", SWM_Q_TRANSSZ }, + { "Gimp", "gimp", SWM_Q_FLOAT | SWM_Q_ANYWHERE }, + { "XTerm", "xterm", SWM_Q_XTERM_FONTADJ }, + { "xine", "Xine Window", SWM_Q_FLOAT | SWM_Q_ANYWHERE }, + { "Xitk", "Xitk Combo", SWM_Q_FLOAT | SWM_Q_ANYWHERE }, + { "xine", "xine Panel", SWM_Q_FLOAT | SWM_Q_ANYWHERE }, + { "Xitk", "Xine Window", SWM_Q_FLOAT | SWM_Q_ANYWHERE }, + { "xine", "xine Video Fullscreen Window", SWM_Q_FULLSCREEN | SWM_Q_FLOAT }, + { "pcb", "pcb", SWM_Q_FLOAT }, { NULL, NULL, 0}, }; @@ -425,8 +438,6 @@ setscreencolor(char *val, int i, int c) i, ScreenCount(display)); } -void new_region(struct swm_screen *, int, int, int, int); - void custom_region(char *val) { @@ -694,15 +705,15 @@ bar_toggle(struct swm_region *r, union arg *args) DNPRINTF(SWM_D_MISC, "bar_toggle\n"); - if (bar_enabled) { + if (bar_enabled) for (i = 0; i < sc; i++) TAILQ_FOREACH(tmpr, &screens[i].rl, entry) XUnmapWindow(display, tmpr->bar_window); - } else { + else for (i = 0; i < sc; i++) TAILQ_FOREACH(tmpr, &screens[i].rl, entry) XMapRaised(display, tmpr->bar_window); - } + bar_enabled = !bar_enabled; for (i = 0; i < sc; i++) for (j = 0; j < SWM_WS_MAX; j++) @@ -806,6 +817,21 @@ version(struct swm_region *r, union arg *args) } void +client_msg(struct ws_win *win, Atom a) +{ + XClientMessageEvent cm; + + bzero(&cm, sizeof cm); + cm.type = ClientMessage; + cm.window = win->id; + cm.message_type = aprot; + cm.format = 32; + cm.data.l[0] = a; + cm.data.l[1] = CurrentTime; + XSendEvent(display, win->id, False, 0L, (XEvent *)&cm); +} + +void config_win(struct ws_win *win) { XConfigureEvent ce; @@ -1262,6 +1288,10 @@ focus(struct swm_region *r, union arg *args) case SWM_ARG_ID_FOCUSMAIN: winfocus = TAILQ_FIRST(wl); + if (winfocus == cur_focus) + winfocus = cur_focus->ws->focus_prev; + if (winfocus == NULL) + return; break; default: @@ -1345,7 +1375,11 @@ stack_floater(struct ws_win *win, struct swm_region *r) bzero(&wc, sizeof wc); mask = CWX | CWY | CWBorderWidth | CWWidth | CWHeight; - wc.border_width = 1; + if ((win->quirks & SWM_Q_FULLSCREEN) && (win->g.w == WIDTH(r)) && + (win->g.h == HEIGHT(r))) + wc.border_width = 0; + else + wc.border_width = 1; if (win->transient && (win->quirks & SWM_Q_TRANSSZ)) { win->g.w = (double)WIDTH(r) * dialog_ratio; win->g.h = (double)HEIGHT(r) * dialog_ratio; @@ -1761,9 +1795,16 @@ send_to_ws(struct swm_region *r, union arg *args) void wkill(struct swm_region *r, union arg *args) { - DNPRINTF(SWM_D_MISC, "wkill\n"); - if(r->ws->focus != NULL) + DNPRINTF(SWM_D_MISC, "wkill %d\n", args->id); + + if(r->ws->focus == NULL) + return; + + if (args->id == SWM_ARG_ID_KILLWINDOW) XKillClient(display, r->ws->focus->id); + else + if (r->ws->focus->can_delete) + client_msg(r->ws->focus, adelete); } void @@ -1857,7 +1898,8 @@ struct key { { MODKEY, XK_b, bar_toggle, {0} }, { MODKEY, XK_Tab, focus, {.id = SWM_ARG_ID_FOCUSNEXT} }, { MODKEY | ShiftMask, XK_Tab, focus, {.id = SWM_ARG_ID_FOCUSPREV} }, - { MODKEY | ShiftMask, XK_x, wkill, {0} }, + { MODKEY | ShiftMask, XK_x, wkill, {.id = SWM_ARG_ID_KILLWINDOW} }, + { MODKEY, XK_x, wkill, {.id = SWM_ARG_ID_DELETEWINDOW} }, { MODKEY, XK_s, screenshot, {.id = SWM_ARG_ID_SS_ALL} }, { MODKEY | ShiftMask, XK_s, screenshot, {.id = SWM_ARG_ID_SS_WINDOW} }, { MODKEY, XK_t, floating_toggle,{0} }, @@ -2169,9 +2211,10 @@ manage_window(Window id) Window trans; struct workspace *ws; struct ws_win *win; - int format, i, ws_idx; + int format, i, ws_idx, n; unsigned long nitems, bytes; Atom ws_idx_atom = 0, type; + Atom *prot = NULL, *pp; unsigned char ws_idx_str[SWM_PROPLEN], *prop = NULL; struct swm_region *r; long mask; @@ -2197,6 +2240,14 @@ manage_window(Window id) DNPRINTF(SWM_D_MISC, "manage_window: win %u transient %u\n", (unsigned)win->id, win->transient); } + /* get supported protocols */ + if (XGetWMProtocols(display, id, &prot, &n)) { + for (i = 0, pp = prot; i < n; i++, pp++) + if (*pp == adelete) + win->can_delete = 1; + if (prot) + XFree(prot); + } /* * Figure out where to put the window. If it was previously assigned to @@ -2270,6 +2321,14 @@ manage_window(Window id) XConfigureWindow(display, win->id, mask, &wc); } + /* Reset font sizes (the bruteforce way; no default keybinding). */ + if (win->quirks & SWM_Q_XTERM_FONTADJ) { + for (i = 0; i < SWM_MAX_FONT_STEPS; i++) + fake_keypress(win, XK_KP_Subtract, ShiftMask); + for (i = 0; i < SWM_MAX_FONT_STEPS; i++) + fake_keypress(win, XK_KP_Add, ShiftMask); + } + XSelectInput(display, id, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); @@ -2360,13 +2419,13 @@ configurerequest(XEvent *e) if (win->ws->r != NULL) { /* this seems to be full screen */ if (win->g.w >= WIDTH(win->ws->r)) { - win->g.x = -1; + win->g.x = 0; win->g.w = WIDTH(win->ws->r); ev->value_mask |= CWX | CWWidth; } if (win->g.h >= HEIGHT(win->ws->r)) { /* kill border */ - win->g.y = -1; + win->g.y = 0; win->g.h = HEIGHT(win->ws->r); ev->value_mask |= CWY | CWHeight; } @@ -2571,13 +2630,12 @@ getstate(Window w) unsigned long n, extra; Atom real; - astate = XInternAtom(display, "WM_STATE", False); status = XGetWindowProperty(display, w, astate, 0L, 2L, False, astate, &real, &format, &n, &extra, (unsigned char **)&p); if (status != Success) return (-1); if (n != 0) - result = *p; + result = *((long *)p); XFree(p); return (result); } @@ -2735,6 +2793,11 @@ screenchange(XEvent *e) { TAILQ_FOREACH(r, &screens[i].rl, entry) TAILQ_FOREACH(win, &r->ws->winlist, entry) XUnmapWindow(display, win->id); + + /* add bars to all regions */ + for (i = 0; i < ScreenCount(display); i++) + TAILQ_FOREACH(r, &screens[i].rl, entry) + bar_setup(r); stack(); } @@ -2858,6 +2921,8 @@ main(int argc, char *argv[]) errx(1, "other wm running"); astate = XInternAtom(display, "WM_STATE", False); + aprot = XInternAtom(display, "WM_PROTOCOLS", False); + adelete = XInternAtom(display, "WM_DELETE_WINDOW", False); /* look for local and global conf file */ pwd = getpwuid(getuid());