Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: XWorkspaces does not refresh the viewport list #2693

Closed
5 tasks done
Pachin0 opened this issue Apr 20, 2022 · 8 comments
Closed
5 tasks done

[Bug]: XWorkspaces does not refresh the viewport list #2693

Pachin0 opened this issue Apr 20, 2022 · 8 comments

Comments

@Pachin0
Copy link

Pachin0 commented Apr 20, 2022

Checklist

  • I have read the appropriate section in the contributing guidelines
  • I believe this issue is a problem with polybar itself and not a misconfiguration on my part
  • I have searched for other open and closed issues that may have already reported this problem
  • I have checked the known issues page for this problem.
  • I have followed the debugging guide to narrow down the problem to a minimal config.

Steps to reproduce

  1. Have a window manager that does not have independent workspaces. Ala xmonad, where a tag can be on any monitor.
  2. Have 2 monitors or more
  3. Have it support the desktop_viewport ewmh extension (I implemented viewport support for my xmonad)
  4. See how polybar, when it is started, reads the list of workspaces and their viewports. When pinned-workspaces is on, polybar would include in its workspace list, only the workspaces that were on its monitor during startup and not update with the changing net_desktop_viewport

I believe qtile has the same behaviour, where our workpaces change their viewports dynamically, depending on the monitor we display them.

Minimal config

[bar/this]
width = 100%
height = 24pt
monitor = yourmonitor

background = #000000
foreground = #ffffff
line-size = 3pt

border-size = 4pt
border-color = #00000000
modules-left = xworkspaces




[module/xworkspaces]
type = internal/xworkspaces

label-active = %name%
label-active-background = ${colors.background-alt}
label-active-underline= ${colors.primary}
label-active-padding = 1

label-occupied = %name%
label-occupied-padding = 1

label-urgent = %name%
label-urgent-background = ${colors.alert}
label-urgent-padding = 1

label-empty = %name%
label-empty-foreground = ${colors.disabled}
label-empty-padding = 1
pin-workspaces = true

Polybar log

No response

Expected behavior

Since the pinned workspaces implementation of polybar right now, does not expect workspaces to have their viewports dynamically, I think xworkspaces module should refresh it when it changes.

Actual behavior

See how polybar, when it is started, reads the list of workspaces and their viewports. When pinned-workspaces is on, polybar would include in its workspace list, only the workspaces that were on its monitor during startup and not update with the changing net_desktop_viewport

Window Manager and Version

xmonad with ewmh and my _net_desktop_viewport implementation

Linux Distribution

gentoo

Polybar version

polybar 3.6.2

Additional Context / Screenshots

I believe any wm with viewport support and tags that are shared in all monitors support ewmh this way.

Here it is a SS of wmctl -d when the current focused monitor is in workspace 1 (the 0 1366 viewport) and the other visible monitor is resting with workspace 2 (0 0 viewport). (mind the other non visible workspaces I like setting them in the focused monitor viewport, so that polybar maybe if this resolves, has close to my eye the workspaces I might go)

$ wmctrl -d
0  * DG: N/A  VP: 1366,0  WA: N/A  1
1  - DG: N/A  VP: 0,0     WA: N/A  2
2  - DG: N/A  VP: 1366,0  WA: N/A  3
3  - DG: N/A  VP: 1366,0  WA: N/A  4
4  - DG: N/A  VP: 1366,0  WA: N/A  5
5  - DG: N/A  VP: 1366,0  WA: N/A  6
6  - DG: N/A  VP: 1366,0  WA: N/A  7
7  - DG: N/A  VP: 1366,0  WA: N/A  8
8  - DG: N/A  VP: 1366,0  WA: N/A  9

Now this is what happens when I switch the tags across my monitors. See how workspace 1 and 2 have had their viewports switched (ignore the hidden workspaces 3 - 9)

0  * DG: N/A  VP: 0,0     WA: N/A  1
1  - DG: N/A  VP: 1366,0  WA: N/A  2
2  - DG: N/A  VP: 0,0     WA: N/A  3
3  - DG: N/A  VP: 0,0     WA: N/A  4
4  - DG: N/A  VP: 0,0     WA: N/A  5
5  - DG: N/A  VP: 0,0     WA: N/A  6
6  - DG: N/A  VP: 0,0     WA: N/A  7
7  - DG: N/A  VP: 0,0     WA: N/A  8
8  - DG: N/A  VP: 0,0     WA: N/A  9

If you want to run this with xmonad, you have to include the viewport support on your log hook with these 2 functions

getDesktopViewport = withWindowSet $ \x -> do
  sort' <- mkViewPortSort getWsCompare
  let cS = W.current x
      vS = W.visible x
      hWs = W.hidden x 
      viewPorts = sort' $ map mkViewPort' (cS : vS)
        ++ map (`mkViewPort` cS) hWs 
  setDesktopViewport $ viewPortList viewPorts
  where
    mkViewPort w s = (W.tag w, screenToViewPort s)
    mkViewPort' s = mkViewPort (W.workspace s) s
    mkViewPortSort cmpX = do
      cmp <- cmpX
      return $ sortBy (\a b -> cmp (fst a) (fst b))
    viewPortList list = concatMap ((\(a,b) -> a : [b]) . snd ) list
    
setDesktopViewport :: [Position] -> X ()
setDesktopViewport l = withDisplay $ \dpy -> do
  a <- io $ internAtom dpy "_NET_DESKTOP_VIEWPORT" True
  r <- asks theRoot
  let n = map fromIntegral l
  io $ changeProperty32 dpy r a cARDINAL propModeReplace n

and also add this into the startup hook

setSupported :: X ()
setSupported = withDisplay $ \dpy -> do
    r <- asks theRoot
    a <- getAtom "_NET_SUPPORTED"
    supp <- mapM getAtom ["_NET_WM_STATE_HIDDEN"
                         ,"_NET_WM_STATE_DEMANDS_ATTENTION"
                         ,"_NET_NUMBER_OF_DESKTOPS"
                         ,"_NET_CLIENT_LIST"
                         ,"_NET_CLIENT_LIST_STACKING"
                         ,"_NET_CURRENT_DESKTOP"
                         ,"_NET_DESKTOP_NAMES"
                         ,"_NET_ACTIVE_WINDOW"
                         ,"_NET_WM_DESKTOP"
                         ,"_NET_WM_STRUT"
                         ,"_NET_DESKTOP_VIEWPORT"
                         ]
    io $ changeProperty32 dpy r a aTOM propModeReplace (fmap fromIntegral supp)`
@patrick96
Copy link
Member

In addition to the output of wmctrl -d, can you also post the output of xprop -root as well as which workspaces polybar actually displays on which screen in the two scenarios you posted?

@Pachin0
Copy link
Author

Pachin0 commented Apr 23, 2022

Here it is. The polybars have pinned-workspaces = true. Mind you that polybar does get it the workspaces to display right, but only at startup, as the workspaces change around their viewport the bar does not update them afterwards.

First focus is on worspace 1, right screen (0 1366) and the other visible workspace is on the left monitor (0 0). I launched the 2 polybars with this setup.

AT_SPI_BUS(STRING) = "unix:path=/run/user/1000/at-spi/bus_0,guid=211360c467283d395768304e626362fd"
XFree86_DDC_EDID1_RAWDATA(INTEGER) = 0, -1, -1, -1, -1, -1, -1, 0, 48, -82, 20, 10, 1, 1, 1, 1, 44, 23, 1, 3, -128, 41, 23, 120, 42, -15, 37, -92, 84, 86, -97, 40, 12, 80, 84, -83, -50, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 102, 33, 86, -86, 81, 0, 30, 48, 70, -113, 51, 0, -102, -26, 16, 0, 0, 30, 102, 33, 80, -80, 81, 0, 27, 48, 64, 112, 54, 0, -102, -26, 16,
0, 0, 30, 0, 0, 0, -3, 0, 50, 75, 30, 60, 14, 0, 10, 32, 32, 32, 32, 32, 32, 0, 0, 0, -4, 0, 76, 69, 78, 32, 76, 83, 49, 57, 50, 50, 119, 65, 10, 1, -115, 2, 3, 27, 97, 35, 9, 7, 7, -125,
1, 0, 0, 103, 3, 12, 0, 32, 0, -128, 45, 67, -112, -124, 2, -30, 0, 15, -116, 10, -48, -118, 32, -32, 45, 16, 16, 62, -106, 0, -96, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 41
GDK_VISUALS(INTEGER) = 1287, 1705
_NET_DESKTOP_VIEWPORT(CARDINAL) = 1366, 0, 0, 0, 1366, 0, 1366, 0, 1366, 0, 1366, 0, 1366, 0,
1366, 0, 1366, 0
ESETROOT_PMAP_ID(PIXMAP): pixmap id # 0xc00004
_XROOTPMAP_ID(PIXMAP): pixmap id # 0xc00004
_NET_SUPPORTING_WM_CHECK(WINDOW): window id # 0x800001
_NET_SUPPORTED(ATOM) = _NET_SUPPORTING_WM_CHECK, _NET_WM_NAME, _NET_WM_STATE_HIDDEN, _NET_WM_STATE_DEMANDS_ATTENTION, _NET_NUMBER_OF_DESKTOPS, _NET_CLIENT_LIST, _NET_CLIENT_LIST_STACKING,
_NET_CURRENT_DESKTOP, _NET_DESKTOP_NAMES, _NET_ACTIVE_WINDOW, _NET_WM_DESKTOP, _NET_WM_STRUT
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1600006
_NET_CLIENT_LIST_STACKING(WINDOW): window id # 0x120002c, 0x1600006, 0xe0068d
_NET_CLIENT_LIST(WINDOW): window id # 0x120002c, 0x1600006, 0xe0068d
_NET_DESKTOP_NAMES(UTF8_STRING) = "1", "2", "3", "4", "5", "6", "7", "8", "9"
_NET_NUMBER_OF_DESKTOPS(CARDINAL) = 9
_NET_CURRENT_DESKTOP(CARDINAL) = 0
_XKB_RULES_NAMES(STRING) = "evdev", "pc105", "us", "", ""
XFree86_has_VT(INTEGER) = 1
XFree86_VT(INTEGER) = 1
Xorg_Seat(STRING) = "seat0"

The polybar on the right monitor (0 1366) displays 1 3 4 5 6 7 7 8 9
and the polybar on the left displays only workspace 2. This is actually correct, but look what happens if I focus another workspace on the left monitor (0,0), in this case i'll put workspace 3 to be on the left monitor (0,0)

AT_SPI_BUS(STRING) = "unix:path=/run/user/1000/at-spi/bus_0,guid=211360c467283d395768304e626362fd"
XFree86_DDC_EDID1_RAWDATA(INTEGER) = 0, -1, -1, -1, -1, -1, -1, 0, 48, -82, 20, 10, 1, 1, 1, 1, 44, 23, 1, 3, -128, 41, 23, 120, 42, -15, 37, -92, 84, 86, -97, 40, 12, 80, 84, -83, -50, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 102, 33, 86, -86, 81, 0, 30, 48, 70, -113, 51, 0, -102, -26, 16, 0, 0, 30, 102, 33, 80, -80, 81, 0, 27, 48, 64, 112, 54, 0, -102, -26, 16, 0, 0, 30, 0, 0, 0, -3, 0, 50, 75, 30, 60, 14, 0, 10, 32, 32, 32, 32, 32, 32, 0, 0, 0, -4, 0, 76, 69, 78, 32, 76, 83, 49, 57, 50, 50, 119, 65, 10, 1, -115, 2, 3, 27, 97, 35, 9, 7, 7, -125, 1, 0, 0, 103, 3, 12, 0, 32, 0, -128, 45, 67, -112, -124, 2, -30, 0, 15, -116, 10, -48, -118, 32, -32, 45, 16, 16, 62, -106, 0, -96, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 41
GDK_VISUALS(INTEGER) = 1287, 1705
_NET_DESKTOP_VIEWPORT(CARDINAL) = 1366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
ESETROOT_PMAP_ID(PIXMAP): pixmap id # 0xc00004
_XROOTPMAP_ID(PIXMAP): pixmap id # 0xc00004
_NET_SUPPORTING_WM_CHECK(WINDOW): window id # 0x800001
_NET_SUPPORTED(ATOM) = _NET_SUPPORTING_WM_CHECK, _NET_WM_NAME, _NET_WM_STATE_HIDDEN, _NET_WM_STATE_DEMANDS_ATTENTION, _NET_NUMBER_OF_DESKTOPS, _NET_CLIENT_LIST, _NET_CLIENT_LIST_STACKING, _NET_CURRENT_DESKTOP, _NET_DESKTOP_NAMES, _NET_ACTIVE_WINDOW, _NET_WM_DESKTOP, _NET_WM_STRUT
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1600006
_NET_CLIENT_LIST_STACKING(WINDOW): window id # 0x120002c, 0xe0068d, 0x1600006
_NET_CLIENT_LIST(WINDOW): window id # 0x120002c, 0xe0068d, 0x1600006
_NET_DESKTOP_NAMES(UTF8_STRING) = "1", "2", "3", "4", "5", "6", "7", "8", "9"
_NET_NUMBER_OF_DESKTOPS(CARDINAL) = 9
_NET_CURRENT_DESKTOP(CARDINAL) = 2
_XKB_RULES_NAMES(STRING) = "evdev", "pc105", "us", "", ""
XFree86_has_VT(INTEGER) = 1
XFree86_VT(INTEGER) = 1
Xorg_Seat(STRING) = "seat0"

The window manager was set the workspace 3 and all the other workspaces except 1 to be displayed on the left polybar. Yet the left polybar only shows workspace 2, and the right polybar still shows workspace 1 3 4 5 6 7 8 9. The correct thing to show would be that the left polybar now shows 2 3 4 5 6 7 8 9 and the right polybar shows only workspace 1.

@patrick96
Copy link
Member

Thanks for the detailed info :)

Can you try out PR #2698, it should update the module whenever you change _NET_DESKTOP_VIEWPORT

@Pachin0
Copy link
Author

Pachin0 commented Apr 25, 2022

It works amaizingly. Now practically any window manager that uses _NET_DESKTOP_VIEWPORT under the sun works amazingly out of the box with polybar.

@Pachin0
Copy link
Author

Pachin0 commented Apr 25, 2022

is it possible to add a label-visible for the pin-workspaces option? So we can apply a different underline or color to the workspaces that are visible in the other monitors

patrick96 added a commit to patrick96/polybar that referenced this issue Apr 25, 2022
@patrick96
Copy link
Member

Thanks for testing :)

is it possible to add a label-visible for the pin-workspaces option?

The xworkspaces module doesn't have label-visible at all. Also, the EWMH spec doesn't seem to expose the active workspace on other monitors. #950 is the tracking issue for label-visible in the xworkspaces module.

@patrick96 patrick96 added this to the 3.6.3 milestone Apr 25, 2022
@Pachin0
Copy link
Author

Pachin0 commented Apr 25, 2022

You are right that it does not work with the spec. It is possible but you have to get cooperation from the window manager. For instance, I can make my window manager set the invisible workspaces to a viewport that is outside all monitors (in my case 3000,3000 makes those workspaces be ignored when pin-workspaces is on) and just set for the current and visible workspace the correct viewport. That way, polybar only has to check the workspace that its on its same viewport to label it visible. But I don't know if most window managers have thought of doing that hack with setting the viewport of invisible workspaces outside of the screens.

@patrick96
Copy link
Member

I think adding unofficial extensions to the spec creates a lot of problems. For example, your hack does not work for window managers that assing non-visible desktops to monitors and thus also breaks pin-workspaces. Also, according to the spec, this would be indistinguishable from all those desktops being on a monitor at (3000, 3000).

The official spec would need to be extended for this to work, otherwise there is no way WMs get on board with adding these kinds of extensions. Unfortunetaly, there doesn't seem to be much interest in extending the spec: https://gitlab.freedesktop.org/xdg/xdg-specs/-/merge_requests/22#note_395708

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants