bakkeby / patches

Collection of patches for dwm, st and dmenu
286 stars 30 forks source link

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

Closed adetabrani closed 1 year ago

adetabrani commented 1 year ago

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

bakkeby commented 1 year ago

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);
adetabrani commented 1 year ago

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?

bakkeby commented 1 year ago

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:

adetabrani commented 1 year ago

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

bakkeby commented 1 year ago

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

adetabrani commented 1 year ago

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)

bakkeby commented 1 year ago

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).

adetabrani commented 1 year ago

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?

bakkeby commented 1 year ago

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.

adetabrani commented 1 year ago

thank you very much for the help, works great 😊

bakkeby commented 1 year ago

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

adetabrani commented 1 year ago

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

adetabrani commented 1 year ago

Is there any feedback regarding this issue?

adetabrani commented 1 year ago
void
markclient(Client *c)
{
    if (!ISMARKED(c)) {
        c->marked = 1;
        ++num_marked;
        XSetWindowBorder(dpy, c->win, scheme[SchemeMarked][ColBorder].pixel);
    resizeclient(c, c->x, c->y, c->w, c->h);
    }
}

Solved, just added resizeclient to the markclient function