]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-record: Add preferredSession{Type,Launcher}
authorAdrian Vovk <adrianvovk@gmail.com>
Mon, 5 Feb 2024 00:21:29 +0000 (19:21 -0500)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 1 Mar 2024 16:28:10 +0000 (16:28 +0000)
These will be used by display managers to pre-select the user's
preferred desktop environment and display server type. On homed, the
display manager will also be able to set these fields to cache the
user's last selection.

docs/USER_RECORD.md
man/homectl.xml
shell-completion/bash/homectl
src/home/homectl.c
src/shared/user-record-show.c
src/shared/user-record.c
src/shared/user-record.h

index a92711f275997581044a328720a08185425c8bc6..78b29f078ae7ce3ce9477dbb89331b488255319c 100644 (file)
@@ -568,6 +568,15 @@ it is bypassed.
 auto-login. Systems are supposed to automatically log in a user marked this way
 during boot, if there's exactly one user on it defined this way.
 
+`preferredSessionType` → A string that indicates the user's preferred session type
+(i.e. `x11`, `wayland`, or other values valid for `$XDG_SESSION_TYPE`). This should
+be used by the display manager to pre-select the correct environment to log into.
+
+`preferredSessionLauncher` → A string that indicates the user's preferred session launcher
+desktop entry file (i.e. `gnome`, `gnome-classic`, `plasma`, `kodi`, or others that appear
+in `/usr/share/xsessions/` or `/usr/share/wayland-sessions/`). This should be used by the
+display manager to pre-select the correct environment to launch when the user logs in.
+
 `stopDelayUSec` → An unsigned 64-bit integer, indicating the time in µs the
 per-user service manager is kept around after the user fully logged out.  This
 value is honored by
@@ -780,8 +789,8 @@ that may be used in this section are identical to the equally named ones in the
 `luksPbkdfType`, `luksPbkdfForceIterations`, `luksPbkdfTimeCostUSec`, `luksPbkdfMemoryCost`,
 `luksPbkdfParallelThreads`, `luksSectorSize`, `autoResizeMode`, `rebalanceWeight`,
 `rateLimitIntervalUSec`, `rateLimitBurst`, `enforcePasswordPolicy`,
-`autoLogin`, `stopDelayUSec`, `killProcesses`, `passwordChangeMinUSec`,
-`passwordChangeMaxUSec`, `passwordChangeWarnUSec`,
+`autoLogin`, `preferredSessionType`, `preferredSessionLauncher`, `stopDelayUSec`, `killProcesses`,
+`passwordChangeMinUSec`, `passwordChangeMaxUSec`, `passwordChangeWarnUSec`,
 `passwordChangeInactiveUSec`, `passwordChangeNow`, `pkcs11TokenUri`,
 `fido2HmacCredential`.
 
index 521d34124881dc3311bfb9c0cc3c90cac8656006..1a0535cd4a66089dc9d5aa4bf1394010930e2ee5 100644 (file)
 
         <xi:include href="version-info.xml" xpointer="v245"/></listitem>
       </varlistentry>
+
+      <varlistentry>
+        <term><option>--session-launcher=</option><replaceable>LAUNCHER</replaceable></term>
+
+        <listitem><para>Takes a string argument. Configures the user's preferred session launcher
+        .desktop entry file (i.e. <literal>gnome</literal>, <literal>plasma</literal>, or other names that
+        appear in <filename>/usr/share/xesssions/</filename> or <filename>/usr/share/wayland-sessions</filename>).
+        This is read by the display manager to pick the default session that is launched when the user logs in.</para>
+
+        <xi:include href="version-info.xml" xpointer="v256"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--session-type=</option><replaceable>TYPE</replaceable></term>
+
+        <listitem><para>Takes a string argument. Configures the user's preferred session type
+        (i.e. <literal>x11</literal>, <literal>wayland</literal>, and other values accepted by
+        <varname>$XDG_SESSION_TYPE</varname>). This is read by the display manage to pick the
+        default session type the user is logged into.</para>
+
+        <xi:include href="version-info.xml" xpointer="v256"/></listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index 527dd81c458ee1b65b8debe9f95e781419af7dc9..5e2235bc3b062024f48054dcb652b0743441cb1b 100644 (file)
@@ -110,7 +110,9 @@ _homectl() {
                         --auto-login
                      -b --blob
                         --avatar
-                        --login-background'
+                        --login-background
+                        --session-launcher
+                        --session-type'
     )
 
     if __contains_word "$prev" ${OPTS[ARG]}; then
@@ -153,6 +155,12 @@ _homectl() {
             --language)
                 comps=$(localectl list-locales 2>/dev/null)
                 ;;
+            --session-launcher)
+                comps=$(find /usr/share/{x,wayland-}sessions/ -type f -name '*.desktop' -exec basename {} .desktop \; 2>/dev/null | sort -u)
+                ;;
+            --session-type)
+                comps='wayland x11 tty'
+                ;;
         esac
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
         return 0
index 4afdff74c03a80c6f57c1d6085429a8b0ad38639..11a138070b1fd09b2dc28bb4a9cdb88e36bd3b9d 100644 (file)
@@ -2701,6 +2701,9 @@ static int help(int argc, char *argv[], void *userdata) {
                "     --kill-processes=BOOL     Whether to kill user processes when sessions\n"
                "                               terminate\n"
                "     --auto-login=BOOL         Try to log this user in automatically\n"
+               "     --session-launcher=LAUNCHER\n"
+               "                               Preferred session launcher file\n"
+               "     --session-type=TYPE       Preferred session type\n"
                "\nSee the %6$s for details.\n",
                program_invocation_short_name,
                ansi_highlight(),
@@ -2777,6 +2780,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_PASSWORD_CHANGE_INACTIVE,
                 ARG_EXPORT_FORMAT,
                 ARG_AUTO_LOGIN,
+                ARG_SESSION_LAUNCHER,
+                ARG_SESSION_TYPE,
                 ARG_PKCS11_TOKEN_URI,
                 ARG_FIDO2_DEVICE,
                 ARG_FIDO2_WITH_PIN,
@@ -2870,6 +2875,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "password-change-warn",        required_argument, NULL, ARG_PASSWORD_CHANGE_WARN        },
                 { "password-change-inactive",    required_argument, NULL, ARG_PASSWORD_CHANGE_INACTIVE    },
                 { "auto-login",                  required_argument, NULL, ARG_AUTO_LOGIN                  },
+                { "session-launcher",            required_argument, NULL, ARG_SESSION_LAUNCHER,           },
+                { "session-type",                required_argument, NULL, ARG_SESSION_TYPE,               },
                 { "json",                        required_argument, NULL, ARG_JSON                        },
                 { "export-format",               required_argument, NULL, ARG_EXPORT_FORMAT               },
                 { "pkcs11-token-uri",            required_argument, NULL, ARG_PKCS11_TOKEN_URI            },
@@ -3009,7 +3016,9 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_CIFS_USER_NAME:
                 case ARG_CIFS_DOMAIN:
                 case ARG_CIFS_EXTRA_MOUNT_OPTIONS:
-                case ARG_LUKS_EXTRA_MOUNT_OPTIONS: {
+                case ARG_LUKS_EXTRA_MOUNT_OPTIONS:
+                case ARG_SESSION_LAUNCHER:
+                case ARG_SESSION_TYPE: {
 
                         const char *field =
                                            c == ARG_EMAIL_ADDRESS ? "emailAddress" :
@@ -3019,6 +3028,8 @@ static int parse_argv(int argc, char *argv[]) {
                                              c == ARG_CIFS_DOMAIN ? "cifsDomain" :
                                 c == ARG_CIFS_EXTRA_MOUNT_OPTIONS ? "cifsExtraMountOptions" :
                                 c == ARG_LUKS_EXTRA_MOUNT_OPTIONS ? "luksExtraMountOptions" :
+                                        c == ARG_SESSION_LAUNCHER ? "preferredSessionLauncher" :
+                                            c == ARG_SESSION_TYPE ? "preferredSessionType" :
                                                                     NULL;
 
                         assert(field);
index 086d344c01153d0ca62d4d40c74c7241ee016389..23a41534ba5241e000728451777a056f5befcb14 100644 (file)
@@ -575,6 +575,11 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->auto_login >= 0)
                 printf("Autom. Login: %s\n", yes_no(hr->auto_login));
 
+        if (hr->preferred_session_launcher)
+                printf("Sess. Launch: %s\n", hr->preferred_session_launcher);
+        if (hr->preferred_session_type)
+                printf("Session Type: %s\n", hr->preferred_session_type);
+
         if (hr->kill_processes >= 0)
                 printf("  Kill Proc.: %s\n", yes_no(hr->kill_processes));
 
index fc39194ac55ecf747e69f6bffddd19e691318456..fe102b004a1cf2fb297b3d7377bd3564a90bf76e 100644 (file)
@@ -189,6 +189,9 @@ static UserRecord* user_record_free(UserRecord *h) {
         free(h->state);
         free(h->service);
 
+        free(h->preferred_session_type);
+        free(h->preferred_session_launcher);
+
         strv_free(h->pkcs11_token_uri);
         for (size_t i = 0; i < h->n_pkcs11_encrypted_key; i++)
                 pkcs11_encrypted_key_done(h->pkcs11_encrypted_key + i);
@@ -1340,6 +1343,8 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp
                 { "rateLimitBurst",             _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
                 { "enforcePasswordPolicy",      JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, enforce_password_policy),       0         },
                 { "autoLogin",                  JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, auto_login),                    0         },
+                { "preferredSessionType",       JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, preferred_session_type),        JSON_SAFE },
+                { "preferredSessionLauncher",   JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, preferred_session_launcher),    JSON_SAFE },
                 { "stopDelayUSec",              _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, stop_delay_usec),               0         },
                 { "killProcesses",              JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, kill_processes),                0         },
                 { "passwordChangeMinUSec",      _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, password_change_min_usec),      0         },
@@ -1683,6 +1688,8 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla
                 { "rateLimitBurst",             _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
                 { "enforcePasswordPolicy",      JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, enforce_password_policy),       0         },
                 { "autoLogin",                  JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, auto_login),                    0         },
+                { "preferredSessionType",       JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, preferred_session_type),        JSON_SAFE },
+                { "preferredSessionLauncher",   JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, preferred_session_launcher),    JSON_SAFE },
                 { "stopDelayUSec",              _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, stop_delay_usec),               0         },
                 { "killProcesses",              JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, kill_processes),                0         },
                 { "passwordChangeMinUSec",      _JSON_VARIANT_TYPE_INVALID, json_dispatch_uint64,                 offsetof(UserRecord, password_change_min_usec),      0         },
index 1819f55489c68086cedad6040ae4cfc9c97c2481..cca112f5feb98e2f0f4a846882259634d204325f 100644 (file)
@@ -351,6 +351,9 @@ typedef struct UserRecord {
         int auto_login;
         int drop_caches;
 
+        char *preferred_session_type;
+        char *preferred_session_launcher;
+
         uint64_t stop_delay_usec;   /* How long to leave systemd --user around on log-out */
         int kill_processes;         /* Whether to kill user processes forcibly on log-out */