Example #1
0
void
mousefunc_client_move(struct client_ctx *cc, union arg *arg)
{
    XEvent			 ev;
    Time			 ltime = 0;
    struct screen_ctx	*sc = cc->sc;
    struct geom		 xine;
    int			 px, py;

    client_raise(cc);

    if (cc->flags & CLIENT_FREEZE)
        return;

    if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_MOVE]) < 0)
        return;

    xu_ptr_getpos(cc->win, &px, &py);

    for (;;) {
        XMaskEvent(X_Dpy, MOUSEMASK, &ev);

        switch (ev.type) {
        case MotionNotify:
            cc->geom.x = ev.xmotion.x_root - px - cc->bwidth;
            cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;

            xine = screen_find_xinerama(sc,
                                        cc->geom.x + cc->geom.w / 2,
                                        cc->geom.y + cc->geom.h / 2, CWM_GAP);
            cc->geom.x += client_snapcalc(cc->geom.x,
                                          cc->geom.x + cc->geom.w + (cc->bwidth * 2),
                                          xine.x, xine.x + xine.w, sc->snapdist);
            cc->geom.y += client_snapcalc(cc->geom.y,
                                          cc->geom.y + cc->geom.h + (cc->bwidth * 2),
                                          xine.y, xine.y + xine.h, sc->snapdist);

            /* don't move more than 60 times / second */
            if ((ev.xmotion.time - ltime) > (1000 / 60)) {
                ltime = ev.xmotion.time;
                client_move(cc);
            }
            break;
        case ButtonRelease:
            if (ltime)
                client_move(cc);
            xu_ptr_ungrab();
            return;
        }
    }
    /* NOTREACHED */
}
Example #2
0
void
mousefunc_client_move(void *ctx, union arg *arg, enum xev xev)
{
	struct client_ctx	*cc = ctx;
	XEvent			 ev;
	Time			 ltime = 0;
	struct screen_ctx	*sc = cc->sc;
	struct geom		 area;
	int			 px, py;

	client_raise(cc);

	if (cc->flags & CLIENT_FREEZE)
		return;

	xu_ptr_getpos(cc->win, &px, &py);
	if (px < 0) 
		px = 0;
	else if (px > cc->geom.w)
		px = cc->geom.w;
	if (py < 0)
		py = 0;
	else if (py > cc->geom.h)
		py = cc->geom.h;

	xu_ptr_setpos(cc->win, px, py);

	if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_MOVE],
	    CurrentTime) != GrabSuccess)
		return;

	menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);

	for (;;) {
		XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev);

		switch (ev.type) {
		case MotionNotify:
			/* not more than 60 times / second */
			if ((ev.xmotion.time - ltime) <= (1000 / 60))
				continue;
			ltime = ev.xmotion.time;

			cc->geom.x = ev.xmotion.x_root - px - cc->bwidth;
			cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;

			area = screen_area(sc,
			    cc->geom.x + cc->geom.w / 2,
			    cc->geom.y + cc->geom.h / 2, CWM_GAP);
			cc->geom.x += client_snapcalc(cc->geom.x,
			    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
			    area.x, area.x + area.w, sc->snapdist);
			cc->geom.y += client_snapcalc(cc->geom.y,
			    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
			    area.y, area.y + area.h, sc->snapdist);
			client_move(cc);
			menu_windraw(sc, cc->win,
			    "%4d, %-4d", cc->geom.x, cc->geom.y);
			break;
		case ButtonRelease:
			client_move(cc);
			XUnmapWindow(X_Dpy, sc->menu.win);
			XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
			XUngrabPointer(X_Dpy, CurrentTime);
			return;
		}
	}
	/* NOTREACHED */
}
Example #3
0
struct menu *
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
    const char *initial, int flags,
    void (*match)(struct menu_q *, struct menu_q *, char *),
    void (*print)(struct menu *, int))
{
	struct menu_ctx		 mc;
	struct menu_q		 resultq;
	struct menu		*mi = NULL;
	XEvent			 e;
	Window			 focuswin;
	int			 focusrevert, xsave, ysave, xcur, ycur;

	TAILQ_INIT(&resultq);

	xu_ptr_getpos(sc->rootwin, &xsave, &ysave);

	(void)memset(&mc, 0, sizeof(mc));
	mc.sc = sc;
	mc.flags = flags;
	mc.match = match;
	mc.print = print;
	mc.entry = mc.prev = -1;
	mc.geom.x = xsave;
	mc.geom.y = ysave;

	if (mc.flags & CWM_MENU_LIST)
		mc.list = 1;

	(void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr));
	if (initial != NULL)
		(void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr));
	else
		mc.searchstr[0] = '\0';

	mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
	    Conf.bwidth,
	    sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
	mc.xftdraw = XftDrawCreate(X_Dpy, mc.win,
	    sc->visual, sc->colormap);

	XSelectInput(X_Dpy, mc.win, MENUMASK);
	XMapRaised(X_Dpy, mc.win);

	if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
	    CurrentTime) != GrabSuccess) {
		XftDrawDestroy(mc.xftdraw);
		XDestroyWindow(X_Dpy, mc.win);
	}

	XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
	XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime);

	/* make sure keybindings don't remove keys from the menu stream */
	XGrabKeyboard(X_Dpy, mc.win, True,
	    GrabModeAsync, GrabModeAsync, CurrentTime);

	for (;;) {
		mc.changed = 0;

		XWindowEvent(X_Dpy, mc.win, MENUMASK, &e);

		switch (e.type) {
		case KeyPress:
			if ((mi = menu_handle_key(&e, &mc, menuq, &resultq))
			    != NULL)
				goto out;
			/* FALLTHROUGH */
		case Expose:
			menu_draw(&mc, menuq, &resultq);
			break;
		case MotionNotify:
			menu_handle_move(&mc, &resultq,
			    e.xbutton.x, e.xbutton.y);
			break;
		case ButtonRelease:
			if ((mi = menu_handle_release(&mc, &resultq,
			    e.xbutton.x, e.xbutton.y)) != NULL)
				goto out;
			break;
		default:
			break;
		}
	}
out:
	if ((mc.flags & CWM_MENU_DUMMY) == 0 && mi->dummy) {
	       	/* no mouse based match */
		free(mi);
		mi = NULL;
	}

	XftDrawDestroy(mc.xftdraw);
	XDestroyWindow(X_Dpy, mc.win);

	XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
	/* restore if user didn't move */
	xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
	if (xcur == mc.geom.x && ycur == mc.geom.y)
		xu_ptr_setpos(sc->rootwin, xsave, ysave);

	XUngrabPointer(X_Dpy, CurrentTime);
	XUngrabKeyboard(X_Dpy, CurrentTime);

	return(mi);
}
Example #4
0
File: menu.c Project: S010/cwm
struct menu *
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
    char *initial, int dummy,
    void (*match)(struct menu_q *, struct menu_q *, char *),
    void (*print)(struct menu *, int))
{
	struct menu_ctx		 mc;
	struct menu_q		 resultq;
	struct menu		*mi = NULL;
	XEvent			 e;
	Window			 focuswin;
	int			 evmask, focusrevert;
	int			 xsave, ysave, xcur, ycur;

	TAILQ_INIT(&resultq);

	bzero(&mc, sizeof(mc));

	xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y);

	xsave = mc.x;
	ysave = mc.y;

	if (prompt == NULL) {
		evmask = MENUMASK;
		mc.promptstr[0] = '\0';
		mc.list = 1;
	} else {
		evmask = MENUMASK | KEYMASK; /* only accept keys if prompt */
		(void)snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%s",
		    prompt, PROMPT_SCHAR);
		(void)snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%s",
		    mc.promptstr, mc.searchstr, PROMPT_ECHAR);
		mc.width = font_width(sc, mc.dispstr, strlen(mc.dispstr));
		mc.hasprompt = 1;
	}

	if (initial != NULL)
		(void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr));
	else
		mc.searchstr[0] = '\0';

	mc.match = match;
	mc.print = print;
	mc.entry = mc.prev = -1;

	XMoveResizeWindow(X_Dpy, sc->menuwin, mc.x, mc.y, mc.width,
	    font_height(sc));
	XSelectInput(X_Dpy, sc->menuwin, evmask);
	XMapRaised(X_Dpy, sc->menuwin);

	if (xu_ptr_grab(sc->menuwin, MENUGRABMASK, Cursor_question) < 0) {
		XUnmapWindow(X_Dpy, sc->menuwin);
		return (NULL);
	}

	XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
	XSetInputFocus(X_Dpy, sc->menuwin, RevertToPointerRoot, CurrentTime);

	/* make sure keybindings don't remove keys from the menu stream */
	XGrabKeyboard(X_Dpy, sc->menuwin, True,
	    GrabModeAsync, GrabModeAsync, CurrentTime);

	menu_draw(sc, &mc, menuq, &resultq);

	for (;;) {
		mc.changed = 0;

		XWindowEvent(X_Dpy, sc->menuwin, evmask, &e);

		switch (e.type) {
		case KeyPress:
			if ((mi = menu_handle_key(&e, &mc, menuq, &resultq))
			    != NULL)
				goto out;
			/* FALLTHROUGH */
		case Expose:
			menu_draw(sc, &mc, menuq, &resultq);
			break;
		case MotionNotify:
			menu_handle_move(&e, &mc, &resultq, sc);
			break;
		case ButtonRelease:
			if ((mi = menu_handle_release(&e, &mc, sc, &resultq))
			    != NULL)
				goto out;
			break;
		default:
			break;
		}
	}
out:
	if (dummy == 0 && mi->dummy) { /* no mouse based match */
		xfree(mi);
		mi = NULL;
	}

	XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
	/* restore if user didn't move */
	xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
	if (xcur == mc.x && ycur == mc.y)
		xu_ptr_setpos(sc->rootwin, xsave, ysave);
	xu_ptr_ungrab();

	XUnmapWindow(X_Dpy, sc->menuwin);
	XUngrabKeyboard(X_Dpy, CurrentTime);

	return (mi);
}