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:
@@ -103,15 +103,7 @@ func (m Model) updateDeployingConfigsState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
func (m Model) deployConfigurations() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
// Determine the selected window manager
|
||||
var wm deps.WindowManager
|
||||
switch m.selectedWM {
|
||||
case 0:
|
||||
wm = deps.WindowManagerNiri
|
||||
case 1:
|
||||
wm = deps.WindowManagerHyprland
|
||||
default:
|
||||
wm = deps.WindowManagerNiri
|
||||
}
|
||||
wm := m.selectedWindowManager()
|
||||
|
||||
// Determine the selected terminal
|
||||
var terminal deps.Terminal
|
||||
@@ -288,7 +280,8 @@ func (m Model) checkExistingConfigurations() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
var configs []ExistingConfigInfo
|
||||
|
||||
if m.selectedWM == 0 {
|
||||
switch m.selectedWindowManager() {
|
||||
case deps.WindowManagerNiri:
|
||||
niriPath := filepath.Join(os.Getenv("HOME"), ".config", "niri", "config.kdl")
|
||||
niriExists := false
|
||||
if _, err := os.Stat(niriPath); err == nil {
|
||||
@@ -299,7 +292,23 @@ func (m Model) checkExistingConfigurations() tea.Cmd {
|
||||
Path: niriPath,
|
||||
Exists: niriExists,
|
||||
})
|
||||
} else {
|
||||
case deps.WindowManagerMango:
|
||||
mangoConfPath := filepath.Join(os.Getenv("HOME"), ".config", "mango", "config.conf")
|
||||
mangoMainPath := filepath.Join(os.Getenv("HOME"), ".config", "mango", "mango.conf")
|
||||
mangoPath := mangoConfPath
|
||||
mangoExists := false
|
||||
if _, err := os.Stat(mangoConfPath); err == nil {
|
||||
mangoExists = true
|
||||
} else if _, err := os.Stat(mangoMainPath); err == nil {
|
||||
mangoPath = mangoMainPath
|
||||
mangoExists = true
|
||||
}
|
||||
configs = append(configs, ExistingConfigInfo{
|
||||
ConfigType: "Mango",
|
||||
Path: mangoPath,
|
||||
Exists: mangoExists,
|
||||
})
|
||||
default:
|
||||
hyprlandLuaPath := filepath.Join(os.Getenv("HOME"), ".config", "hypr", "hyprland.lua")
|
||||
hyprlandConfPath := filepath.Join(os.Getenv("HOME"), ".config", "hypr", "hyprland.conf")
|
||||
hyprlandPath := hyprlandLuaPath
|
||||
|
||||
@@ -209,12 +209,7 @@ func (m Model) installPackages() tea.Cmd {
|
||||
}
|
||||
|
||||
// Convert TUI selection to deps enum
|
||||
var wm deps.WindowManager
|
||||
if m.selectedWM == 0 {
|
||||
wm = deps.WindowManagerNiri
|
||||
} else {
|
||||
wm = deps.WindowManagerHyprland
|
||||
}
|
||||
wm := m.selectedWindowManager()
|
||||
|
||||
installerProgressChan := make(chan distros.InstallProgressMsg, 100)
|
||||
|
||||
@@ -245,8 +240,11 @@ func (m Model) installPackages() tea.Cmd {
|
||||
}
|
||||
if greeterSelected {
|
||||
compositorName := "niri"
|
||||
if m.selectedWM == 1 {
|
||||
switch m.selectedWindowManager() {
|
||||
case deps.WindowManagerHyprland:
|
||||
compositorName = "Hyprland"
|
||||
case deps.WindowManagerMango:
|
||||
compositorName = "mango"
|
||||
}
|
||||
m.packageProgressChan <- packageInstallProgressMsg{
|
||||
progress: 0.92,
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/deps"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/distros"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
@@ -65,7 +66,7 @@ func (m Model) updateGentooUseFlagsState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.skipGentooUseFlags = !m.skipGentooUseFlags
|
||||
return m, nil
|
||||
case "enter":
|
||||
if m.selectedWM == 1 {
|
||||
if m.selectedWindowManager() == deps.WindowManagerHyprland {
|
||||
return m, m.checkGCCVersion()
|
||||
}
|
||||
return m.enterAuthPhase()
|
||||
|
||||
@@ -199,8 +199,21 @@ func (m Model) viewInstallComplete() string {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
wm := m.selectedWindowManager()
|
||||
|
||||
// mango launches DMS via `exec_once=dms run` (not a systemd session target)
|
||||
loginHint := "If you do not have a greeter, login with \"niri-session\" or \"Hyprland\""
|
||||
switch wm {
|
||||
case deps.WindowManagerNiri:
|
||||
loginHint = "If you do not have a greeter, login with \"niri-session\""
|
||||
case deps.WindowManagerHyprland:
|
||||
loginHint = "If you do not have a greeter, login with \"Hyprland\""
|
||||
case deps.WindowManagerMango:
|
||||
loginHint = "If you do not have a greeter, login with \"mango\""
|
||||
}
|
||||
|
||||
b.WriteString("\n")
|
||||
info := m.styles.Normal.Render("Your system is ready! Log out and log back in to start using\nyour new desktop environment.\nIf you do not have a greeter, login with \"niri-session\" or \"Hyprland\"")
|
||||
info := m.styles.Normal.Render("Your system is ready! Log out and log back in to start using\nyour new desktop environment.\n" + loginHint)
|
||||
b.WriteString(info)
|
||||
b.WriteString("\n\n")
|
||||
|
||||
@@ -209,8 +222,13 @@ func (m Model) viewInstallComplete() string {
|
||||
labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(theme.Subtle))
|
||||
|
||||
b.WriteString(labelStyle.Render("Troubleshooting:") + "\n")
|
||||
b.WriteString(labelStyle.Render(" Disable autostart: ") + cmdStyle.Render("systemctl --user disable dms") + "\n")
|
||||
b.WriteString(labelStyle.Render(" View logs: ") + cmdStyle.Render("journalctl --user -u dms") + "\n")
|
||||
if wm == deps.WindowManagerMango {
|
||||
b.WriteString(labelStyle.Render(" Disable autostart: ") + cmdStyle.Render("remove 'exec_once=dms run' from ~/.config/mango/config.conf") + "\n")
|
||||
b.WriteString(labelStyle.Render(" View logs: ") + cmdStyle.Render("qs -p ~/.config/quickshell/dms log") + "\n")
|
||||
} else {
|
||||
b.WriteString(labelStyle.Render(" Disable autostart: ") + cmdStyle.Render("systemctl --user disable dms") + "\n")
|
||||
b.WriteString(labelStyle.Render(" View logs: ") + cmdStyle.Render("journalctl --user -u dms") + "\n")
|
||||
}
|
||||
|
||||
if m.osInfo != nil {
|
||||
if cmd := uninstallCommand(m.osInfo.Distribution.ID, m.dependencies); cmd != "" {
|
||||
|
||||
@@ -10,6 +10,26 @@ import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
// windowManagerOptions returns the WM enums in selection-list order (debian omits
|
||||
// Hyprland). selectedWM indexes into this, so all index->WM conversions use it.
|
||||
func (m Model) windowManagerOptions() []deps.WindowManager {
|
||||
opts := []deps.WindowManager{deps.WindowManagerNiri}
|
||||
if m.osInfo == nil || m.osInfo.Distribution.ID != "debian" {
|
||||
opts = append(opts, deps.WindowManagerHyprland)
|
||||
}
|
||||
opts = append(opts, deps.WindowManagerMango)
|
||||
return opts
|
||||
}
|
||||
|
||||
// selectedWindowManager maps the current selectedWM index to its WM enum.
|
||||
func (m Model) selectedWindowManager() deps.WindowManager {
|
||||
opts := m.windowManagerOptions()
|
||||
if m.selectedWM >= 0 && m.selectedWM < len(opts) {
|
||||
return opts[m.selectedWM]
|
||||
}
|
||||
return deps.WindowManagerNiri
|
||||
}
|
||||
|
||||
func (m Model) viewSelectWindowManager() string {
|
||||
var b strings.Builder
|
||||
|
||||
@@ -34,6 +54,11 @@ func (m Model) viewSelectWindowManager() string {
|
||||
}{"Hyprland", "Dynamic tiling Wayland compositor."})
|
||||
}
|
||||
|
||||
options = append(options, struct {
|
||||
name string
|
||||
description string
|
||||
}{"mango", "dwl-based dynamic tiling Wayland compositor."})
|
||||
|
||||
for i, option := range options {
|
||||
if i == m.selectedWM {
|
||||
selected := m.styles.SelectedOption.Render("▶ " + option.name)
|
||||
@@ -152,10 +177,7 @@ func (m Model) updateSelectTerminalState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
||||
func (m Model) updateSelectWindowManagerState(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if keyMsg, ok := msg.(tea.KeyMsg); ok {
|
||||
maxWMIndex := 1
|
||||
if m.osInfo != nil && m.osInfo.Distribution.ID == "debian" {
|
||||
maxWMIndex = 0
|
||||
}
|
||||
maxWMIndex := len(m.windowManagerOptions()) - 1
|
||||
|
||||
switch keyMsg.String() {
|
||||
case "up":
|
||||
@@ -190,12 +212,7 @@ func (m Model) detectDependencies() tea.Cmd {
|
||||
}
|
||||
|
||||
// Convert TUI selection to deps enum
|
||||
var wm deps.WindowManager
|
||||
if m.selectedWM == 0 {
|
||||
wm = deps.WindowManagerNiri // First option is Niri
|
||||
} else {
|
||||
wm = deps.WindowManagerHyprland // Second option is Hyprland
|
||||
}
|
||||
wm := m.selectedWindowManager()
|
||||
|
||||
var terminal deps.Terminal
|
||||
if m.osInfo != nil && m.osInfo.Distribution.ID == "gentoo" {
|
||||
|
||||
Reference in New Issue
Block a user