Dear Maintainer, in text console, <Shift>+<F(i)> hotkeys behave in a wrong way, as if they were <Shift>+<F(i+2)>. Single <F(i)> pressed keys function as they should. In x-terminal-emulator those hotkeys work correctly.
The following explanation by from Egmont Koblinger [1] seems relevant: This seems to be a problem with the console-data or kbd or whichever similar package of Linux distros... They offer multiple keymaps, and define function keys differently in them. E.g. type "loadkeys us" -> with the U.S. keymap pressing Shift+F4 will do what you'd expect from Shift-F6. But type "loadkeys ru" -> with the Russian keymap Shift+F6 works as expected. Seems that the kernel's builtin keymap makes the Shift key offset the function keys by 10 (drivers/tty/vt/defkeymap.map says «keycode 64 = F6 F16» and later «string F16 = "\033[29~"»), and this is what mc expects too (mc.lib: «f16=\\e[29~»). Unfortunately, many keymaps, including the probably most widely used "us" wants to be able to assign separate action to F11 and Shift+F1, so they shift by 12 and define «keycode 64 = F6 F18». There's nothing mc could do about this right now, first all the keymaps should be made consistent. [1]: https://mail.gnome.org/archives/mc-devel/2013-January/msg00028.html--- Much of humankind's intellectual and emotional struggle has been not for truth, but against truth. The advance of science has been sporadically fought against for thousands of years. -- C. W. Dalton, "The Right Brain and Religion"
The following explanation by from Egmont Koblinger [1] seems relevant: This seems to be a problem with the console-data or kbd or whichever similar package of Linux distros... They offer multiple keymaps, and define function keys differently in them. E.g. type "loadkeys us" -> with the U.S. keymap pressing Shift+F4 will do what you'd expect from Shift-F6. But type "loadkeys ru" -> with the Russian keymap Shift+F6 works as expected. Seems that the kernel's builtin keymap makes the Shift key offset the function keys by 10 (drivers/tty/vt/defkeymap.map says «keycode 64 = F6 F16» and later «string F16 = "\033[29~"»), and this is what mc expects too (mc.lib: «f16=\\e[29~»). Unfortunately, many keymaps, including the probably most widely used "us" wants to be able to assign separate action to F11 and Shift+F1, so they shift by 12 and define «keycode 64 = F6 F18». There's nothing mc could do about this right now, first all the keymaps should be made consistent. [1]: https://mail.gnome.org/archives/mc-devel/2013-January/msg00028.html--- Much of humankind's intellectual and emotional struggle has been not for truth, but against truth. The advance of science has been sporadically fought against for thousands of years. -- C. W. Dalton, "The Right Brain and Religion"
Hi, I have the same problem with mc 4.7.0.9, and I've solved it via "Learn Keys" option ( Menu -> Options -> Learn Keys ).
698885-submitter@debian.org Cc: Bcc: Subject: Reply-To: tags 698885 fixed thanks for your bug report. See this workaround please: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698885#16 best regards Denis Briand
See upstream in https://midnight-commander.org/ticket/3254 : ``` on the console it's the kbd package that's broken because half of the keymaps are shifted by 2 compared to the other half. To make it worse, the kernel's builtin table just doesn't match the standard "us" layout shipped by kbd or console-tools or whatever that's called nowadays. … Until that one is solved (i.e. the kbd/console-tools package ships keymaps that are consistent with each other and with the kernel's default) there's nothing mc could do. ```
Here's an update. I'm describing what I see on Ubuntu 25.10. The kernel's built-in keymap (drivers/tty/vt/defkeymap.map) hasn't changed. It defines 20 different escape sequences, and has a strong off-by-10 vibe (e.g. Shift+F3 produces the 13th of these sequences). Shift+F1, F11 and Shift+F11 all generate the same sequence, and so do Shift+F2, F12 and Shift+F12. kbd / console-setup has slightly changed. It no longer ships its own keymaps, but rather "loadkeys" launches "ckbcomp" which converts X11's xkb definition files to the console's format. It's a nice move and I do appreciate that the console now uses the better-maintained xkb maps. It hopefully also provides more consistency. The "us" and "ru" keymap no longer differ in the handling of function keys, and I assume all the keymaps are unified now in this regard. (I have no information on other distros, I don't know if others might use a different loadkeys / keyboard data implementation.) The maps loaded by my loadkeys (via ckbcomp), however, do not agree with the kernel's built-in map. They do whatever the "us" layout did for me 13 years ago. There are still only 20 different escape sequences, the same ones as in the bulit-in map. They are laid out off-by-12, to the keys F1..F12 and Shift+F1..Shift+F8. Shift+F9..Shift+F12 do nothing. Terminfo also describes the very same 20 different escape sequences for kf1..kf20, whereas there's no kf21 and above capability.--- So, there are two different possible layouts. The kernel's built-in, presumably used by minimal or embedded Linux systems, ones where the console is not set up with "loadkeys", is fully functional for mc's purposes. However, we'd need to have an exception in the code to know that terminfo's kf13 etc. entries are off by 10, rather than by 12 as for graphical terminals. If we have to have such hacks on top of terminfo then what's the purpose? We could just hardcode the keys and be done with it (as we currently do). The ones loaded by "loadkeys" (at least on Ubuntu 25.10; again: not sure about other distros) could be handled by mc out of the box without any special hack / exception, since the same offset of 12 is used as for any other terminal. However, Shift+F9 (pulldown menu at its previous state) and Shift+F10 (quit without updating the working directory) are unavailable.--- What should be done to fix the situation: Agree on 24 different escape sequences, and their unique assignment to the F1..F12 and Shift+F1..Shift+F12 keys. Then make sure that the kernel's hardcoded table, the tables loaded by loadkeys (generated via ckbcomp, or loaded from its own data files, or whatever), and terminfo (up to kf24) all define these. For the best compatibility, I think the right choice is to keep what's already defined in terminfo, and with the usual off-by-12 mapping, the keys loaded by loadkeys. Add four new entries for the current gaps of Shift+F9..Shift+F12 (terminfo: kf21..kf24). The only component receiving a backwards incompatible change would be the kernel's hardwired table; for downstream distros that do run "loadkeys" this doesn't even matter. e.
ckbcomp is a perl script, its copyright line stating the years 2005-2006, so it's not new at all. It has existed even back then when I made my first observations here. As for the "keycode" lines it generates, it properly generates up to F24 (and beyond for other modifiers), with off-by-12 semantics as we've already established. That is, physical keypresses Shift+F9..Shift+F12 are mapped to the logical symbols F21..F24. So far this is what I'm looking for. The problem is that the corresponding "string" lines are missing, which would define the escape sequence belonging to F21..F24. They can be installed with a script like sudo loadkeys <<EOF string F21 = "\033[35~" string F22 = "\033[36~" string F23 = "\033[37~" string F24 = "\033[38~" EOF and then taught to mc using its "Learn keys" dialog. This way even Shift+F9 and Shift+10 will work as intended. Note that I'm not certain what are the "best" escape sequences to choose, it's always been a mistery to me why and where some numbers are skipped. But as for someone's local fix, it doesn't matter. ckbcomp doesn't emit such individual "string" commands, but emits a magical "strings as usual" line to be processed with loadkeys. This command reverts F1..F20 to their defaults, but luckily leaves the unset-by-default F21..F24 at the values we've set manually. So, subsequent "loadkeys xx" commands won't override them.
Contrary to my previous posts, there might be a strong reason to keep the kernel's current built-in table, and adjust loadkeys+ckbcomp to match that. The kernel's bulit-in table matches the behavior of at least two popular terminals: pterm (putty) and urxvt. Shift-F1 generates \e[23~ etc. (unlike after a loadkeys+ckbcomp when Shift-F1 becomes \e[25~). With these terminals (Linux's hardwired default, putty and urxvt), combined with the corresponding TERM value of linux, putty* or rxvt-unicode*, terminfo's 'kf13' etc. keys are defined with off-by-10 semantics; whereas for most of the xterm-like terminals terminfo defines them with off-by-12 semantics. Notice that the problem already exists with putty and urxvt, independently from the confusion in the Linux kernel vs. loadkeys+ckbcomp. Honestly I have no idea how someone is expected to handle the shifted function keys using terminfo, having no information whether the keys describing them are indexed from 10 or 12. And apparently I'm not the only confused developer. To which the short-term solution is to avoid terminfo and hardwire a handful of potential escape sequences. Which approach, if the console is off-by-2 compared to putty and urxvt (as it is after loadkeys), it is super prone to the shited function keys being interpreted off-by-2 in one or the other. The developer would have to check the TERM value and based on that choose one of two conflicting lookup tables. It would be definitely safer, more reliable if at least these terminals agreed on the sequences they sent. Which would mean to keep the kernel's built-in table as-is, and adjust loadkeys+ckbcomp. Resulting in folks getting angry because then they _again_ cannot tell F11 apart from Shift+F1. I think the only true way out of this mess is to switch to some completely different escape sequences (maybe \e[1;2P ..., \e[15;2~ ... as used by xterm).