mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-08 12:13:31 -04:00
feat(mango): first-class MangoWM support across DMS, dankinstaller & UI tools
- Bring up Mango to parity with niri/hyprland via a native JSON-IPC w/Native MangoServic., replaces the legacy dwl/`mmsg` path and recent breaking changes - Dankinstall: mango supported installer, config/binds templates, and packaging (Arch AUR, Fedora Terra auto-enable, Gentoo GURU) - Window rules: Go provider + CLI + Settings GUI editor - Keybinds + config reload on edit (mmsg dispatch reload_config) - Misc new supported options in DMS settings
This commit is contained in:
@@ -112,6 +112,11 @@ func (a *ArchDistribution) DetectDependenciesWithTerminal(ctx context.Context, w
|
||||
dependencies = append(dependencies, a.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
// Mango-specific tools (dwl-based, uses xwayland-satellite like niri)
|
||||
if wm == deps.WindowManagerMango {
|
||||
dependencies = append(dependencies, a.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
dependencies = append(dependencies, a.detectMatugen())
|
||||
dependencies = append(dependencies, a.detectDgop())
|
||||
|
||||
@@ -172,6 +177,11 @@ func (a *ArchDistribution) isInSystemRepo(pkg string) bool {
|
||||
return exec.Command("pacman", "-Si", pkg).Run() == nil
|
||||
}
|
||||
|
||||
// isSonameProvides reports whether dep is a shared-library soname
|
||||
func isSonameProvides(dep string) bool {
|
||||
return strings.HasSuffix(dep, ".so") || strings.Contains(dep, ".so.")
|
||||
}
|
||||
|
||||
func (a *ArchDistribution) GetPackageMapping(wm deps.WindowManager) map[string]PackageMapping {
|
||||
return a.GetPackageMappingWithVariants(wm, make(map[string]deps.PackageVariant))
|
||||
}
|
||||
@@ -199,6 +209,9 @@ func (a *ArchDistribution) GetPackageMappingWithVariants(wm deps.WindowManager,
|
||||
case deps.WindowManagerNiri:
|
||||
packages["niri"] = a.getNiriMapping(variants["niri"])
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "xwayland-satellite", Repository: RepoTypeSystem}
|
||||
case deps.WindowManagerMango:
|
||||
packages["mango"] = a.getMangoMapping(variants["mango"])
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "xwayland-satellite", Repository: RepoTypeSystem}
|
||||
}
|
||||
|
||||
return packages
|
||||
@@ -222,6 +235,13 @@ func (a *ArchDistribution) getNiriMapping(variant deps.PackageVariant) PackageMa
|
||||
return PackageMapping{Name: "niri", Repository: RepoTypeSystem}
|
||||
}
|
||||
|
||||
func (a *ArchDistribution) getMangoMapping(variant deps.PackageVariant) PackageMapping {
|
||||
if variant == deps.VariantGit {
|
||||
return PackageMapping{Name: "mangowm-git", Repository: RepoTypeAUR}
|
||||
}
|
||||
return PackageMapping{Name: "mangowm", Repository: RepoTypeAUR}
|
||||
}
|
||||
|
||||
func (a *ArchDistribution) getMatugenMapping(variant deps.PackageVariant) PackageMapping {
|
||||
if runtime.GOARCH == "arm64" {
|
||||
return PackageMapping{Name: "matugen-git", Repository: RepoTypeAUR}
|
||||
@@ -724,7 +744,7 @@ func (a *ArchDistribution) installSingleAURPackageInternal(ctx context.Context,
|
||||
continue
|
||||
}
|
||||
seen[dep] = true
|
||||
if a.isInSystemRepo(dep) {
|
||||
if isSonameProvides(dep) || a.isInSystemRepo(dep) {
|
||||
systemPkgs = append(systemPkgs, dep)
|
||||
} else {
|
||||
aurPkgs = append(aurPkgs, dep)
|
||||
|
||||
@@ -337,6 +337,36 @@ func (b *BaseDistribution) detectWindowManager(wm deps.WindowManager) deps.Depen
|
||||
Variant: variant,
|
||||
CanToggle: true,
|
||||
}
|
||||
case deps.WindowManagerMango:
|
||||
status := deps.StatusMissing
|
||||
variant := deps.VariantStable
|
||||
version := ""
|
||||
|
||||
if b.commandExists("mango") {
|
||||
status = deps.StatusInstalled
|
||||
cmd := exec.Command("mango", "-v")
|
||||
if output, err := cmd.Output(); err == nil {
|
||||
outStr := string(output)
|
||||
if strings.Contains(outStr, "git") || strings.Contains(outStr, "dirty") {
|
||||
variant = deps.VariantGit
|
||||
}
|
||||
if versionRegex := regexp.MustCompile(`(\d+\.\d+\.\d+)`); versionRegex.MatchString(outStr) {
|
||||
matches := versionRegex.FindStringSubmatch(outStr)
|
||||
if len(matches) > 1 {
|
||||
version = matches[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return deps.Dependency{
|
||||
Name: "mango",
|
||||
Status: status,
|
||||
Version: version,
|
||||
Description: "dwl-based dynamic tiling Wayland compositor",
|
||||
Required: true,
|
||||
Variant: variant,
|
||||
CanToggle: true,
|
||||
}
|
||||
default:
|
||||
return deps.Dependency{
|
||||
Name: "unknown-wm",
|
||||
|
||||
@@ -77,7 +77,11 @@ func (f *FedoraDistribution) DetectDependenciesWithTerminal(ctx context.Context,
|
||||
|
||||
// Common detections using base methods
|
||||
dependencies = append(dependencies, f.detectGit())
|
||||
dependencies = append(dependencies, f.detectWindowManager(wm))
|
||||
wmDep := f.detectWindowManager(wm)
|
||||
if wm == deps.WindowManagerMango {
|
||||
wmDep.Description = "MangoWM (Wayland compositor) — the Terra repo will be enabled automatically to install it"
|
||||
}
|
||||
dependencies = append(dependencies, wmDep)
|
||||
dependencies = append(dependencies, f.detectQuickshell())
|
||||
dependencies = append(dependencies, f.detectDMSGreeter())
|
||||
dependencies = append(dependencies, f.detectXDGPortal())
|
||||
@@ -93,6 +97,11 @@ func (f *FedoraDistribution) DetectDependenciesWithTerminal(ctx context.Context,
|
||||
dependencies = append(dependencies, f.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
// Mango-specific tools (dwl-based, uses xwayland-satellite like niri)
|
||||
if wm == deps.WindowManagerMango {
|
||||
dependencies = append(dependencies, f.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
dependencies = append(dependencies, f.detectMatugen())
|
||||
dependencies = append(dependencies, f.detectDgop())
|
||||
|
||||
@@ -139,6 +148,10 @@ func (f *FedoraDistribution) GetPackageMappingWithVariants(wm deps.WindowManager
|
||||
case deps.WindowManagerNiri:
|
||||
packages["niri"] = f.getNiriMapping(variants["niri"])
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "xwayland-satellite", Repository: RepoTypeSystem}
|
||||
case deps.WindowManagerMango:
|
||||
// mangowm resolves via Terra, enabled automatically by enableTerraRepo.
|
||||
packages["mango"] = PackageMapping{Name: "mangowm", Repository: RepoTypeSystem}
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "xwayland-satellite", Repository: RepoTypeSystem}
|
||||
}
|
||||
|
||||
return packages
|
||||
@@ -159,7 +172,7 @@ func (f *FedoraDistribution) getDmsMapping(variant deps.PackageVariant) PackageM
|
||||
}
|
||||
|
||||
func (f *FedoraDistribution) getHyprlandMapping(_ deps.PackageVariant) PackageMapping {
|
||||
return PackageMapping{Name: "hyprland", Repository: RepoTypeCOPR, RepoURL: "sdegler/hyprland"}
|
||||
return PackageMapping{Name: "hyprland", Repository: RepoTypeCOPR, RepoURL: "lionheartp/Hyprland"}
|
||||
}
|
||||
|
||||
func (f *FedoraDistribution) getNiriMapping(variant deps.PackageVariant) PackageMapping {
|
||||
@@ -297,6 +310,22 @@ func (f *FedoraDistribution) InstallPackages(ctx context.Context, dependencies [
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2b: Enable Terra repo for MangoWM (not in Fedora's repos). Must run
|
||||
// before the DNF phase so `mangowm` resolves.
|
||||
if wm == deps.WindowManagerMango {
|
||||
progressChan <- InstallProgressMsg{
|
||||
Phase: PhaseSystemPackages,
|
||||
Progress: 0.25,
|
||||
Step: "Enabling Terra repository for MangoWM...",
|
||||
IsComplete: false,
|
||||
NeedsSudo: true,
|
||||
LogOutput: "Setting up the Terra repo (fyralabs) to provide mango",
|
||||
}
|
||||
if err := f.enableTerraRepo(ctx, sudoPassword, progressChan); err != nil {
|
||||
return fmt.Errorf("failed to enable Terra repository: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 3: System Packages (DNF)
|
||||
if len(dnfPkgs) > 0 {
|
||||
progressChan <- InstallProgressMsg{
|
||||
@@ -423,6 +452,30 @@ func (f *FedoraDistribution) extractPackageNames(packages []PackageMapping) []st
|
||||
return names
|
||||
}
|
||||
|
||||
// enableTerraRepo registers the persistent Terra repo (via terra-release) so
|
||||
// `mangowm` resolves in the DNF phase. $releasever is single-quoted so dnf, not
|
||||
// the shell, expands it.
|
||||
func (f *FedoraDistribution) enableTerraRepo(ctx context.Context, sudoPassword string, progressChan chan<- InstallProgressMsg) error {
|
||||
// Skip if Terra is already configured
|
||||
if exec.CommandContext(ctx, "sh", "-c",
|
||||
"rpm -q terra-release >/dev/null 2>&1 || test -f /etc/yum.repos.d/terra.repo").Run() == nil {
|
||||
f.log("Terra repository already configured, skipping enable")
|
||||
return nil
|
||||
}
|
||||
|
||||
f.log("Enabling Terra repository (fyralabs) for mango...")
|
||||
cmd := privesc.ExecCommand(ctx, sudoPassword,
|
||||
`dnf install -y --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release 2>&1`)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
f.logError("failed to enable Terra repository", err)
|
||||
f.log(fmt.Sprintf("Terra enable output: %s", string(output)))
|
||||
return fmt.Errorf("failed to enable Terra repository: %w", err)
|
||||
}
|
||||
f.log(fmt.Sprintf("Terra repository enabled: %s", string(output)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FedoraDistribution) enableCOPRRepos(ctx context.Context, coprPkgs []PackageMapping, sudoPassword string, progressChan chan<- InstallProgressMsg) error {
|
||||
enabledRepos := make(map[string]bool)
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ func (g *GentooDistribution) DetectDependenciesWithTerminal(ctx context.Context,
|
||||
dependencies = append(dependencies, g.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
// Mango-specific tools (dwl-based, uses xwayland-satellite like niri)
|
||||
if wm == deps.WindowManagerMango {
|
||||
dependencies = append(dependencies, g.detectXwaylandSatellite())
|
||||
}
|
||||
|
||||
dependencies = append(dependencies, g.detectMatugen())
|
||||
dependencies = append(dependencies, g.detectDgop())
|
||||
|
||||
@@ -176,6 +181,10 @@ func (g *GentooDistribution) GetPackageMappingWithVariants(wm deps.WindowManager
|
||||
case deps.WindowManagerNiri:
|
||||
packages["niri"] = g.getNiriMapping(variants["niri"])
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "gui-apps/xwayland-satellite", Repository: RepoTypeGURU, AcceptKeywords: archKeyword}
|
||||
case deps.WindowManagerMango:
|
||||
packages["mango"] = g.getMangoMapping(variants["mango"])
|
||||
packages["scenefx"] = PackageMapping{Name: "gui-libs/scenefx", Repository: RepoTypeGURU, AcceptKeywords: archKeyword}
|
||||
packages["xwayland-satellite"] = PackageMapping{Name: "gui-apps/xwayland-satellite", Repository: RepoTypeGURU, AcceptKeywords: archKeyword}
|
||||
}
|
||||
|
||||
return packages
|
||||
@@ -197,6 +206,10 @@ func (g *GentooDistribution) getNiriMapping(_ deps.PackageVariant) PackageMappin
|
||||
return PackageMapping{Name: "gui-wm/niri", Repository: RepoTypeGURU, UseFlags: "dbus screencast", AcceptKeywords: g.getArchKeyword()}
|
||||
}
|
||||
|
||||
func (g *GentooDistribution) getMangoMapping(_ deps.PackageVariant) PackageMapping {
|
||||
return PackageMapping{Name: "gui-wm/mangowm", Repository: RepoTypeGURU, AcceptKeywords: g.getArchKeyword()}
|
||||
}
|
||||
|
||||
func (g *GentooDistribution) getPrerequisites() []string {
|
||||
return []string{
|
||||
"app-eselect/eselect-repository",
|
||||
|
||||
Reference in New Issue
Block a user