From 37a843323d882eb65e50024cbfc5d1a008828c55 Mon Sep 17 00:00:00 2001 From: bbedward Date: Mon, 8 Dec 2025 20:40:13 -0500 Subject: [PATCH] dankisntall: add hyprland session target, disable hyprland-git variant universally --- core/cmd/dankinstall/main.go | 5 ++++ core/internal/config/deployer_test.go | 6 ++--- core/internal/config/embedded/hyprland.conf | 4 +++- core/internal/distros/arch.go | 11 +++++---- core/internal/distros/base.go | 26 +++++++++++++++++++++ core/internal/distros/fedora.go | 5 +--- core/internal/distros/gentoo.go | 8 ++----- 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/core/cmd/dankinstall/main.go b/core/cmd/dankinstall/main.go index 44412388..3c72553a 100644 --- a/core/cmd/dankinstall/main.go +++ b/core/cmd/dankinstall/main.go @@ -12,6 +12,11 @@ import ( var Version = "dev" func main() { + if os.Getuid() == 0 { + fmt.Fprintln(os.Stderr, "Error: dankinstall must not be run as root") + os.Exit(1) + } + fileLogger, err := log.NewFileLogger() if err != nil { fmt.Printf("Warning: Failed to create log file: %v\n", err) diff --git a/core/internal/config/deployer_test.go b/core/internal/config/deployer_test.go index cb99680d..bc816cf7 100644 --- a/core/internal/config/deployer_test.go +++ b/core/internal/config/deployer_test.go @@ -406,7 +406,7 @@ func TestHyprlandConfigDeployment(t *testing.T) { content, err := os.ReadFile(result.Path) require.NoError(t, err) assert.Contains(t, string(content), "# MONITOR CONFIG") - assert.Contains(t, string(content), "bind = $mod, T, exec, $TERMINAL") + assert.Contains(t, string(content), "bind = $mod, T, exec, ghostty") assert.Contains(t, string(content), "exec-once = ") }) @@ -442,7 +442,7 @@ general { require.NoError(t, err) assert.Contains(t, string(newContent), "monitor = DP-1, 1920x1080@144") assert.Contains(t, string(newContent), "monitor = HDMI-A-1, 3840x2160@60") - assert.Contains(t, string(newContent), "bind = $mod, T, exec, $TERMINAL") + assert.Contains(t, string(newContent), "bind = $mod, T, exec, kitty") assert.NotContains(t, string(newContent), "monitor = eDP-2") }) } @@ -460,7 +460,7 @@ func TestHyprlandConfigStructure(t *testing.T) { assert.Contains(t, HyprlandConfig, "# STARTUP APPS") assert.Contains(t, HyprlandConfig, "# INPUT CONFIG") assert.Contains(t, HyprlandConfig, "# KEYBINDINGS") - assert.Contains(t, HyprlandConfig, "bind = $mod, T, exec, $TERMINAL") + assert.Contains(t, HyprlandConfig, "bind = $mod, T, exec, {{TERMINAL_COMMAND}}") assert.Contains(t, HyprlandConfig, "bind = $mod, space, exec, dms ipc call spotlight toggle") assert.Contains(t, HyprlandConfig, "windowrulev2 = noborder, class:^(com\\.mitchellh\\.ghostty)$") } diff --git a/core/internal/config/embedded/hyprland.conf b/core/internal/config/embedded/hyprland.conf index e4eabf24..fa1a56fb 100644 --- a/core/internal/config/embedded/hyprland.conf +++ b/core/internal/config/embedded/hyprland.conf @@ -10,6 +10,8 @@ monitor = , preferred,auto,auto # ================== # STARTUP APPS # ================== +exec-once = dbus-update-activation-environment --systemd --all +exec-once = systemctl --user start hyprland-session.target exec-once = bash -c "wl-paste --watch cliphist store &" # ================== @@ -126,7 +128,7 @@ layerrule = noanim, ^(quickshell)$ $mod = SUPER # === Application Launchers === -bind = $mod, T, exec, $TERMINAL +bind = $mod, T, exec, {{TERMINAL_COMMAND}} bind = $mod, space, exec, dms ipc call spotlight toggle bind = $mod, V, exec, dms ipc call clipboard toggle bind = $mod, M, exec, dms ipc call processlist focusOrToggle diff --git a/core/internal/distros/arch.go b/core/internal/distros/arch.go index 10249128..cb77f219 100644 --- a/core/internal/distros/arch.go +++ b/core/internal/distros/arch.go @@ -186,10 +186,7 @@ func (a *ArchDistribution) getQuickshellMapping(variant deps.PackageVariant) Pac return PackageMapping{Name: "quickshell-git", Repository: RepoTypeAUR} } -func (a *ArchDistribution) getHyprlandMapping(variant deps.PackageVariant) PackageMapping { - if variant == deps.VariantGit { - return PackageMapping{Name: "hyprland-git", Repository: RepoTypeAUR} - } +func (a *ArchDistribution) getHyprlandMapping(_ deps.PackageVariant) PackageMapping { return PackageMapping{Name: "hyprland", Repository: RepoTypeSystem} } @@ -363,6 +360,12 @@ func (a *ArchDistribution) InstallPackages(ctx context.Context, dependencies []d a.log(fmt.Sprintf("Warning: failed to write environment config: %v", err)) } + if wm == deps.WindowManagerHyprland { + if err := a.WriteHyprlandSessionTarget(); err != nil { + a.log(fmt.Sprintf("Warning: failed to write hyprland session target: %v", err)) + } + } + if err := a.EnableDMSService(ctx); err != nil { a.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err)) } diff --git a/core/internal/distros/base.go b/core/internal/distros/base.go index ee3aa866..1c918dfc 100644 --- a/core/internal/distros/base.go +++ b/core/internal/distros/base.go @@ -611,6 +611,32 @@ func (b *BaseDistribution) EnableDMSService(ctx context.Context) error { return nil } +func (b *BaseDistribution) WriteHyprlandSessionTarget() error { + homeDir, err := os.UserHomeDir() + if err != nil { + return fmt.Errorf("failed to get home directory: %w", err) + } + + targetDir := filepath.Join(homeDir, ".config", "systemd", "user") + if err := os.MkdirAll(targetDir, 0755); err != nil { + return fmt.Errorf("failed to create systemd user directory: %w", err) + } + + targetPath := filepath.Join(targetDir, "hyprland-session.target") + content := `[Unit] +Description=Hyprland Session Target +Requires=graphical-session.target +After=graphical-session.target +` + + if err := os.WriteFile(targetPath, []byte(content), 0644); err != nil { + return fmt.Errorf("failed to write hyprland-session.target: %w", err) + } + + b.log(fmt.Sprintf("Wrote hyprland-session.target to %s", targetPath)) + return nil +} + // installDMSBinary installs the DMS binary from GitHub releases func (b *BaseDistribution) installDMSBinary(ctx context.Context, sudoPassword string, progressChan chan<- InstallProgressMsg) error { b.log("Installing/updating DMS binary...") diff --git a/core/internal/distros/fedora.go b/core/internal/distros/fedora.go index 39b21ff7..c5eeba6a 100644 --- a/core/internal/distros/fedora.go +++ b/core/internal/distros/fedora.go @@ -166,10 +166,7 @@ func (f *FedoraDistribution) getDmsMapping(variant deps.PackageVariant) PackageM return PackageMapping{Name: "dms", Repository: RepoTypeCOPR, RepoURL: "avengemedia/dms"} } -func (f *FedoraDistribution) getHyprlandMapping(variant deps.PackageVariant) PackageMapping { - if variant == deps.VariantGit { - return PackageMapping{Name: "hyprland-git", Repository: RepoTypeCOPR, RepoURL: "solopasha/hyprland"} - } +func (f *FedoraDistribution) getHyprlandMapping(_ deps.PackageVariant) PackageMapping { return PackageMapping{Name: "hyprland", Repository: RepoTypeCOPR, RepoURL: "solopasha/hyprland"} } diff --git a/core/internal/distros/gentoo.go b/core/internal/distros/gentoo.go index 1ddbf589..60b58364 100644 --- a/core/internal/distros/gentoo.go +++ b/core/internal/distros/gentoo.go @@ -207,12 +207,8 @@ func (g *GentooDistribution) getDmsMapping(_ deps.PackageVariant) PackageMapping return PackageMapping{Name: "dms", Repository: RepoTypeManual, BuildFunc: "installDankMaterialShell"} } -func (g *GentooDistribution) getHyprlandMapping(variant deps.PackageVariant) PackageMapping { - archKeyword := g.getArchKeyword() - if variant == deps.VariantGit { - return PackageMapping{Name: "gui-wm/hyprland", Repository: RepoTypeGURU, UseFlags: "X", AcceptKeywords: archKeyword} - } - return PackageMapping{Name: "gui-wm/hyprland", Repository: RepoTypeSystem, UseFlags: "X", AcceptKeywords: archKeyword} +func (g *GentooDistribution) getHyprlandMapping(_ deps.PackageVariant) PackageMapping { + return PackageMapping{Name: "gui-wm/hyprland", Repository: RepoTypeSystem, UseFlags: "X", AcceptKeywords: g.getArchKeyword()} } func (g *GentooDistribution) getNiriMapping(_ deps.PackageVariant) PackageMapping {