Ticket #4632 (accepted defect)
Shift-F2 recognized as F12
Reported by: | gnachman3 | Owned by: | zaytsev |
---|---|---|---|
Priority: | major | Milestone: | 4.8.34 |
Component: | mc-tty | Version: | master |
Keywords: | Cc: | egmont | |
Blocked By: | Blocking: | ||
Branch state: | no branch | Votes for changeset: |
Description
I built mc from master at commit c8eec91cb6260781eb055fe1b45f5d848cbd121c.
The output of mc -V is:
GNU Midnight Commander unknown
Built with GLib 2.82.4
Built with S-Lang 2.3.3 with terminfo database
Built with libssh2 1.11.1
With builtin editor
With subshell support as default
With support for background operations
With mouse support on xterm
With support for X11 events
With multiple codepages support
Virtual File Systems:
cpiofs, tarfs, sfs, extfs, ftpfs, sftpfs, shell
Data types:
char: 8; int: 32; long: 64; void *: 64; size_t: 64; off_t: 64; uintmax_t: 64;
I am the author of iTerm2. A user reported that Shift-F2 (and other shift+function key combos) did not work.
Using mc's "Options > Learn Keys" feature, I can see that when I press Shift+F2 it is recognized as F12. I have a completely stock configuration. This is on macOS.
I verified that iTerm2 correctly sends \e[1;2Q when you press Shift+F2. I was able to reproduce the same problem in xterm, Kitty, and Alacritty. The built-in macOS Terminal does not seem to support shift+function keys at all. My $TERM is set to xterm-256color. infocmp -x gives kf2=\EOQ but as far as I know terminfo isn't very useful for function keys combined with modifiers like shift (I could be wrong about this).
I searched the issues and found some very old ones about shift+function key having other problems. I'm sure there's a lot of history here! I would love to help fix this problem whether from my end (if it's a bug in iTerm2) or yours.
Change History
comment:2 Changed 5 weeks ago by zaytsev
- Cc egmont added
The closest bug to this one I think is this: #3254. I have recently tried Linux console and observed that Shift+Fx keys are off by 2. Another more general issue where more background is explained is #3087.
To be honest, I don't have time to delve into this and my own understanding is very limited. Basically, I think there is a matrix of combinations:
1) Screen library used by mc - ncurses or slang
2) Terminal emulators - Linux console vs. xterm-compatible terminals and others
With some (or all?) combinations Shift+Fx keys behave in a surprising way. The problem is that (most) computers have F-keys from F1 to F12, but some have them up to F10 only. Now, with some combinations of screen library and terminal emulator Shift+F1 is seen as "F13" (F12 + 1) and with some as "F11" (F10 + 1).
I think that the current state is that we've been patching mc until it started behaving in an unsurprising way on Linux with xterm-compatible terminals for users with F1..F12 keys. Other combinations (notably Linux console) are still "broken" and my understanding until now was that there is not much we can do about it.
If someone can explain the problem summarizing the 20 years of struggle for working Shift-Fx keys in a better way than I did, and propose a good solution that fixes everything and breaks nothing this would be great :) I'm CC'ing egmont as he is extremely knowledgeable on the subject.
comment:3 Changed 5 weeks ago by egmont
I'm CC'ing egmont as he is extremely knowledgeable on the subject.
No, unfortunately I'm not :(
Here's what I'd roughly do:
Let's ignore the Linux console. It's a very limited tool, presumably the vast majority of people only use it for firefighting but not for everyday productive work. According to my latest memories, some keyboard layouts are off-by-2 compared to some others (i.e. some shift by 10, some shift by 12). There's nothing we could do to fix that (well, apart from getting in touch with Linux / kbd developers).
Let's focus on graphical terminals. Figure out what's going on there. If there's an off-by-2 difference between ncurses and slang then just somehow offset mc's code to take that into account. (I'm not familiar with the details, don't see how this boils down to actionable steps, source code patch, etc..)
comment:4 Changed 5 weeks ago by gnachman3
I had written a long and fascinating reply but Safari crashed and lost it.
The bad F12 mapping was added in 43c99a14dae3e5aa8562022cbd6441cac8e24edc. I installed Ubuntu 9 and it didn't match the behavior in the commit description; Xcode and Gnome Terminal both matched modern terms for F12. Shift-F2 behavior differed between them. The Linux console was incompatible with them for both keys, as expected.
Are you open other using a reporting control sequence to detect modern terminals and provide different behavior for them, or is it necessary to base the key mapping solely on $TERM and other locally available info? Some apps like neovim use reporting a lot while others avoid it at all costs.
As far as I can tell there isn't an existing definition for Shift+function keys, so users are on their own to define that. I don't know enough about mc's configuration system to say if adding it would break things.
Probably users have hacked their terminal configs to work around these issues, so we also have to think about them. I'm not sure how you trade off breaking weird configs versus making things work better for new users or users with standard configs.
comment:5 Changed 5 weeks ago by zaytsev
I had written a long and fascinating reply but Safari crashed and lost it.
I have a rule of writing longer texts in a text editor, or, at least, copying it to the clipboard before sending. Modern garbage software loses text all the time. Yet, even I get tricked sometimes - with age comes forgetfulness. I feel for you, and too bad that the original text is gone...
As far as I can tell there isn't an existing definition for Shift+function keys, so users are on their own to define that.
You have to look here for things like "f11 / f12 / ..." (Shift+F1, Shift+F2, ... in our language):
https://github.com/MidnightCommander/mc/blob/master/misc/mc.default.keymap
You will see that there are lots of keys defined there, and users will definitively get affected.
Are you open other using a reporting control sequence to detect modern terminals and provide different behavior for them.
For some specific usages I think it's possible, but for key mapping I rather feel that we should patch the sequences in mc.lib per $TERM definition if necessary, instead of adding even more code to query what terminal reports on top of what the screen library is already (possibly) doing.
I'm not sure how you trade off breaking weird configs versus making things work better for new users or users with standard configs.
I would prefer things to be working out of the box for new users or users of the new systems.
So, can you share what's wrong with Slava's commit and what is the current state with the terminal emulators? I did some research for console, and the situation seems to be as follows:
System | $TERM | Codes |
Fedora, Ubuntu Alpine | linux vt102 | F1..F12: ^[[[A^[[[B^[[[C^[[[D^[[[E^[[17~ ^[[18~^[[19~^[[20~^[[21~^[[23~^[[24~ Shift-F1..F8: ^[[25~^[[26~^[[28~^[[29~^[[31~^[[32~^[[33~^[[34~ Shift-F9..F12: no reaction |
Linux kernel | linux | F1..F12: ^[[[A^[[[B^[[[C^[[[D^[[[E^[[17~ ^[[18~^[[19~^[[20~^[[21~^[[23~^[[24~ F13..F20: ^[[25~^[[26~^[[28~^[[29~^[[31~^[[32~^[[33~^[[34~ |
FreeBSD | xterm | F1..F12: ^[OP^[OQ^[OR^[OS^[[15~^[[17~ ^[[18~^[[19~^[[20~^[[21~^[[23~^[[24~ Shift-F1..F12: no reaction |
OpenIndiana Solaris 11.4 | sun-color | F1..F12: control virtual consoles Shift-F1..F12: ^[[224z^[[225z^[[226z^[[227z^[[228z^[[229z ^[[230z^[[231z^[[232z^[[233z^[[234z^[[235z |
- Ubuntu, Fedora console - Shift-F1 behaves as Shift-F3 and so on...
- Alpine console is completely broken, because of vt102 (TBD: need to check if it works in screen)
- FreeBSD and Solaris consoles are already doing the right thing (magically?)
Source: https://github.com/torvalds/linux/blob/master/drivers/tty/vt/defkeymap.map
So maybe we can just fix it, at least for physical consoles, or am I being naive? We won't get around physical F11/F12 producing different sequences from Shift-F1 and Shift-F2. There will still confusion remaining as to how key bindings are working and people will wonder why no action can be bound to physcial F11/F12 (unless we implement them under a different name like pf11, pf12, pf21, pf22). But overall, a very long-standing problem will be solved for a lot of users.
comment:6 Changed 5 weeks ago by zaytsev
Branch: 4632_shift_fx
Initial changeset: 3b913c7c3ec0527d3dfc8176075265b56d1e771e
Fixes Ubuntu, Fedora & Alpine consoles for me.
comment:7 Changed 5 weeks ago by zaytsev
Re-reading your original text, it seems that we might be talking past each other. Please have a look here:
https://github.com/MidnightCommander/mc/blob/master/doc/FAQ#L240
It appears to me that you are confused by F12 sequence being interpreted as Shift-F2, but this is correct by convention. There are no separate F11 and F12 keys, they are (were) supposed to work as Shift-F1 and Shift-F2. Maybe these days terminal emulators send different escape sequences for Shift-F1 and F11, thus one could theoretically tell one from another. However, we don't have a way of mapping them in mc, and we don't expect to introduce one.
So apart from Linux console, it seems that everything actually behaves like it should.
comment:8 Changed 5 weeks ago by gnachman3
I did a survey of how the currently popular terminals that I can run easily behave:
Terminal | Shift-F2 | F12 |
Terminal | Nothing | ESC-[24~ |
Tera Term | Nothing | ESC-[24~ |
Konsole on Kubuntu 24 | ESC-O2Q | ESC-[24~ |
Gnome Terminal on Ubuntu 9 | ESC-O1;2Q | ESC-[24~ |
PuTTY | ESC-[24~ | ESC-[24~ |
urxvt on Ubuntu 24 | ESC-[24~ | ESC-[24~ |
Eterm | ESC-[24~ | ESC-[24~ |
iTerm2 | ESC-[1;2Q | ESC-[24~ |
Xterm | ESC-[1;2Q | ESC-[24~ |
Gnome Terminal on Ubuntu 24 | ESC-[1;2Q | ESC-[24~ |
Xterm on Ubuntu 24 | ESC-[1;2Q | ESC-[24~ |
Alacritty | ESC-[1;2Q | ESC-[24~ |
Kitty | ESC-[1;2Q | ESC-[24~ |
Wezterm | ESC-[1;2Q | ESC-[24~ |
Hyper | ESC-[1;2Q | ESC-[24~ |
Foot on Ubuntu 24 | ESC-[1;2Q | ESC-[24~ |
ConEmu? | ESC-[1;2Q | ESC-[24~ |
Windows Terminal | ESC-[1;2Q | ESC-[24~ |
Terminator | ESC-[1;2Q | ESC-[24~ |
st | ESC-[1;2Q | ESC-[24~ |
Xterm on Ubuntu 9 | ESC-[1;2P | ESC-[24~ |
So, can you share what's wrong with Slava's commit and what is the current state with the terminal emulators
I think it's a mistake to treat esc [1;2Q as F12. I don't know if that was more popular back in 2009 but it certainly isn't a good choice in 2025. I didn't test consoles because that is a particularly weird edge case, but perhaps it's more important to your users than I imagine.
It appears to me that you are confused by F12 sequence being interpreted as Shift-F2, but this is correct by convention. There are no separate F11 and F12 keys, they are (were) supposed to work as Shift-F1 and Shift-F2.
I don't think that is true any more; to the extent there is a convention it's that ESC [1;2Q is almost always Shfit-F2 and almost never F12.
Of course, I care about more than just Shift-F2, but it's a starting point and I suspect we'll find similar patterns for other F keys. If we can agree on a general direction I can do more research.
comment:9 Changed 5 weeks ago by zaytsev
Of course, I care about more than just Shift-F2, but it's a starting point and I suspect we'll find similar patterns for other F keys. If we can agree on a general direction I can do more research.
It seems that I still couldn't manage to get my point across to you:
In the Midnight Commander world, there are currently no such keys as F11 and F12. These are by convention defined as equivalent to Shift+F1 and Shift+F2 from the dawn of times. That's it.
You will note that our menu bar at the bottom ends at F10, there are no blocks foreseen for F11 and F12. But most importantly, in our key mapping engine and shipped maps F11 means Shift+F1, F12 means Shift+F2, F13 means Shift+F3 and so on. If you want to define F12 in the keymap, there is no way to do so, because it just doesn't have a name - f12 means Shift+F2 for us by definition.
So the commit by Slava seems to do exactly the right thing in the context of Midnight Commander and according to the table that you have kindly compiled. It makes sure, that F12 (if such key is physically present on the keyboard) and Shift+F2 are recognized and treated exactly the same for all known terminals.
Looking at this issue, I have found out that on Linux consoles the keys seem to be shifted, so I made a branch to fix this. But "fixing" what you want to fix would involve some sort of changes to the key mapping engine, as I have already tried to explain above.
- We could change the meaning of f11 and f12 in our world to mean stand-alone physical keys and say that what was previously meant by f11 is now f13, and add 4 more keys (f21, f22, f23, f23). I think that this will cause a huge amount of chaos and innumerable sufferings, so a terrible idea.
- We could introduce new keys like I mentioned above (pf11 and pf12), and remove sequences used for pf12 from f12. This way, users will be able to map F12 and Shift-F2 separately in all terminals which provide this feature (according to your table, most of them do it now). We don't provide any mappings for F11 and F12 at the moment and aren't planning to. We also haven't had any user requests to do so. So while this idea is generally workable, I'm not enthusiastic about it.
- We could do nothing except for fixing Linux console (not really same issue) and think about using this text as a documentation somewhere to fix #3087 and avoid further confusion.
Am I making any sense to you know? Actually, I'd be curious what is exactly your motivation for looking into it. Did you get any user requests to that effect, of you need to use these keys yourself for some reason?
comment:10 Changed 5 weeks ago by egmont
I have found out that on Linux consoles the keys seem to be shifted, so I made a branch to fix this.
As discussed in #3254, and also briefly mentioned by me the other day, the various international keyboard layouts have an off-by-2 discrepancy among them. IIRC, even the US English kbd layout shipped by the kbd package is off-by-2 compared to the table hardwired in the Linux kernel.
That is, that's how it was about a decade ago.
Unless this has completely been fixed since then (bringing all the intl maps and the kernel's built-in map in sync), there's no way for mc to fix this. Applying an off-by-2 change would fix the situation for some keymaps and would break for the other half. It's a neverending back-and-forth.
So, in order to validate this proposed change, we'd first need to make sure that kbd and the kernel have already fixed their side of the story.
comment:11 Changed 5 weeks ago by egmont
In the Midnight Commander world, there are currently no such keys as F11 and F12. These are by convention defined as equivalent to Shift+F1 and Shift+F2 from the dawn of times. That's it.
f12 means Shift+F2 for us by definition
@zaytsev I disagree with you here.
I'd like to challenge this decision. Just because it's been this way forever doesn't have to mean that it needs to stay this way. I think it's time for a big cleanup.
The vast majority of the keyboards have 12 function keys. I don't think I've ever seen a computer with more. F11 is often unavailable since many terminals go fullscreen then. If mc's default configs, bottom button layout etc. decide to only use the first 10 function keys, that's absolutely fine. If mc doesn't even optionally support the physical F11 and F12 keys, that's not a big deal either IMHO.
But the idea of denoting Shift by an offset of 10 (or 12 or whatever amount) instead, i.e. saying F15 (or F17) instead of Shift+F5, is braindamaged, is not aligned with reality (the physical keys and their printed labels that one has to press). It's time to eliminate it.
All throughout mc, including its user interface, hotkeys as displayed in menus, the "Leans keys" dialog, config files, documentation, etc., mc should say Shift+F5 and friends because that's what it is, saying F15 (or F17) instead of Shift+F5 is a lie.
Once this transition is made, it no longer really makes a big difference if mc supports up to F10 or up to the physical F12 button or even further up to extremely rare keys. That is, as long as the underlying terminal's actual behavior allows to distinguish them. If not then of course there'll be some clash, just like there is now.
Also, as a bonus, nothing would stop mc from even recognizing Ctrl+Fx and Ctrl+Shift+Fx in modern terminals.
The idea that the user interface or config file says e.g. F15, and as a user I'm supposed to understand that it actually stands for Shift+F5 (or maybe even worse: Shift+F3), is just plain wrong. Let's call it what it is. Call it Shift+F5 (or Shift+F3 or whatever I have to press). Let's do this change throughout the entire the UI, config files and documentation; and as many places internally in the source code as possible.
There's definitely a need for Shift+F1 .. Shift+F10. Let's focus on these, and call them what they really are: Shift+F1 to Shift+F10. There's a smaller need for the physical F11 and F12, as well as Shift+F11 and Shift+F12 keys. Maybe support them on a best effort basis, subject to support in the underlying components. And, again, call them what they actuall are: F11, F12, Shift+F11, Shift+F12.
Put the user first, put reality first. Build the technical bits around it. Not the other way around.
Rather than defending the status quo, I think mc deserves a heavy overhaul here. If the price to pay for that is a one-time migration of config files and whatnot (maybe even bumping the version to 4.9.0), so be it.
comment:12 Changed 5 weeks ago by zaytsev
@zaytsev I disagree with you here.
There is nothing here to agree or disagree with. I'm just explaining how/why things are the way they are. Also, I haven't made any decisions to challenge or otherwise. I just outlined some "cheap" ways to change things and tried to explain why they are all bad.
Rather than defending the status quo, I think mc deserves a heavy overhaul here. If the price to pay for that is a one-time migration of config files and whatnot (maybe even bumping the version to 4.9.0), so be it.
I actually agree with most of your message, which (not surprisingly) goes in the direction of solving #3087 by rewriting the key mapping engine. The only thing you are wrong about is "the price to pay". The one-time config migration is really the last thing I'm worried about.
My biggest problem is that this is a huge project (if done right), and I can't even tell if this would take me a few weeks or a few months of work without further investigation. But regardless of that estimate, my total time budget for mc right now is more like a few hours a week.
In my opinion, mc has tons of other critical problems that are jeopardizing the future of the project. If you are interested, I can tell you a bit more about them. Anyway, this particular problem, while bad, is not one of those in my opinion. So my strategy is to spend my limited time on what I think is the best use.
If you want to say that you are volunteering to do it yourself, be my guest. I know how competent you are, that you write clean code, care about results, and take responsibility for things you break. I can't offer much in the way of support, maybe a little review and some limited testing, and I won't hold up your patches. But that's about it.
comment:13 Changed 5 weeks ago by zaytsev
- Status changed from new to accepted
- Owner set to zaytsev
- Milestone changed from Future Releases to 4.8.34
To check Linux console thing.
comment:14 Changed 5 weeks ago by egmont
There is nothing here to agree or disagree with. I'm just explaining how/why things are the way they are.
Oh, I misunderstood you then, I thought you meant to keep things this way. My bad.
The only thing you are wrong about is "the price to pay".
I'm not "wrong" here, it's just an aspect of the story that I simply forgot to mention :) You're right, it's definitely more costly to go for the right solution.
Unfortunately my motivation to volunteer to free software has severely dropped during the last couple of years; I prefer to spend my free time on other things, so unfortunately I most likely won't work on this (or any other bigger task).
comment:15 Changed 5 weeks ago by zaytsev
Unfortunately my motivation to volunteer to free software has severely dropped during the last couple of years; I prefer to spend my free time on other things
Oh, I think my motivation is alright, it's just that I still haven't found a way to reconcile working on mc with making a living outside of academia, and stealing a few hours here and there after a full-time job is just exploitation. I guess I'd still be happy to work on mc part-time, even at a somewhat discounted rate. It would be really fun to have at least a small team to tackle some fundamental problems (hush... mc^2 anyone ;-) ?), but that sounds even more unlikely than finding a sponsor to pay for at least a few days a month. Maybe I should simply ask around though :-)
comment:16 Changed 5 weeks ago by egmont
Some funding could boost my motivation, too :-) Anyone lurking around here who invested in Bitcoin in 2009? :-D
comment:17 Changed 5 weeks ago by zaytsev
Anyone lurking around here who invested in Bitcoin in 2009? :-D
Maybe we should integrate a miner in the next release :-) One of my acquittances has accidentally made a fortune during the last cycle, but he's built himself a house, bought a 911 and is now taking helicopter lessons. No signs of spending any of that money on mc, or at least paying for my helicopter lessons anytime soon.
comment:18 Changed 5 weeks ago by zaytsev
I've checked the kernel layout and kdb and they seem to be still out of sync. I'm not sure who has to fix what though, and whether this is of much relevance at all.
My understanding is that all modern Linux distributions (Fedora, Ubuntu) come with kbd maps. I want to make things work out of the box for people using their virtual consoles. My branch leads to that effect.
Maybe if mc is started on serial console without kbd, then it will lead to off by two there. But I guess that's less problematic than the situation right now (serial possibly not having off-by-two, but virtual being offset and nothing is working on Alpine).
comment:19 Changed 5 weeks ago by ossi
i think i agree with that logic.
by extension that means that to the degree that it even matters, the kernel should budge, because it's being outvoted by far.
and i'll have to unhack my remap.inc, because i made it match the kernel map.
note that the authoritative keymap setting comes from the console-setup-linux package (at least on debian). kbd only provides the tooling. and it uses xkb keymaps, to some degree.
in the serial case, only the keymap of the system that hosts the terminal is relevant for what keys are sent. unlike with telnet/ssh/etc., TERM is not transmitted in this case, so extra setup is needed if a non-dumb terminal is to be assumed. and as with any remote access, any particular value of $TERM may be interpreted differently, depending on whether terminfo (ncurses) or termcap (traditional) are used, and which version thereof.
comment:20 Changed 5 weeks ago by zaytsev
I have submitted a patch to the kernel:
https://lore.kernel.org/linux-serial/20250119184733.9468-1-yury@shurup.com/T/#u
Let's see what happens.
comment:21 Changed 5 weeks ago by gnachman3
Thanks for the explanation, @zaytsev and sorry for the wild goose chase. A user added a comment (https://gitlab.com/gnachman/iterm2/-/issues/10717#note_229461355260350) on an ancient issue, complaining that shift-function keys didn't work as expected. I then went down a rabbit hole :)
As far as getting paid for work, Github Sponsors and Patreon are better than nothing. I make more than minimum wage but nowhere near enough for helicopter lessons :). A little shameless self-promotion goes a long way.