mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-04 12:52:06 -04:00
321 lines
9.9 KiB
Go
321 lines
9.9 KiB
Go
package providers
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type MiracleConfig struct {
|
|
Terminal string `yaml:"terminal"`
|
|
ActionKey string `yaml:"action_key"`
|
|
DefaultActionOverrides []MiracleActionOverride `yaml:"default_action_overrides"`
|
|
CustomActions []MiracleCustomAction `yaml:"custom_actions"`
|
|
}
|
|
|
|
type MiracleActionOverride struct {
|
|
Name string `yaml:"name"`
|
|
Action string `yaml:"action"`
|
|
Modifiers []string `yaml:"modifiers"`
|
|
Key string `yaml:"key"`
|
|
}
|
|
|
|
type MiracleCustomAction struct {
|
|
Command string `yaml:"command"`
|
|
Action string `yaml:"action"`
|
|
Modifiers []string `yaml:"modifiers"`
|
|
Key string `yaml:"key"`
|
|
}
|
|
|
|
type MiracleKeyBinding struct {
|
|
Mods []string
|
|
Key string
|
|
Action string
|
|
Comment string
|
|
}
|
|
|
|
var miracleDefaultBinds = []MiracleKeyBinding{
|
|
{Mods: []string{"Super"}, Key: "Return", Action: "terminal", Comment: "Open terminal"},
|
|
{Mods: []string{"Super"}, Key: "v", Action: "request_vertical", Comment: "Layout windows vertically"},
|
|
{Mods: []string{"Super"}, Key: "h", Action: "request_horizontal", Comment: "Layout windows horizontally"},
|
|
{Mods: []string{"Super"}, Key: "Up", Action: "select_up", Comment: "Select window above"},
|
|
{Mods: []string{"Super"}, Key: "Down", Action: "select_down", Comment: "Select window below"},
|
|
{Mods: []string{"Super"}, Key: "Left", Action: "select_left", Comment: "Select window left"},
|
|
{Mods: []string{"Super"}, Key: "Right", Action: "select_right", Comment: "Select window right"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "Up", Action: "move_up", Comment: "Move window up"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "Down", Action: "move_down", Comment: "Move window down"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "Left", Action: "move_left", Comment: "Move window left"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "Right", Action: "move_right", Comment: "Move window right"},
|
|
{Mods: []string{"Super"}, Key: "r", Action: "toggle_resize", Comment: "Toggle resize mode"},
|
|
{Mods: []string{"Super"}, Key: "f", Action: "fullscreen", Comment: "Toggle fullscreen"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "q", Action: "quit_active_window", Comment: "Close window"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "e", Action: "quit_compositor", Comment: "Exit compositor"},
|
|
{Mods: []string{"Super"}, Key: "Space", Action: "toggle_floating", Comment: "Toggle floating"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "p", Action: "toggle_pinned_to_workspace", Comment: "Toggle pinned to workspace"},
|
|
{Mods: []string{"Super"}, Key: "w", Action: "toggle_tabbing", Comment: "Toggle tabbing layout"},
|
|
{Mods: []string{"Super"}, Key: "s", Action: "toggle_stacking", Comment: "Toggle stacking layout"},
|
|
{Mods: []string{"Super"}, Key: "1", Action: "select_workspace_0", Comment: "Workspace 1"},
|
|
{Mods: []string{"Super"}, Key: "2", Action: "select_workspace_1", Comment: "Workspace 2"},
|
|
{Mods: []string{"Super"}, Key: "3", Action: "select_workspace_2", Comment: "Workspace 3"},
|
|
{Mods: []string{"Super"}, Key: "4", Action: "select_workspace_3", Comment: "Workspace 4"},
|
|
{Mods: []string{"Super"}, Key: "5", Action: "select_workspace_4", Comment: "Workspace 5"},
|
|
{Mods: []string{"Super"}, Key: "6", Action: "select_workspace_5", Comment: "Workspace 6"},
|
|
{Mods: []string{"Super"}, Key: "7", Action: "select_workspace_6", Comment: "Workspace 7"},
|
|
{Mods: []string{"Super"}, Key: "8", Action: "select_workspace_7", Comment: "Workspace 8"},
|
|
{Mods: []string{"Super"}, Key: "9", Action: "select_workspace_8", Comment: "Workspace 9"},
|
|
{Mods: []string{"Super"}, Key: "0", Action: "select_workspace_9", Comment: "Workspace 10"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "1", Action: "move_to_workspace_0", Comment: "Move to workspace 1"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "2", Action: "move_to_workspace_1", Comment: "Move to workspace 2"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "3", Action: "move_to_workspace_2", Comment: "Move to workspace 3"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "4", Action: "move_to_workspace_3", Comment: "Move to workspace 4"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "5", Action: "move_to_workspace_4", Comment: "Move to workspace 5"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "6", Action: "move_to_workspace_5", Comment: "Move to workspace 6"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "7", Action: "move_to_workspace_6", Comment: "Move to workspace 7"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "8", Action: "move_to_workspace_7", Comment: "Move to workspace 8"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "9", Action: "move_to_workspace_8", Comment: "Move to workspace 9"},
|
|
{Mods: []string{"Super", "Shift"}, Key: "0", Action: "move_to_workspace_9", Comment: "Move to workspace 10"},
|
|
}
|
|
|
|
func ParseMiracleConfig(configPath string) (*MiracleConfig, error) {
|
|
expanded, err := utils.ExpandPath(configPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
info, err := os.Stat(expanded)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var configFile string
|
|
if info.IsDir() {
|
|
configFile = filepath.Join(expanded, "config.yaml")
|
|
} else {
|
|
configFile = expanded
|
|
}
|
|
|
|
data, err := os.ReadFile(configFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var config MiracleConfig
|
|
if err := yaml.Unmarshal(data, &config); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if config.ActionKey == "" {
|
|
config.ActionKey = "meta"
|
|
}
|
|
|
|
return &config, nil
|
|
}
|
|
|
|
func resolveMiracleModifier(mod, actionKey string) string {
|
|
switch mod {
|
|
case "primary":
|
|
return resolveActionKey(actionKey)
|
|
case "alt", "alt_left", "alt_right":
|
|
return "Alt"
|
|
case "shift", "shift_left", "shift_right":
|
|
return "Shift"
|
|
case "ctrl", "ctrl_left", "ctrl_right":
|
|
return "Ctrl"
|
|
case "meta", "meta_left", "meta_right":
|
|
return "Super"
|
|
default:
|
|
return mod
|
|
}
|
|
}
|
|
|
|
func resolveActionKey(actionKey string) string {
|
|
switch actionKey {
|
|
case "meta":
|
|
return "Super"
|
|
case "alt":
|
|
return "Alt"
|
|
case "ctrl":
|
|
return "Ctrl"
|
|
default:
|
|
return "Super"
|
|
}
|
|
}
|
|
|
|
func miracleKeyCodeToName(keyCode string) string {
|
|
name := strings.TrimPrefix(keyCode, "KEY_")
|
|
name = strings.ToLower(name)
|
|
|
|
switch name {
|
|
case "enter":
|
|
return "Return"
|
|
case "space":
|
|
return "Space"
|
|
case "up":
|
|
return "Up"
|
|
case "down":
|
|
return "Down"
|
|
case "left":
|
|
return "Left"
|
|
case "right":
|
|
return "Right"
|
|
case "tab":
|
|
return "Tab"
|
|
case "escape", "esc":
|
|
return "Escape"
|
|
case "delete":
|
|
return "Delete"
|
|
case "backspace":
|
|
return "BackSpace"
|
|
case "home":
|
|
return "Home"
|
|
case "end":
|
|
return "End"
|
|
case "pageup":
|
|
return "Page_Up"
|
|
case "pagedown":
|
|
return "Page_Down"
|
|
case "print":
|
|
return "Print"
|
|
case "pause":
|
|
return "Pause"
|
|
case "volumeup":
|
|
return "XF86AudioRaiseVolume"
|
|
case "volumedown":
|
|
return "XF86AudioLowerVolume"
|
|
case "mute":
|
|
return "XF86AudioMute"
|
|
case "micmute":
|
|
return "XF86AudioMicMute"
|
|
case "brightnessup":
|
|
return "XF86MonBrightnessUp"
|
|
case "brightnessdown":
|
|
return "XF86MonBrightnessDown"
|
|
case "kbdillumup":
|
|
return "XF86KbdBrightnessUp"
|
|
case "kbdillumdown":
|
|
return "XF86KbdBrightnessDown"
|
|
case "comma":
|
|
return "comma"
|
|
case "minus":
|
|
return "minus"
|
|
case "equal":
|
|
return "equal"
|
|
}
|
|
|
|
if len(name) == 1 {
|
|
return name
|
|
}
|
|
|
|
return name
|
|
}
|
|
|
|
func MiracleConfigToBindings(config *MiracleConfig) []MiracleKeyBinding {
|
|
overridden := make(map[string]bool)
|
|
var bindings []MiracleKeyBinding
|
|
|
|
for _, override := range config.DefaultActionOverrides {
|
|
mods := make([]string, 0, len(override.Modifiers))
|
|
for _, mod := range override.Modifiers {
|
|
mods = append(mods, resolveMiracleModifier(mod, config.ActionKey))
|
|
}
|
|
|
|
bindings = append(bindings, MiracleKeyBinding{
|
|
Mods: mods,
|
|
Key: miracleKeyCodeToName(override.Key),
|
|
Action: override.Name,
|
|
Comment: miracleActionDescription(override.Name),
|
|
})
|
|
overridden[override.Name] = true
|
|
}
|
|
|
|
for _, def := range miracleDefaultBinds {
|
|
if overridden[def.Action] {
|
|
continue
|
|
}
|
|
bindings = append(bindings, def)
|
|
}
|
|
|
|
for _, custom := range config.CustomActions {
|
|
mods := make([]string, 0, len(custom.Modifiers))
|
|
for _, mod := range custom.Modifiers {
|
|
mods = append(mods, resolveMiracleModifier(mod, config.ActionKey))
|
|
}
|
|
|
|
bindings = append(bindings, MiracleKeyBinding{
|
|
Mods: mods,
|
|
Key: miracleKeyCodeToName(custom.Key),
|
|
Action: custom.Command,
|
|
Comment: custom.Command,
|
|
})
|
|
}
|
|
|
|
return bindings
|
|
}
|
|
|
|
func miracleActionDescription(action string) string {
|
|
switch action {
|
|
case "terminal":
|
|
return "Open terminal"
|
|
case "request_vertical":
|
|
return "Layout windows vertically"
|
|
case "request_horizontal":
|
|
return "Layout windows horizontally"
|
|
case "select_up":
|
|
return "Select window above"
|
|
case "select_down":
|
|
return "Select window below"
|
|
case "select_left":
|
|
return "Select window left"
|
|
case "select_right":
|
|
return "Select window right"
|
|
case "move_up":
|
|
return "Move window up"
|
|
case "move_down":
|
|
return "Move window down"
|
|
case "move_left":
|
|
return "Move window left"
|
|
case "move_right":
|
|
return "Move window right"
|
|
case "toggle_resize":
|
|
return "Toggle resize mode"
|
|
case "fullscreen":
|
|
return "Toggle fullscreen"
|
|
case "quit_active_window":
|
|
return "Close window"
|
|
case "quit_compositor":
|
|
return "Exit compositor"
|
|
case "toggle_floating":
|
|
return "Toggle floating"
|
|
case "toggle_pinned_to_workspace":
|
|
return "Toggle pinned to workspace"
|
|
case "toggle_tabbing":
|
|
return "Toggle tabbing layout"
|
|
case "toggle_stacking":
|
|
return "Toggle stacking layout"
|
|
case "magnifier_on":
|
|
return "Enable magnifier"
|
|
case "magnifier_off":
|
|
return "Disable magnifier"
|
|
case "magnifier_increase_size":
|
|
return "Increase magnifier area"
|
|
case "magnifier_decrease_size":
|
|
return "Decrease magnifier area"
|
|
case "magnifier_increase_scale":
|
|
return "Increase magnifier scale"
|
|
case "magnifier_decrease_scale":
|
|
return "Decrease magnifier scale"
|
|
}
|
|
|
|
if num, ok := strings.CutPrefix(action, "select_workspace_"); ok {
|
|
return "Workspace " + num
|
|
}
|
|
if num, ok := strings.CutPrefix(action, "move_to_workspace_"); ok {
|
|
return "Move to workspace " + num
|
|
}
|
|
|
|
return action
|
|
}
|