bakkeby / dwm-flexipatch

A dwm build with preprocessor directives to decide which patches to include during build time
MIT License
1.15k stars 232 forks source link

Trouble centering cursor over window when using skippy-xd #185

Open 766F6964 opened 2 years ago

766F6964 commented 2 years ago

Overview I am currently trying to integrate skippy-xd seamlessly in my dwm-flexipatch build. Skippy-xd is a program that essentially allows me to quickly get an overview of all active windows and jump to one without having to go through each tag, very handy if you forgot on which tag the window was, that you would like to switch to.

Configuration: I am running void linux with my dwm-flexipatch build. It is important to note that I already enabled the focusonnetactive patch, which was required to get skippy-xd to work properly in the first place.

Problem: When I run skippy-xd and select a window in the overview, it does switch correctly to the window even if it is on a different tag. The problem is that dwm places the mouse cursor at the left border of the left monitor, instead of the center of the selected window. I would like that after selecting a window in the skippy-xd view, that dwm places the mouse cursor in the center of the selected window, regardless of what monitor it is on. I am not 100% sure if this problem is dwm related, - but since the main functionality of skippy-xd seems to work fine, the cursor centering would be up to dwm. Is there a simple solution to fix this problem?

bakkeby commented 2 years ago

skippy-xd, never heard of that one before.

The warping of the mouse cursor is handled by skippy-xd:

$ grep -rn XWarpPointer skippy-xd
skippy-xd/src/clientwin.c:466:      XWarpPointer(ps->dpy, None, cw->wid_client,
skippy-xd/src/focus.h:32:       XWarpPointer(ps->dpy, None, cw->mini.window, 0, 0, 0, 0, cw->mini.width / 2, cw->mini.height / 2);

The cursor is moved if the movePointerOnRaise option is enabled.

void
childwin_focus(ClientWin *cw) {
    session_t * const ps = cw->mainwin->ps;

    if (ps->o.movePointerOnRaise)
        XWarpPointer(ps->dpy, None, cw->wid_client,
                0, 0, 0, 0, cw->src.width / 2, cw->src.height / 2);
    XRaiseWindow(ps->dpy, cw->wid_client);
    wm_activate_window(ps, cw->wid_client);
    XFlush(ps->dpy);
}

So you can try setting movePointerOnRaise to false in the skippy-xd.rc file and instead rely on the warp patch to move the cursor.

I believe the reason for the mouse cursor moving to the far left is that in dwm when a window is on a tag that is not displayed then the window is moved out of the way to a negative x position. The cursor ends up on the far left when skippy-xd tries to move the cursor to that location.

766F6964 commented 2 years ago

Thanks for the reply. The warp patch does not seem like an ideal solution. I only would want this behavior when the workspace is switched via skippy-xd, but not when I perform manual tag switching, then the cursor shouldn't get centered. Also, the warp patch only seems to partially work - it does center the mouse cursor if the selected window is on a different monitor, if it is on the current one, the cursor does not get centered. Is it possible to get the center-cursor-to-selected-window-behavior on all windows, but only when the switch to a different tag is done via skippy-xd, and not manually?

bakkeby commented 2 years ago

To do that I think you would need to move the warp call after the focus(c); statements in the clientmessage function:

    } else if (cme->message_type == netatom[NetActiveWindow]) {
        #if FOCUSONNETACTIVE_PATCH
        if (c->tags & c->mon->tagset[c->mon->seltags])
            focus(c);
        else {
            for (i = 0; i < NUMTAGS && !((1 << i) & c->tags); i++);
            if (i < NUMTAGS) {
                if (c != selmon->sel)
                    unfocus(selmon->sel, 0, NULL);
                selmon = c->mon;
                if (((1 << i) & TAGMASK) != selmon->tagset[selmon->seltags])
                    view(&((Arg) { .ui = 1 << i }));
                focus(c);
                restack(selmon);
            }
        }
        #else
        if (c != selmon->sel && !c->isurgent)
            seturgent(c, 1);
        #endif // FOCUSONNETACTIVE_PATCH
    }

and remove the warp call from the restack function.

If you are serious about getting the built-in warp functionality in skippy-xd to work then that is possible, but you would have to make changes in the showhide function to instead of moving windows to a negative x position (and back) you would change the state of the window between NormalState and IconicState and map/unmap the windows.