]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind-session-dbus: allow to set display name via dbus
authorDavid Tardon <dtardon@redhat.com>
Fri, 10 Jun 2022 13:07:01 +0000 (15:07 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 22 Jun 2022 20:34:29 +0000 (22:34 +0200)
Currently, the only way to set display name of a graphical session is to
pass it to CreateSession(). But modern display managers like gdm start
the display server as part of the user session, which means that the
display name isn't known yet when the session is being created. Hence,
let's make it possible to set it later.

man/org.freedesktop.login1.xml
src/login/logind-session-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/org.freedesktop.login1.conf

index 108a47a38da93de3b11d7e91f9fc3245c5eb7d9d..4cc9f2789193b0827b1f2b9f22c3c2a7b10e80c7 100644 (file)
@@ -1075,6 +1075,7 @@ node /org/freedesktop/login1/session/1 {
       TakeControl(in  b force);
       ReleaseControl();
       SetType(in  s type);
+      SetDisplay(in  s display);
       TakeDevice(in  u major,
                  in  u minor,
                  out h fd,
@@ -1172,6 +1173,8 @@ node /org/freedesktop/login1/session/1 {
 
     <variablelist class="dbus-method" generated="True" extra-ref="SetType()"/>
 
+    <variablelist class="dbus-method" generated="True" extra-ref="SetDisplay()"/>
+
     <variablelist class="dbus-method" generated="True" extra-ref="TakeDevice()"/>
 
     <variablelist class="dbus-method" generated="True" extra-ref="ReleaseDevice()"/>
@@ -1268,6 +1271,11 @@ node /org/freedesktop/login1/session/1 {
       connection. This should help prevent a session from entering an inconsistent state, for example if the
       controller crashes. The only argument <varname>type</varname> is the new session type.</para>
 
+      <para><function>SetDisplay()</function> allows the display name of the graphical session to be changed. This is
+      useful if the display server is started as part of the session. It can only be called by session's current
+      controller. If <function>TakeControl()</function> has not been called, this method will fail. The only argument
+      <varname>display</varname> is the new display name.</para>
+
       <para><function>TakeDevice()</function> allows a session controller to get a file descriptor for a
       specific device. Pass in the major and minor numbers of the character device and
       <filename>systemd-logind</filename> will return a file descriptor for the device. Only a limited set of
index 7d46759822bf83b7baa8fdf8d8f09ff0d8ec9f90..539109c5e8867f753d4744ba432bfb20585b365a 100644 (file)
@@ -413,6 +413,30 @@ static int method_set_type(sd_bus_message *message, void *userdata, sd_bus_error
         return sd_bus_reply_method_return(message, NULL);
 }
 
+static int method_set_display(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Session *s = ASSERT_PTR(userdata);
+        const char *display;
+        int r;
+
+        assert(message);
+
+        r = sd_bus_message_read(message, "s", &display);
+        if (r < 0)
+                return r;
+
+        if (!session_is_controller(s, sd_bus_message_get_sender(message)))
+                return sd_bus_error_set(error, BUS_ERROR_NOT_IN_CONTROL, "You must be in control of this session to set display");
+
+        if (!SESSION_TYPE_IS_GRAPHICAL(s->type))
+                return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Setting display is only supported for graphical sessions");
+
+        r = session_set_display(s, display);
+        if (r < 0)
+                return r;
+
+        return sd_bus_reply_method_return(message, NULL);
+}
+
 static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Session *s = userdata;
         uint32_t major, minor;
@@ -901,6 +925,11 @@ static const sd_bus_vtable session_vtable[] = {
                                 SD_BUS_NO_RESULT,
                                 method_set_type,
                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetDisplay",
+                                SD_BUS_ARGS("s", display),
+                                SD_BUS_NO_RESULT,
+                                method_set_display,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_ARGS("TakeDevice",
                                 SD_BUS_ARGS("u", major, "u", minor),
                                 SD_BUS_RESULT("h", fd, "b", inactive),
index 4995e5885aae24c9aace1254759f3534d28e557d..ac3904352e950176d414490912bd919cd3f826c8 100644 (file)
@@ -1044,6 +1044,26 @@ void session_set_type(Session *s, SessionType t) {
         session_send_changed(s, "Type", NULL);
 }
 
+int session_set_display(Session *s, const char *display) {
+        int r;
+
+        assert(s);
+        assert(display);
+
+        if (streq(s->display, display))
+                return 0;
+
+        r = free_and_strdup(&s->display, display);
+        if (r < 0)
+                return r;
+
+        session_save(s);
+
+        session_send_changed(s, "Display", NULL);
+
+        return 1;
+}
+
 static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
         Session *s = userdata;
 
index 5c35071dc52bc2ae8761501832a1dc1dcf71e7a7..6b6ac2d573f43ecc7fdd407d5b5f1d73cad39690 100644 (file)
@@ -137,6 +137,7 @@ int session_set_idle_hint(Session *s, bool b);
 int session_get_locked_hint(Session *s);
 void session_set_locked_hint(Session *s, bool b);
 void session_set_type(Session *s, SessionType t);
+int session_set_display(Session *s, const char *display);
 int session_create_fifo(Session *s);
 int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error);
 int session_stop(Session *s, bool force);
index 95d2ef0f0633e63dcb47e794d847093a789d550f..6113b64aa7e5a2efb627e8650551f2a5fe8b98a1 100644 (file)
                        send_interface="org.freedesktop.login1.User"
                        send_member="Kill"/>
 
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Session"
+                       send_member="SetDisplay"/>
+
                 <allow receive_sender="org.freedesktop.login1"/>
         </policy>