-
-
Notifications
You must be signed in to change notification settings - Fork 279
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
Dynamic Status Bars support for XMonad.Hooks.StatusBar #463
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First glance: nice. I love the simplicity of the user interface. I'll need to take a closer look at the internals later.
*> cleanAll | ||
*> updateSBs f | ||
, logHook = logHook conf *> logSBs | ||
, handleEventHook = eventHookSBs f <> handleEventHook conf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably won't interact well with #460. :-/
And that's partly my fault, as my Rescreen module doesn't compose very well. On the other hand it abstracts away the peculiarities of the X server sending multiple Configure and RRScreenChangeNotify events in a strange order. We'll need to think about this some more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could maybe synthesize the RRScreenChangeNotify event that was discarded by Rescreen and explicitly invoke handleEventHook on it. It's a horrible hack, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only took that event because it was the one used in DynamicBars
, but I don't really know if it's the best choice...
What's the problem here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that my X.H.Rescreen
module completely replaces xmonad's handling of Configure and RRScreenChangeNotify events in a way that doesn't compose well with other hooks (prevents other hooks from seeing all the events, prevents xmonad core from handling any of the events). It needs to do this because the X server sends several such events on every xrandr change, so
- if one wants to attach a hook that restarts something (bars that don't reposition themselves, for example), the events need to be debounced for the hook to be invoked only once
- if one wants to attach two different hooks, one for actual screen layout reconfiguration, another for just connect/disconnect of outputs, we need to look at all the events to detect which of the two situations it was
If this went into the core with two additional hooks in XConfig, everything would then compose nicely, but the xmonad philosophy (as I see it) has always been to keep the core minimal and try to do as much as possible in optional contrib modules. It usually works well, it just sometimes gets awkward if contrib modules interact/overlap as we never know if the user will use one, the other, or both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow, don't all event handlers that are composed with <>
see the same events? I think the All False
will only prevent the xmonad default handler from being dispatched, and it doesn't affect the other events right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All events handlers do see the same events, but X.H.Rescreen
looks into the X event queue directly and discards duplicate events, so other hooks only see the first Configure or RRScreenChangeNotify event, whichever comes first, and all the other events are discarded. I should probably explain this more clearly in the documentation there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright that makes sense now
Well, I guess we should export the event handler (and the other hooks) from this module and explain how to make it work with X.H.Rescreen
(Adding it to the RescreenConfig
, and manually add the startup hook). I'm not sure that calling the handleEvent
on it manually is a good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@liskin so what should we do here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing for now. :-)
I got an idea that might improve composability of stuff like this (something like extensible state, just for XConfig, an "extensible config"). But I'd like to finish other stuff first, so let's not worry about the interaction here and deal with it later. I don't really need X.H.Rescreen in my config, auto-xrandr is more trouble than it's worth, so I'll just try using your code and see how it behaves. (But I won't get to it sooner than end of this week.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not at all urgent, so take your time!
1174e81
to
68b72b0
Compare
8b91e49
to
cb0a409
Compare
ae38e7f
to
2e6687d
Compare
1d3ae60
to
bcf376c
Compare
Alright, I've been using this for a couple of months now, and it's been working great. Except for a minor issue: sometimes, some bars don't get started. Not sure why, it doesn't seem like a problem with the code itself.
|
bcf376c
to
073a3ae
Compare
As we discussed on the IRC, this was because of |
Overall it looks good. But I have a issue here.
And set external monitor to be primary.
|
Thanks for your feedback! For your use case, I think this is out of the scope of this PR (and I guess of xmonad? not sure). We can't control which id is given to which screen. But maybe I'm wrong, I know very little about X. |
So I think for my use-case, I need to do a bit of hack. Let me see. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks cool 👍
I'll play around with the actual functionality a bit more in the coming days
073a3ae
to
751e440
Compare
It's often difficult to make contrib modules work together. When one depends on a functionality of another, it is often necessary to expose lots of low-level functions and hooks and have the user combine these into a complex configuration that works. This is error-prone, and arguably a bad UX in general. This commit presents a simple solution to that problem inspired by "extensible state": extensible config. It allows contrib modules to store custom configuration values inside XConfig. This lets them create custom hooks, ensure they hook into xmonad core only once, and possibly other use cases I haven't thought of yet. This requires changes to xmonad core: xmonad/xmonad#294 A couple examples of what this gives us: * [X.H.RescreenHook](xmonad#460) can be made safe to apply multiple times, making it composable and usable in other contrib modules like X.H.StatusBar * `withSB` from X.H.StatusBar can also be made safe to apply multiple times, and we can even provide an API [similar to what we had before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar) if we want (probably not, consistency with the new dynamic status bars of xmonad#463 is more important) * The [X.H.EwmhDesktops refactor](xmonad#399) can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API. And we will finally be able to have composable EWMH hooks. Related: xmonad/xmonad#294
It's often difficult to make contrib modules work together. When one depends on a functionality of another, it is often necessary to expose lots of low-level functions and hooks and have the user combine these into a complex configuration that works. This is error-prone, and arguably a bad UX in general. This commit presents a simple solution to that problem inspired by "extensible state": extensible config. It allows contrib modules to store custom configuration values inside XConfig. This lets them create custom hooks, ensure they hook into xmonad core only once, and possibly other use cases I haven't thought of yet. This requires changes to xmonad core: xmonad/xmonad#294 A couple examples of what this gives us: * [X.H.RescreenHook](xmonad#460) can be made safe to apply multiple times, making it composable and usable in other contrib modules like X.H.StatusBar * `withSB` from X.H.StatusBar can also be made safe to apply multiple times, and we can even provide an API [similar to what we had before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar) if we want (probably not, consistency with the new dynamic status bars of xmonad#463 is more important) * The [X.H.EwmhDesktops refactor](xmonad#399) can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API. And we will finally be able to have composable EWMH hooks. Related: xmonad/xmonad#294
6043ae8
to
ca21c3f
Compare
It's often difficult to make contrib modules work together. When one depends on a functionality of another, it is often necessary to expose lots of low-level functions and hooks and have the user combine these into a complex configuration that works. This is error-prone, and arguably a bad UX in general. This commit presents a simple solution to that problem inspired by "extensible state": extensible config. It allows contrib modules to store custom configuration values inside XConfig. This lets them create custom hooks, ensure they hook into xmonad core only once, and possibly other use cases I haven't thought of yet. This requires changes to xmonad core: xmonad/xmonad#294 A couple examples of what this gives us: * [X.H.RescreenHook](xmonad#460) can be made safe to apply multiple times, making it composable and usable in other contrib modules like X.H.StatusBar * `withSB` from X.H.StatusBar can also be made safe to apply multiple times, and we can even provide an API [similar to what we had before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar) if we want (probably not, consistency with the new dynamic status bars of xmonad#463 is more important) * The [X.H.EwmhDesktops refactor](xmonad#399) can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API. And we will finally be able to have composable EWMH hooks. Related: xmonad/xmonad#294
As we spoke in the IRC, I mentioned that the commands themselves are used to keep track of what's launched. If someone could give it a proof read, we can merge this tonight 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No further suggestions :-)
command specific - The names were awfully long. spawnStatusBar and killStatusBar are perfectly fine alternatives. - It's more flexible to have killStatusBar command specific. Also added killAllStatusBars to provide the old functionality
This is heavily inspired by "XMonad.Hooks.DynamicBars", but it can be used with any status-bar.
101a18f
to
d2f3a8d
Compare
It's often difficult to make contrib modules work together. When one depends on a functionality of another, it is often necessary to expose lots of low-level functions and hooks and have the user combine these into a complex configuration that works. This is error-prone, and arguably a bad UX in general. This commit presents a simple solution to that problem inspired by "extensible state": extensible config. It allows contrib modules to store custom configuration values inside XConfig. This lets them create custom hooks, ensure they hook into xmonad core only once, and possibly other use cases I haven't thought of yet. This requires changes to xmonad core: xmonad/xmonad#294 A couple examples of what this gives us: * [X.H.RescreenHook](xmonad#460) can be made safe to apply multiple times, making it composable and usable in other contrib modules like X.H.StatusBar * `withSB` from X.H.StatusBar can also be made safe to apply multiple times, and we can even provide an API [similar to what we had before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar) if we want (probably not, consistency with the new dynamic status bars of xmonad#463 is more important) * The [X.H.EwmhDesktops refactor](xmonad#399) can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API. And we will finally be able to have composable EWMH hooks. Related: xmonad/xmonad#294
`statusBarGeneric`: A generic `StatusBarConfig` that launches a status bar but takes a generic `X ()` logging function instead of a `PP`. This has several uses: * With `xmonadPropLog` or `xmonadPropLog'` in the logging function, a custom non-`PP`-based logger can be used for logging into an `xmobar`. * With `mempty` as the logging function, it's possible to manage a status bar that reads information from EWMH properties like `taffybar`. * With `mempty` as the logging function, any other dock like `trayer` or `stalonetray` can be managed by this module. Related: xmonad#463
This is a function that takes a pretty-printer and makes it aware of copies of the currently focused window. This is particularly nice when using it with a StatusBarConfig. Related: xmonad#463
Description
This provides dynamic status bars, that react to screen configuration changes. This needs the new interface from #443 and the splitting from #465, so I'm marking the PR as a draft till that's resolved.
Heavily inspired by "XMonad.Hooks.DynamicBars"
Checklist
I've read CONTRIBUTING.md
I tested my changes with xmonad-testing
I updated the
CHANGES.md
fileI updated the
XMonad.Doc.Extending
file (if appropriate)