bakkeby / patches

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

Pin systray to both screens on dual-monitor setup #51

Closed Zsargul closed 2 years ago

Zsargul commented 2 years ago

I am using the systray patch alongside statuscmd and status2d. I managed to get them working together after some trouble but now another patch, status bar on all monitors is causing some trouble. Basically, as intended, the status bar is being displayed with the length of the systray in mind, therefore preventing overlap with applet icons and so on:

image

The problem however starts once I try to display this on both my monitors. My second monitor, although also displaying the status bar as per the status bar on all monitors patch, does not display the systray but still takes into account the systray's "offset", resulting in the following strange look:

image

I pinned the systray to this other monitor and it then displayed correctly, but obviously the old monitor (now without the systray) was now the one with this weird bug.

Would it be possible to pin the systray to both screens in order to get around this weird problem?

bakkeby commented 2 years ago

It is a limitation of X that you can't display the same window in two places at the same time. The systay is a window and each systay icon are also individual windows.

In this case your only option is to either display the systay on a dedicated monitor or on the active monitor.

bakkeby commented 2 years ago

Using the status on all monitors patch is fine in this context.

The weird "glitch" that you are referring to is simply that in drawbar (and possibly in buttonpress) you are at some point getting the width of the systray and using that when calculating the position of the status.

The getting of the systray width must take into account whether the systay is being drawn on the given monitor or not. That's all.

Zsargul commented 2 years ago

Thanks for your reply. After taking a look and some tinkering I found a fix by changing some lines in the drawstatusbar and buttonpress functions.

drawstatusbar

I changed the original (which was already changed a bit previously to fix an unrelated problem) from:

ret = m->ww - w;
x = ret - getsystraywidth(); /* Prevent overlap of status2d and systray */

to this:

if (showsystray && m == systraytomon(m) && !systrayonleft) {
    ret = m->ww - w;
    x = ret - getsystraywidth(); /* Prevent overlap of status2d and systray */
} else {
    ret = x = m->ww - w;    
}

buttonpress

As you said, this function used getsystraywidth and initially resulted in a weird offset that made the clickable block area slightly bigger than the text itself. I fixed this by changing the lines:

x = selmon->ww - TEXTW(stext) + lrpad - getsystraywidth();

to:

/* Render clickable block area with systray's length automatically
 * added on */
if (showsystray && m == systraytomon(m) && !systrayonleft) {
    x = selmon->ww - TEXTW(stext) + lrpad; 
} else {
    /* Move clickable block area slightly to the right to account
     * for systray length */
    x = selmon->ww - TEXTW(stext) + lrpad + getsystraywidth();
}

I've only been using/tinkering with DWM for a short while so I don't have a good understanding of the patches and source code, but I assume that the if-statement guard uses systraytomon(m) to check whether or not the monitor m in question has the systray assigned to it.

The buttonpress solution seems to break again if a new application is opened that spawns an applet (such as telegram) because the bar isn't redrawn properly and rather than updating the systray's width, it uses the initial width taken up by applets launched at boot time. But at least I got the main problem fixed lol.

bakkeby commented 2 years ago

The buttonpress solution seems to break again if a new application is opened that spawns an applet (such as telegram) because the bar isn't redrawn properly and rather than updating the systray's width, it uses the initial width taken up by applets launched at boot time.

I assume that you are using the systray patch from the suckless site then. That does indeed not update the bar when new icons are added to the bar. You can add a call to drawbar after the call to updatesystray() in the clientmessage function to alleviate this some. If you want to eliminate these issues you'll want to do this in more places.

Zsargul commented 2 years ago

I assume that you are using the systray patch from the suckless site then. That does indeed not update the bar when new icons are added to the bar.

Is there a version of the patch that does update the bar when new icons are added? If so I'd rather just swap my current version for that to make sure no issues related to this are unaccounted for.

bakkeby commented 2 years ago

I have a version in this repository, but that is specifically for combining with the alpha patch.

The only practical difference is how the original one resizes the bar to add space for the systay window vs the alpha version where the systay is placed on top of the bar and space is made available within the bar (space after the status).