bakkeby/patches

dwm-focusedontop - continously switching focus in monocle layout

fitrh opened this issue · 9 comments

fitrh commented

Hi, after applying dwm-focusedontop patch, i found misbehavior when using it with monocle layout as default layout, it seem that the clients switching focus continously until swithced to another layout or try to click outside window area, here the preview

simplescreenrecorder-2021-05-07_00.29.48.mp4

Thanks for the report. I believe this has to do with a combination of how the sloppy focus work combined with the simplistic way the monocle layout arranges clients.

The monocle layout just places them all in order:

	for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
		resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);

I suspect that at this point the X server will send an EnterNotify event for the window under the mouse cursor, which will trigger another focus change later on.

If you move the mouse cursor to be on top of the bar then you shouldn't have this issue when spawning new clients.

Possibly the attach bottom patch would also avoid this, but I'm not too sure about that.

Maybe it doesn't make much sense to have focusedontop in combination with the monocle layout given that all tiled windows take up all of the screen.

+ if (focusedontop && c->mon->lt[c->mon->sellt]->arrange) {

Perhaps this would be better written as:

+		if (focusedontop && c->mon->lt[c->mon->sellt]->arrange && c->mon->lt[c->mon->sellt]->arrange != &monocle) {

In principle you can also have this issue with deck layouts. There are variants of both monocle and deck layouts that don't even bring the clients into view if they are not on top of the "stack" which would also address this issue.

I'm not sure if it is possible to get this patch to fully work with monocle and deck layouts without specially designed arrange functions that take all of this behaviour into account.

fitrh commented

Yes, i have done that, checking for if it is not in monocle layout inside focus function and checking if it is monocle layout inside focusstack function, but i think i can't get it work, because with this workaround, we lose the focused on top ability inside the monocle layout

@fitrh, could you try adding

XSync(dpy, True);

at the end of the new if statement in the focus function and see if that solves the issue for you?

void
focus(Client *c)
{
...
		if (focusedontop && c->mon->lt[c->mon->sellt]->arrange) {
...
			for (f = c->mon->stack; f; f = f->snext)
				if (f != c && f->isfloating && ISVISIBLE(f) && !f->alwaysontop) {
					XConfigureWindow(dpy, f->win, CWSibling|CWStackMode, &wc);
					wc.sibling = f->win;
				}
			XSync(dpy, True); // <-- add this
		}
...

I think this is cheating, but I don't see a clean way of doing it.

fitrh commented

I have added XSync(dpy, True) and remove the condition for monocle layout, it have an issue with dialog window, in my case, i have 2 client in monocle layout, firefox and uGet, if i close uGet, which is have a dialog confirmation window, after closed, the dialog window disappeared but i still can switching focus between firefox and the dialog window, it is like we still have 2 client even there are only one client

Yes I guess that would be a side effect of this change.

Alright, you can remove that line or change the True to False.

Now try adding this at the very end of the enternotify function:

XEvent xev;
while (XCheckMaskEvent(dpy, EnterWindowMask, &xev));

Seems to work fine for me. Also there are some focus issues so you may want to add this to the end of manage (if you want to ensure that new clients get focus instead of what's underneath the mouse) and at the end of focusstack so that you can actually reach all clients using keyboard shortcuts.

fitrh commented

@bakkeby thank you, i think this is better workaround, work fine for me too even without add it to focusstack function, or did you have some use case where we need to add it to focusstack ?

@fitrh I opened a lot of terminals in monocle layout, then I made several of them floating (e.g. 4 windows, overlapping).

What I found was that when I used focusstack I was able to focus on three of the four windows, but I could never get to the fourth one regardless of what direction I'd use focusstack in. Helps having different content on each window. With the change to that function I was able to get to all windows. I guess just try and see if you can replicate the issue, and if not then I guess you don't need the change.

fitrh commented

I get it now, i can reproduce the issue and adding it to focusstack solve it.