bakkeby/patches

exclude the "no-border for unselected clients' behavior for the "mark and scratchpad" functionality

adetabrani opened this issue ยท 14 comments

Hi Bak, can we exclude the no-border for unselected clients patch behavior for the mark and renamedscratchpad functionality? because I often get confused about the window I'm marking and in scratchpad mode (normal & selected) when used in conjunction with your noborder patch, I want to still display the border when the window is marked and in scratchpad mode even though the window is not focused

simplescreenrecorder-.4.webm

If you look at the no-border-for-unselected-clients patch then there are two relevant checks.

Line 28 (in resizeclient):

+	if (c == selmon->sel)
+		wc.border_width = c->bw;

Line 43 (in showhide):

+		if (selmon->sel == c)
+			XMoveWindow(dpy, c->win, c->x, c->y);

I think you can just add exceptions in these if statements, e.g.

Line 28 (in resizeclient):

+	if (c == selmon->sel || ISMARKED(c) || c->scratchkey)
+		wc.border_width = c->bw;

Line 43 (in showhide):

+		if (selmon->sel == c || ISMARKED(c) || c->scratchkey)
+			XMoveWindow(dpy, c->win, c->x, c->y);

Thanks, works very well. Is your noborder patch intentional to always produce border focus even if it's only one window? is it possible to eliminate it when there is only 1 window and in a monocle layout?

Is your noborder patch intentional to always produce border focus even if it's only one window?

The patch is just a simple example of how to have no borders for unselected clients. When there is only one window it is usually selected so I'd say the answer is yes.

is it possible to eliminate it when there is only 1 window and in a monocle layout?

You could have another check alongside the two if statements referred to in the previous comment that works out whether this is a single tiled client or not.

It can get convoluted and maybe not so intuitive to read. Here is an example using precedence.

void
resizeclient(Client *c, int x, int y, int w, int h)
{
	XWindowChanges wc;
	int show_border = 0;

	c->oldx = c->x; c->x = wc.x = x;
	c->oldy = c->y; c->y = wc.y = y;
	c->oldw = c->w; c->w = wc.width = w;
	c->oldh = c->h; c->h = wc.height = h;

	if (c == selmon->sel)
		show_border = 1;

	if (c->isfloating == 0 && !(nexttiled(c->mon->clients) != c || nexttiled(c->next) != NULL))
		show_border = 0;

	if (ISMARKED(c) || c->scratchkey)
		show_border = 1;

	if (show_border)
		wc.border_width = c->bw;
	else {
		wc.border_width = 0;
		wc.x += c->bw;
		wc.y += c->bw;
	}
	
	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
	configure(c);
	XSync(dpy, False);
}

It reads as:

  • by default we do not show the border
  • if this is the selected client then we show the border
  • but if the client is tiled and it is the only tiled client, then we do not show the border
  • finally, if the client is marked or a scratchpad, then we show the border regardless

wow cool, thanks. I think your noborder patch also has a little bug with the awesomebar patch, when you hide some GUI window (eg: simplescreenrecorder, inkscape) and then bring them up again, the window is overwritten by the background layer on the previous window

simplescreenrecorder-.2.webm

That may be an application specific issue. Does it make any difference if you run a compositor?

When it run without the compositor this bug does not occur.

I have also tested it with a fresh install when I apply the noborder patch after awesomebar this bug will occur if run together with the compositor (picom)

Curious. It could be the general noborder issue.

In the resizeclient function a call to sendevent is made to signal to the window that the size has changed. After that a call to configure is made that sends a configure request to the window as well because some programs cause issues.

In principle the same logic should be made in the configure function when sending border details. Optionally the decision on whether to include the border or not can be forwarded to the configure function (would need a signature change).

simplescreenrecorder.webm

hi bak, it seems this bug is resolved if I open a new window, Is it possible to provide an event (i'm not sure, maybe arrange) every time a hidden window is displayed?

For the original patch I would try something like this:

diff --git a/dwm.c b/dwm.c
index 1450e65..d21ef86 100644
--- a/dwm.c
+++ b/dwm.c
@@ -542,7 +542,13 @@ configure(Client *c)
        ce.y = c->y;
        ce.width = c->w;
        ce.height = c->h;
-       ce.border_width = c->bw;
+       if (c == selmon->sel)
+               ce.border_width = c->bw;
+       else {
+               ce.border_width = 0;
+               ce.width += c->bw;
+               ce.height += c->bw;
+       }
        ce.above = None;
        ce.override_redirect = False;
        XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);

That is; apply the same change that was made in the resizeclient function to the configure function.

thank you very much for the help, works great ๐Ÿ˜Š

I take it that solved the issue. I'll look into updating the patches.

simplescreenrecorder.webm

Hi bak, sorry for reopening this issue, I just realized that when I marked all the windows, the border mark didn't immediately appear on all the windows but had to focus on the windows one by one, how to solve this?

Sorry if in the video the border mark color isn't very clear because I set it to yellow