diff --git a/src/modules/displaymanager/displaymanager.conf b/src/modules/displaymanager/displaymanager.conf index 18e956f27..81469bd58 100644 --- a/src/modules/displaymanager/displaymanager.conf +++ b/src/modules/displaymanager/displaymanager.conf @@ -64,6 +64,12 @@ sysconfigSetup: false # # greetd has configurable user and group; the user and group is created if it # does not exist, and the user is set as default-session user. +# +# lightdm has a list of greeters to look for, preferring them in order if +# they are installed (if not, picks the alphabetically first greeter that is installed). +# greetd: greeter_user: "tom_bombadil" greeter_group: "wheel" +lightdm: + preferred_greeters: ["lightdm-greeter.desktop", "slick-greeter.desktop"] diff --git a/src/modules/displaymanager/displaymanager.schema.yaml b/src/modules/displaymanager/displaymanager.schema.yaml index 2f1da9d56..ab89c0ada 100644 --- a/src/modules/displaymanager/displaymanager.schema.yaml +++ b/src/modules/displaymanager/displaymanager.schema.yaml @@ -26,4 +26,7 @@ properties: greeter_user: { type: string } greeter_group: { type: string } additionalProperties: false - + lightdm: + type: object + properties: + preferred_greeters: { type: array, items: { type: string } } diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 608b443ad..b403a382a 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -544,6 +544,11 @@ class DMlightdm(DisplayManager): name = "lightdm" executable = "lightdm" + # Can be overridden in the .conf file. With no value it won't match any + # desktop file in the xgreeters directory and instead we end up picking + # the alphabetically first file there. + preferred_greeters = [] + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with LightDM as Desktop Manager # Ideally, we should use configparser for the ini conf file, @@ -633,41 +638,56 @@ class DMlightdm(DisplayManager): ) ) + def find_preferred_greeter(self, greeters_dir): + """ + On Debian, lightdm-greeter.desktop is typically a symlink managed + by update-alternatives pointing to /etc/alternatives/lightdm-greeter + which is also a symlink to a real .desktop file back in /usr/share/xgreeters/ + + Returns a path *into the mounted target* of the preferred greeter -- usually + a .desktop file that specifies where the actual executable is. May return + None to indicate nothing-was-found. + """ + greeters_dir = "usr/share/xgreeters" + greeters_target_path = os.path.join(self.root_mount_point, greeters_dir) + available_names = os.listdir(greeters_target_path) + available_names.sort() + desktop_names = [n for n in self.preferred_greeters if n in available_names] # Preferred ones + if desktop_names: + return desktop_names[0] + desktop_names = [n for n in available_names if n.endswith(".desktop")] # .. otherwise any .desktop + if desktop_names: + return desktop_names[0] + return None + + def greeter_setup(self): - lightdm_conf_path = os.path.join( - self.root_mount_point, "etc/lightdm/lightdm.conf" - ) + lightdm_conf_path = os.path.join(self.root_mount_point, "etc/lightdm/lightdm.conf") + greeter_path = self.find_preferred_greeter() - # configure lightdm-greeter - greeter_path = os.path.join( - self.root_mount_point, "usr/share/xgreeters" - ) + if greeter_path is not None and os.path.exists(greeter_path): + greeter = os.path.basename(os.path.realpath(greeter_path)) # Follow symlinks, hope they are not absolute + if greeter.endswith('.desktop'): + greeter = greeter[:-8] # Remove ".desktop" from end - if (os.path.exists(greeter_path)): - # configure first found lightdm-greeter - for entry in os.listdir(greeter_path): - if entry.endswith('.desktop'): - greeter = entry.split('.')[0] - libcalamares.utils.debug( - "found greeter {!s}".format(greeter) - ) - os.system( - "sed -i -e \"s/^.*greeter-session=.*" - "/greeter-session={!s}/\" {!s}".format( - greeter, - lightdm_conf_path - ) - ) - libcalamares.utils.debug( - "{!s} configured as greeter.".format(greeter) - ) - break + libcalamares.utils.debug("found greeter {!s}".format(greeter)) + os.system( + "sed -i -e \"s/^.*greeter-session=.*" + "/greeter-session={!s}/\" {!s}".format( + greeter, + lightdm_conf_path + ) + ) + libcalamares.utils.debug("{!s} configured as greeter.".format(greeter)) + else: + if greeter_path is None: + libcalamares.utils.error("No greeter found at all, preferred {!s}".format(self.preferred_greeters)) else: - return ( - _("Cannot configure LightDM"), - _("No LightDM greeter installed.") - ) - + libcalamares.utils.error("Greeter {!s} selected but file does not exist".format(greeter_path)) + return ( + _("Cannot configure LightDM"), + _("No LightDM greeter installed.") + ) class DMslim(DisplayManager): name = "slim"