X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=d6f4d233378c18e69d671195000ee4dae4575137;hb=11e890bb3f0ce8bcabc3fa8f35a8699ac106ab2d;hp=520f15624a421e8191c0075c9698cade8a4fec98;hpb=a2a8bae91b7dcc662140ef915f8da5d104feb91c;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 520f156..d6f4d23 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -126,6 +126,7 @@ u_int32_t swm_debug = 0 #define MODKEY Mod1Mask #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) +#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define SWM_PROPLEN (16) #define X(r) (r)->g.x #define Y(r) (r)->g.y @@ -157,6 +158,8 @@ double dialog_ratio = .6; char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; char bar_ext[SWM_BAR_MAX]; +char bar_vertext[SWM_BAR_MAX]; +int bar_version = 0; sig_atomic_t bar_alarm = 0; int bar_delay = 30; int bar_enabled = 1; @@ -312,6 +315,7 @@ union arg { char **argv; }; +/* quirks */ struct quirk { char *class; char *name; @@ -323,6 +327,37 @@ struct quirk { { NULL, NULL, 0}, }; +/* events */ +void expose(XEvent *); +void keypress(XEvent *); +void buttonpress(XEvent *); +void configurerequest(XEvent *); +void configurenotify(XEvent *); +void destroynotify(XEvent *); +void enternotify(XEvent *); +void focusin(XEvent *); +void mappingnotify(XEvent *); +void maprequest(XEvent *); +void propertynotify(XEvent *); +void unmapnotify(XEvent *); +void visibilitynotify(XEvent *); + +void (*handler[LASTEvent])(XEvent *) = { + [Expose] = expose, + [KeyPress] = keypress, + [ButtonPress] = buttonpress, + [ConfigureRequest] = configurerequest, + [ConfigureNotify] = configurenotify, + [DestroyNotify] = destroynotify, + [EnterNotify] = enternotify, + [FocusIn] = focusin, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, + [PropertyNotify] = propertynotify, + [UnmapNotify] = unmapnotify, + [VisibilityNotify] = visibilitynotify, +}; + unsigned long name_to_color(char *colorname) { @@ -566,8 +601,8 @@ bar_update(void) for (i = 0; i < ScreenCount(display); i++) { x = 1; TAILQ_FOREACH(r, &screens[i].rl, entry) { - snprintf(loc, sizeof loc, "%s %d:%d %s", - s, x++, r->ws->idx + 1, bar_ext); + snprintf(loc, sizeof loc, "%s %d:%d %s %s", + s, x++, r->ws->idx + 1, bar_ext, bar_vertext); bar_print(r, loc); } } @@ -693,6 +728,17 @@ bar_setup(struct swm_region *r) } void +version(struct swm_region *r, union arg *args) +{ + bar_version = !bar_version; + if (bar_version) + strlcpy(bar_vertext, cvstag, sizeof bar_vertext); + else + strlcpy(bar_vertext, "", sizeof bar_vertext); + bar_update(); +} + +void config_win(struct ws_win *win) { XConfigureEvent ce; @@ -1482,6 +1528,9 @@ send_to_ws(struct swm_region *r, union arg *args) Atom ws_idx_atom = 0; unsigned char ws_idx_str[SWM_PROPLEN]; + if (win == NULL) + return; + DNPRINTF(SWM_D_MOVE, "send_to_ws: win: %lu\n", win->id); ws = win->ws; @@ -1605,23 +1654,133 @@ struct key { { MODKEY | ShiftMask, XK_x, wkill, {0} }, { MODKEY, XK_s, screenshot, {.id = SWM_ARG_ID_SS_ALL} }, { MODKEY | ShiftMask, XK_s, screenshot, {.id = SWM_ARG_ID_SS_WINDOW} }, + { MODKEY | ShiftMask, XK_v, version, {0} }, }; void -click(struct swm_region *r, union arg *args) +resize_window(struct ws_win *win) { - DNPRINTF(SWM_D_MOUSE, "click: button: %d\n", args->id); + unsigned int mask; + XWindowChanges wc; + struct swm_region *r; - switch (args->id) { - case Button1: - break; - case Button2: - break; - case Button3: - break; - default: + r = root_to_region(win->wa.root); + bzero(&wc, sizeof wc); + mask = CWX | CWY | CWBorderWidth | CWWidth | CWHeight; + wc.border_width = 1; + wc.width = win->g.w; + wc.height = win->g.h; + wc.x = (WIDTH(r) - win->g.w) / 2; + wc.y = (HEIGHT(r) - win->g.h) / 2; + + DNPRINTF(SWM_D_STACK, "resize_window: win %lu x %d y %d w %d h %d\n", + win->id, wc.x, wc.y, wc.width, wc.height); + + XConfigureWindow(display, win->id, mask, &wc); + config_win(win); +} + +void +resize(struct ws_win *win, union arg *args) +{ + XEvent ev; + + DNPRINTF(SWM_D_MOUSE, "resize: win %d floating %d trans %d\n", + win->id, win->floating, win->transient); + + if (!(win->transient != 0 || win->floating != 0)) return; - } + + if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync, + GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess) + return; + XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w, win->g.h); + do { + XMaskEvent(display, MOUSEMASK | ExposureMask | + SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + XSync(display, False); + if (ev.xmotion.x < 0) + ev.xmotion.x = 0; + if (ev.xmotion.y < 0) + ev.xmotion.y = 0; + win->g.w = ev.xmotion.x; + win->g.h = ev.xmotion.y; + resize_window(win); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w - 1, + win->g.h - 1); + XUngrabPointer(display, CurrentTime); + + /* drain events */ + while (XCheckMaskEvent(display, EnterWindowMask, &ev)); +} + +void +move_window(struct ws_win *win) +{ + unsigned int mask; + XWindowChanges wc; + struct swm_region *r; + + r = root_to_region(win->wa.root); + bzero(&wc, sizeof wc); + mask = CWX | CWY; + wc.x = win->g.x; + wc.y = win->g.y; + + DNPRINTF(SWM_D_STACK, "move_window: win %lu x %d y %d w %d h %d\n", + win->id, wc.x, wc.y, wc.width, wc.height); + + XConfigureWindow(display, win->id, mask, &wc); + config_win(win); +} + +void +move(struct ws_win *win, union arg *args) +{ + XEvent ev; + + DNPRINTF(SWM_D_MOUSE, "move: win %d floating %d trans %d\n", + win->id, win->floating, win->transient); + + if (!(win->transient != 0 || win->floating != 0)) + return; + + if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync, + GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess) + return; + XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0); + do { + XMaskEvent(display, MOUSEMASK | ExposureMask | + SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + XSync(display, False); + win->g.x = ev.xmotion.x_root; + win->g.y = ev.xmotion.y_root; + move_window(win); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0); + XUngrabPointer(display, CurrentTime); + + /* drain events */ + while (XCheckMaskEvent(display, EnterWindowMask, &ev)); } /* mouse */ @@ -1630,11 +1789,12 @@ struct button { unsigned int action; unsigned int mask; unsigned int button; - void (*func)(struct swm_region *r, union arg *); + void (*func)(struct ws_win *, union arg *); union arg args; } buttons[] = { /* action key mouse button func args */ - { client_click, MODKEY, Button1, click, {.id=Button1} }, + { client_click, MODKEY, Button3, resize, {0} }, + { client_click, MODKEY, Button1, move, {0} }, }; void @@ -1750,8 +1910,7 @@ buttonpress(XEvent *e) if (action == buttons[i].action && buttons[i].func && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(root_to_region(ev->root), - &buttons[i].args); + buttons[i].func(win, &buttons[i].args); } void @@ -2075,22 +2234,6 @@ visibilitynotify(XEvent *e) bar_update(); } -void (*handler[LASTEvent])(XEvent *) = { - [Expose] = expose, - [KeyPress] = keypress, - [ButtonPress] = buttonpress, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [FocusIn] = focusin, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify, - [VisibilityNotify] = visibilitynotify, -}; - int xerror_start(Display *d, XErrorEvent *ee) {