[systemd-devel] [RFC] logind: introduce session "positions"

David Herrmann dh.herrmann at gmail.com
Mon Dec 2 04:57:48 PST 2013


Hi

On Sun, Dec 1, 2013 at 6:02 PM, Shawn Landden <shawn at churchofgit.com> wrote:
> On Sun, Dec 1, 2013 at 3:43 AM, David Herrmann <dh.herrmann at gmail.com> wrote:
>> logind has no concept of session ordering. Sessions have a unique name,
>> some attributes about the capabilities and that's already it. There is
>> currently no stable+total order on sessions. If we use the logind API to
>> switch between sessions, we are faced with an unordered list of sessions
>> we have no clue of.
>>
>> This used to be no problem on seats with VTs or on seats with only a
>> single active session. However, with the introduction of multi-session
>> capability for seats without VTs, we need to find a way to order sessions
>> in a stable way.
>>
>> This patch introduces session "positions". A position is a simple integer
>> assigned to a session which is never changed implicitly (currently, we
>> also don't change it explicitly, but that may be changed someday). For
>> seats with VTs, we force the position to be the same as the VTnr. Without
>> VTs, we simply find the lowest unassigned number and use it as position.
>> If position-assignment fails or if, for any reason, we decide to not
>> assign a position to a session, the position is set to 0 (which is treated
>> as invalid position).
>> During session_load() or if two sessions have the same VTnr, we may end up
>> with two sessions with the same position (this shouldn't happen, but lets
>> be fail-safe in case some other part of the stack fails). This case is
>> dealt with gracefully by ignoring any session but the first session
>> assigned to the position. Thus, session->pos is a hint, seat->positions[i]
>> is the definite position-assignment. Always verify both match in case you
>> need to modify them!
>>
>> Additionally, we introduce SwitchTo(unsigned int) on the seat-dbus-API.
>> You can call it with any integer value != 0 and logind will try to switch
>> to the request position. If you implement a compositor or any other
>> session-controller, you simply watch for ctrl+alt+F1 to F12 and call
>> SwitchTo(Fx). logind will figure a way out deal with this number.
>> For convenience, we also introduce SwitchToNext/Previous(). It should be
>> called on ctrl+alt+Left/Right (like the kernel-console used to support).
> This has some conflict with workspaces, but not in gnome-shell (w/o
> gnome-tweak-tool)
> as there workspaces are all vertical. I personally like the idea.

Umm, right. These keys are already used by some compositors. But we
would have to introduce XKB_KEY_XF86Switch_To_Next/Previous, anyway.
So these actions are not bound to any shortcuts but it depends on your
keymap. This is the same as with XKB_KEY_XF86Switch_To_VTx which are
also bound by your keymap, not by your compositor.

>>
>> Note that the public API (SwitchTo*()) is *not* bound to the underlying
>> logic that is implemented now. We don't export "session-positions" on the
>> dbus/C API! They are an implementation detail. Instead, the SwitchTo*()
>> API is supposed to be a hint to let logind choose the session-switching
>> logic. Any foreground session-controller is free to enumerate/order
>> existing sessions according to their needs and call Session.Activate()
>> manually. But the SwitchTo*() API provides a uniform behavior across
>> session-controllers.
>>
>> Background: Session-switching keys depend on the active keymap. The XKB
>> specification provides the XKB_KEY_XF86Switch_VT_1-12 key-symbols which
>> have to be mapped by all keymaps to allow session-switching. It is usually
>> bound to ctrl+alt+Fx but may be set differently. A compositor passes any
>> keyboard input to XKB before passing it to clients. In case a key-press
>> invokes the XKB_KEY_XF86Switch_VT_x action, the keypress is *not*
>> forwarded to clients, but instead a session-switch is scheduled.
>>
>> This actually prevents us from handling these keys outside of the session.
>> If an active compositor has a keymap with a different mapping of these
>> keys, and logind itself tries to catch these combinations, we end up with
>> the key-press sent to the compositor's clients *and* handled by logind.
>> This is *bad* and we must avoid this. The only situation where a
>> background process is allowed to handle key-presses is debugging and
>> emergency-keys. In these cases, we don't care for keymap mismatches and
>> accept the double-event. Another exception is unmapped keys like
>> PowerOff/Suspend (even though this one is controversial).
>>
>> Future ideas: As this commit-msg isn't long enough, yet, some notes on
>> future ideas. The current position-assignment is compatible with the
>> legacy VT numbers. However, it is a rather outdated way of addressing
>> sessions. Instead, we can make use of session-classes of logind. We
>> already tag session with one of the classes "greeter", "user",
>> "background", "lock-screen". So one of my ideas is to make
>> "position-assignment" a "per-class" thing. And instead of mapping F1-F12
>> directly to the positions, we map it as follows:
>>  - F1: Activate the last-spawned session in the "greeter" class. Usually,
>>        only a single greeter should be active, but in case
>>        systemd-welcomed runs and gdm is spawned later, this will switch to
>>        gdm (actually gdm.service should stop systemd-welcomed.service but
>>        lets be overly pedantic here).
>>  - F2: Activate the session from the "user" class which has been active
>>        last. So if you switch to F1 and back to F2, you're guaranteed to
>>        get back to your last active user-session.
>>  - F3-F11: Direct mapping to "user" sessions. So F3 maps to the
>>            user-session with position 3, F11 to position 11 (or apply a
>>            "-2" offset, so F3=>1 and F11=>9..)
>>  - F12: Switch to the last-spawned session in the "emergency" class. This
>>         doesn't exist, yet, but we could start sessions showing the
>>         kernel-log or an emergency-console here.
>>
>> Inside of each group, you can use SwitchToNext/Previous() to switch to the
>> next/previous session. As only the "user" group has a way of directly
>> addressing sessions, this is needed for the "greeter" and "emergency"
>> groups. Note that both groups are expected to only have one session, so
>> this is really just a fallback for odd cases. However, for the "user"
>> group the Next/Previous can come in quite handy.
> Emergency sessions are light weight enough that we could auto-spawn them like
> we currently do with gettys on VTs.

Indeed. All you have to do is symlink autovt at tty12.service to your
emergency-session. Something similar (eg., autovt at f12.service) could
be done for seats without VTs.

Cheers
David


More information about the systemd-devel mailing list