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

[Feature request] Allow actions on hover #1064

Open
navxio opened this issue Mar 2, 2018 · 35 comments · May be fixed by #2868
Open

[Feature request] Allow actions on hover #1064

navxio opened this issue Mar 2, 2018 · 35 comments · May be fixed by #2868
Assignees
Labels

Comments

@navxio
Copy link

navxio commented Mar 2, 2018

Like showing buttons for next/previous on the music module on hover

@patrick96
Copy link
Member

Having hover actions is probably something that can be implemented. However, the second part about showing certain mpd buttons on hover only, would likely require custom ipc commands for each module, as well as a bunch of new config options to tell polybar what to do on hover. I'll add this to the list of feature requests but I don't know when/if we're going to implement this.

@BVollmerhaus
Copy link

BVollmerhaus commented Aug 21, 2018

To add to this, I'd love if this would allow replacing the hovered module with another for the duration of the hover. For example, when hovering over the battery module, it would be replaced with the backlight module, etc. No idea how this could look in the config file, but I think it's worth considering.

@daraul
Copy link

daraul commented Oct 9, 2018

I think this is the only thing polybar sorely needs. How can I help?

@patrick96
Copy link
Member

Hi @daraul thanks for offering to help!

There hasn't been any work done on this yet. Currently we are focusing on fixing bugs and making polybar more maintainable.

We could most use your help on the tracking down and fixing bugs part (there are enough out here). Comment on any issue you'd like to take up like you did here and we would be happy to give you directions.

If you want to work on this feature here that is fine too. Just be aware that the process may be slower because we don't have that much capacity and new features are not top priority. I think here, before you start coding, you should do a write up of what what new formatting tags and config keys you would need to add and how they would behave (their semantics). Then we can decide if that approach is feasible (UX and complexity-wise), after that you should be able to actually start coding.

Thank you very much for helping! 😃

@daraul
Copy link

daraul commented Oct 10, 2018

@patrick96 I probably should have mentioned that I've done no work with C++ as yet 😆

I'll be happy to tackle a couple small bugs to get myself up to speed, though

@patrick96
Copy link
Member

@daraul Oh, that changes things. I don't want to spam this issue with this, please write me an email (address should be in my profile) with what languages you have experience with, and I'll try to find some things you can work on.

@NBonaparte
Copy link
Member

Just some pointers if anyone wants to work on this (and also a reminder to myself):

https://github.com/jaagr/polybar/blob/abdd5f9233bebd2c6a0fbe310ed8a0f4f5f36981/src/components/bar.cpp#L604

is used to track motion events (i.e. the position of the cursor). I already used this to detect when to change the mouse cursor, so it shouldn't be too hard to insert the actual functionality.

From there, the action handling should be similar to that in

https://github.com/jaagr/polybar/blob/abdd5f9233bebd2c6a0fbe310ed8a0f4f5f36981/src/components/bar.cpp#L673

and we'll probably have to create a new mousebtn enum type like HOVER.

@gamehelp16
Copy link

Another thing that is nice to have is the ability to change the styling (like background and text color) of an element on mouseover.

@yassinebridi
Copy link

This is a really nice feature, and could make polybar a lot cleaner. Right now i'm only relying on notify-send to get the desired infos.

@eHoward1996
Copy link

Any progress on this? Hovering on modules would be a grade A+ feature.

@Astrono2
Copy link

I don't see any assignees. Is this issue free for the taking?
I'm switching to polybar and miss this feature from my previous bar. If no one's working on it I can, but I have school so It would be slow.

@patrick96
Copy link
Member

@Astrono2 Yeah, this can be worked on, I'll assign it to you.

What was your previous bar?

Let me know if you need any help and also feel free to just ask for feedback if you're not sure about certain design decisions.

@Astrono2
Copy link

My previous (and current until I finish switching) bar is the one that comes with KDE Plasma.

I'm looking at the codebase right now, starting from the links provided above (checking the same methods but in master) and recursively looking for the definitions of methods/classes involved.

Also this could be the jumping point for #534, which is actually the feature I miss from Plasma.

@Astrono2
Copy link

Astrono2 commented Jul 12, 2021

Hey quick question:
At the moment, if a bar has no cursor-click or cursor-scroll, bar::handle(const evt::motion_notify& evt) is not called.
Could anyone point me to where this behavior is defined?

Edit: nvm I found it here.

@Astrono2
Copy link

@patrick96

I'm guessing that storing the currently hovered action as an action_t is a bad idea because I can't trust m_action_blocks to not change from one event to the next, right?

How would you recommend I go about keeping track of an action/action block for an arbitrary amount of time?

@patrick96
Copy link
Member

I'm guessing that storing the currently hovered action as an action_t is a bad idea because I can't trust m_action_blocks to not change from one event to the next, right?

Exactly. An action_t is only valid within a render cycle, but not between two cycles. I kind of forgot this, but this was one of the main difficulties I stumbled over the last time I thought about how this could be implemented.
Unless we somehow assign unique IDs to action blocks that don't change between render cycles, it is impossible to accurately keep track of action blocks. Imagine the mouse is hovering over some text and in the next render cycle the entire bar content is completely changed except for the hovered text and action block, but the action block was now produced by a different module, can we still say it is the same action block?

I think a good enough solution would be to store the action string and if they match the action string in a new render cycle, it can be considered the same action block. Maybe instead of storing the entire string, we could also just store a hash or something.

@Astrono2
Copy link

I'm adding a hover action to custom/script for debugging, and the key strings (click-left, click-middle, etc.) are hardcoded per-module D:
#1524 would be great for future features that also add new mouse interactions.
After I get some debugging set up, I'll check how well using the action strings holds up and get back to you on that.

@Astrono2
Copy link

Astrono2 commented Jul 13, 2021

Okay, so I have another dilemma:
We don't want the bar to be listening to mouse motion events and window leave events if there are no cursors, no dimming and no hover actions, that would be wasteful. But I'm not quite sure how to implement a check to see if there can/will be a hover action anywhere on the bar.
Maybe there could be a bool somewhere and modules that implement hover actions would be required to set it to true in their constructor??
For now I'll set it to always listen to mouse motion events for testing.

@Astrono2
Copy link

Progress update!
2021-07-13-12-09-19
Using the action string is holding up so far. Now I have to deal with the flickering when changing sizes.
@patrick96 I think the cleanest implementation would require a new meta module. I'm more of a C person than a C++ person, and I find abstract classes a bit confusing. Could something like class date_module : public timer_module<date_module>, public hover_module<date_module> be valid?

@patrick96
Copy link
Member

Nice progress!

#1524 would be great for future features that also add new mouse interactions.

I know 🙈

Maybe there could be a bool somewhere and modules that implement hover actions would be required to set it to true in their constructor??

Hmm, this doesn't work if the user creates a hover action using an action tag. Either we de/re-register after each render cycle depending on whether there are hover regions currently on the bar or we just always listen for motion events. I'm not sure how expensive it is to constantly change the event mask on a window. Always listening for motion events is certainly easier to implement.

@patrick96 I think the cleanest implementation would require a new meta module. I'm more of a C person than a C++ person, and I find abstract classes a bit confusing. Could something like class date_module : public timer_module<date_module>, public hover_module<date_module> be valid?

This depends on what you want your hover module to do. It seems to me on the module side there isn't much to do, we just have to add a new mouse button and a hover key.

@Astrono2
Copy link

Hmm, this doesn't work if the user creates a hover action using an action tag. Either we de/re-register after each render cycle depending on whether there are hover regions currently on the bar or we just always listen for motion events. I'm not sure how expensive it is to constantly change the event mask on a window. Always listening for motion events is certainly easier to implement.

I mean, in that case it's just a case of making the modules set the bool and also the config or config parser set the bool, to cover both cases. Or maybe we could always listen for motion events and add a key to manually disable listening for motion events for performance? And mention in the wiki something like "This will prevent cursor-click, cursor-scroll and hover from working. Use it if you're not using those functionalities"

This depends on what you want your hover module to do. It seems to me on the module side there isn't much to do, we just have to add a new mouse button and a hover key.

I'm thinking about the flicker when a module shrinks on hover. A hover module could add a middle step between the output set by the module and the actual output, padding with whitespace to ensure that the width of the module stays greater or equal to the width it had when it received the hover event.
It's either that or just making the flickering not our problem and let each module handle it.
If I were to make a hover module for that, I could then also add some quality of life features, like separating the hover event into hover_start and hover_end.

@Astrono2
Copy link

Or, with tooltips in mind, we could put the hover logic in the base module, and enable it/disable it based on whether there is a hover action (in the code or in the config) and whether a future 'tooltip' key is set. I figure if tooltips are implemented, they should be implemented for all modules.

@patrick96
Copy link
Member

I mean, in that case it's just a case of making the modules set the bool and also the config or config parser set the bool, to cover both cases.

This doesn't cover everything. For example a script could generate a hover action, there is no way for polybar to know this beforehand.

I'm thinking about the flicker when a module shrinks on hover. A hover module could add a middle step between the output set by the module and the actual output, padding with whitespace to ensure that the width of the module stays greater or equal to the width it had when it received the hover event.

Hmm, like if the hover action is the toggle action on the date module and the alternative label is much smaller?
This would only cover a small part of this problem though. Imagine the hover action affects a different module on the bar, then we would still have a flicker.

Also, there is currently no way to know which module a click action is coming from.

@Astrono2
Copy link

Hmm that's what I feared. I guess the best option is to leave the flicker just to have the feature ready, and leave it to each module to deal with. Then someone who's more familiar with the codebase might come up with a fix.
Maybe leave something in the docs recommending to not move things around on hover or shrink the hover module (?)

@Astrono2
Copy link

Progress on this feature is currently on hold, as I've noticed that this feature is dependent of #2469
It could be done without but it would greatly increase complexity and would involve reworking other parts of the codebase.

@SystematicError
Copy link

Has this been implemented or any rough way to do this as of now (perhaps with any forks?), I want to make it so that when hovering over my time module, it can show a small popup including more detailed info like the date.

@patrick96
Copy link
Member

@SystematicError #2466 is the current progress.

@Astrono2
Copy link

Astrono2 commented Oct 4, 2021

Progress on this feature is currently on hold, as I've noticed that this feature is dependent of #2469 It could be done without but it would greatly increase complexity and would involve reworking other parts of the codebase.

Well, #2469 was closed, so I can keep working on this. Sadly I'm quite busy at the moment, but I'll try to get to it as soon as possible.

@patrick96
Copy link
Member

No pressure, take your time :)

@daylamtayari
Copy link

@Astrono2 Since I see its been almost a year, just wanted to see what the current status of this is or have you just not had the time?

@Astrono2
Copy link

Tbh I forgot about this 😅. I'll get back to it this week. Sorry for the delay.

@daylamtayari
Copy link

No worries, assumed as much or that you had just gotten busy. Thanks!

@Astrono2
Copy link

Astrono2 commented Sep 6, 2022

It's working. It was pretty simple to implement. Now I have to test it and check that the API is usable and make the bar only listen to mouse motion events if needed.

One question though: I'm testing using a script module and I noticed that the docs show an example like

click-left = echo left %counter%

But all the mouse related actions as far as I can tell don't affect the text of the module. The example does nothing because the echo just screams into the void. Is this intended behaviour?

Also should I leave adding hover actions to existing modules for a different pull request or do it all in one? (I'm thinking that the date module could have a setting for using hover instead of click for showing date-alt and time-alt)

@daylamtayari
Copy link

I am not one of the developers or maintainers of polybar but I would split adding hover actions to existing modules into a different pull request just since it would considerably help code clarity and segment two different improvements.

@Astrono2
Copy link

Hi! Sorry for the delay again 😅, I got my first job as a programmer!!

Anyways, I think I have the code working in my fork. I'll work on the documentation and changelog now and make a PR soon!

@Astrono2 Astrono2 linked a pull request Nov 21, 2022 that will close this issue
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.