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

Hide tab bar upon key release #5654

Open
linkert opened this issue Aug 8, 2020 · 8 comments
Open

Hide tab bar upon key release #5654

linkert opened this issue Aug 8, 2020 · 8 comments
Labels
component: config Issues related to configuration. component: keyinput Issues related to processing keypresses. priority: 2 - low Issues which are currently not very important.

Comments

@linkert
Copy link

linkert commented Aug 8, 2020

First of all, thank you :)

I have a suggestion for additional option besides regular delay in ms for "the c.tabs.show_swiching_delay" option. So I have the tabs on the right, auto hiding after 1000ms. Works fine, but at times I have quite a lot of tabs open I want to find a particular one and I keep switching up and down the list of tabs to keep the tab-panel open for longer than 1000ms.

How about providing an option to have it disappear on key release? I think having the tab panel hide when I release the shift key would feel really natural and intuitive since I already have it pressed to access upper case J and K.

There's probably a much better way to configure this but something like below:

## Which key to release or duration to set (in milliseconds) to show the tab bar before 
## hiding it when tabs.show is set to 'switching'.
## Type: Int
c.tabs.show_switching_delay = 'shift 0'

Meaning hide upon releasing shift with zero ms delay. Could also be set to 'shift 100' for a slight delay after releasing shift OR just '800' for an 800 ms delay.

@user202729
Copy link
Contributor

Makes sense, although I suppose this is not something most people would need, and it would not be easy to configure. (also if shift is released before 1000ms, when should the tab bar be hidden?)

As a workaround: have something in config.py (or a userscript, if you're on Linux) to listen to keyboard events and change the configuration for tabs.show_switching_delay correspondingly.

Another workaround is to use gt (:buffer) instead.

@linkert
Copy link
Author

linkert commented Aug 8, 2020

Makes sense, although I suppose this is not something most people would need, and it would not be easy to configure. (also if shift is released before 1000ms, when should the tab bar be hidden?)

Really? I would think most people who hides their tab bar would probably benifit using this. No unflexible delay to set, does not show tab bar for longer than needed - intuitive to keep open for as long as needed and will probably come natural without much instructions for most users

Maybe you are correct, most people don't use qutebrowser and those who do probably leaves the configuration alone :P

Workflow example would go like this:

  1. Shift (held pressed) + j - Switches tab and shows the previously hidden tab bar
  2. Shift (still pressed) - Tab bar keeps being visible as user looks over list of tabs
  3. Shift (still pressed down) + j, j, j, j - User finds the tab and navigates to the tab
  4. Shift (gets released) - Depending on configuration the tab bar either hides instantly (0ms) OR starts counting down the value of ms set e.g 1000ms, 50ms, 260ms.

@The-Compiler
Copy link
Member

You're definitely not the first one to want this - the main problem with it is that it doesn't really fit in well with how qutebrowser works (both from the code and from a user's perspective):

A quite central concept in qutebrowser is that keypresses are mapped to commands, and the same commands can also be run in other ways (via the qutebrowser commandline, by running qutebrowser :cmd, from an userscript, etc.). No keybindings are hardcoded, it's all keys bound to commands via the (default) config.

This, as well as a scrolling implementation relying on keypress/release (#4768) breaks that concept - I see how it can be useful, but there will need to be some solution of how this fits in with the existing mental model (and code). I didn't really think about it much so far, though.

For an "automatic" solution, it seems like quite a bit of magic - also, what would happen when an user bound those keys to e.g. gt and gT instead of J and K? Perhaps your configuration example (where the modifier needs to be given explicitly in the tabs.show_switching_delay setting) would be a way out of that, at least from an user's perspective. Definitely requires some more thought before any code is written, though.

@The-Compiler The-Compiler added component: config Issues related to configuration. component: keyinput Issues related to processing keypresses. priority: 2 - low Issues which are currently not very important. labels Aug 11, 2020
@user202729
Copy link
Contributor

I think that all of those can be solved with key-up binding (to avoid being confusing, the easiest way would be to only allow binding one-key key-up without modifier).

So bind j to scroll --start down and release j to scroll --stop. Or <shift> to set tabs.show always and release <shift> to set tabs.show switching.

@The-Compiler
Copy link
Member

@user202729 You wouldn't want the tab bar to show up (and stay there) every time you use Shift to e.g. go back via H 😉

I suppose it'd work if we had a "hide the tab bar now if it happens to be in switching mode" command, but that seems quite hacky as well.

@user202729
Copy link
Contributor

... then J sets tabs.show=always.

"Hide the tab bar now" command should work too.

@al-caveman
Copy link
Contributor

al-caveman commented Sep 7, 2020

A quite central concept in qutebrowser is that keypresses are mapped to commands, and the same commands can also be run in other ways (via the qutebrowser commandline, by running qutebrowser :cmd, from an userscript, etc.). No keybindings are hardcoded, it's all keys bound to commands via the (default) config.

@The-Compiler how easy would it be to map key releases to commands?

e.g. just like the regular qutebrowser :cmd, except for the fact that the release of a key is also considered an event that can trigger running command (not only key presses)?

e.g. <KEY> refers to event when key is pressed, while ^<KEY> is for the releasing moment. this way we can have config.bind('<Ctrl>', 'set tabs show always') and config.bind('^<Ctrl>', 'set tabs show never') to achieve the desired effect of unhiding upon key pressing a key, and hiding upon releasing it.

a more realistic example:

config.bind('<Ctrl>', 'set tabs show always')
config.bind('^<Ctrl>', 'set tabs show never')
config.bind('<Ctrl-n>', 'tab-next')
config.bind('<Ctrl-p>', 'tab-prev')

a neat side effect would be even more laziness, by doing things like these quick peeking commands:

# quick peek at next tab, reverts peek upon key release
config.bind('<Ctrl-l>', 'tab-focus last') 
config.bind('^<Ctrl-l>', 'tab-focus last')

imagine how more lazy we can get? just put finger there, and simply release finger to go back. this way we become even more energy efficient as the brain will think even less and less muscles will be used. one step towards perfect nerd utopia where things just happen by desiring them.


alternative syntax: add optional argument to config.bind, e.g. config.bind(KEYS, COMMAND, event=press), where event is either 'press' or 'release' (defaults to current behaviour 'press'). this way, we get:

config.bind('<Ctrl>', 'set tabs show always')
config.bind('<Ctrl>', 'set tabs show never', 'release')
config.bind('<Ctrl-n>', 'tab-next')
config.bind('<Ctrl-p>', 'tab-prev')
config.bind('<Ctrl-l>', 'tab-focus last') 
config.bind('<Ctrl-l>', 'tab-focus last', 'release')

or maybe a new mode? e.g. --release mode?

@The-Compiler
Copy link
Member

For some more inspiration from an UX perspective, herbstluftwm recently implemented this with a virtual "Release" keyboard "modifier", see herbstluftwm/herbstluftwm#1446 and herbstluftwm/herbstluftwm#1443.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: config Issues related to configuration. component: keyinput Issues related to processing keypresses. priority: 2 - low Issues which are currently not very important.
Projects
None yet
Development

No branches or pull requests

4 participants