Open Subnet-Masked opened 4 years ago
Update: This also applies to other keystrokes such as CTRL + K and likely more
Technically, the ctrl
+w
isn't closing the tab (default behavior), but getting caught so that a native dialog gets in the way to prevent the tab from being closed via beforeUnload
. Same applies to several other browser keystrokes.
@marusak: FWIW, I wrote a lot about this topic three years ago in https://github.com/cockpit-project/cockpit/issues/7956.
The result was implementing the beforeUnload
event in https://github.com/cockpit-project/cockpit/pull/7985/files#diff-69d5f18370238cd010ba0c0230bcd1b3R171-R179
I suggested workarounds in the thread in the first link in this comment. Some options were sticky keys (usually an accessibility feature), chording with alt (and stripping out alt when it is sent), and so on. We could use one or more of these methods as work-arounds.
The big problem is that we're in a browser and browsers eat certain keypresses. Only some of them can be overridden. Many cannot. (Here's a list of common shortcuts: https://unboxhow.com/list-of-common-keyboard-shortcuts-that-work-in-all-web-browsers)
Once upon a time, over a decade ago, I did make a web-based terminal that proxied commands through a connector based on a Java applet and then, later, Flash to get around these restrictions. (Or was it Flash first, then Java? It doesn't matter though, both have been deprecated and are no longer possible to use.) I don't think there's a similar workaround these days.
I wonder if there might be a way to add a button on the terminal window in the browser, similar to how Android apps add a CTRL button via an option in terminal apps?
So, at the top of the window, maybe you click a button "hold CTRL" and then press your key. Then pass the fake CTRL + [key] into the terminal?
See mock up image
If I understand it correctly: That's similar to the sticky keys solution, but only works for control, and I guess is a 1-time toggle (so you have to switch to the mouse, click it, then switch back to the keyboard for your key combo)?
"Sticky Keys" is an accessibility feature of most OSes (some Linux desktops, like GNOME have this; macOS and Windows also have it). But it should work here as well.
From WikiPedia @ https://en.wikipedia.org/wiki/Sticky_keys:
Sticky keys is an accessibility feature of some graphical user interfaces to assist users who have physical disabilities or help users reduce repetitive strain injury (or a syndrome called the Emacs Pinky). It serializes keystrokes instead of pressing multiple keys at a time, allowing the user to press and release a modifier key, such as Shift, Ctrl, Alt, or the Windows key, and have it remain active until any other key is pressed.
For general sticky keys support, there should be:
Additionally, there should be:
The main idea is that you can use the keyboard for all of the input, instead of having to switch to the mouse and back to the keyboard for some of the keypresses.
If you do (out of habit) hit control-w or one of the other reserved keypresses, you could tap control, a status indicator shows up that you're pressing ctrl
, and then you tap w.
and I guess is a 1-time toggle (so you have to switch to the mouse, click it, then switch back to the keyboard for your key combo)?
Yes, Not necessarily a great solution but an idea...
I tried using sticky keys on my Gnome desktop at home and win10 at work, but both still resulted in the browser catching the keystroke and it not getting into the web terminal.
Maybe there is an obvious way that I am missing here though. My thought with the "Hold CTRL" button is that it would allow you to completely avoid passing CTRL + [key] through the browser and instead using the button and letting the JS (Or otherwise) catch the next key you press, then send the CTRL + [key] using the Javascript instead, thus avoiding conflicting keystrokes in the browser itself.
For general sticky keys support, there should be:
- a UI toggle to enable it (on the right side of the terminal bar?)
- a status on what modifier keys are currently being "pressed" (on the left side of the terminal bar, as PF4 labels/badges?)
Additionally, there should be:
- auto-cancellation on a successful keystroke (so pressing chords still works as expected)
- toggling the keypress off (hitting control a second time would disable it)
You nailed it with this.
The main idea is that you can use the keyboard for all of the input, instead of having to switch to the mouse and back to the keyboard for some of the keypresses.
If you do (out of habit) hit control-w or one of the other reserved keypresses, you could tap control, a status indicator shows up that you're pressing ctrl, and then you tap w.
I do really like this idea, tapping control instead of holding it, if that is possible to catch in a browser that would be a much preferred solution over the button!
Is anyone working on this? We still wait till we decide what solution we want?
Is anyone working on this?
Not to my knowledge. But I don't like the 'click on the button to hold key'. It is barely usable. I would look through https://xtermjs.org/docs/ to see if there is no better way. For example https://xtermjs.org/docs/api/terminal/classes/terminal/#attachcustomkeyeventhandler might help us. But as mentioned above, not all keys combinations can be caught, some never reach us as browser keeps them for itself. I think we might go with ctrl+shift+
instead of ctrl+
. But really no good ideas here.
When we go with button that is keyboard toggable, then it should be easily discoverable how it works.
I don't like the 'click on the button to hold key'.
Me neither. However I do like the tap ctrl
then tap key
approach as that could even work with hold ctrl
and tap key
for key combinations that aren't blocked by the browser.
I don't like the ctrl+shift+
as that will get blocked as well since browsers (generally) use it for enhanced functionaly. Eg. ctrl+shift+t
opens previously closed tab, ctrl+shift+w
closes the browser (firefox at least, not sure about others) itself.
Another idea is to use alt
/alt gr
instead of ctrl
(or alt
instead of shift
in the ctrl+shift+
approach, but that might invoke OS functions instead)
I think we might go with
ctrl+shift+
instead ofctrl+
That was what I was originally going to suggest before I went off trying to find another solution, but, in Chrome at least, ctrl+shift+
still does the same as ctrl+
in a lot of cases, such as crtl+shift+w
as @DejfCold mentioned...
Another idea is to use
alt
/alt gr
instead ofctrl
(oralt
instead ofshift
in thectrl+shift+
approach, but that might invoke OS functions instead)
I can confirm that my system catches a lot of ctrl+alt+
as system commands... Not sure if Windows or Mac do this though.
alt/alt gr instead of ctrl
Which doesn't on many keyboards, including ANSI (EN-US) keyboards.
As mentioned before, I've researched all the solutions and the only one that really works as transparently as possible (without a plugin-based approach, which wouldn't be supported now in browsers anyway) is to use a form of Sticky Keys, as I suggested above.
We'd need to use keydown
and keyup
events:
With the sticky keys feature on:
This should transparently handle chords and not be noticed unless someone taps modifier keys.
We should probably consider having this on by default.
Note: keydown & keyup handle taps of modifier keys, whereas keypress and other key related JS does not (and are deprecated anyway).
Not to interfere with the research / implementation, but one more (maybe drastic) way would be to run Cockpit in a dedicated window (at least using Chrome). Quoting FAQ from Chrome extension called Secure Shell:
How do I send Ctrl+W, Ctrl+N or Ctrl+T to the terminal?
Chrome blocks tab contents from getting access to these (and a few other) shortcuts. You can open Secure Shell in a dedicated window to get around this limitation. The exact method depends on a few factors.
If you're running the app (not the extension), right-click on the Secure Shell icon and enable “Open as Window”. After that, any time you launch Secure Shell it will open in a new window and handle these directly.
This is what I get if I run this app/extension:
And it indeed catches the Ctrl-W
here.
Not sure if the regular page can summon such browser window. Also not sure if such feature is available on Firefox.
Keyboard shortcuts also work in Cockpit Client, the desktop app on Flathub. https://flathub.org/apps/details/org.cockpit_project.CockpitClient (It's for Linux only, as it has parts of Cockpit embedded within and uses ssh to contact remote hosts that have Cockpit installed.)
It's definitely a problem with browsers themselves handling the keyboard shortcuts.
There's not really a way to solve this without a lot of hacky workarounds on Windows and macOS. (For Linux, there's our official app on Flathub.) As for workarounds that we could use in-browser, I've detailed them above.
There's really not much more that we can do, aside from implement what I suggested.
Cockpit version: 225 OS: Windows 10 Page: Terminal
When using the terminal, trying to use CTRL + W pops up a window asking if I am sure I want to close the tab and does not pass the keystroke into the terminal.
Steps to reproduce
From testing, this applies to Chrome and Firefox.