88 "path/filepath"
99 "strings"
1010
11+ "github.com/AvengeMedia/DankMaterialShell/core/internal/distros"
1112 "github.com/AvengeMedia/DankMaterialShell/core/internal/greeter"
1213 "github.com/AvengeMedia/DankMaterialShell/core/internal/log"
1314 "github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
@@ -77,6 +78,28 @@ func installGreeter() error {
7778 return err
7879 }
7980
81+ // Debian/openSUSE
82+ greeter .TryInstallGreeterPackage (logFunc , "" )
83+ if isPackageOnlyGreeterDistro () && ! greeter .IsGreeterPackaged () {
84+ return fmt .Errorf ("dms-greeter must be installed from distro packages on this distribution. %s" , packageInstallHint ())
85+ }
86+ if greeter .IsGreeterPackaged () && greeter .HasLegacyLocalGreeterWrapper () {
87+ return fmt .Errorf ("legacy manual wrapper detected at /usr/local/bin/dms-greeter; remove it before using packaged dms-greeter: sudo rm -f /usr/local/bin/dms-greeter" )
88+ }
89+
90+ // If already fully configured, prompt the user
91+ if isGreeterEnabled () {
92+ fmt .Print ("\n Greeter is already installed and configured. Re-run to re-sync settings and permissions? [Y/n]: " )
93+ var response string
94+ fmt .Scanln (& response )
95+ response = strings .TrimSpace (strings .ToLower (response ))
96+ if response == "n" || response == "no" {
97+ fmt .Println ("Run 'dms greeter sync' to re-sync theme and settings at any time." )
98+ return nil
99+ }
100+ fmt .Println ()
101+ }
102+
80103 fmt .Println ("\n Detecting DMS installation..." )
81104 dmsPath , err := greeter .DetectDMSPath ()
82105 if err != nil {
@@ -114,7 +137,12 @@ func installGreeter() error {
114137 }
115138
116139 fmt .Println ("\n Configuring greetd..." )
117- if err := greeter .ConfigureGreetd (dmsPath , selectedCompositor , logFunc , "" ); err != nil {
140+ // Use empty path when packaged (greeter finds /usr/share/quickshell/dms-greeter); else use user's DMS path
141+ greeterPathForConfig := ""
142+ if ! greeter .IsGreeterPackaged () {
143+ greeterPathForConfig = dmsPath
144+ }
145+ if err := greeter .ConfigureGreetd (greeterPathForConfig , selectedCompositor , logFunc , "" ); err != nil {
118146 return err
119147 }
120148
@@ -123,11 +151,22 @@ func installGreeter() error {
123151 return err
124152 }
125153
154+ if err := ensureGraphicalTarget (); err != nil {
155+ return err
156+ }
157+
158+ if err := handleConflictingDisplayManagers (); err != nil {
159+ return err
160+ }
161+
162+ if err := ensureGreetdEnabled (); err != nil {
163+ return err
164+ }
165+
126166 fmt .Println ("\n === Installation Complete ===" )
127- fmt .Println ("\n To test the greeter, run:" )
167+ fmt .Println ("\n To start the greeter now , run:" )
128168 fmt .Println (" sudo systemctl start greetd" )
129- fmt .Println ("\n To enable on boot, run:" )
130- fmt .Println (" sudo systemctl enable --now greetd" )
169+ fmt .Println ("\n Or reboot to see the greeter at next boot." )
131170
132171 return nil
133172}
@@ -327,20 +366,29 @@ func ensureGreetdEnabled() error {
327366 fmt .Println (" ✓ Unmasked greetd" )
328367 }
329368
330- switch state .EnabledState {
331- case "disabled" , "masked" , "masked-runtime" :
369+ if state .EnabledState == "enabled" || state .EnabledState == "enabled-runtime" {
370+ fmt .Println (" Reasserting greetd as active display manager..." )
371+ } else {
332372 fmt .Println (" Enabling greetd service..." )
333- enableCmd := exec .Command ("sudo" , "systemctl" , "enable" , "greetd" )
334- enableCmd .Stdout = os .Stdout
335- enableCmd .Stderr = os .Stderr
336- if err := enableCmd .Run (); err != nil {
337- return fmt .Errorf ("failed to enable greetd: %w" , err )
338- }
339- fmt .Println (" ✓ Enabled greetd service" )
340- case "enabled" , "enabled-runtime" :
341- fmt .Println (" ✓ greetd is already enabled" )
342- default :
343- fmt .Printf (" ℹ greetd is in state '%s' (should work, no action needed)\n " , state .EnabledState )
373+ }
374+
375+ enableCmd := exec .Command ("sudo" , "systemctl" , "enable" , "--force" , "greetd" )
376+ enableCmd .Stdout = os .Stdout
377+ enableCmd .Stderr = os .Stderr
378+ if err := enableCmd .Run (); err != nil {
379+ return fmt .Errorf ("failed to enable greetd: %w" , err )
380+ }
381+
382+ enabledState , _ , verifyErr := checkSystemdServiceEnabled ("greetd" )
383+ if verifyErr != nil {
384+ fmt .Printf (" ⚠ Warning: Could not verify greetd enabled state: %v\n " , verifyErr )
385+ } else {
386+ switch enabledState {
387+ case "enabled" , "enabled-runtime" , "static" , "indirect" , "alias" :
388+ fmt .Printf (" ✓ greetd enabled (state: %s)\n " , enabledState )
389+ default :
390+ return fmt .Errorf ("greetd is still in state '%s' after enable operation" , enabledState )
391+ }
344392 }
345393
346394 return nil
@@ -446,6 +494,10 @@ func enableGreeter() error {
446494 }
447495
448496 configContent := string (data )
497+ if greeter .IsGreeterPackaged () && greeter .HasLegacyLocalGreeterWrapper () {
498+ return fmt .Errorf ("legacy manual wrapper detected at /usr/local/bin/dms-greeter; remove it before using packaged dms-greeter: sudo rm -f /usr/local/bin/dms-greeter" )
499+ }
500+
449501 configAlreadyCorrect := strings .Contains (configContent , "dms-greeter" )
450502
451503 if configAlreadyCorrect {
@@ -611,6 +663,48 @@ func detectConfiguredCompositor() string {
611663 return ""
612664}
613665
666+ func packageInstallHint () string {
667+ osInfo , err := distros .GetOSInfo ()
668+ if err != nil {
669+ return "Install package: dms-greeter"
670+ }
671+ config , exists := distros .Registry [osInfo .Distribution .ID ]
672+ if ! exists {
673+ return "Install package: dms-greeter"
674+ }
675+
676+ switch config .Family {
677+ case distros .FamilyDebian :
678+ return "Install with 'sudo apt install dms-greeter' (requires DankLinux OBS repo — see https://danklinux.com/docs/dankgreeter/installation#debian)"
679+ case distros .FamilySUSE :
680+ return "Install with 'sudo zypper install dms-greeter' (requires DankLinux OBS repo — see https://danklinux.com/docs/dankgreeter/installation#opensuse)"
681+ case distros .FamilyUbuntu :
682+ return "Install with 'sudo apt install dms-greeter' (requires ppa:avengemedia/danklinux: sudo add-apt-repository ppa:avengemedia/danklinux)"
683+ case distros .FamilyFedora :
684+ return "Install with 'sudo dnf install dms-greeter' (requires COPR: sudo dnf copr enable avengemedia/danklinux)"
685+ case distros .FamilyArch :
686+ return "Install from AUR with 'paru -S greetd-dms-greeter-git' or 'yay -S greetd-dms-greeter-git'"
687+ default :
688+ return "Run 'dms greeter install' to install greeter"
689+ }
690+ }
691+
692+ func isPackageOnlyGreeterDistro () bool {
693+ osInfo , err := distros .GetOSInfo ()
694+ if err != nil {
695+ return false
696+ }
697+ config , exists := distros .Registry [osInfo .Distribution .ID ]
698+ if ! exists {
699+ return false
700+ }
701+ return config .Family == distros .FamilyDebian ||
702+ config .Family == distros .FamilySUSE ||
703+ config .Family == distros .FamilyUbuntu ||
704+ config .Family == distros .FamilyFedora ||
705+ config .Family == distros .FamilyArch
706+ }
707+
614708func promptCompositorChoice (compositors []string ) (string , error ) {
615709 fmt .Println ("\n Multiple compositors detected:" )
616710 for i , comp := range compositors {
@@ -679,7 +773,7 @@ func checkGreeterStatus() error {
679773 }
680774 } else {
681775 fmt .Println (" ✗ Greeter config not found" )
682- fmt .Println (" Run 'dms greeter install' to install greeter" )
776+ fmt .Printf (" %s \n " , packageInstallHint () )
683777 }
684778
685779 fmt .Println ("\n Group Membership:" )
@@ -689,12 +783,13 @@ func checkGreeterStatus() error {
689783 return fmt .Errorf ("failed to check groups: %w" , err )
690784 }
691785
692- inGreeterGroup := strings .Contains (string (groupsOutput ), "greeter" )
786+ greeterGroup := greeter .DetectGreeterGroup ()
787+ inGreeterGroup := strings .Contains (string (groupsOutput ), greeterGroup )
693788 if inGreeterGroup {
694- fmt .Println (" ✓ User is in greeter group" )
789+ fmt .Printf (" ✓ User is in %s group\n " , greeterGroup )
695790 } else {
696- fmt .Println (" ✗ User is NOT in greeter group" )
697- fmt .Println (" Run 'dms greeter install ' to add user to greeter group " )
791+ fmt .Printf (" ✗ User is NOT in %s group\n " , greeterGroup )
792+ fmt .Println (" Run 'dms greeter sync ' to set up group membership and permissions " )
698793 }
699794
700795 cacheDir := "/var/cache/dms-greeter"
@@ -703,7 +798,7 @@ func checkGreeterStatus() error {
703798 fmt .Printf (" ✓ %s exists\n " , cacheDir )
704799 } else {
705800 fmt .Printf (" ✗ %s not found\n " , cacheDir )
706- fmt .Println (" Run 'dms greeter install' to create cache directory" )
801+ fmt .Printf (" %s \n " , packageInstallHint () )
707802 return nil
708803 }
709804
0 commit comments