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

implement focused-monitor css class #536

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

echarliewhite
Copy link

This pull request adds css classes which indicate whether or not a taffybar
window is on the currently focused monitor (see #399).

This is working on my setup (XMonad, two monitors, one taffybar on each), but
has not been tested otherwise. There are a few issues that should probably be
addressed before merging (see below).

Implementation notes (short version)

  • Each taffybar window subscribes to _NET_CURRENT_DESKTOP changes
  • on a desktop change, taffybar window location is compared against the active
    monitor's geometry, which is acquired from XMonad via pagerHints
  • The top-level window is given a css class of either "focused-monitor" or
    "unfocused-monitor"

Implementation notes (long version)

  • The general approach is copied from Workspaces.hs
  • Currently each taffybar window subscribes to _NET_CURRENT_DESKTOP changes
    upon creation (in buildBarWindow), and will unsubscribe if the window is
    destroyed.
    • These separate subscriptions could probably be merged into one subscription
      in buildContext, but I was unsure about how to unsubscribe if a context
      is destroyed (while the taffybar process continues to run). I'm guessing
      this never happens, but wasn't sure.
  • A new hint _XMONAD_FOCUSED_MONITOR_GEOMETRY is added to PagerHints
    • it contains XMonad's focused screen geometry as a string with format
      "x y w h"
    • I had to use screen geometry because XMonad's ScreenID and taffybar's
      monitorNumber didn't always match up (not sure why)
    • non-XMonad implementations might use _NET_DESKTOP_LAYOUT_Sn or
      _NET_WORK_AREA
  • small stuff:
    • rateLimitFn and updateWidgetClasses are copied from Workspaces.hs,
      could move these to Util.hs, since they are shared
    • the css classes and rateLimit are currently hardcoded
    • I'm new at haskell so most of this is a combination of trial-and-error and
      copy-pasting. updateTaffyWindowStatus in particular should be closely
      reviewed 😬

@echarliewhite
Copy link
Author

I'm using it like to make my focused monitor workspace widget look like this:
scrot1

and unfocused monitor:
scrot2

@colonelpanic8
Copy link
Member

colonelpanic8 commented Oct 20, 2021

Why is this code in context though?

@echarliewhite
Copy link
Author

echarliewhite commented Oct 20, 2021

I thought about putting it in Workspaces, but it occurred to me that someone might want to make use of the css class on a bar that doesn't have a workspace widget. buildBarWindow seemed like the logical place to put the event subscription. Everything else could be moved into a new/different module, if that's preferable.

@echarliewhite
Copy link
Author

Or I could just put it in Workspaces, if the "no workspace widget" use case isn't a concern

@colonelpanic8
Copy link
Member

colonelpanic8 commented Oct 20, 2021

I thought about putting it in Workspaces, but it occurred to me that someone might want to make use of the css class on a bar that doesn't have a workspace widget.

Yeah, that makes sense.

small stuff:

  • rateLimitFn and updateWidgetClasses are copied from Workspaces.hs,
    could move these to Util.hs, since they are shared

Yeah, this is a huge redflag.

The right way to do this is to decouple the representation of stuff related ewmh from the workspace widget, and then provide updates to our internal view of ewmh state over a channel.

This would allow all workspaces to share the same event handling, and also enable your use case of having widgets other than workspaces have access to ewmh state.

@colonelpanic8
Copy link
Member

The right way to do this is to decouple the representation of stuff related ewmh from the workspace widget, and then provide updates to our internal view of ewmh state over a channel.

This would allow all workspaces to share the same event handling, and also enable your use case of having widgets other than workspaces have access to ewmh state.

This might all be a bit too much for you to do, but there are some simple improvements you would need to make to this before I would consider merging.

  1. I seriously doubt that we need rateLimit here. Thats necessary in workspaces, but in this case, we should just be able to unconditionally listen on all events. Doubt we will get spammed.
  2. Don't copy updateWidgetClasses...
  3. The intention is to remove the pagerHints module from taffybar See Remove pagerHints module #526 . A copy of this module has been moved to xmonad-contrib (see X.U.TaffybarPagerHints: init xmonad/xmonad-contrib#579). The reason for this is that it does not make sense to have all of taffybar as a dependency for xmonad configurations.

I had to use screen geometry because XMonad's ScreenID and taffybar's
monitorNumber didn't always match up (not sure why)

I believe that this is because ScreenId is either internal to XMonad or an X11 property, while monitorNumber should be something that is obtained from gdk. I still think there should a way to establish a mapping between them that makes sense. Did you look in to this at all? In general pagerHints is a hack that we should avoid extending or overusing.

@echarliewhite
Copy link
Author

Thanks for taking a look at this :)

@echarliewhite
Copy link
Author

Didn't mean to close this, my finger slipped -_-

@echarliewhite
Copy link
Author

echarliewhite commented Oct 21, 2021

I seriously doubt that we need rateLimit here. Thats necessary in workspaces, but in this case, we should just be able to unconditionally listen on all events. Doubt we will get spammed.
Don't copy updateWidgetClasses...

👍

I believe that this is because ScreenId is either internal to XMonad or an X11 property, while monitorNumber should be something that is obtained from gdk. I still think there should a way to establish a mapping between them that makes sense. Did you look in to this at all? In general pagerHints is a hack that we should avoid extending or overusing.

As far as I can tell, gdk is using X11's numbering system (https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/x11/gdkscreen-x11.c#L1067). XMonad applies its own numbering (https://hackage.haskell.org/package/xmonad-0.15/docs/src/XMonad.StackSet.html#new), but I think it matches Xinerama's numbering (https://gitlab.freedesktop.org/xorg/lib/libxinerama/-/blob/master/src/Xinerama.c#L313). To follow it farther than this I'll need to figure out X11's internal messaging, but my guess is that Xinerama's numbering is independent of the numbering that gdk uses via ScreenOfDisplay. Thinking back, reconfiguring with xrandr may have triggered the issue, I'll have to test that.

@echarliewhite
Copy link
Author

Avoiding use of PagerHints would require either XMonad support for additional EWMH hints (as discussed in xmonad/xmonad-contrib#150) or getting the active monitor via _NET_ACTIVE_WINDOW (which wouldn't work for empty workspaces)

@colonelpanic8
Copy link
Member

Avoiding use of PagerHints would require either XMonad support for additional EWMH hints (as discussed in xmonad/xmonad-contrib#150) or getting the active monitor via _NET_ACTIVE_WINDOW (which wouldn't work for empty workspaces)

or making the monitor/screen number stuff work properly, which would be the solution I would prefer.

@colonelpanic8
Copy link
Member

I actually think that #399 is describing a behavior that is slightly different than what we have here btw.

The desired behavior there is to show as active on each monitor the workspace that is displayed on THAT monitor.

@colonelpanic8
Copy link
Member

I'm using it like to make my focused monitor workspace widget look like this: scrot1

and unfocused monitor: scrot2

These look really good btw. Can you share the css for them?

@echarliewhite
Copy link
Author

Avoiding use of PagerHints would require either XMonad support for additional EWMH hints (as discussed in xmonad/xmonad-contrib#150) or getting the active monitor via _NET_ACTIVE_WINDOW (which wouldn't work for empty workspaces)

or making the monitor/screen number stuff work properly, which would be the solution I would prefer.

Unfortunately this still requires pagerHints since taffybar can't see ScreenId otherwise. I don't think EWMH hints can do this — _NET_DESKTOP_LAYOUT_Sn is the closest thing to what we'd want, but the pager is supposed to set that to tell the WM which desktops are on which screen.

@echarliewhite
Copy link
Author

echarliewhite commented Oct 22, 2021

These look really good btw. Can you share the css for them?

Sure thing: https://gist.github.com/echarliewhite/19c80ec49592161cc74bccc62a3d53ae

This reminds me that this css contains a workaround for another issue (#506 (comment))

@echarliewhite
Copy link
Author

I can see two main ways to handle communication with XMonad:

  1. Figure out the screen number mismatch, then set a new pagerHint that
    contains ScreenId to workspace mappings
    • This would replace _XMONAD_VISIBLE_WORKSPACES
  2. Implement the _NET_DESKTOP_VIEWPORT hint in XMonad

Both approaches could also address #399

@echarliewhite
Copy link
Author

2. Implement the `_NET_DESKTOP_VIEWPORT` hint in XMonad

I'm going to see if I can do this. It might take a while.

@colonelpanic8
Copy link
Member

@echarliewhite any thoughts about finishing this?

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

Successfully merging this pull request may close these issues.

None yet

2 participants