What controls the mapping between Ctrl+Alt+F keys, TTYs and X sessions

keyboard-layoutttyx11

On my CentOS system, Ctrl+Alt+F1 shows the X Windows session known as :0, but on other systems Ctrl+Alt+F7 may do the same thing. What determines how Fn keys are mapped to X sessions and TTYs?

Related but different: What happens when Ctrl + Alt + F<Num> is pressed?

Best Answer

Keyboard maps and the applications themselves

As should be clear from the Q&A that you referenced, the recognition of the actual key chords comes down to what is programmed into keyboard maps. Furthermore, there are two different keyboard maps involved, as evidenced by the fact that there are two different sets of chords.

  • The X11 server has its own keyboard map that translates input events from keyboard devices. This translates chords of the form ⎈ Control+⎇ Alt+Fn into requests (made by the X11 server) to change the active kernel virtual terminal.
  • The kernel's built-in terminal emulator has its own keyboard map that translates input events from keyboard devices. This translates chords of the form ⎇ Alt+Fn into requests to change the active kernel virtual terminal. Notice that this map does not require ⎈ Control, although chords with ⎈ Control are conventionally mapped to the same action.

On many Linux operating systems, at least, the latter keyboard map is derived from the former by the configuration mechanism, and the system administrator only configures one map in a single place. But there are two actual maps.

Which takes effect depends from which kernel virtual terminal is active. This is because the X11 server uses a protocol whereby it effectively "owns" one of the kernel virtual terminals.

  • When that terminal is switched to, the X11 server switches the KVT subsystem into a mode where the kernel's own built-in terminal emulator is disconnected from the keyboard input devices outright or the virtual terminal is switched into a raw keycode mode so that the kernel's built-in terminal emulator performs no mapping,
  • When that terminal is switched away from, the X11 server undoes this.

This is so that the X11 server can share the various I/O devices with the kernel's built-in terminal emulator. (If it uses I/O devices to which the kernel's built-in terminal emulator is not attached at all, this sharing protocol is unnecessary.) When it is in charge of the I/O devices, its keyboard map applies; when the kernel's built-in terminal emulator is in charge, its keyboard map applies.

This brings us to how the X11 server decides which kernel virtual terminal it "owns" in the first place, because that decision is up to it. There are three approaches:

  • It allocates the first available kernel virtual terminal. In this mode, which ⎇ Alt+Fn keyboard chord is the one for switching to the X11 session can vary at runtime, depending from what else is started by the system and what order services happen to start in.
    • If there are fixed TUI login services (running getty or similar) on (say) kernel virtual terminals 1 to 4, the X11 server finds KVT number 5 as the next available virtual terminal, and ⎇ Alt+F5 is consequently the keyboard chord.
    • If (say) the system is bringing up TUI login services on demand (as KVTs are switched-to by the user) and none happen to have been brought up yet, the X11 server finds KVT number 1 as the next available virtual terminal, and ⎇ Alt+F1 is consequently the keyboard chord.
  • It allocates the (ostensibly reserved to it) kernel virtual terminal that it is told to on the command line. One of the command-line arguments to the server program is the number of the kernel virtual terminal to use. So if (say) it is given the argument vt7 here, ⎇ Alt+F7 is consequently the keyboard chord.
  • It uses the current kernel virtual terminal. This is for the (nowadays more unusual) case of logging on to a TUI login session on a KVT and then starting the X11 server from that login session.

A couple of decades ago, the general convention was for the X11 server to be allocated to KVT number 7. But this has since changed on several operating systems. And it was not even the original general convention in the Linux operating system world, at least. (Of course, the idea of multiple kernel virtual terminals pre-dates Linux, and actual Unices had yet other conventions still.)

It changed over a decade ago on the Fedora family of operating systems because people wanted the system to display a splash screen all of the way from early in the operating system bootstrap until the X11 server was ready to take over, with no screen clear+redraw or flickering into and out of another display mode caused by the kernel's built-in terminal emulator being brought up on KVT number 1 before the X11 server started up on another KVT and forced a switch to it (as it does). The change was simply to not bring up kernel's built-in terminal emulator on KVT number 1, it having been disabled there by the splash screen, and make that the KVT that the X11 server then used, giving a seamless transition from splash screen to GUI login screen.

(People erroneously ascribe this change to systemd. In fact, it pre-dated systemd by years, and happend during the time that Fedora used upstart. Indeed, and somewhat ironically given people's erroneous ascription, when systemd first came out a few years later the systemd people did not know about this change, and did not make systemd copy what upstart had been doing, causing a conflict on KVT number 1 between a TUI login session and the X11 server.)

Hence you find that whilst on some operating systems the X11 server is using KVT number 7, on others it is KVT number 1.

On yet others still, such as Debian 9, the thing allocating KVT number 1 is now a different graphical subsystem, not an X11 server, for the primary GUI login interface; and there is a secondary X11 server, allocated another KVT, for each GUI login session. (⎈ Control+)⎇ Alt+F1 switches to the primary GUI login interface, and (⎈ Control+)⎇ Alt+F2 switches to (the first such, if any) GUI login session.

Further reading

Related Question