mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-31 08:52:49 -05:00
Compare commits
5 Commits
f6a776a692
...
8838fd67b9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8838fd67b9 | ||
|
|
c570e20308 | ||
|
|
0a00ef39e3 | ||
|
|
9a08b81214 | ||
|
|
c617ae26a2 |
37
.gitignore
vendored
37
.gitignore
vendored
@@ -102,39 +102,6 @@ go.work.sum
|
|||||||
# .idea/
|
# .idea/
|
||||||
# .vscode/
|
# .vscode/
|
||||||
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
||||||
#
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Code coverage profiles and other test artifacts
|
|
||||||
*.out
|
|
||||||
coverage.*
|
|
||||||
*.coverprofile
|
|
||||||
profile.cov
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
|
||||||
go.work.sum
|
|
||||||
|
|
||||||
# env file
|
|
||||||
.env
|
|
||||||
|
|
||||||
# Editor/IDE
|
|
||||||
# .idea/
|
|
||||||
# .vscode/
|
|
||||||
|
|
||||||
bin/
|
bin/
|
||||||
|
|
||||||
# Extracted source trees in Ubuntu package directories
|
# Extracted source trees in Ubuntu package directories
|
||||||
@@ -142,3 +109,7 @@ distro/ubuntu/*/dms-git-repo/
|
|||||||
distro/ubuntu/*/DankMaterialShell-*/
|
distro/ubuntu/*/DankMaterialShell-*/
|
||||||
distro/ubuntu/danklinux/*/dsearch-*/
|
distro/ubuntu/danklinux/*/dsearch-*/
|
||||||
distro/ubuntu/danklinux/*/dgop-*/
|
distro/ubuntu/danklinux/*/dgop-*/
|
||||||
|
|
||||||
|
# direnv
|
||||||
|
.envrc
|
||||||
|
.direnv/
|
||||||
|
|||||||
@@ -12,6 +12,21 @@ Enable pre-commit hooks to catch CI failures before pushing:
|
|||||||
git config core.hooksPath .githooks
|
git config core.hooksPath .githooks
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Nix Development Shell
|
||||||
|
|
||||||
|
If you have Nix installed with flakes enabled, you can use the provided development shell which includes all necessary dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop
|
||||||
|
```
|
||||||
|
|
||||||
|
This will provide:
|
||||||
|
- Go 1.24 toolchain (go, gopls, delve, go-tools) and GNU Make
|
||||||
|
- Quickshell and required QML packages
|
||||||
|
- Properly configured QML2_IMPORT_PATH
|
||||||
|
|
||||||
|
The dev shell automatically creates the `.qmlls.ini` file in the `quickshell/` directory.
|
||||||
|
|
||||||
## VSCode Setup
|
## VSCode Setup
|
||||||
|
|
||||||
This is a monorepo, the easiest thing to do is to open an editor in either `quickshell`, `core`, or both depending on which part of the project you are working on.
|
This is a monorepo, the easiest thing to do is to open an editor in either `quickshell`, `core`, or both depending on which part of the project you are working on.
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ func TestHyprlandConfigDeployment(t *testing.T) {
|
|||||||
content, err := os.ReadFile(result.Path)
|
content, err := os.ReadFile(result.Path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Contains(t, string(content), "# MONITOR CONFIG")
|
assert.Contains(t, string(content), "# MONITOR CONFIG")
|
||||||
assert.Contains(t, string(content), "bind = $mod, T, exec, ghostty")
|
assert.Contains(t, string(content), "bind = $mod, T, exec, $TERMINAL")
|
||||||
assert.Contains(t, string(content), "exec-once = ")
|
assert.Contains(t, string(content), "exec-once = ")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -471,7 +471,7 @@ general {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Contains(t, string(newContent), "monitor = DP-1, 1920x1080@144")
|
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), "monitor = HDMI-A-1, 3840x2160@60")
|
||||||
assert.Contains(t, string(newContent), "bind = $mod, T, exec, kitty")
|
assert.Contains(t, string(newContent), "bind = $mod, T, exec, $TERMINAL")
|
||||||
assert.NotContains(t, string(newContent), "monitor = eDP-2")
|
assert.NotContains(t, string(newContent), "monitor = eDP-2")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -487,14 +487,11 @@ func TestNiriConfigStructure(t *testing.T) {
|
|||||||
|
|
||||||
func TestHyprlandConfigStructure(t *testing.T) {
|
func TestHyprlandConfigStructure(t *testing.T) {
|
||||||
assert.Contains(t, HyprlandConfig, "# MONITOR CONFIG")
|
assert.Contains(t, HyprlandConfig, "# MONITOR CONFIG")
|
||||||
assert.Contains(t, HyprlandConfig, "# ENVIRONMENT VARS")
|
|
||||||
assert.Contains(t, HyprlandConfig, "# STARTUP APPS")
|
assert.Contains(t, HyprlandConfig, "# STARTUP APPS")
|
||||||
assert.Contains(t, HyprlandConfig, "# INPUT CONFIG")
|
assert.Contains(t, HyprlandConfig, "# INPUT CONFIG")
|
||||||
assert.Contains(t, HyprlandConfig, "# KEYBINDINGS")
|
assert.Contains(t, HyprlandConfig, "# KEYBINDINGS")
|
||||||
assert.Contains(t, HyprlandConfig, "{{POLKIT_AGENT_PATH}}")
|
assert.Contains(t, HyprlandConfig, "{{POLKIT_AGENT_PATH}}")
|
||||||
assert.Contains(t, HyprlandConfig, "{{TERMINAL_COMMAND}}")
|
assert.Contains(t, HyprlandConfig, "bind = $mod, T, exec, $TERMINAL")
|
||||||
assert.Contains(t, HyprlandConfig, "exec-once = dms run")
|
|
||||||
assert.Contains(t, HyprlandConfig, "bind = $mod, T, exec,")
|
|
||||||
assert.Contains(t, HyprlandConfig, "bind = $mod, space, exec, dms ipc call spotlight toggle")
|
assert.Contains(t, HyprlandConfig, "bind = $mod, space, exec, dms ipc call spotlight toggle")
|
||||||
assert.Contains(t, HyprlandConfig, "windowrule {")
|
assert.Contains(t, HyprlandConfig, "windowrule {")
|
||||||
assert.Contains(t, HyprlandConfig, "match:class = ^(com\\.mitchellh\\.ghostty)$")
|
assert.Contains(t, HyprlandConfig, "match:class = ^(com\\.mitchellh\\.ghostty)$")
|
||||||
|
|||||||
@@ -7,20 +7,10 @@
|
|||||||
# monitor = eDP-2, 2560x1600@239.998993, 2560x0, 1, vrr, 1
|
# monitor = eDP-2, 2560x1600@239.998993, 2560x0, 1, vrr, 1
|
||||||
monitor = , preferred,auto,auto
|
monitor = , preferred,auto,auto
|
||||||
|
|
||||||
# ==================
|
|
||||||
# ENVIRONMENT VARS
|
|
||||||
# ==================
|
|
||||||
env = QT_QPA_PLATFORM,wayland
|
|
||||||
env = ELECTRON_OZONE_PLATFORM_HINT,auto
|
|
||||||
env = QT_QPA_PLATFORMTHEME,gtk3
|
|
||||||
env = QT_QPA_PLATFORMTHEME_QT6,gtk3
|
|
||||||
env = TERMINAL,{{TERMINAL_COMMAND}}
|
|
||||||
|
|
||||||
# ==================
|
# ==================
|
||||||
# STARTUP APPS
|
# STARTUP APPS
|
||||||
# ==================
|
# ==================
|
||||||
exec-once = bash -c "wl-paste --watch cliphist store &"
|
exec-once = bash -c "wl-paste --watch cliphist store &"
|
||||||
exec-once = dms run
|
|
||||||
exec-once = {{POLKIT_AGENT_PATH}}
|
exec-once = {{POLKIT_AGENT_PATH}}
|
||||||
|
|
||||||
# ==================
|
# ==================
|
||||||
@@ -233,7 +223,7 @@ layerrule {
|
|||||||
$mod = SUPER
|
$mod = SUPER
|
||||||
|
|
||||||
# === Application Launchers ===
|
# === Application Launchers ===
|
||||||
bind = $mod, T, exec, {{TERMINAL_COMMAND}}
|
bind = $mod, T, exec, $TERMINAL
|
||||||
bind = $mod, space, exec, dms ipc call spotlight toggle
|
bind = $mod, space, exec, dms ipc call spotlight toggle
|
||||||
bind = $mod, V, exec, dms ipc call clipboard toggle
|
bind = $mod, V, exec, dms ipc call clipboard toggle
|
||||||
bind = $mod, M, exec, dms ipc call processlist focusOrToggle
|
bind = $mod, M, exec, dms ipc call processlist focusOrToggle
|
||||||
|
|||||||
@@ -116,15 +116,9 @@ overview {
|
|||||||
// See the binds section below for more spawn examples.
|
// See the binds section below for more spawn examples.
|
||||||
// This line starts waybar, a commonly used bar for Wayland compositors.
|
// This line starts waybar, a commonly used bar for Wayland compositors.
|
||||||
spawn-at-startup "bash" "-c" "wl-paste --watch cliphist store &"
|
spawn-at-startup "bash" "-c" "wl-paste --watch cliphist store &"
|
||||||
spawn-at-startup "dms" "run"
|
|
||||||
spawn-at-startup "{{POLKIT_AGENT_PATH}}"
|
spawn-at-startup "{{POLKIT_AGENT_PATH}}"
|
||||||
environment {
|
environment {
|
||||||
XDG_CURRENT_DESKTOP "niri"
|
XDG_CURRENT_DESKTOP "niri"
|
||||||
QT_QPA_PLATFORM "wayland"
|
|
||||||
ELECTRON_OZONE_PLATFORM_HINT "auto"
|
|
||||||
QT_QPA_PLATFORMTHEME "gtk3"
|
|
||||||
QT_QPA_PLATFORMTHEME_QT6 "gtk3"
|
|
||||||
TERMINAL "{{TERMINAL_COMMAND}}"
|
|
||||||
}
|
}
|
||||||
hotkey-overlay {
|
hotkey-overlay {
|
||||||
skip-at-startup
|
skip-at-startup
|
||||||
|
|||||||
@@ -357,6 +357,15 @@ func (a *ArchDistribution) InstallPackages(ctx context.Context, dependencies []d
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := a.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := a.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
a.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.EnableDMSService(ctx); err != nil {
|
||||||
|
a.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Phase 7: Complete
|
// Phase 7: Complete
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
|
|||||||
@@ -549,6 +549,68 @@ func (b *BaseDistribution) runWithProgressStepTimeout(cmd *exec.Cmd, progressCha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseDistribution) DetectTerminalFromDeps(dependencies []deps.Dependency) deps.Terminal {
|
||||||
|
for _, dep := range dependencies {
|
||||||
|
switch dep.Name {
|
||||||
|
case "ghostty":
|
||||||
|
return deps.TerminalGhostty
|
||||||
|
case "kitty":
|
||||||
|
return deps.TerminalKitty
|
||||||
|
case "alacritty":
|
||||||
|
return deps.TerminalAlacritty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deps.TerminalGhostty
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseDistribution) WriteEnvironmentConfig(terminal deps.Terminal) error {
|
||||||
|
homeDir, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get home directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
envDir := filepath.Join(homeDir, ".config", "environment.d")
|
||||||
|
if err := os.MkdirAll(envDir, 0755); err != nil {
|
||||||
|
return fmt.Errorf("failed to create environment.d directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var terminalCmd string
|
||||||
|
switch terminal {
|
||||||
|
case deps.TerminalGhostty:
|
||||||
|
terminalCmd = "ghostty"
|
||||||
|
case deps.TerminalKitty:
|
||||||
|
terminalCmd = "kitty"
|
||||||
|
case deps.TerminalAlacritty:
|
||||||
|
terminalCmd = "alacritty"
|
||||||
|
default:
|
||||||
|
terminalCmd = "ghostty"
|
||||||
|
}
|
||||||
|
|
||||||
|
content := fmt.Sprintf(`QT_QPA_PLATFORM=wayland
|
||||||
|
ELECTRON_OZONE_PLATFORM_HINT=auto
|
||||||
|
QT_QPA_PLATFORMTHEME=gtk3
|
||||||
|
QT_QPA_PLATFORMTHEME_QT6=gtk3
|
||||||
|
TERMINAL=%s
|
||||||
|
`, terminalCmd)
|
||||||
|
|
||||||
|
envFile := filepath.Join(envDir, "90-dms.conf")
|
||||||
|
if err := os.WriteFile(envFile, []byte(content), 0644); err != nil {
|
||||||
|
return fmt.Errorf("failed to write environment config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.log(fmt.Sprintf("Wrote environment config to %s", envFile))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseDistribution) EnableDMSService(ctx context.Context) error {
|
||||||
|
cmd := exec.CommandContext(ctx, "systemctl", "--user", "enable", "--now", "dms")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("failed to enable dms service: %w", err)
|
||||||
|
}
|
||||||
|
b.log("Enabled dms systemd user service")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// installDMSBinary installs the DMS binary from GitHub releases
|
// installDMSBinary installs the DMS binary from GitHub releases
|
||||||
func (b *BaseDistribution) installDMSBinary(ctx context.Context, sudoPassword string, progressChan chan<- InstallProgressMsg) error {
|
func (b *BaseDistribution) installDMSBinary(ctx context.Context, sudoPassword string, progressChan chan<- InstallProgressMsg) error {
|
||||||
b.log("Installing/updating DMS binary...")
|
b.log("Installing/updating DMS binary...")
|
||||||
|
|||||||
@@ -333,6 +333,15 @@ func (d *DebianDistribution) InstallPackages(ctx context.Context, dependencies [
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := d.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := d.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
d.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.EnableDMSService(ctx); err != nil {
|
||||||
|
d.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
Progress: 1.0,
|
Progress: 1.0,
|
||||||
|
|||||||
@@ -357,6 +357,15 @@ func (f *FedoraDistribution) InstallPackages(ctx context.Context, dependencies [
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := f.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := f.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
f.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := f.EnableDMSService(ctx); err != nil {
|
||||||
|
f.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Phase 7: Complete
|
// Phase 7: Complete
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
|
|||||||
@@ -451,6 +451,15 @@ func (g *GentooDistribution) InstallPackages(ctx context.Context, dependencies [
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := g.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := g.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
g.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.EnableDMSService(ctx); err != nil {
|
||||||
|
g.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
Progress: 1.0,
|
Progress: 1.0,
|
||||||
|
|||||||
@@ -372,6 +372,15 @@ func (o *OpenSUSEDistribution) InstallPackages(ctx context.Context, dependencies
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := o.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := o.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
o.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.EnableDMSService(ctx); err != nil {
|
||||||
|
o.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
|
|||||||
@@ -352,6 +352,15 @@ func (u *UbuntuDistribution) InstallPackages(ctx context.Context, dependencies [
|
|||||||
LogOutput: "Starting post-installation configuration...",
|
LogOutput: "Starting post-installation configuration...",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminal := u.DetectTerminalFromDeps(dependencies)
|
||||||
|
if err := u.WriteEnvironmentConfig(terminal); err != nil {
|
||||||
|
u.log(fmt.Sprintf("Warning: failed to write environment config: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := u.EnableDMSService(ctx); err != nil {
|
||||||
|
u.log(fmt.Sprintf("Warning: failed to enable dms service: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Phase 7: Complete
|
// Phase 7: Complete
|
||||||
progressChan <- InstallProgressMsg{
|
progressChan <- InstallProgressMsg{
|
||||||
Phase: PhaseComplete,
|
Phase: PhaseComplete,
|
||||||
|
|||||||
@@ -371,6 +371,18 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
|||||||
|
|
||||||
node.SetName(parts[0])
|
node.SetName(parts[0])
|
||||||
for _, arg := range parts[1:] {
|
for _, arg := range parts[1:] {
|
||||||
|
if strings.Contains(arg, "=") {
|
||||||
|
kv := strings.SplitN(arg, "=", 2)
|
||||||
|
switch kv[1] {
|
||||||
|
case "true":
|
||||||
|
node.AddProperty(kv[0], true, "")
|
||||||
|
case "false":
|
||||||
|
node.AddProperty(kv[0], false, "")
|
||||||
|
default:
|
||||||
|
node.AddProperty(kv[0], kv[1], "")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
node.AddArgument(arg, "")
|
node.AddArgument(arg, "")
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
@@ -379,7 +391,7 @@ func (n *NiriProvider) buildActionNode(action string) *document.Node {
|
|||||||
func (n *NiriProvider) parseActionParts(action string) []string {
|
func (n *NiriProvider) parseActionParts(action string) []string {
|
||||||
var parts []string
|
var parts []string
|
||||||
var current strings.Builder
|
var current strings.Builder
|
||||||
var inQuote, escaped bool
|
var inQuote, escaped, wasQuoted bool
|
||||||
|
|
||||||
for _, r := range action {
|
for _, r := range action {
|
||||||
switch {
|
switch {
|
||||||
@@ -389,17 +401,19 @@ func (n *NiriProvider) parseActionParts(action string) []string {
|
|||||||
case r == '\\':
|
case r == '\\':
|
||||||
escaped = true
|
escaped = true
|
||||||
case r == '"':
|
case r == '"':
|
||||||
|
wasQuoted = true
|
||||||
inQuote = !inQuote
|
inQuote = !inQuote
|
||||||
case r == ' ' && !inQuote:
|
case r == ' ' && !inQuote:
|
||||||
if current.Len() > 0 {
|
if current.Len() > 0 || wasQuoted {
|
||||||
parts = append(parts, current.String())
|
parts = append(parts, current.String())
|
||||||
current.Reset()
|
current.Reset()
|
||||||
|
wasQuoted = false
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
current.WriteRune(r)
|
current.WriteRune(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if current.Len() > 0 {
|
if current.Len() > 0 || wasQuoted {
|
||||||
parts = append(parts, current.String())
|
parts = append(parts, current.String())
|
||||||
}
|
}
|
||||||
return parts
|
return parts
|
||||||
@@ -508,6 +522,10 @@ func (n *NiriProvider) writeBindNode(sb *strings.Builder, bind *overrideBind, in
|
|||||||
sb.WriteString(" ")
|
sb.WriteString(" ")
|
||||||
n.writeArg(sb, arg.ValueString(), forceQuote)
|
n.writeArg(sb, arg.ValueString(), forceQuote)
|
||||||
}
|
}
|
||||||
|
if child.Properties.Exist() {
|
||||||
|
sb.WriteString(" ")
|
||||||
|
sb.WriteString(strings.TrimLeft(child.Properties.String(), " "))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sb.WriteString("; }\n")
|
sb.WriteString("; }\n")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,6 +265,11 @@ func (p *NiriParser) parseKeybindNode(node *document.Node, _ string) *NiriKeyBin
|
|||||||
for _, arg := range actionNode.Arguments {
|
for _, arg := range actionNode.Arguments {
|
||||||
args = append(args, arg.ValueString())
|
args = append(args, arg.ValueString())
|
||||||
}
|
}
|
||||||
|
if actionNode.Properties != nil {
|
||||||
|
if val, ok := actionNode.Properties.Get("focus"); ok {
|
||||||
|
args = append(args, "focus="+val.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var description string
|
var description string
|
||||||
|
|||||||
@@ -602,8 +602,24 @@ func TestNiriParseActionWithProperties(t *testing.T) {
|
|||||||
for _, kb := range result.Section.Keybinds {
|
for _, kb := range result.Section.Keybinds {
|
||||||
switch kb.Action {
|
switch kb.Action {
|
||||||
case "move-column-to-workspace":
|
case "move-column-to-workspace":
|
||||||
if len(kb.Args) != 1 {
|
if len(kb.Args) != 2 {
|
||||||
t.Errorf("move-column-to-workspace should have 1 arg, got %d", len(kb.Args))
|
t.Errorf("move-column-to-workspace should have 2 args (index + focus), got %d", len(kb.Args))
|
||||||
|
}
|
||||||
|
hasIndex := false
|
||||||
|
hasFocus := false
|
||||||
|
for _, arg := range kb.Args {
|
||||||
|
if arg == "1" || arg == "2" {
|
||||||
|
hasIndex = true
|
||||||
|
}
|
||||||
|
if arg == "focus=false" {
|
||||||
|
hasFocus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasIndex {
|
||||||
|
t.Errorf("move-column-to-workspace missing index arg")
|
||||||
|
}
|
||||||
|
if !hasFocus {
|
||||||
|
t.Errorf("move-column-to-workspace missing focus=false arg")
|
||||||
}
|
}
|
||||||
case "next-window":
|
case "next-window":
|
||||||
if kb.Key != "Tab" {
|
if kb.Key != "Tab" {
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
quickshell = {
|
quickshell = {
|
||||||
package = lib.mkPackageOption pkgs "quickshell" {};
|
package = lib.mkPackageOption dmsPkgs "quickshell" {
|
||||||
|
extraDescription = "The quickshell package to use (defaults to be built from source, in the commit 26531f due to unreleased features used by DMS).";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
logs.save = lib.mkEnableOption "saving logs from DMS greeter to file";
|
logs.save = lib.mkEnableOption "saving logs from DMS greeter to file";
|
||||||
logs.path = lib.mkOption {
|
logs.path = lib.mkOption {
|
||||||
|
|||||||
45
flake.nix
45
flake.nix
@@ -52,7 +52,8 @@
|
|||||||
+ "_"
|
+ "_"
|
||||||
+ (self.shortRev or "dirty");
|
+ (self.shortRev or "dirty");
|
||||||
in {
|
in {
|
||||||
dms-shell = pkgs.buildGoModule (let
|
dms-shell = pkgs.buildGoModule (
|
||||||
|
let
|
||||||
rootSrc = ./.;
|
rootSrc = ./.;
|
||||||
in {
|
in {
|
||||||
inherit version;
|
inherit version;
|
||||||
@@ -68,9 +69,9 @@
|
|||||||
"-X main.Version=${version}"
|
"-X main.Version=${version}"
|
||||||
];
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = with pkgs; [
|
||||||
pkgs.installShellFiles
|
installShellFiles
|
||||||
pkgs.makeWrapper
|
.makeWrapper
|
||||||
];
|
];
|
||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
@@ -112,7 +113,8 @@
|
|||||||
mainProgram = "dms";
|
mainProgram = "dms";
|
||||||
platforms = pkgs.lib.platforms.linux;
|
platforms = pkgs.lib.platforms.linux;
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
default = self.packages.${system}.dms-shell;
|
default = self.packages.${system}.dms-shell;
|
||||||
}
|
}
|
||||||
@@ -125,5 +127,38 @@
|
|||||||
nixosModules.dankMaterialShell = mkModuleWithDmsPkgs ./distro/nix/nixos.nix;
|
nixosModules.dankMaterialShell = mkModuleWithDmsPkgs ./distro/nix/nixos.nix;
|
||||||
|
|
||||||
nixosModules.greeter = mkModuleWithDmsPkgs ./distro/nix/greeter.nix;
|
nixosModules.greeter = mkModuleWithDmsPkgs ./distro/nix/greeter.nix;
|
||||||
|
|
||||||
|
devShells = forEachSystem (
|
||||||
|
system: pkgs: let
|
||||||
|
qmlPkgs =
|
||||||
|
[
|
||||||
|
quickshell.packages.${system}.default
|
||||||
|
]
|
||||||
|
++ (with pkgs.kdePackages; [
|
||||||
|
qtdeclarative
|
||||||
|
kirigami.unwrapped
|
||||||
|
sonnet
|
||||||
|
qtmultimedia
|
||||||
|
]);
|
||||||
|
in {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs;
|
||||||
|
[
|
||||||
|
go_1_24
|
||||||
|
gopls
|
||||||
|
delve
|
||||||
|
go-tools
|
||||||
|
gnumake
|
||||||
|
]
|
||||||
|
++ qmlPkgs;
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
touch quickshell/.qmlls.ini 2>/dev/null
|
||||||
|
'';
|
||||||
|
|
||||||
|
QML2_IMPORT_PATH = pkgs.lib.concatStringsSep ":" (map (o: "${o}/lib/qt-6/qml") qmlPkgs);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,14 +197,26 @@ const ACTION_ARGS = {
|
|||||||
{ name: "focus", type: "bool", label: "Follow focus", default: false }
|
{ name: "focus", type: "bool", label: "Follow focus", default: false }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"move-column-to-workspace-down": {
|
||||||
|
args: [{ name: "focus", type: "bool", label: "Follow focus", default: false }]
|
||||||
|
},
|
||||||
|
"move-column-to-workspace-up": {
|
||||||
|
args: [{ name: "focus", type: "bool", label: "Follow focus", default: false }]
|
||||||
|
},
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
args: [{ name: "opts", type: "screenshot", label: "Options" }]
|
args: [{ name: "show-pointer", type: "bool", label: "Show pointer" }]
|
||||||
},
|
},
|
||||||
"screenshot-screen": {
|
"screenshot-screen": {
|
||||||
args: [{ name: "opts", type: "screenshot", label: "Options" }]
|
args: [
|
||||||
|
{ name: "show-pointer", type: "bool", label: "Show pointer" },
|
||||||
|
{ name: "write-to-disk", type: "bool", label: "Save to disk" }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"screenshot-window": {
|
"screenshot-window": {
|
||||||
args: [{ name: "opts", type: "screenshot", label: "Options" }]
|
args: [
|
||||||
|
{ name: "show-pointer", type: "bool", label: "Show pointer" },
|
||||||
|
{ name: "write-to-disk", type: "bool", label: "Save to disk" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,11 +300,12 @@ function getActionLabel(action) {
|
|||||||
if (!action)
|
if (!action)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
const dmsAct = findDmsAction(action);
|
var dmsAct = findDmsAction(action);
|
||||||
if (dmsAct)
|
if (dmsAct)
|
||||||
return dmsAct.label;
|
return dmsAct.label;
|
||||||
|
|
||||||
const compAct = findCompositorAction(action);
|
var base = action.split(" ")[0];
|
||||||
|
var compAct = findCompositorAction(base);
|
||||||
if (compAct)
|
if (compAct)
|
||||||
return compAct.label;
|
return compAct.label;
|
||||||
|
|
||||||
@@ -337,7 +350,8 @@ function isValidAction(action) {
|
|||||||
function isKnownCompositorAction(action) {
|
function isKnownCompositorAction(action) {
|
||||||
if (!action)
|
if (!action)
|
||||||
return false;
|
return false;
|
||||||
return findCompositorAction(action) !== null;
|
var base = action.split(" ")[0];
|
||||||
|
return findCompositorAction(base) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSpawnAction(command, args) {
|
function buildSpawnAction(command, args) {
|
||||||
@@ -404,10 +418,10 @@ function parseCompositorActionArgs(action) {
|
|||||||
if (!ACTION_ARGS[base])
|
if (!ACTION_ARGS[base])
|
||||||
return { base: action, args: {} };
|
return { base: action, args: {} };
|
||||||
|
|
||||||
var argConfig = ACTION_ARGS[base];
|
|
||||||
var argParts = parts.slice(1);
|
var argParts = parts.slice(1);
|
||||||
|
|
||||||
if (base === "move-column-to-workspace") {
|
switch (base) {
|
||||||
|
case "move-column-to-workspace":
|
||||||
for (var i = 0; i < argParts.length; i++) {
|
for (var i = 0; i < argParts.length; i++) {
|
||||||
if (argParts[i] === "focus=true" || argParts[i] === "focus=false") {
|
if (argParts[i] === "focus=true" || argParts[i] === "focus=false") {
|
||||||
args.focus = argParts[i] === "focus=true";
|
args.focus = argParts[i] === "focus=true";
|
||||||
@@ -415,15 +429,25 @@ function parseCompositorActionArgs(action) {
|
|||||||
args.index = argParts[i];
|
args.index = argParts[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (base.startsWith("screenshot")) {
|
break;
|
||||||
args.opts = {};
|
case "move-column-to-workspace-down":
|
||||||
for (var j = 0; j < argParts.length; j += 2) {
|
case "move-column-to-workspace-up":
|
||||||
if (j + 1 < argParts.length)
|
for (var k = 0; k < argParts.length; k++) {
|
||||||
args.opts[argParts[j]] = argParts[j + 1];
|
if (argParts[k] === "focus=true" || argParts[k] === "focus=false")
|
||||||
|
args.focus = argParts[k] === "focus=true";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (base.startsWith("screenshot")) {
|
||||||
|
for (var j = 0; j < argParts.length; j++) {
|
||||||
|
var kv = argParts[j].split("=");
|
||||||
|
if (kv.length === 2)
|
||||||
|
args[kv[0]] = kv[1] === "true";
|
||||||
}
|
}
|
||||||
} else if (argParts.length > 0) {
|
} else if (argParts.length > 0) {
|
||||||
args.value = argParts.join(" ");
|
args.value = argParts.join(" ");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { base: base, args: args };
|
return { base: base, args: args };
|
||||||
}
|
}
|
||||||
@@ -437,25 +461,30 @@ function buildCompositorAction(base, args) {
|
|||||||
if (!args || Object.keys(args).length === 0)
|
if (!args || Object.keys(args).length === 0)
|
||||||
return base;
|
return base;
|
||||||
|
|
||||||
if (base === "move-column-to-workspace") {
|
switch (base) {
|
||||||
|
case "move-column-to-workspace":
|
||||||
if (args.index)
|
if (args.index)
|
||||||
parts.push(args.index);
|
parts.push(args.index);
|
||||||
if (args.focus === true)
|
if (args.focus === false)
|
||||||
parts.push("focus=true");
|
|
||||||
else if (args.focus === false)
|
|
||||||
parts.push("focus=false");
|
parts.push("focus=false");
|
||||||
} else if (base.startsWith("screenshot") && args.opts) {
|
break;
|
||||||
for (var key in args.opts) {
|
case "move-column-to-workspace-down":
|
||||||
if (args.opts[key] !== undefined && args.opts[key] !== "") {
|
case "move-column-to-workspace-up":
|
||||||
parts.push(key);
|
if (args.focus === false)
|
||||||
parts.push(args.opts[key]);
|
parts.push("focus=false");
|
||||||
}
|
break;
|
||||||
}
|
default:
|
||||||
|
if (base.startsWith("screenshot")) {
|
||||||
|
if (args["show-pointer"] === true)
|
||||||
|
parts.push("show-pointer=true");
|
||||||
|
if (args["write-to-disk"] === true)
|
||||||
|
parts.push("write-to-disk=true");
|
||||||
} else if (args.value) {
|
} else if (args.value) {
|
||||||
parts.push(args.value);
|
parts.push(args.value);
|
||||||
} else if (args.index) {
|
} else if (args.index) {
|
||||||
parts.push(args.index);
|
parts.push(args.index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parts.join(" ");
|
return parts.join(" ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Loader {
|
|||||||
property bool isRightBarEdge: false
|
property bool isRightBarEdge: false
|
||||||
property bool isTopBarEdge: false
|
property bool isTopBarEdge: false
|
||||||
property bool isBottomBarEdge: false
|
property bool isBottomBarEdge: false
|
||||||
|
property string _registeredScreenName: ""
|
||||||
|
|
||||||
asynchronous: false
|
asynchronous: false
|
||||||
|
|
||||||
@@ -198,13 +199,16 @@ Loader {
|
|||||||
if (!hasPopout)
|
if (!hasPopout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BarWidgetService.registerWidget(widgetId, parentScreen.name, item);
|
_registeredScreenName = parentScreen.name;
|
||||||
|
BarWidgetService.registerWidget(widgetId, _registeredScreenName, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unregisterWidget() {
|
function unregisterWidget() {
|
||||||
if (!widgetId || !parentScreen?.name)
|
if (!widgetId || !_registeredScreenName)
|
||||||
return;
|
return;
|
||||||
BarWidgetService.unregisterWidget(widgetId, parentScreen.name);
|
|
||||||
|
BarWidgetService.unregisterWidget(widgetId, _registeredScreenName);
|
||||||
|
_registeredScreenName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWidgetComponent(widgetId, components) {
|
function getWidgetComponent(widgetId, components) {
|
||||||
|
|||||||
@@ -597,7 +597,7 @@ Item {
|
|||||||
onSaveBind: (originalKey, newData) => {
|
onSaveBind: (originalKey, newData) => {
|
||||||
KeybindsService.saveBind(originalKey, newData);
|
KeybindsService.saveBind(originalKey, newData);
|
||||||
keybindsTab._editingKey = newData.key;
|
keybindsTab._editingKey = newData.key;
|
||||||
keybindsTab.expandedKey = modelData.action;
|
keybindsTab.expandedKey = newData.action;
|
||||||
}
|
}
|
||||||
onRemoveBind: key => {
|
onRemoveBind: key => {
|
||||||
const remainingKey = bindItem.keys.find(k => k.key !== key)?.key ?? "";
|
const remainingKey = bindItem.keys.find(k => k.key !== key)?.key ?? "";
|
||||||
|
|||||||
@@ -650,9 +650,10 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onWheel: wheel => {
|
onWheel: wheel => {
|
||||||
if (!root.recording)
|
if (!root.recording) {
|
||||||
|
wheel.accepted = false;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
wheel.accepted = true;
|
wheel.accepted = true;
|
||||||
|
|
||||||
const mods = [];
|
const mods = [];
|
||||||
@@ -959,12 +960,12 @@ Item {
|
|||||||
Layout.preferredWidth: 120
|
Layout.preferredWidth: 120
|
||||||
compactMode: true
|
compactMode: true
|
||||||
currentValue: {
|
currentValue: {
|
||||||
const action = root.editAction;
|
const base = root.editAction.split(" ")[0];
|
||||||
const cats = KeybindsService.getCompositorCategories();
|
const cats = KeybindsService.getCompositorCategories();
|
||||||
for (const cat of cats) {
|
for (const cat of cats) {
|
||||||
const actions = KeybindsService.getCompositorActions(cat);
|
const actions = KeybindsService.getCompositorActions(cat);
|
||||||
for (const act of actions) {
|
for (const act of actions) {
|
||||||
if (act.id === action)
|
if (act.id === base)
|
||||||
return cat;
|
return cat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1024,12 +1025,13 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: optionsRow
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
visible: root._actionType === "compositor" && !root.useCustomCompositor && Actions.getActionArgConfig(root.editAction)
|
visible: root._actionType === "compositor" && !root.useCustomCompositor && Actions.getActionArgConfig(root.editAction)
|
||||||
|
|
||||||
property var argConfig: Actions.getActionArgConfig(root.editAction)
|
readonly property var argConfig: Actions.getActionArgConfig(root.editAction)
|
||||||
property var parsedArgs: Actions.parseCompositorActionArgs(root.editAction)
|
readonly property var parsedArgs: Actions.parseCompositorActionArgs(root.editAction)
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: I18n.tr("Options")
|
text: I18n.tr("Options")
|
||||||
@@ -1048,56 +1050,75 @@ Item {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
visible: {
|
visible: {
|
||||||
const cfg = parent.parent.argConfig;
|
const cfg = optionsRow.argConfig;
|
||||||
if (!cfg || !cfg.config || !cfg.config.args)
|
if (!cfg?.config?.args)
|
||||||
return false;
|
return false;
|
||||||
const firstArg = cfg.config.args[0];
|
const firstArg = cfg.config.args[0];
|
||||||
return firstArg && (firstArg.type === "text" || firstArg.type === "number");
|
return firstArg && (firstArg.type === "text" || firstArg.type === "number");
|
||||||
}
|
}
|
||||||
placeholderText: {
|
placeholderText: optionsRow.argConfig?.config?.args?.[0]?.placeholder || ""
|
||||||
const cfg = parent.parent.argConfig;
|
|
||||||
if (!cfg || !cfg.config || !cfg.config.args)
|
Connections {
|
||||||
return "";
|
target: optionsRow
|
||||||
return cfg.config.args[0]?.placeholder || "";
|
function onParsedArgsChanged() {
|
||||||
|
const newText = optionsRow.parsedArgs?.args?.value || optionsRow.parsedArgs?.args?.index || "";
|
||||||
|
if (argValueField.text !== newText)
|
||||||
|
argValueField.text = newText;
|
||||||
}
|
}
|
||||||
text: parent.parent.parsedArgs?.args?.value || parent.parent.parsedArgs?.args?.index || ""
|
}
|
||||||
onTextChanged: {
|
|
||||||
const cfg = parent.parent.argConfig;
|
Component.onCompleted: {
|
||||||
|
text = optionsRow.parsedArgs?.args?.value || optionsRow.parsedArgs?.args?.index || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditingFinished: {
|
||||||
|
const cfg = optionsRow.argConfig;
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
return;
|
return;
|
||||||
const base = parent.parent.parsedArgs?.base || root.editAction.split(" ")[0];
|
const parsed = optionsRow.parsedArgs;
|
||||||
const args = cfg.config.args[0]?.type === "number" ? {
|
const args = {};
|
||||||
index: text
|
if (cfg.config.args[0]?.type === "number")
|
||||||
} : {
|
args.index = text;
|
||||||
value: text
|
else
|
||||||
};
|
args.value = text;
|
||||||
|
if (parsed?.args?.focus === false)
|
||||||
|
args.focus = false;
|
||||||
root.updateEdit({
|
root.updateEdit({
|
||||||
action: Actions.buildCompositorAction(base, args)
|
action: Actions.buildCompositorAction(parsed?.base || cfg.base, args)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: {
|
visible: {
|
||||||
const cfg = parent.parent.argConfig;
|
const cfg = optionsRow.argConfig;
|
||||||
return cfg && cfg.base === "move-column-to-workspace";
|
if (!cfg)
|
||||||
|
return false;
|
||||||
|
switch (cfg.base) {
|
||||||
|
case "move-column-to-workspace":
|
||||||
|
case "move-column-to-workspace-down":
|
||||||
|
case "move-column-to-workspace-up":
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
id: focusToggle
|
id: focusToggle
|
||||||
checked: parent.parent.parent.parsedArgs?.args?.focus === true
|
checked: optionsRow.parsedArgs?.args?.focus !== false
|
||||||
onCheckedChanged: {
|
onToggled: newChecked => {
|
||||||
const cfg = parent.parent.parent.argConfig;
|
const cfg = optionsRow.argConfig;
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
return;
|
return;
|
||||||
const parsed = parent.parent.parent.parsedArgs;
|
const parsed = optionsRow.parsedArgs;
|
||||||
const args = {
|
const args = {};
|
||||||
index: parsed?.args?.index || "",
|
if (cfg.base === "move-column-to-workspace")
|
||||||
focus: checked
|
args.index = parsed?.args?.index || "";
|
||||||
};
|
if (!newChecked)
|
||||||
|
args.focus = false;
|
||||||
root.updateEdit({
|
root.updateEdit({
|
||||||
action: Actions.buildCompositorAction("move-column-to-workspace", args)
|
action: Actions.buildCompositorAction(cfg.base, args)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1110,53 +1131,22 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: {
|
visible: optionsRow.argConfig?.base?.startsWith("screenshot") ?? false
|
||||||
const cfg = parent.parent.argConfig;
|
|
||||||
return cfg && cfg.base && cfg.base.startsWith("screenshot");
|
|
||||||
}
|
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
id: writeToDiskToggle
|
|
||||||
checked: parent.parent.parent.parent.parsedArgs?.args?.opts?.["write-to-disk"] === "true"
|
|
||||||
onCheckedChanged: {
|
|
||||||
const parsed = parent.parent.parent.parent.parsedArgs;
|
|
||||||
const base = parsed?.base || "screenshot";
|
|
||||||
const opts = parsed?.args?.opts || {};
|
|
||||||
opts["write-to-disk"] = checked ? "true" : "";
|
|
||||||
root.updateEdit({
|
|
||||||
action: Actions.buildCompositorAction(base, {
|
|
||||||
opts: opts
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Save")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
id: showPointerToggle
|
id: showPointerToggle
|
||||||
checked: parent.parent.parent.parent.parsedArgs?.args?.opts?.["show-pointer"] === "true"
|
checked: optionsRow.parsedArgs?.args?.["show-pointer"] === true
|
||||||
onCheckedChanged: {
|
onToggled: newChecked => {
|
||||||
const parsed = parent.parent.parent.parent.parsedArgs;
|
const parsed = optionsRow.parsedArgs;
|
||||||
const base = parsed?.base || "screenshot";
|
const base = parsed?.base || "screenshot";
|
||||||
const opts = parsed?.args?.opts || {};
|
const args = Object.assign({}, parsed?.args || {});
|
||||||
opts["show-pointer"] = checked ? "true" : "";
|
args["show-pointer"] = newChecked;
|
||||||
root.updateEdit({
|
root.updateEdit({
|
||||||
action: Actions.buildCompositorAction(base, {
|
action: Actions.buildCompositorAction(base, args)
|
||||||
opts: opts
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,6 +1157,31 @@ Item {
|
|||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: optionsRow.argConfig?.base !== "screenshot"
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: writeToDiskToggle
|
||||||
|
checked: optionsRow.parsedArgs?.args?.["write-to-disk"] === true
|
||||||
|
onToggled: newChecked => {
|
||||||
|
const parsed = optionsRow.parsedArgs;
|
||||||
|
const base = parsed?.base || "screenshot-screen";
|
||||||
|
const args = Object.assign({}, parsed?.args || {});
|
||||||
|
args["write-to-disk"] = newChecked;
|
||||||
|
root.updateEdit({
|
||||||
|
action: Actions.buildCompositorAction(base, args)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Save")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user