1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

Compare commits

...

10 Commits

Author SHA1 Message Date
bbedward
468e569bc7 modals: single window optimization 2025-12-01 17:49:32 -05:00
purian23
139c99001a Update dms core internal paths 2025-12-01 17:28:19 -05:00
bbedward
bd99be15c2 brightness: fix ddc erasing devices, fix OSD behaviors 2025-12-01 16:32:34 -05:00
purian23
1d91d8fd94 Add desktop & icon to distro pacakges 2025-12-01 15:46:15 -05:00
purian23
f425f86101 Localize Systemd & Simplify builds 2025-12-01 15:21:04 -05:00
bbedward
83a6b7567f wallpaper: vram optimizations 2025-12-01 13:54:29 -05:00
bbedward
9184c70883 fix workflow 2025-12-01 12:25:55 -05:00
bbedward
f5ca4ccce5 core: update to golangci-lint v2 2025-12-01 12:23:52 -05:00
dms-ci[bot]
50f174be92 nix: update vendorHash for go.mod changes 2025-12-01 16:56:36 +00:00
bbedward
e5d11ce535 brightness: add udev monitor, bind OSDs to netlink events
fixes #863
2025-12-01 11:54:20 -05:00
75 changed files with 2050 additions and 1217 deletions

View File

@@ -3,15 +3,15 @@ name: Go CI
on: on:
push: push:
branches: branches:
- '**' - "**"
paths: paths:
- 'core/**' - "core/**"
- '.github/workflows/go-ci.yml' - ".github/workflows/go-ci.yml"
pull_request: pull_request:
branches: [master, main] branches: [master, main]
paths: paths:
- 'core/**' - "core/**"
- '.github/workflows/go-ci.yml' - ".github/workflows/go-ci.yml"
concurrency: concurrency:
group: go-ci-${{ github.ref }} group: go-ci-${{ github.ref }}
@@ -42,9 +42,9 @@ jobs:
fi fi
- name: Run golangci-lint - name: Run golangci-lint
uses: golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v9
with: with:
version: latest version: v2.6
working-directory: core working-directory: core
- name: Test - name: Test

View File

@@ -597,7 +597,10 @@ jobs:
%{_builddir}/dms-cli completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : %{_builddir}/dms-cli completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || :
%{_builddir}/dms-cli completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : %{_builddir}/dms-cli completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || :
install -Dm644 %{_builddir}/dms-qml/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service
install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop
install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
install -dm755 %{buildroot}%{_datadir}/quickshell/dms install -dm755 %{buildroot}%{_datadir}/quickshell/dms
cp -r %{_builddir}/dms-qml/* %{buildroot}%{_datadir}/quickshell/dms/ cp -r %{_builddir}/dms-qml/* %{buildroot}%{_datadir}/quickshell/dms/
@@ -623,6 +626,8 @@ jobs:
%doc README.md CONTRIBUTING.md %doc README.md CONTRIBUTING.md
%{_datadir}/quickshell/dms/ %{_datadir}/quickshell/dms/
%{_userunitdir}/dms.service %{_userunitdir}/dms.service
%{_datadir}/applications/dms-open.desktop
%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
%files -n dms-cli %files -n dms-cli
%{_bindir}/dms %{_bindir}/dms

156
Makefile Normal file
View File

@@ -0,0 +1,156 @@
# Root Makefile for DankMaterialShell (DMS)
# Orchestrates building, installation, and systemd management
# Build configuration
BINARY_NAME=dms
CORE_DIR=core
BUILD_DIR=$(CORE_DIR)/bin
PREFIX ?= /usr/local
INSTALL_DIR=$(PREFIX)/bin
DATA_DIR=$(PREFIX)/share
ICON_DIR=$(DATA_DIR)/icons/hicolor/scalable/apps
USER_HOME := $(if $(SUDO_USER),$(shell getent passwd $(SUDO_USER) | cut -d: -f6),$(HOME))
SYSTEMD_USER_DIR=$(USER_HOME)/.config/systemd/user
SHELL_DIR=quickshell
SHELL_INSTALL_DIR=$(DATA_DIR)/quickshell/dms
ASSETS_DIR=assets
APPLICATIONS_DIR=$(DATA_DIR)/applications
.PHONY: all build clean install install-bin install-shell install-completions install-systemd install-icon install-desktop uninstall uninstall-bin uninstall-shell uninstall-completions uninstall-systemd uninstall-icon uninstall-desktop help
all: build
build:
@echo "Building $(BINARY_NAME)..."
@$(MAKE) -C $(CORE_DIR) build
@echo "Build complete"
clean:
@echo "Cleaning build artifacts..."
@$(MAKE) -C $(CORE_DIR) clean
@echo "Clean complete"
# Installation targets
install-bin:
@echo "Installing $(BINARY_NAME) to $(INSTALL_DIR)..."
@install -D -m 755 $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_DIR)/$(BINARY_NAME)
@echo "Binary installed"
install-shell:
@echo "Installing shell files to $(SHELL_INSTALL_DIR)..."
@mkdir -p $(SHELL_INSTALL_DIR)
@cp -r $(SHELL_DIR)/* $(SHELL_INSTALL_DIR)/
@rm -rf $(SHELL_INSTALL_DIR)/.git* $(SHELL_INSTALL_DIR)/.github
@echo "Shell files installed"
install-completions:
@echo "Installing shell completions..."
@mkdir -p $(DATA_DIR)/bash-completion/completions
@mkdir -p $(DATA_DIR)/zsh/site-functions
@mkdir -p $(DATA_DIR)/fish/vendor_completions.d
@$(BUILD_DIR)/$(BINARY_NAME) completion bash > $(DATA_DIR)/bash-completion/completions/dms 2>/dev/null || true
@$(BUILD_DIR)/$(BINARY_NAME) completion zsh > $(DATA_DIR)/zsh/site-functions/_dms 2>/dev/null || true
@$(BUILD_DIR)/$(BINARY_NAME) completion fish > $(DATA_DIR)/fish/vendor_completions.d/dms.fish 2>/dev/null || true
@echo "Shell completions installed"
install-systemd:
@echo "Installing systemd user service..."
@mkdir -p $(SYSTEMD_USER_DIR)
@if [ -n "$(SUDO_USER)" ]; then chown -R $(SUDO_USER):$(SUDO_USER) $(SYSTEMD_USER_DIR); fi
@sed 's|/usr/bin/dms|$(INSTALL_DIR)/dms|g' $(ASSETS_DIR)/systemd/dms.service > $(SYSTEMD_USER_DIR)/dms.service
@chmod 644 $(SYSTEMD_USER_DIR)/dms.service
@if [ -n "$(SUDO_USER)" ]; then chown $(SUDO_USER):$(SUDO_USER) $(SYSTEMD_USER_DIR)/dms.service; fi
@echo "Systemd service installed to $(SYSTEMD_USER_DIR)/dms.service"
install-icon:
@echo "Installing icon..."
@install -D -m 644 $(ASSETS_DIR)/danklogo.svg $(ICON_DIR)/danklogo.svg
@gtk-update-icon-cache -q $(DATA_DIR)/icons/hicolor 2>/dev/null || true
@echo "Icon installed"
install-desktop:
@echo "Installing desktop entry..."
@install -D -m 644 $(ASSETS_DIR)/dms-open.desktop $(APPLICATIONS_DIR)/dms-open.desktop
@update-desktop-database -q $(APPLICATIONS_DIR) 2>/dev/null || true
@echo "Desktop entry installed"
install: build install-bin install-shell install-completions install-systemd install-icon install-desktop
@echo ""
@echo "Installation complete!"
@echo ""
@echo "To enable and start DMS:"
@echo " systemctl --user enable --now dms"
# Uninstallation targets
uninstall-bin:
@echo "Removing $(BINARY_NAME) from $(INSTALL_DIR)..."
@rm -f $(INSTALL_DIR)/$(BINARY_NAME)
@echo "Binary removed"
uninstall-shell:
@echo "Removing shell files from $(SHELL_INSTALL_DIR)..."
@rm -rf $(SHELL_INSTALL_DIR)
@echo "Shell files removed"
uninstall-completions:
@echo "Removing shell completions..."
@rm -f $(DATA_DIR)/bash-completion/completions/dms
@rm -f $(DATA_DIR)/zsh/site-functions/_dms
@rm -f $(DATA_DIR)/fish/vendor_completions.d/dms.fish
@echo "Shell completions removed"
uninstall-systemd:
@echo "Removing systemd user service..."
@rm -f $(SYSTEMD_USER_DIR)/dms.service
@echo "Systemd service removed"
@echo "Note: Stop/disable service manually if running: systemctl --user stop dms"
uninstall-icon:
@echo "Removing icon..."
@rm -f $(ICON_DIR)/danklogo.svg
@gtk-update-icon-cache -q $(DATA_DIR)/icons/hicolor 2>/dev/null || true
@echo "Icon removed"
uninstall-desktop:
@echo "Removing desktop entry..."
@rm -f $(APPLICATIONS_DIR)/dms-open.desktop
@update-desktop-database -q $(APPLICATIONS_DIR) 2>/dev/null || true
@echo "Desktop entry removed"
uninstall: uninstall-systemd uninstall-desktop uninstall-icon uninstall-completions uninstall-shell uninstall-bin
@echo ""
@echo "Uninstallation complete!"
# Target assist
help:
@echo "Available targets:"
@echo ""
@echo "Build:"
@echo " all (default) - Build the DMS binary"
@echo " build - Same as 'all'"
@echo " clean - Clean build artifacts"
@echo ""
@echo "Install:"
@echo " install - Build and install everything (requires sudo)"
@echo " install-bin - Install only the binary"
@echo " install-shell - Install only shell files"
@echo " install-completions - Install only shell completions"
@echo " install-systemd - Install only systemd service"
@echo " install-icon - Install only icon"
@echo " install-desktop - Install only desktop entry"
@echo ""
@echo "Uninstall:"
@echo " uninstall - Remove everything (requires sudo)"
@echo " uninstall-bin - Remove only the binary"
@echo " uninstall-shell - Remove only shell files"
@echo " uninstall-completions - Remove only shell completions"
@echo " uninstall-systemd - Remove only systemd service"
@echo " uninstall-icon - Remove only icon"
@echo " uninstall-desktop - Remove only desktop entry"
@echo ""
@echo "Usage:"
@echo " sudo make install - Build and install DMS"
@echo " sudo make uninstall - Remove DMS"
@echo " systemctl --user enable --now dms - Enable and start service"

View File

@@ -1,77 +1,105 @@
linters-settings: version: "2"
errcheck:
check-type-assertions: false
check-blank: false
exclude-functions:
# Cleanup/destroy operations
- (io.Closer).Close
- (*os.File).Close
- (net.Conn).Close
- (*net.Conn).Close
# Signal handling
- (*os.Process).Signal
- (*os.Process).Kill
# DBus cleanup
- (*github.com/godbus/dbus/v5.Conn).RemoveMatchSignal
- (*github.com/godbus/dbus/v5.Conn).RemoveSignal
# Encoding to network connections (if conn is bad, nothing we can do)
- (*encoding/json.Encoder).Encode
- (net.Conn).Write
# Command execution where failure is expected/ignored
- (*os/exec.Cmd).Run
- (*os/exec.Cmd).Start
# Flush operations
- (*bufio.Writer).Flush
# Scanning user input
- fmt.Scanln
- fmt.Scanf
# Parse operations where default value is acceptable
- fmt.Sscanf
# Flag operations
- (*github.com/spf13/pflag.FlagSet).MarkHidden
# Binary encoding to buffer (can't fail for basic types)
- binary.Write
# File operations in cleanup paths
- os.Rename
- os.Remove
- (*os.File).WriteString
issues: linters:
exclude-rules: enable:
- path: _test\.go - revive
linters:
- errcheck settings:
- govet revive:
- unused rules:
- ineffassign - name: use-any
- staticcheck severity: error
- gosimple errcheck:
# Exclude cleanup/teardown method calls from errcheck check-type-assertions: false
- linters: check-blank: false
- errcheck exclude-functions:
text: "Error return value of `.+\\.(Destroy|Release|Stop|Close|Roundtrip|Store)` is not checked" # Cleanup/destroy operations
# Exclude internal state update methods that are best-effort - (io.Closer).Close
- linters: - (*os.File).Close
- errcheck - (net.Conn).Close
text: "Error return value of `[mb]\\.\\w*(update|initialize|recreate|acquire|enumerate|list|List|Ensure|refresh|Lock)\\w*` is not checked" - (*net.Conn).Close
# Exclude SetMode on wayland power controls (best-effort) # Signal handling
- linters: - (*os.Process).Signal
- errcheck - (*os.Process).Kill
text: "Error return value of `.+\\.SetMode` is not checked" # DBus cleanup
# Exclude AddMatchSignal which is best-effort monitoring setup - (*github.com/godbus/dbus/v5.Conn).RemoveMatchSignal
- linters: - (*github.com/godbus/dbus/v5.Conn).RemoveSignal
- errcheck # Encoding to network connections (if conn is bad, nothing we can do)
text: "Error return value of `.+\\.AddMatchSignal` is not checked" - (*encoding/json.Encoder).Encode
# Exclude wayland pkg from errcheck and ineffassign (generated code patterns) - (net.Conn).Write
- linters: # Command execution where failure is expected/ignored
- errcheck - (*os/exec.Cmd).Run
- ineffassign - (*os/exec.Cmd).Start
path: pkg/go-wayland/ # Flush operations
# Exclude proto pkg from ineffassign (generated protocol code) - (*bufio.Writer).Flush
- linters: # Scanning user input
- ineffassign - fmt.Scanln
path: internal/proto/ - fmt.Scanf
# binary.Write to bytes.Buffer can't fail # Parse operations where default value is acceptable
- linters: - fmt.Sscanf
- errcheck # Flag operations
text: "Error return value of `binary\\.Write` is not checked" - (*github.com/spf13/pflag.FlagSet).MarkHidden
# Binary encoding to buffer (can't fail for basic types)
- binary.Write
# File operations in cleanup paths
- os.Rename
- os.Remove
- os.RemoveAll
- (*os.File).WriteString
# Stdout/stderr writes (can't meaningfully handle failure)
- fmt.Fprintln
- fmt.Fprintf
- fmt.Fprint
# Writing to pipes (if pipe is bad, nothing we can do)
- (*io.PipeWriter).Write
- (*os.File).Write
exclusions:
rules:
# Exclude generated mocks from all linters
- path: internal/mocks/
linters:
- errcheck
- govet
- unused
- ineffassign
- staticcheck
- gosimple
- revive
- path: _test\.go
linters:
- errcheck
- govet
- unused
- ineffassign
- staticcheck
- gosimple
# Exclude cleanup/teardown method calls from errcheck
- linters:
- errcheck
text: "Error return value of `.+\\.(Destroy|Release|Stop|Close|Roundtrip|Store)` is not checked"
# Exclude internal state update methods that are best-effort
- linters:
- errcheck
text: "Error return value of `[mb]\\.\\w*(update|initialize|recreate|acquire|enumerate|list|List|Ensure|refresh|Lock)\\w*` is not checked"
# Exclude SetMode on wayland power controls (best-effort)
- linters:
- errcheck
text: "Error return value of `.+\\.SetMode` is not checked"
# Exclude AddMatchSignal which is best-effort monitoring setup
- linters:
- errcheck
text: "Error return value of `.+\\.AddMatchSignal` is not checked"
# Exclude wayland pkg from errcheck and ineffassign (generated code patterns)
- linters:
- errcheck
- ineffassign
path: pkg/go-wayland/
# Exclude proto pkg from ineffassign (generated protocol code)
- linters:
- ineffassign
path: internal/proto/
# binary.Write to bytes.Buffer can't fail
- linters:
- errcheck
text: "Error return value of `binary\\.Write` is not checked"

View File

@@ -186,7 +186,7 @@ func runOpen(target string) {
} }
} }
params := map[string]interface{}{ params := map[string]any{
"target": actualTarget, "target": actualTarget,
} }

View File

@@ -11,6 +11,8 @@ require (
github.com/fsnotify/fsnotify v1.9.0 github.com/fsnotify/fsnotify v1.9.0
github.com/godbus/dbus/v5 v5.2.0 github.com/godbus/dbus/v5 v5.2.0
github.com/holoplot/go-evdev v0.0.0-20250804134636-ab1d56a1fe83 github.com/holoplot/go-evdev v0.0.0-20250804134636-ab1d56a1fe83
github.com/pilebones/go-udev v0.9.1
github.com/sblinch/kdl-go v0.0.0-20250930225324-bf4099d4614a
github.com/spf13/cobra v1.10.1 github.com/spf13/cobra v1.10.1
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39
@@ -32,7 +34,6 @@ require (
github.com/kevinburke/ssh_config v1.4.0 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect
github.com/sblinch/kdl-go v0.0.0-20250930225324-bf4099d4614a // indirect
github.com/sergi/go-diff v1.4.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect
github.com/stretchr/objx v0.5.3 // indirect github.com/stretchr/objx v0.5.3 // indirect
golang.org/x/crypto v0.45.0 // indirect golang.org/x/crypto v0.45.0 // indirect

View File

@@ -24,16 +24,12 @@ github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoF
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
github.com/charmbracelet/x/ansi v0.11.0 h1:uuIVK7GIplwX6UBIz8S2TF8nkr7xRlygSsBRjSJqIvA=
github.com/charmbracelet/x/ansi v0.11.0/go.mod h1:uQt8bOrq/xgXjlGcFMc8U2WYbnxyjrKhnvTQluvfCaE=
github.com/charmbracelet/x/ansi v0.11.2 h1:XAG3FSjiVtFvgEgGrNBkCNNYrsucAt8c6bfxHyROLLs= github.com/charmbracelet/x/ansi v0.11.2 h1:XAG3FSjiVtFvgEgGrNBkCNNYrsucAt8c6bfxHyROLLs=
github.com/charmbracelet/x/ansi v0.11.2/go.mod h1:9tY2bzX5SiJCU0iWyskjBeI2BRQfvPqI+J760Mjf+Rg= github.com/charmbracelet/x/ansi v0.11.2/go.mod h1:9tY2bzX5SiJCU0iWyskjBeI2BRQfvPqI+J760Mjf+Rg=
github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4=
github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA=
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
github.com/clipperhouse/displaywidth v0.5.0 h1:AIG5vQaSL2EKqzt0M9JMnvNxOCRTKUc4vUnLWGgP89I=
github.com/clipperhouse/displaywidth v0.5.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s= github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s=
github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
@@ -43,8 +39,6 @@ github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsV
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -62,19 +56,14 @@ github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo=
github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs= github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs=
github.com/go-git/go-billy/v6 v6.0.0-20251111123000-fb5ff8f3f0b0 h1:EC9n6hr6yKDoVJ6g7Ko523LbbceJfR0ohbOp809Fyf4=
github.com/go-git/go-billy/v6 v6.0.0-20251111123000-fb5ff8f3f0b0/go.mod h1:E3VhlS+AKkrq6ZNn1axE2/nDRJ87l1FJk9r5HT2vPX0=
github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0 h1:eY5aB2GXiVdgTueBcqsBt53WuJTRZAuCdIS/86Pcq5c= github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0 h1:eY5aB2GXiVdgTueBcqsBt53WuJTRZAuCdIS/86Pcq5c=
github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0/go.mod h1:0NjwVNrwtVFZBReAp5OoGklGJIgJFEbVyHneAr4lc8k= github.com/go-git/go-billy/v6 v6.0.0-20251126203821-7f9c95185ee0/go.mod h1:0NjwVNrwtVFZBReAp5OoGklGJIgJFEbVyHneAr4lc8k=
github.com/go-git/go-git-fixtures/v5 v5.1.1 h1:OH8i1ojV9bWfr0ZfasfpgtUXQHQyVS8HXik/V1C099w= github.com/go-git/go-git-fixtures/v5 v5.1.1 h1:OH8i1ojV9bWfr0ZfasfpgtUXQHQyVS8HXik/V1C099w=
github.com/go-git/go-git-fixtures/v5 v5.1.1/go.mod h1:Altk43lx3b1ks+dVoAG2300o5WWUnktvfY3VI6bcaXU= github.com/go-git/go-git-fixtures/v5 v5.1.1/go.mod h1:Altk43lx3b1ks+dVoAG2300o5WWUnktvfY3VI6bcaXU=
github.com/go-git/go-git/v6 v6.0.0-20251112161705-8cc3e21f07a9 h1:SOFrnF9LCssC6q6Rb0084Bzg2aBYbe8QXv9xKGXmt/w=
github.com/go-git/go-git/v6 v6.0.0-20251112161705-8cc3e21f07a9/go.mod h1:0wtvm/JfPC9RFVEAP3ks0ec5h64/qmZkTTUE3pjz7Hc=
github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805 h1:jxQ3BzYeErNRvlI/4+0mpwqMzvB4g97U+ksfgvrUEbY= github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805 h1:jxQ3BzYeErNRvlI/4+0mpwqMzvB4g97U+ksfgvrUEbY=
github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805/go.mod h1:dIwT3uWK1ooHInyVnK2JS5VfQ3peVGYaw2QPqX7uFvs= github.com/go-git/go-git/v6 v6.0.0-20251128074608-48f817f57805/go.mod h1:dIwT3uWK1ooHInyVnK2JS5VfQ3peVGYaw2QPqX7uFvs=
github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE= github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=
github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk= github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8=
github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/godbus/dbus/v5 v5.2.0/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
@@ -95,8 +84,9 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -111,6 +101,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/pilebones/go-udev v0.9.1 h1:uN72M1C1fgzhsVmBGEM8w9RD1JY4iVsPZpr+Z6rb3O8=
github.com/pilebones/go-udev v0.9.1/go.mod h1:Bgcl07crebF3JSeS4+nuaRvhWFdCeFoBhXXeAp93XNo=
github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -139,12 +131,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0=
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY= golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY=
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=

View File

@@ -22,8 +22,19 @@ func LocateDMSConfig() (string, error) {
primaryPaths = append(primaryPaths, filepath.Join(configHome, "quickshell", "dms")) primaryPaths = append(primaryPaths, filepath.Join(configHome, "quickshell", "dms"))
} }
primaryPaths = append(primaryPaths, "/usr/share/quickshell/dms") // System data directories
dataDirs := os.Getenv("XDG_DATA_DIRS")
if dataDirs == "" {
dataDirs = "/usr/local/share:/usr/share"
}
for _, dir := range strings.Split(dataDirs, ":") {
if dir != "" {
primaryPaths = append(primaryPaths, filepath.Join(dir, "quickshell", "dms"))
}
}
// System config directories (fallback)
configDirs := os.Getenv("XDG_CONFIG_DIRS") configDirs := os.Getenv("XDG_CONFIG_DIRS")
if configDirs == "" { if configDirs == "" {
configDirs = "/etc/xdg" configDirs = "/etc/xdg"

View File

@@ -64,7 +64,7 @@ func (l *FileLogger) writeToFile(message string) {
redacted := l.redactPassword(message) redacted := l.redactPassword(message)
timestamp := time.Now().Format("15:04:05.000") timestamp := time.Now().Format("15:04:05.000")
l.writer.WriteString(fmt.Sprintf("[%s] %s\n", timestamp, redacted)) //nolint:errcheck fmt.Fprintf(l.writer, "[%s] %s\n", timestamp, redacted)
l.writer.Flush() l.writer.Flush()
} }

View File

@@ -104,13 +104,13 @@ func GetLogger() *Logger {
// * Convenience wrappers // * Convenience wrappers
func Debug(msg any, keyvals ...any) { GetLogger().Logger.Debug(msg, keyvals...) } func Debug(msg any, keyvals ...any) { GetLogger().Debug(msg, keyvals...) }
func Debugf(format string, v ...any) { GetLogger().Logger.Debugf(format, v...) } func Debugf(format string, v ...any) { GetLogger().Debugf(format, v...) }
func Info(msg any, keyvals ...any) { GetLogger().Logger.Info(msg, keyvals...) } func Info(msg any, keyvals ...any) { GetLogger().Info(msg, keyvals...) }
func Infof(format string, v ...any) { GetLogger().Logger.Infof(format, v...) } func Infof(format string, v ...any) { GetLogger().Infof(format, v...) }
func Warn(msg any, keyvals ...any) { GetLogger().Logger.Warn(msg, keyvals...) } func Warn(msg any, keyvals ...any) { GetLogger().Warn(msg, keyvals...) }
func Warnf(format string, v ...any) { GetLogger().Logger.Warnf(format, v...) } func Warnf(format string, v ...any) { GetLogger().Warnf(format, v...) }
func Error(msg any, keyvals ...any) { GetLogger().Logger.Error(msg, keyvals...) } func Error(msg any, keyvals ...any) { GetLogger().Error(msg, keyvals...) }
func Errorf(format string, v ...any) { GetLogger().Logger.Errorf(format, v...) } func Errorf(format string, v ...any) { GetLogger().Errorf(format, v...) }
func Fatal(msg any, keyvals ...any) { GetLogger().Logger.Fatal(msg, keyvals...) } func Fatal(msg any, keyvals ...any) { GetLogger().Fatal(msg, keyvals...) }
func Fatalf(format string, v ...any) { GetLogger().Logger.Fatalf(format, v...) } func Fatalf(format string, v ...any) { GetLogger().Fatalf(format, v...) }

View File

@@ -141,7 +141,7 @@ type MockCUPSClientInterface_CancelAllJob_Call struct {
// CancelAllJob is a helper method to define mock.On call // CancelAllJob is a helper method to define mock.On call
// - printer string // - printer string
// - purge bool // - purge bool
func (_e *MockCUPSClientInterface_Expecter) CancelAllJob(printer any, purge any) *MockCUPSClientInterface_CancelAllJob_Call { func (_e *MockCUPSClientInterface_Expecter) CancelAllJob(printer interface{}, purge interface{}) *MockCUPSClientInterface_CancelAllJob_Call {
return &MockCUPSClientInterface_CancelAllJob_Call{Call: _e.mock.On("CancelAllJob", printer, purge)} return &MockCUPSClientInterface_CancelAllJob_Call{Call: _e.mock.On("CancelAllJob", printer, purge)}
} }
@@ -188,7 +188,7 @@ type MockCUPSClientInterface_CancelJob_Call struct {
// CancelJob is a helper method to define mock.On call // CancelJob is a helper method to define mock.On call
// - jobID int // - jobID int
// - purge bool // - purge bool
func (_e *MockCUPSClientInterface_Expecter) CancelJob(jobID any, purge any) *MockCUPSClientInterface_CancelJob_Call { func (_e *MockCUPSClientInterface_Expecter) CancelJob(jobID interface{}, purge interface{}) *MockCUPSClientInterface_CancelJob_Call {
return &MockCUPSClientInterface_CancelJob_Call{Call: _e.mock.On("CancelJob", jobID, purge)} return &MockCUPSClientInterface_CancelJob_Call{Call: _e.mock.On("CancelJob", jobID, purge)}
} }
@@ -558,7 +558,7 @@ type MockCUPSClientInterface_GetJobs_Call struct {
// - firstJobId int // - firstJobId int
// - limit int // - limit int
// - attributes []string // - attributes []string
func (_e *MockCUPSClientInterface_Expecter) GetJobs(printer any, class any, whichJobs any, myJobs any, firstJobId any, limit any, attributes any) *MockCUPSClientInterface_GetJobs_Call { func (_e *MockCUPSClientInterface_Expecter) GetJobs(printer interface{}, class interface{}, whichJobs interface{}, myJobs interface{}, firstJobId interface{}, limit interface{}, attributes interface{}) *MockCUPSClientInterface_GetJobs_Call {
return &MockCUPSClientInterface_GetJobs_Call{Call: _e.mock.On("GetJobs", printer, class, whichJobs, myJobs, firstJobId, limit, attributes)} return &MockCUPSClientInterface_GetJobs_Call{Call: _e.mock.On("GetJobs", printer, class, whichJobs, myJobs, firstJobId, limit, attributes)}
} }
@@ -673,7 +673,7 @@ type MockCUPSClientInterface_GetPrinters_Call struct {
// GetPrinters is a helper method to define mock.On call // GetPrinters is a helper method to define mock.On call
// - attributes []string // - attributes []string
func (_e *MockCUPSClientInterface_Expecter) GetPrinters(attributes any) *MockCUPSClientInterface_GetPrinters_Call { func (_e *MockCUPSClientInterface_Expecter) GetPrinters(attributes interface{}) *MockCUPSClientInterface_GetPrinters_Call {
return &MockCUPSClientInterface_GetPrinters_Call{Call: _e.mock.On("GetPrinters", attributes)} return &MockCUPSClientInterface_GetPrinters_Call{Call: _e.mock.On("GetPrinters", attributes)}
} }
@@ -813,7 +813,7 @@ type MockCUPSClientInterface_PausePrinter_Call struct {
// PausePrinter is a helper method to define mock.On call // PausePrinter is a helper method to define mock.On call
// - printer string // - printer string
func (_e *MockCUPSClientInterface_Expecter) PausePrinter(printer any) *MockCUPSClientInterface_PausePrinter_Call { func (_e *MockCUPSClientInterface_Expecter) PausePrinter(printer interface{}) *MockCUPSClientInterface_PausePrinter_Call {
return &MockCUPSClientInterface_PausePrinter_Call{Call: _e.mock.On("PausePrinter", printer)} return &MockCUPSClientInterface_PausePrinter_Call{Call: _e.mock.On("PausePrinter", printer)}
} }
@@ -1009,7 +1009,7 @@ type MockCUPSClientInterface_ResumePrinter_Call struct {
// ResumePrinter is a helper method to define mock.On call // ResumePrinter is a helper method to define mock.On call
// - printer string // - printer string
func (_e *MockCUPSClientInterface_Expecter) ResumePrinter(printer any) *MockCUPSClientInterface_ResumePrinter_Call { func (_e *MockCUPSClientInterface_Expecter) ResumePrinter(printer interface{}) *MockCUPSClientInterface_ResumePrinter_Call {
return &MockCUPSClientInterface_ResumePrinter_Call{Call: _e.mock.On("ResumePrinter", printer)} return &MockCUPSClientInterface_ResumePrinter_Call{Call: _e.mock.On("ResumePrinter", printer)}
} }
@@ -1069,7 +1069,7 @@ type MockCUPSClientInterface_SendRequest_Call struct {
// - url string // - url string
// - req *ipp.Request // - req *ipp.Request
// - additionalResponseData io.Writer // - additionalResponseData io.Writer
func (_e *MockCUPSClientInterface_Expecter) SendRequest(url any, req any, additionalResponseData any) *MockCUPSClientInterface_SendRequest_Call { func (_e *MockCUPSClientInterface_Expecter) SendRequest(url interface{}, req interface{}, additionalResponseData interface{}) *MockCUPSClientInterface_SendRequest_Call {
return &MockCUPSClientInterface_SendRequest_Call{Call: _e.mock.On("SendRequest", url, req, additionalResponseData)} return &MockCUPSClientInterface_SendRequest_Call{Call: _e.mock.On("SendRequest", url, req, additionalResponseData)}
} }

View File

@@ -259,7 +259,7 @@ type MockEvdevDevice_State_Call struct {
// State is a helper method to define mock.On call // State is a helper method to define mock.On call
// - t go_evdev.EvType // - t go_evdev.EvType
func (_e *MockEvdevDevice_Expecter) State(t any) *MockEvdevDevice_State_Call { func (_e *MockEvdevDevice_Expecter) State(t interface{}) *MockEvdevDevice_State_Call {
return &MockEvdevDevice_State_Call{Call: _e.mock.On("State", t)} return &MockEvdevDevice_State_Call{Call: _e.mock.On("State", t)}
} }
@@ -285,8 +285,7 @@ func (_c *MockEvdevDevice_State_Call) RunAndReturn(run func(go_evdev.EvType) (go
func NewMockEvdevDevice(t interface { func NewMockEvdevDevice(t interface {
mock.TestingT mock.TestingT
Cleanup(func()) Cleanup(func())
}, }) *MockEvdevDevice {
) *MockEvdevDevice {
mock := &MockEvdevDevice{} mock := &MockEvdevDevice{}
mock.Mock.Test(t) mock.Mock.Test(t)

View File

@@ -989,7 +989,7 @@ type MockActiveConnection_SubscribeState_Call struct {
// SubscribeState is a helper method to define mock.On call // SubscribeState is a helper method to define mock.On call
// - receiver chan gonetworkmanager.StateChange // - receiver chan gonetworkmanager.StateChange
// - exit chan struct{} // - exit chan struct{}
func (_e *MockActiveConnection_Expecter) SubscribeState(receiver any, exit any) *MockActiveConnection_SubscribeState_Call { func (_e *MockActiveConnection_Expecter) SubscribeState(receiver interface{}, exit interface{}) *MockActiveConnection_SubscribeState_Call {
return &MockActiveConnection_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)} return &MockActiveConnection_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)}
} }

View File

@@ -359,7 +359,7 @@ type MockConnection_GetSecrets_Call struct {
// GetSecrets is a helper method to define mock.On call // GetSecrets is a helper method to define mock.On call
// - settingName string // - settingName string
func (_e *MockConnection_Expecter) GetSecrets(settingName any) *MockConnection_GetSecrets_Call { func (_e *MockConnection_Expecter) GetSecrets(settingName interface{}) *MockConnection_GetSecrets_Call {
return &MockConnection_GetSecrets_Call{Call: _e.mock.On("GetSecrets", settingName)} return &MockConnection_GetSecrets_Call{Call: _e.mock.On("GetSecrets", settingName)}
} }
@@ -564,7 +564,7 @@ type MockConnection_Update_Call struct {
// Update is a helper method to define mock.On call // Update is a helper method to define mock.On call
// - settings gonetworkmanager.ConnectionSettings // - settings gonetworkmanager.ConnectionSettings
func (_e *MockConnection_Expecter) Update(settings any) *MockConnection_Update_Call { func (_e *MockConnection_Expecter) Update(settings interface{}) *MockConnection_Update_Call {
return &MockConnection_Update_Call{Call: _e.mock.On("Update", settings)} return &MockConnection_Update_Call{Call: _e.mock.On("Update", settings)}
} }
@@ -610,7 +610,7 @@ type MockConnection_UpdateUnsaved_Call struct {
// UpdateUnsaved is a helper method to define mock.On call // UpdateUnsaved is a helper method to define mock.On call
// - settings gonetworkmanager.ConnectionSettings // - settings gonetworkmanager.ConnectionSettings
func (_e *MockConnection_Expecter) UpdateUnsaved(settings any) *MockConnection_UpdateUnsaved_Call { func (_e *MockConnection_Expecter) UpdateUnsaved(settings interface{}) *MockConnection_UpdateUnsaved_Call {
return &MockConnection_UpdateUnsaved_Call{Call: _e.mock.On("UpdateUnsaved", settings)} return &MockConnection_UpdateUnsaved_Call{Call: _e.mock.On("UpdateUnsaved", settings)}
} }

View File

@@ -1463,7 +1463,7 @@ type MockDevice_Reapply_Call struct {
// - connection gonetworkmanager.Connection // - connection gonetworkmanager.Connection
// - versionId uint64 // - versionId uint64
// - flags uint32 // - flags uint32
func (_e *MockDevice_Expecter) Reapply(connection any, versionId any, flags any) *MockDevice_Reapply_Call { func (_e *MockDevice_Expecter) Reapply(connection interface{}, versionId interface{}, flags interface{}) *MockDevice_Reapply_Call {
return &MockDevice_Reapply_Call{Call: _e.mock.On("Reapply", connection, versionId, flags)} return &MockDevice_Reapply_Call{Call: _e.mock.On("Reapply", connection, versionId, flags)}
} }
@@ -1509,7 +1509,7 @@ type MockDevice_SetPropertyAutoConnect_Call struct {
// SetPropertyAutoConnect is a helper method to define mock.On call // SetPropertyAutoConnect is a helper method to define mock.On call
// - _a0 bool // - _a0 bool
func (_e *MockDevice_Expecter) SetPropertyAutoConnect(_a0 any) *MockDevice_SetPropertyAutoConnect_Call { func (_e *MockDevice_Expecter) SetPropertyAutoConnect(_a0 interface{}) *MockDevice_SetPropertyAutoConnect_Call {
return &MockDevice_SetPropertyAutoConnect_Call{Call: _e.mock.On("SetPropertyAutoConnect", _a0)} return &MockDevice_SetPropertyAutoConnect_Call{Call: _e.mock.On("SetPropertyAutoConnect", _a0)}
} }
@@ -1555,7 +1555,7 @@ type MockDevice_SetPropertyManaged_Call struct {
// SetPropertyManaged is a helper method to define mock.On call // SetPropertyManaged is a helper method to define mock.On call
// - _a0 bool // - _a0 bool
func (_e *MockDevice_Expecter) SetPropertyManaged(_a0 any) *MockDevice_SetPropertyManaged_Call { func (_e *MockDevice_Expecter) SetPropertyManaged(_a0 interface{}) *MockDevice_SetPropertyManaged_Call {
return &MockDevice_SetPropertyManaged_Call{Call: _e.mock.On("SetPropertyManaged", _a0)} return &MockDevice_SetPropertyManaged_Call{Call: _e.mock.On("SetPropertyManaged", _a0)}
} }
@@ -1602,7 +1602,7 @@ type MockDevice_SubscribeState_Call struct {
// SubscribeState is a helper method to define mock.On call // SubscribeState is a helper method to define mock.On call
// - receiver chan gonetworkmanager.DeviceStateChange // - receiver chan gonetworkmanager.DeviceStateChange
// - exit chan struct{} // - exit chan struct{}
func (_e *MockDevice_Expecter) SubscribeState(receiver any, exit any) *MockDevice_SubscribeState_Call { func (_e *MockDevice_Expecter) SubscribeState(receiver interface{}, exit interface{}) *MockDevice_SubscribeState_Call {
return &MockDevice_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)} return &MockDevice_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)}
} }

View File

@@ -2021,7 +2021,7 @@ type MockDeviceWireless_Reapply_Call struct {
// - connection gonetworkmanager.Connection // - connection gonetworkmanager.Connection
// - versionId uint64 // - versionId uint64
// - flags uint32 // - flags uint32
func (_e *MockDeviceWireless_Expecter) Reapply(connection any, versionId any, flags any) *MockDeviceWireless_Reapply_Call { func (_e *MockDeviceWireless_Expecter) Reapply(connection interface{}, versionId interface{}, flags interface{}) *MockDeviceWireless_Reapply_Call {
return &MockDeviceWireless_Reapply_Call{Call: _e.mock.On("Reapply", connection, versionId, flags)} return &MockDeviceWireless_Reapply_Call{Call: _e.mock.On("Reapply", connection, versionId, flags)}
} }
@@ -2112,7 +2112,7 @@ type MockDeviceWireless_SetPropertyAutoConnect_Call struct {
// SetPropertyAutoConnect is a helper method to define mock.On call // SetPropertyAutoConnect is a helper method to define mock.On call
// - _a0 bool // - _a0 bool
func (_e *MockDeviceWireless_Expecter) SetPropertyAutoConnect(_a0 any) *MockDeviceWireless_SetPropertyAutoConnect_Call { func (_e *MockDeviceWireless_Expecter) SetPropertyAutoConnect(_a0 interface{}) *MockDeviceWireless_SetPropertyAutoConnect_Call {
return &MockDeviceWireless_SetPropertyAutoConnect_Call{Call: _e.mock.On("SetPropertyAutoConnect", _a0)} return &MockDeviceWireless_SetPropertyAutoConnect_Call{Call: _e.mock.On("SetPropertyAutoConnect", _a0)}
} }
@@ -2158,7 +2158,7 @@ type MockDeviceWireless_SetPropertyManaged_Call struct {
// SetPropertyManaged is a helper method to define mock.On call // SetPropertyManaged is a helper method to define mock.On call
// - _a0 bool // - _a0 bool
func (_e *MockDeviceWireless_Expecter) SetPropertyManaged(_a0 any) *MockDeviceWireless_SetPropertyManaged_Call { func (_e *MockDeviceWireless_Expecter) SetPropertyManaged(_a0 interface{}) *MockDeviceWireless_SetPropertyManaged_Call {
return &MockDeviceWireless_SetPropertyManaged_Call{Call: _e.mock.On("SetPropertyManaged", _a0)} return &MockDeviceWireless_SetPropertyManaged_Call{Call: _e.mock.On("SetPropertyManaged", _a0)}
} }
@@ -2205,7 +2205,7 @@ type MockDeviceWireless_SubscribeState_Call struct {
// SubscribeState is a helper method to define mock.On call // SubscribeState is a helper method to define mock.On call
// - receiver chan gonetworkmanager.DeviceStateChange // - receiver chan gonetworkmanager.DeviceStateChange
// - exit chan struct{} // - exit chan struct{}
func (_e *MockDeviceWireless_Expecter) SubscribeState(receiver any, exit any) *MockDeviceWireless_SubscribeState_Call { func (_e *MockDeviceWireless_Expecter) SubscribeState(receiver interface{}, exit interface{}) *MockDeviceWireless_SubscribeState_Call {
return &MockDeviceWireless_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)} return &MockDeviceWireless_SubscribeState_Call{Call: _e.mock.On("SubscribeState", receiver, exit)}
} }

View File

@@ -61,7 +61,7 @@ type MockNetworkManager_ActivateConnection_Call struct {
// - connection gonetworkmanager.Connection // - connection gonetworkmanager.Connection
// - device gonetworkmanager.Device // - device gonetworkmanager.Device
// - specificObject *dbus.Object // - specificObject *dbus.Object
func (_e *MockNetworkManager_Expecter) ActivateConnection(connection any, device any, specificObject any) *MockNetworkManager_ActivateConnection_Call { func (_e *MockNetworkManager_Expecter) ActivateConnection(connection interface{}, device interface{}, specificObject interface{}) *MockNetworkManager_ActivateConnection_Call {
return &MockNetworkManager_ActivateConnection_Call{Call: _e.mock.On("ActivateConnection", connection, device, specificObject)} return &MockNetworkManager_ActivateConnection_Call{Call: _e.mock.On("ActivateConnection", connection, device, specificObject)}
} }
@@ -121,7 +121,7 @@ type MockNetworkManager_ActivateWirelessConnection_Call struct {
// - connection gonetworkmanager.Connection // - connection gonetworkmanager.Connection
// - device gonetworkmanager.Device // - device gonetworkmanager.Device
// - accessPoint gonetworkmanager.AccessPoint // - accessPoint gonetworkmanager.AccessPoint
func (_e *MockNetworkManager_Expecter) ActivateWirelessConnection(connection any, device any, accessPoint any) *MockNetworkManager_ActivateWirelessConnection_Call { func (_e *MockNetworkManager_Expecter) ActivateWirelessConnection(connection interface{}, device interface{}, accessPoint interface{}) *MockNetworkManager_ActivateWirelessConnection_Call {
return &MockNetworkManager_ActivateWirelessConnection_Call{Call: _e.mock.On("ActivateWirelessConnection", connection, device, accessPoint)} return &MockNetworkManager_ActivateWirelessConnection_Call{Call: _e.mock.On("ActivateWirelessConnection", connection, device, accessPoint)}
} }
@@ -143,7 +143,7 @@ func (_c *MockNetworkManager_ActivateWirelessConnection_Call) RunAndReturn(run f
} }
// AddAndActivateConnection provides a mock function with given fields: connection, device // AddAndActivateConnection provides a mock function with given fields: connection, device
func (_m *MockNetworkManager) AddAndActivateConnection(connection map[string]map[string]any, device gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error) { func (_m *MockNetworkManager) AddAndActivateConnection(connection map[string]map[string]interface{}, device gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error) {
ret := _m.Called(connection, device) ret := _m.Called(connection, device)
if len(ret) == 0 { if len(ret) == 0 {
@@ -152,10 +152,10 @@ func (_m *MockNetworkManager) AddAndActivateConnection(connection map[string]map
var r0 gonetworkmanager.ActiveConnection var r0 gonetworkmanager.ActiveConnection
var r1 error var r1 error
if rf, ok := ret.Get(0).(func(map[string]map[string]any, gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error)); ok { if rf, ok := ret.Get(0).(func(map[string]map[string]interface{}, gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error)); ok {
return rf(connection, device) return rf(connection, device)
} }
if rf, ok := ret.Get(0).(func(map[string]map[string]any, gonetworkmanager.Device) gonetworkmanager.ActiveConnection); ok { if rf, ok := ret.Get(0).(func(map[string]map[string]interface{}, gonetworkmanager.Device) gonetworkmanager.ActiveConnection); ok {
r0 = rf(connection, device) r0 = rf(connection, device)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -163,7 +163,7 @@ func (_m *MockNetworkManager) AddAndActivateConnection(connection map[string]map
} }
} }
if rf, ok := ret.Get(1).(func(map[string]map[string]any, gonetworkmanager.Device) error); ok { if rf, ok := ret.Get(1).(func(map[string]map[string]interface{}, gonetworkmanager.Device) error); ok {
r1 = rf(connection, device) r1 = rf(connection, device)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
@@ -178,15 +178,15 @@ type MockNetworkManager_AddAndActivateConnection_Call struct {
} }
// AddAndActivateConnection is a helper method to define mock.On call // AddAndActivateConnection is a helper method to define mock.On call
// - connection map[string]map[string]any // - connection map[string]map[string]interface{}
// - device gonetworkmanager.Device // - device gonetworkmanager.Device
func (_e *MockNetworkManager_Expecter) AddAndActivateConnection(connection any, device any) *MockNetworkManager_AddAndActivateConnection_Call { func (_e *MockNetworkManager_Expecter) AddAndActivateConnection(connection interface{}, device interface{}) *MockNetworkManager_AddAndActivateConnection_Call {
return &MockNetworkManager_AddAndActivateConnection_Call{Call: _e.mock.On("AddAndActivateConnection", connection, device)} return &MockNetworkManager_AddAndActivateConnection_Call{Call: _e.mock.On("AddAndActivateConnection", connection, device)}
} }
func (_c *MockNetworkManager_AddAndActivateConnection_Call) Run(run func(connection map[string]map[string]any, device gonetworkmanager.Device)) *MockNetworkManager_AddAndActivateConnection_Call { func (_c *MockNetworkManager_AddAndActivateConnection_Call) Run(run func(connection map[string]map[string]interface{}, device gonetworkmanager.Device)) *MockNetworkManager_AddAndActivateConnection_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
run(args[0].(map[string]map[string]any), args[1].(gonetworkmanager.Device)) run(args[0].(map[string]map[string]interface{}), args[1].(gonetworkmanager.Device))
}) })
return _c return _c
} }
@@ -196,13 +196,13 @@ func (_c *MockNetworkManager_AddAndActivateConnection_Call) Return(_a0 gonetwork
return _c return _c
} }
func (_c *MockNetworkManager_AddAndActivateConnection_Call) RunAndReturn(run func(map[string]map[string]any, gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error)) *MockNetworkManager_AddAndActivateConnection_Call { func (_c *MockNetworkManager_AddAndActivateConnection_Call) RunAndReturn(run func(map[string]map[string]interface{}, gonetworkmanager.Device) (gonetworkmanager.ActiveConnection, error)) *MockNetworkManager_AddAndActivateConnection_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
// AddAndActivateWirelessConnection provides a mock function with given fields: connection, device, accessPoint // AddAndActivateWirelessConnection provides a mock function with given fields: connection, device, accessPoint
func (_m *MockNetworkManager) AddAndActivateWirelessConnection(connection map[string]map[string]any, device gonetworkmanager.Device, accessPoint gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error) { func (_m *MockNetworkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device gonetworkmanager.Device, accessPoint gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error) {
ret := _m.Called(connection, device, accessPoint) ret := _m.Called(connection, device, accessPoint)
if len(ret) == 0 { if len(ret) == 0 {
@@ -211,10 +211,10 @@ func (_m *MockNetworkManager) AddAndActivateWirelessConnection(connection map[st
var r0 gonetworkmanager.ActiveConnection var r0 gonetworkmanager.ActiveConnection
var r1 error var r1 error
if rf, ok := ret.Get(0).(func(map[string]map[string]any, gonetworkmanager.Device, gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error)); ok { if rf, ok := ret.Get(0).(func(map[string]map[string]interface{}, gonetworkmanager.Device, gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error)); ok {
return rf(connection, device, accessPoint) return rf(connection, device, accessPoint)
} }
if rf, ok := ret.Get(0).(func(map[string]map[string]any, gonetworkmanager.Device, gonetworkmanager.AccessPoint) gonetworkmanager.ActiveConnection); ok { if rf, ok := ret.Get(0).(func(map[string]map[string]interface{}, gonetworkmanager.Device, gonetworkmanager.AccessPoint) gonetworkmanager.ActiveConnection); ok {
r0 = rf(connection, device, accessPoint) r0 = rf(connection, device, accessPoint)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -222,7 +222,7 @@ func (_m *MockNetworkManager) AddAndActivateWirelessConnection(connection map[st
} }
} }
if rf, ok := ret.Get(1).(func(map[string]map[string]any, gonetworkmanager.Device, gonetworkmanager.AccessPoint) error); ok { if rf, ok := ret.Get(1).(func(map[string]map[string]interface{}, gonetworkmanager.Device, gonetworkmanager.AccessPoint) error); ok {
r1 = rf(connection, device, accessPoint) r1 = rf(connection, device, accessPoint)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
@@ -237,16 +237,16 @@ type MockNetworkManager_AddAndActivateWirelessConnection_Call struct {
} }
// AddAndActivateWirelessConnection is a helper method to define mock.On call // AddAndActivateWirelessConnection is a helper method to define mock.On call
// - connection map[string]map[string]any // - connection map[string]map[string]interface{}
// - device gonetworkmanager.Device // - device gonetworkmanager.Device
// - accessPoint gonetworkmanager.AccessPoint // - accessPoint gonetworkmanager.AccessPoint
func (_e *MockNetworkManager_Expecter) AddAndActivateWirelessConnection(connection any, device any, accessPoint any) *MockNetworkManager_AddAndActivateWirelessConnection_Call { func (_e *MockNetworkManager_Expecter) AddAndActivateWirelessConnection(connection interface{}, device interface{}, accessPoint interface{}) *MockNetworkManager_AddAndActivateWirelessConnection_Call {
return &MockNetworkManager_AddAndActivateWirelessConnection_Call{Call: _e.mock.On("AddAndActivateWirelessConnection", connection, device, accessPoint)} return &MockNetworkManager_AddAndActivateWirelessConnection_Call{Call: _e.mock.On("AddAndActivateWirelessConnection", connection, device, accessPoint)}
} }
func (_c *MockNetworkManager_AddAndActivateWirelessConnection_Call) Run(run func(connection map[string]map[string]any, device gonetworkmanager.Device, accessPoint gonetworkmanager.AccessPoint)) *MockNetworkManager_AddAndActivateWirelessConnection_Call { func (_c *MockNetworkManager_AddAndActivateWirelessConnection_Call) Run(run func(connection map[string]map[string]interface{}, device gonetworkmanager.Device, accessPoint gonetworkmanager.AccessPoint)) *MockNetworkManager_AddAndActivateWirelessConnection_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
run(args[0].(map[string]map[string]any), args[1].(gonetworkmanager.Device), args[2].(gonetworkmanager.AccessPoint)) run(args[0].(map[string]map[string]interface{}), args[1].(gonetworkmanager.Device), args[2].(gonetworkmanager.AccessPoint))
}) })
return _c return _c
} }
@@ -256,7 +256,7 @@ func (_c *MockNetworkManager_AddAndActivateWirelessConnection_Call) Return(_a0 g
return _c return _c
} }
func (_c *MockNetworkManager_AddAndActivateWirelessConnection_Call) RunAndReturn(run func(map[string]map[string]any, gonetworkmanager.Device, gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error)) *MockNetworkManager_AddAndActivateWirelessConnection_Call { func (_c *MockNetworkManager_AddAndActivateWirelessConnection_Call) RunAndReturn(run func(map[string]map[string]interface{}, gonetworkmanager.Device, gonetworkmanager.AccessPoint) (gonetworkmanager.ActiveConnection, error)) *MockNetworkManager_AddAndActivateWirelessConnection_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
@@ -332,7 +332,7 @@ type MockNetworkManager_CheckpointAdjustRollbackTimeout_Call struct {
// CheckpointAdjustRollbackTimeout is a helper method to define mock.On call // CheckpointAdjustRollbackTimeout is a helper method to define mock.On call
// - checkpoint gonetworkmanager.Checkpoint // - checkpoint gonetworkmanager.Checkpoint
// - addTimeout uint32 // - addTimeout uint32
func (_e *MockNetworkManager_Expecter) CheckpointAdjustRollbackTimeout(checkpoint any, addTimeout any) *MockNetworkManager_CheckpointAdjustRollbackTimeout_Call { func (_e *MockNetworkManager_Expecter) CheckpointAdjustRollbackTimeout(checkpoint interface{}, addTimeout interface{}) *MockNetworkManager_CheckpointAdjustRollbackTimeout_Call {
return &MockNetworkManager_CheckpointAdjustRollbackTimeout_Call{Call: _e.mock.On("CheckpointAdjustRollbackTimeout", checkpoint, addTimeout)} return &MockNetworkManager_CheckpointAdjustRollbackTimeout_Call{Call: _e.mock.On("CheckpointAdjustRollbackTimeout", checkpoint, addTimeout)}
} }
@@ -392,7 +392,7 @@ type MockNetworkManager_CheckpointCreate_Call struct {
// - devices []gonetworkmanager.Device // - devices []gonetworkmanager.Device
// - rollbackTimeout uint32 // - rollbackTimeout uint32
// - flags uint32 // - flags uint32
func (_e *MockNetworkManager_Expecter) CheckpointCreate(devices any, rollbackTimeout any, flags any) *MockNetworkManager_CheckpointCreate_Call { func (_e *MockNetworkManager_Expecter) CheckpointCreate(devices interface{}, rollbackTimeout interface{}, flags interface{}) *MockNetworkManager_CheckpointCreate_Call {
return &MockNetworkManager_CheckpointCreate_Call{Call: _e.mock.On("CheckpointCreate", devices, rollbackTimeout, flags)} return &MockNetworkManager_CheckpointCreate_Call{Call: _e.mock.On("CheckpointCreate", devices, rollbackTimeout, flags)}
} }
@@ -438,7 +438,7 @@ type MockNetworkManager_CheckpointDestroy_Call struct {
// CheckpointDestroy is a helper method to define mock.On call // CheckpointDestroy is a helper method to define mock.On call
// - checkpoint gonetworkmanager.Checkpoint // - checkpoint gonetworkmanager.Checkpoint
func (_e *MockNetworkManager_Expecter) CheckpointDestroy(checkpoint any) *MockNetworkManager_CheckpointDestroy_Call { func (_e *MockNetworkManager_Expecter) CheckpointDestroy(checkpoint interface{}) *MockNetworkManager_CheckpointDestroy_Call {
return &MockNetworkManager_CheckpointDestroy_Call{Call: _e.mock.On("CheckpointDestroy", checkpoint)} return &MockNetworkManager_CheckpointDestroy_Call{Call: _e.mock.On("CheckpointDestroy", checkpoint)}
} }
@@ -496,7 +496,7 @@ type MockNetworkManager_CheckpointRollback_Call struct {
// CheckpointRollback is a helper method to define mock.On call // CheckpointRollback is a helper method to define mock.On call
// - checkpoint gonetworkmanager.Checkpoint // - checkpoint gonetworkmanager.Checkpoint
func (_e *MockNetworkManager_Expecter) CheckpointRollback(checkpoint any) *MockNetworkManager_CheckpointRollback_Call { func (_e *MockNetworkManager_Expecter) CheckpointRollback(checkpoint interface{}) *MockNetworkManager_CheckpointRollback_Call {
return &MockNetworkManager_CheckpointRollback_Call{Call: _e.mock.On("CheckpointRollback", checkpoint)} return &MockNetworkManager_CheckpointRollback_Call{Call: _e.mock.On("CheckpointRollback", checkpoint)}
} }
@@ -542,7 +542,7 @@ type MockNetworkManager_DeactivateConnection_Call struct {
// DeactivateConnection is a helper method to define mock.On call // DeactivateConnection is a helper method to define mock.On call
// - connection gonetworkmanager.ActiveConnection // - connection gonetworkmanager.ActiveConnection
func (_e *MockNetworkManager_Expecter) DeactivateConnection(connection any) *MockNetworkManager_DeactivateConnection_Call { func (_e *MockNetworkManager_Expecter) DeactivateConnection(connection interface{}) *MockNetworkManager_DeactivateConnection_Call {
return &MockNetworkManager_DeactivateConnection_Call{Call: _e.mock.On("DeactivateConnection", connection)} return &MockNetworkManager_DeactivateConnection_Call{Call: _e.mock.On("DeactivateConnection", connection)}
} }
@@ -588,7 +588,7 @@ type MockNetworkManager_Enable_Call struct {
// Enable is a helper method to define mock.On call // Enable is a helper method to define mock.On call
// - enableNDisable bool // - enableNDisable bool
func (_e *MockNetworkManager_Expecter) Enable(enableNDisable any) *MockNetworkManager_Enable_Call { func (_e *MockNetworkManager_Expecter) Enable(enableNDisable interface{}) *MockNetworkManager_Enable_Call {
return &MockNetworkManager_Enable_Call{Call: _e.mock.On("Enable", enableNDisable)} return &MockNetworkManager_Enable_Call{Call: _e.mock.On("Enable", enableNDisable)}
} }
@@ -703,7 +703,7 @@ type MockNetworkManager_GetDeviceByIpIface_Call struct {
// GetDeviceByIpIface is a helper method to define mock.On call // GetDeviceByIpIface is a helper method to define mock.On call
// - interfaceId string // - interfaceId string
func (_e *MockNetworkManager_Expecter) GetDeviceByIpIface(interfaceId any) *MockNetworkManager_GetDeviceByIpIface_Call { func (_e *MockNetworkManager_Expecter) GetDeviceByIpIface(interfaceId interface{}) *MockNetworkManager_GetDeviceByIpIface_Call {
return &MockNetworkManager_GetDeviceByIpIface_Call{Call: _e.mock.On("GetDeviceByIpIface", interfaceId)} return &MockNetworkManager_GetDeviceByIpIface_Call{Call: _e.mock.On("GetDeviceByIpIface", interfaceId)}
} }
@@ -2087,7 +2087,7 @@ type MockNetworkManager_Reload_Call struct {
// Reload is a helper method to define mock.On call // Reload is a helper method to define mock.On call
// - flags uint32 // - flags uint32
func (_e *MockNetworkManager_Expecter) Reload(flags any) *MockNetworkManager_Reload_Call { func (_e *MockNetworkManager_Expecter) Reload(flags interface{}) *MockNetworkManager_Reload_Call {
return &MockNetworkManager_Reload_Call{Call: _e.mock.On("Reload", flags)} return &MockNetworkManager_Reload_Call{Call: _e.mock.On("Reload", flags)}
} }
@@ -2133,7 +2133,7 @@ type MockNetworkManager_SetPropertyWirelessEnabled_Call struct {
// SetPropertyWirelessEnabled is a helper method to define mock.On call // SetPropertyWirelessEnabled is a helper method to define mock.On call
// - _a0 bool // - _a0 bool
func (_e *MockNetworkManager_Expecter) SetPropertyWirelessEnabled(_a0 any) *MockNetworkManager_SetPropertyWirelessEnabled_Call { func (_e *MockNetworkManager_Expecter) SetPropertyWirelessEnabled(_a0 interface{}) *MockNetworkManager_SetPropertyWirelessEnabled_Call {
return &MockNetworkManager_SetPropertyWirelessEnabled_Call{Call: _e.mock.On("SetPropertyWirelessEnabled", _a0)} return &MockNetworkManager_SetPropertyWirelessEnabled_Call{Call: _e.mock.On("SetPropertyWirelessEnabled", _a0)}
} }
@@ -2179,7 +2179,7 @@ type MockNetworkManager_Sleep_Call struct {
// Sleep is a helper method to define mock.On call // Sleep is a helper method to define mock.On call
// - sleepNWake bool // - sleepNWake bool
func (_e *MockNetworkManager_Expecter) Sleep(sleepNWake any) *MockNetworkManager_Sleep_Call { func (_e *MockNetworkManager_Expecter) Sleep(sleepNWake interface{}) *MockNetworkManager_Sleep_Call {
return &MockNetworkManager_Sleep_Call{Call: _e.mock.On("Sleep", sleepNWake)} return &MockNetworkManager_Sleep_Call{Call: _e.mock.On("Sleep", sleepNWake)}
} }

View File

@@ -57,7 +57,7 @@ type MockSettings_AddConnection_Call struct {
// AddConnection is a helper method to define mock.On call // AddConnection is a helper method to define mock.On call
// - settings gonetworkmanager.ConnectionSettings // - settings gonetworkmanager.ConnectionSettings
func (_e *MockSettings_Expecter) AddConnection(settings any) *MockSettings_AddConnection_Call { func (_e *MockSettings_Expecter) AddConnection(settings interface{}) *MockSettings_AddConnection_Call {
return &MockSettings_AddConnection_Call{Call: _e.mock.On("AddConnection", settings)} return &MockSettings_AddConnection_Call{Call: _e.mock.On("AddConnection", settings)}
} }
@@ -115,7 +115,7 @@ type MockSettings_AddConnectionUnsaved_Call struct {
// AddConnectionUnsaved is a helper method to define mock.On call // AddConnectionUnsaved is a helper method to define mock.On call
// - settings gonetworkmanager.ConnectionSettings // - settings gonetworkmanager.ConnectionSettings
func (_e *MockSettings_Expecter) AddConnectionUnsaved(settings any) *MockSettings_AddConnectionUnsaved_Call { func (_e *MockSettings_Expecter) AddConnectionUnsaved(settings interface{}) *MockSettings_AddConnectionUnsaved_Call {
return &MockSettings_AddConnectionUnsaved_Call{Call: _e.mock.On("AddConnectionUnsaved", settings)} return &MockSettings_AddConnectionUnsaved_Call{Call: _e.mock.On("AddConnectionUnsaved", settings)}
} }
@@ -173,7 +173,7 @@ type MockSettings_GetConnectionByUUID_Call struct {
// GetConnectionByUUID is a helper method to define mock.On call // GetConnectionByUUID is a helper method to define mock.On call
// - uuid string // - uuid string
func (_e *MockSettings_Expecter) GetConnectionByUUID(uuid any) *MockSettings_GetConnectionByUUID_Call { func (_e *MockSettings_Expecter) GetConnectionByUUID(uuid interface{}) *MockSettings_GetConnectionByUUID_Call {
return &MockSettings_GetConnectionByUUID_Call{Call: _e.mock.On("GetConnectionByUUID", uuid)} return &MockSettings_GetConnectionByUUID_Call{Call: _e.mock.On("GetConnectionByUUID", uuid)}
} }
@@ -431,7 +431,7 @@ type MockSettings_SaveHostname_Call struct {
// SaveHostname is a helper method to define mock.On call // SaveHostname is a helper method to define mock.On call
// - hostname string // - hostname string
func (_e *MockSettings_Expecter) SaveHostname(hostname any) *MockSettings_SaveHostname_Call { func (_e *MockSettings_Expecter) SaveHostname(hostname interface{}) *MockSettings_SaveHostname_Call {
return &MockSettings_SaveHostname_Call{Call: _e.mock.On("SaveHostname", hostname)} return &MockSettings_SaveHostname_Call{Call: _e.mock.On("SaveHostname", hostname)}
} }

View File

@@ -24,11 +24,11 @@ func (_m *MockBusObject) EXPECT() *MockBusObject_Expecter {
// AddMatchSignal provides a mock function with given fields: iface, member, options // AddMatchSignal provides a mock function with given fields: iface, member, options
func (_m *MockBusObject) AddMatchSignal(iface string, member string, options ...dbus.MatchOption) *dbus.Call { func (_m *MockBusObject) AddMatchSignal(iface string, member string, options ...dbus.MatchOption) *dbus.Call {
_va := make([]any, len(options)) _va := make([]interface{}, len(options))
for _i := range options { for _i := range options {
_va[_i] = options[_i] _va[_i] = options[_i]
} }
var _ca []any var _ca []interface{}
_ca = append(_ca, iface, member) _ca = append(_ca, iface, member)
_ca = append(_ca, _va...) _ca = append(_ca, _va...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -58,9 +58,9 @@ type MockBusObject_AddMatchSignal_Call struct {
// - iface string // - iface string
// - member string // - member string
// - options ...dbus.MatchOption // - options ...dbus.MatchOption
func (_e *MockBusObject_Expecter) AddMatchSignal(iface any, member any, options ...any) *MockBusObject_AddMatchSignal_Call { func (_e *MockBusObject_Expecter) AddMatchSignal(iface interface{}, member interface{}, options ...interface{}) *MockBusObject_AddMatchSignal_Call {
return &MockBusObject_AddMatchSignal_Call{Call: _e.mock.On("AddMatchSignal", return &MockBusObject_AddMatchSignal_Call{Call: _e.mock.On("AddMatchSignal",
append([]any{iface, member}, options...)...)} append([]interface{}{iface, member}, options...)...)}
} }
func (_c *MockBusObject_AddMatchSignal_Call) Run(run func(iface string, member string, options ...dbus.MatchOption)) *MockBusObject_AddMatchSignal_Call { func (_c *MockBusObject_AddMatchSignal_Call) Run(run func(iface string, member string, options ...dbus.MatchOption)) *MockBusObject_AddMatchSignal_Call {
@@ -87,8 +87,8 @@ func (_c *MockBusObject_AddMatchSignal_Call) RunAndReturn(run func(string, strin
} }
// Call provides a mock function with given fields: method, flags, args // Call provides a mock function with given fields: method, flags, args
func (_m *MockBusObject) Call(method string, flags dbus.Flags, args ...any) *dbus.Call { func (_m *MockBusObject) Call(method string, flags dbus.Flags, args ...interface{}) *dbus.Call {
var _ca []any var _ca []interface{}
_ca = append(_ca, method, flags) _ca = append(_ca, method, flags)
_ca = append(_ca, args...) _ca = append(_ca, args...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -98,7 +98,7 @@ func (_m *MockBusObject) Call(method string, flags dbus.Flags, args ...any) *dbu
} }
var r0 *dbus.Call var r0 *dbus.Call
if rf, ok := ret.Get(0).(func(string, dbus.Flags, ...any) *dbus.Call); ok { if rf, ok := ret.Get(0).(func(string, dbus.Flags, ...interface{}) *dbus.Call); ok {
r0 = rf(method, flags, args...) r0 = rf(method, flags, args...)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -117,18 +117,18 @@ type MockBusObject_Call_Call struct {
// Call is a helper method to define mock.On call // Call is a helper method to define mock.On call
// - method string // - method string
// - flags dbus.Flags // - flags dbus.Flags
// - args ...any // - args ...interface{}
func (_e *MockBusObject_Expecter) Call(method any, flags any, args ...any) *MockBusObject_Call_Call { func (_e *MockBusObject_Expecter) Call(method interface{}, flags interface{}, args ...interface{}) *MockBusObject_Call_Call {
return &MockBusObject_Call_Call{Call: _e.mock.On("Call", return &MockBusObject_Call_Call{Call: _e.mock.On("Call",
append([]any{method, flags}, args...)...)} append([]interface{}{method, flags}, args...)...)}
} }
func (_c *MockBusObject_Call_Call) Run(run func(method string, flags dbus.Flags, args ...any)) *MockBusObject_Call_Call { func (_c *MockBusObject_Call_Call) Run(run func(method string, flags dbus.Flags, args ...interface{})) *MockBusObject_Call_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]any, len(args)-2) variadicArgs := make([]interface{}, len(args)-2)
for i, a := range args[2:] { for i, a := range args[2:] {
if a != nil { if a != nil {
variadicArgs[i] = a.(any) variadicArgs[i] = a.(interface{})
} }
} }
run(args[0].(string), args[1].(dbus.Flags), variadicArgs...) run(args[0].(string), args[1].(dbus.Flags), variadicArgs...)
@@ -141,14 +141,14 @@ func (_c *MockBusObject_Call_Call) Return(_a0 *dbus.Call) *MockBusObject_Call_Ca
return _c return _c
} }
func (_c *MockBusObject_Call_Call) RunAndReturn(run func(string, dbus.Flags, ...any) *dbus.Call) *MockBusObject_Call_Call { func (_c *MockBusObject_Call_Call) RunAndReturn(run func(string, dbus.Flags, ...interface{}) *dbus.Call) *MockBusObject_Call_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
// CallWithContext provides a mock function with given fields: ctx, method, flags, args // CallWithContext provides a mock function with given fields: ctx, method, flags, args
func (_m *MockBusObject) CallWithContext(ctx context.Context, method string, flags dbus.Flags, args ...any) *dbus.Call { func (_m *MockBusObject) CallWithContext(ctx context.Context, method string, flags dbus.Flags, args ...interface{}) *dbus.Call {
var _ca []any var _ca []interface{}
_ca = append(_ca, ctx, method, flags) _ca = append(_ca, ctx, method, flags)
_ca = append(_ca, args...) _ca = append(_ca, args...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -158,7 +158,7 @@ func (_m *MockBusObject) CallWithContext(ctx context.Context, method string, fla
} }
var r0 *dbus.Call var r0 *dbus.Call
if rf, ok := ret.Get(0).(func(context.Context, string, dbus.Flags, ...any) *dbus.Call); ok { if rf, ok := ret.Get(0).(func(context.Context, string, dbus.Flags, ...interface{}) *dbus.Call); ok {
r0 = rf(ctx, method, flags, args...) r0 = rf(ctx, method, flags, args...)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -178,18 +178,18 @@ type MockBusObject_CallWithContext_Call struct {
// - ctx context.Context // - ctx context.Context
// - method string // - method string
// - flags dbus.Flags // - flags dbus.Flags
// - args ...any // - args ...interface{}
func (_e *MockBusObject_Expecter) CallWithContext(ctx any, method any, flags any, args ...any) *MockBusObject_CallWithContext_Call { func (_e *MockBusObject_Expecter) CallWithContext(ctx interface{}, method interface{}, flags interface{}, args ...interface{}) *MockBusObject_CallWithContext_Call {
return &MockBusObject_CallWithContext_Call{Call: _e.mock.On("CallWithContext", return &MockBusObject_CallWithContext_Call{Call: _e.mock.On("CallWithContext",
append([]any{ctx, method, flags}, args...)...)} append([]interface{}{ctx, method, flags}, args...)...)}
} }
func (_c *MockBusObject_CallWithContext_Call) Run(run func(ctx context.Context, method string, flags dbus.Flags, args ...any)) *MockBusObject_CallWithContext_Call { func (_c *MockBusObject_CallWithContext_Call) Run(run func(ctx context.Context, method string, flags dbus.Flags, args ...interface{})) *MockBusObject_CallWithContext_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]any, len(args)-3) variadicArgs := make([]interface{}, len(args)-3)
for i, a := range args[3:] { for i, a := range args[3:] {
if a != nil { if a != nil {
variadicArgs[i] = a.(any) variadicArgs[i] = a.(interface{})
} }
} }
run(args[0].(context.Context), args[1].(string), args[2].(dbus.Flags), variadicArgs...) run(args[0].(context.Context), args[1].(string), args[2].(dbus.Flags), variadicArgs...)
@@ -202,7 +202,7 @@ func (_c *MockBusObject_CallWithContext_Call) Return(_a0 *dbus.Call) *MockBusObj
return _c return _c
} }
func (_c *MockBusObject_CallWithContext_Call) RunAndReturn(run func(context.Context, string, dbus.Flags, ...any) *dbus.Call) *MockBusObject_CallWithContext_Call { func (_c *MockBusObject_CallWithContext_Call) RunAndReturn(run func(context.Context, string, dbus.Flags, ...interface{}) *dbus.Call) *MockBusObject_CallWithContext_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
@@ -287,7 +287,7 @@ type MockBusObject_GetProperty_Call struct {
// GetProperty is a helper method to define mock.On call // GetProperty is a helper method to define mock.On call
// - p string // - p string
func (_e *MockBusObject_Expecter) GetProperty(p any) *MockBusObject_GetProperty_Call { func (_e *MockBusObject_Expecter) GetProperty(p interface{}) *MockBusObject_GetProperty_Call {
return &MockBusObject_GetProperty_Call{Call: _e.mock.On("GetProperty", p)} return &MockBusObject_GetProperty_Call{Call: _e.mock.On("GetProperty", p)}
} }
@@ -309,8 +309,8 @@ func (_c *MockBusObject_GetProperty_Call) RunAndReturn(run func(string) (dbus.Va
} }
// Go provides a mock function with given fields: method, flags, ch, args // Go provides a mock function with given fields: method, flags, ch, args
func (_m *MockBusObject) Go(method string, flags dbus.Flags, ch chan *dbus.Call, args ...any) *dbus.Call { func (_m *MockBusObject) Go(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}) *dbus.Call {
var _ca []any var _ca []interface{}
_ca = append(_ca, method, flags, ch) _ca = append(_ca, method, flags, ch)
_ca = append(_ca, args...) _ca = append(_ca, args...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -320,7 +320,7 @@ func (_m *MockBusObject) Go(method string, flags dbus.Flags, ch chan *dbus.Call,
} }
var r0 *dbus.Call var r0 *dbus.Call
if rf, ok := ret.Get(0).(func(string, dbus.Flags, chan *dbus.Call, ...any) *dbus.Call); ok { if rf, ok := ret.Get(0).(func(string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call); ok {
r0 = rf(method, flags, ch, args...) r0 = rf(method, flags, ch, args...)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -340,18 +340,18 @@ type MockBusObject_Go_Call struct {
// - method string // - method string
// - flags dbus.Flags // - flags dbus.Flags
// - ch chan *dbus.Call // - ch chan *dbus.Call
// - args ...any // - args ...interface{}
func (_e *MockBusObject_Expecter) Go(method any, flags any, ch any, args ...any) *MockBusObject_Go_Call { func (_e *MockBusObject_Expecter) Go(method interface{}, flags interface{}, ch interface{}, args ...interface{}) *MockBusObject_Go_Call {
return &MockBusObject_Go_Call{Call: _e.mock.On("Go", return &MockBusObject_Go_Call{Call: _e.mock.On("Go",
append([]any{method, flags, ch}, args...)...)} append([]interface{}{method, flags, ch}, args...)...)}
} }
func (_c *MockBusObject_Go_Call) Run(run func(method string, flags dbus.Flags, ch chan *dbus.Call, args ...any)) *MockBusObject_Go_Call { func (_c *MockBusObject_Go_Call) Run(run func(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{})) *MockBusObject_Go_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]any, len(args)-3) variadicArgs := make([]interface{}, len(args)-3)
for i, a := range args[3:] { for i, a := range args[3:] {
if a != nil { if a != nil {
variadicArgs[i] = a.(any) variadicArgs[i] = a.(interface{})
} }
} }
run(args[0].(string), args[1].(dbus.Flags), args[2].(chan *dbus.Call), variadicArgs...) run(args[0].(string), args[1].(dbus.Flags), args[2].(chan *dbus.Call), variadicArgs...)
@@ -364,14 +364,14 @@ func (_c *MockBusObject_Go_Call) Return(_a0 *dbus.Call) *MockBusObject_Go_Call {
return _c return _c
} }
func (_c *MockBusObject_Go_Call) RunAndReturn(run func(string, dbus.Flags, chan *dbus.Call, ...any) *dbus.Call) *MockBusObject_Go_Call { func (_c *MockBusObject_Go_Call) RunAndReturn(run func(string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call) *MockBusObject_Go_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
// GoWithContext provides a mock function with given fields: ctx, method, flags, ch, args // GoWithContext provides a mock function with given fields: ctx, method, flags, ch, args
func (_m *MockBusObject) GoWithContext(ctx context.Context, method string, flags dbus.Flags, ch chan *dbus.Call, args ...any) *dbus.Call { func (_m *MockBusObject) GoWithContext(ctx context.Context, method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}) *dbus.Call {
var _ca []any var _ca []interface{}
_ca = append(_ca, ctx, method, flags, ch) _ca = append(_ca, ctx, method, flags, ch)
_ca = append(_ca, args...) _ca = append(_ca, args...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -381,7 +381,7 @@ func (_m *MockBusObject) GoWithContext(ctx context.Context, method string, flags
} }
var r0 *dbus.Call var r0 *dbus.Call
if rf, ok := ret.Get(0).(func(context.Context, string, dbus.Flags, chan *dbus.Call, ...any) *dbus.Call); ok { if rf, ok := ret.Get(0).(func(context.Context, string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call); ok {
r0 = rf(ctx, method, flags, ch, args...) r0 = rf(ctx, method, flags, ch, args...)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@@ -402,18 +402,18 @@ type MockBusObject_GoWithContext_Call struct {
// - method string // - method string
// - flags dbus.Flags // - flags dbus.Flags
// - ch chan *dbus.Call // - ch chan *dbus.Call
// - args ...any // - args ...interface{}
func (_e *MockBusObject_Expecter) GoWithContext(ctx any, method any, flags any, ch any, args ...any) *MockBusObject_GoWithContext_Call { func (_e *MockBusObject_Expecter) GoWithContext(ctx interface{}, method interface{}, flags interface{}, ch interface{}, args ...interface{}) *MockBusObject_GoWithContext_Call {
return &MockBusObject_GoWithContext_Call{Call: _e.mock.On("GoWithContext", return &MockBusObject_GoWithContext_Call{Call: _e.mock.On("GoWithContext",
append([]any{ctx, method, flags, ch}, args...)...)} append([]interface{}{ctx, method, flags, ch}, args...)...)}
} }
func (_c *MockBusObject_GoWithContext_Call) Run(run func(ctx context.Context, method string, flags dbus.Flags, ch chan *dbus.Call, args ...any)) *MockBusObject_GoWithContext_Call { func (_c *MockBusObject_GoWithContext_Call) Run(run func(ctx context.Context, method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{})) *MockBusObject_GoWithContext_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]any, len(args)-4) variadicArgs := make([]interface{}, len(args)-4)
for i, a := range args[4:] { for i, a := range args[4:] {
if a != nil { if a != nil {
variadicArgs[i] = a.(any) variadicArgs[i] = a.(interface{})
} }
} }
run(args[0].(context.Context), args[1].(string), args[2].(dbus.Flags), args[3].(chan *dbus.Call), variadicArgs...) run(args[0].(context.Context), args[1].(string), args[2].(dbus.Flags), args[3].(chan *dbus.Call), variadicArgs...)
@@ -426,7 +426,7 @@ func (_c *MockBusObject_GoWithContext_Call) Return(_a0 *dbus.Call) *MockBusObjec
return _c return _c
} }
func (_c *MockBusObject_GoWithContext_Call) RunAndReturn(run func(context.Context, string, dbus.Flags, chan *dbus.Call, ...any) *dbus.Call) *MockBusObject_GoWithContext_Call { func (_c *MockBusObject_GoWithContext_Call) RunAndReturn(run func(context.Context, string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call) *MockBusObject_GoWithContext_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
@@ -478,11 +478,11 @@ func (_c *MockBusObject_Path_Call) RunAndReturn(run func() dbus.ObjectPath) *Moc
// RemoveMatchSignal provides a mock function with given fields: iface, member, options // RemoveMatchSignal provides a mock function with given fields: iface, member, options
func (_m *MockBusObject) RemoveMatchSignal(iface string, member string, options ...dbus.MatchOption) *dbus.Call { func (_m *MockBusObject) RemoveMatchSignal(iface string, member string, options ...dbus.MatchOption) *dbus.Call {
_va := make([]any, len(options)) _va := make([]interface{}, len(options))
for _i := range options { for _i := range options {
_va[_i] = options[_i] _va[_i] = options[_i]
} }
var _ca []any var _ca []interface{}
_ca = append(_ca, iface, member) _ca = append(_ca, iface, member)
_ca = append(_ca, _va...) _ca = append(_ca, _va...)
ret := _m.Called(_ca...) ret := _m.Called(_ca...)
@@ -512,9 +512,9 @@ type MockBusObject_RemoveMatchSignal_Call struct {
// - iface string // - iface string
// - member string // - member string
// - options ...dbus.MatchOption // - options ...dbus.MatchOption
func (_e *MockBusObject_Expecter) RemoveMatchSignal(iface any, member any, options ...any) *MockBusObject_RemoveMatchSignal_Call { func (_e *MockBusObject_Expecter) RemoveMatchSignal(iface interface{}, member interface{}, options ...interface{}) *MockBusObject_RemoveMatchSignal_Call {
return &MockBusObject_RemoveMatchSignal_Call{Call: _e.mock.On("RemoveMatchSignal", return &MockBusObject_RemoveMatchSignal_Call{Call: _e.mock.On("RemoveMatchSignal",
append([]any{iface, member}, options...)...)} append([]interface{}{iface, member}, options...)...)}
} }
func (_c *MockBusObject_RemoveMatchSignal_Call) Run(run func(iface string, member string, options ...dbus.MatchOption)) *MockBusObject_RemoveMatchSignal_Call { func (_c *MockBusObject_RemoveMatchSignal_Call) Run(run func(iface string, member string, options ...dbus.MatchOption)) *MockBusObject_RemoveMatchSignal_Call {
@@ -541,7 +541,7 @@ func (_c *MockBusObject_RemoveMatchSignal_Call) RunAndReturn(run func(string, st
} }
// SetProperty provides a mock function with given fields: p, v // SetProperty provides a mock function with given fields: p, v
func (_m *MockBusObject) SetProperty(p string, v any) error { func (_m *MockBusObject) SetProperty(p string, v interface{}) error {
ret := _m.Called(p, v) ret := _m.Called(p, v)
if len(ret) == 0 { if len(ret) == 0 {
@@ -549,7 +549,7 @@ func (_m *MockBusObject) SetProperty(p string, v any) error {
} }
var r0 error var r0 error
if rf, ok := ret.Get(0).(func(string, any) error); ok { if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
r0 = rf(p, v) r0 = rf(p, v)
} else { } else {
r0 = ret.Error(0) r0 = ret.Error(0)
@@ -565,14 +565,14 @@ type MockBusObject_SetProperty_Call struct {
// SetProperty is a helper method to define mock.On call // SetProperty is a helper method to define mock.On call
// - p string // - p string
// - v any // - v interface{}
func (_e *MockBusObject_Expecter) SetProperty(p any, v any) *MockBusObject_SetProperty_Call { func (_e *MockBusObject_Expecter) SetProperty(p interface{}, v interface{}) *MockBusObject_SetProperty_Call {
return &MockBusObject_SetProperty_Call{Call: _e.mock.On("SetProperty", p, v)} return &MockBusObject_SetProperty_Call{Call: _e.mock.On("SetProperty", p, v)}
} }
func (_c *MockBusObject_SetProperty_Call) Run(run func(p string, v any)) *MockBusObject_SetProperty_Call { func (_c *MockBusObject_SetProperty_Call) Run(run func(p string, v interface{})) *MockBusObject_SetProperty_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(any)) run(args[0].(string), args[1].(interface{}))
}) })
return _c return _c
} }
@@ -582,13 +582,13 @@ func (_c *MockBusObject_SetProperty_Call) Return(_a0 error) *MockBusObject_SetPr
return _c return _c
} }
func (_c *MockBusObject_SetProperty_Call) RunAndReturn(run func(string, any) error) *MockBusObject_SetProperty_Call { func (_c *MockBusObject_SetProperty_Call) RunAndReturn(run func(string, interface{}) error) *MockBusObject_SetProperty_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }
// StoreProperty provides a mock function with given fields: p, value // StoreProperty provides a mock function with given fields: p, value
func (_m *MockBusObject) StoreProperty(p string, value any) error { func (_m *MockBusObject) StoreProperty(p string, value interface{}) error {
ret := _m.Called(p, value) ret := _m.Called(p, value)
if len(ret) == 0 { if len(ret) == 0 {
@@ -596,7 +596,7 @@ func (_m *MockBusObject) StoreProperty(p string, value any) error {
} }
var r0 error var r0 error
if rf, ok := ret.Get(0).(func(string, any) error); ok { if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
r0 = rf(p, value) r0 = rf(p, value)
} else { } else {
r0 = ret.Error(0) r0 = ret.Error(0)
@@ -612,14 +612,14 @@ type MockBusObject_StoreProperty_Call struct {
// StoreProperty is a helper method to define mock.On call // StoreProperty is a helper method to define mock.On call
// - p string // - p string
// - value any // - value interface{}
func (_e *MockBusObject_Expecter) StoreProperty(p any, value any) *MockBusObject_StoreProperty_Call { func (_e *MockBusObject_Expecter) StoreProperty(p interface{}, value interface{}) *MockBusObject_StoreProperty_Call {
return &MockBusObject_StoreProperty_Call{Call: _e.mock.On("StoreProperty", p, value)} return &MockBusObject_StoreProperty_Call{Call: _e.mock.On("StoreProperty", p, value)}
} }
func (_c *MockBusObject_StoreProperty_Call) Run(run func(p string, value any)) *MockBusObject_StoreProperty_Call { func (_c *MockBusObject_StoreProperty_Call) Run(run func(p string, value interface{})) *MockBusObject_StoreProperty_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(any)) run(args[0].(string), args[1].(interface{}))
}) })
return _c return _c
} }
@@ -629,7 +629,7 @@ func (_c *MockBusObject_StoreProperty_Call) Return(_a0 error) *MockBusObject_Sto
return _c return _c
} }
func (_c *MockBusObject_StoreProperty_Call) RunAndReturn(run func(string, any) error) *MockBusObject_StoreProperty_Call { func (_c *MockBusObject_StoreProperty_Call) RunAndReturn(run func(string, interface{}) error) *MockBusObject_StoreProperty_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }

View File

@@ -150,7 +150,7 @@ type MockConn_Read_Call struct {
// Read is a helper method to define mock.On call // Read is a helper method to define mock.On call
// - b []byte // - b []byte
func (_e *MockConn_Expecter) Read(b any) *MockConn_Read_Call { func (_e *MockConn_Expecter) Read(b interface{}) *MockConn_Read_Call {
return &MockConn_Read_Call{Call: _e.mock.On("Read", b)} return &MockConn_Read_Call{Call: _e.mock.On("Read", b)}
} }
@@ -243,7 +243,7 @@ type MockConn_SetDeadline_Call struct {
// SetDeadline is a helper method to define mock.On call // SetDeadline is a helper method to define mock.On call
// - t time.Time // - t time.Time
func (_e *MockConn_Expecter) SetDeadline(t any) *MockConn_SetDeadline_Call { func (_e *MockConn_Expecter) SetDeadline(t interface{}) *MockConn_SetDeadline_Call {
return &MockConn_SetDeadline_Call{Call: _e.mock.On("SetDeadline", t)} return &MockConn_SetDeadline_Call{Call: _e.mock.On("SetDeadline", t)}
} }
@@ -289,7 +289,7 @@ type MockConn_SetReadDeadline_Call struct {
// SetReadDeadline is a helper method to define mock.On call // SetReadDeadline is a helper method to define mock.On call
// - t time.Time // - t time.Time
func (_e *MockConn_Expecter) SetReadDeadline(t any) *MockConn_SetReadDeadline_Call { func (_e *MockConn_Expecter) SetReadDeadline(t interface{}) *MockConn_SetReadDeadline_Call {
return &MockConn_SetReadDeadline_Call{Call: _e.mock.On("SetReadDeadline", t)} return &MockConn_SetReadDeadline_Call{Call: _e.mock.On("SetReadDeadline", t)}
} }
@@ -335,7 +335,7 @@ type MockConn_SetWriteDeadline_Call struct {
// SetWriteDeadline is a helper method to define mock.On call // SetWriteDeadline is a helper method to define mock.On call
// - t time.Time // - t time.Time
func (_e *MockConn_Expecter) SetWriteDeadline(t any) *MockConn_SetWriteDeadline_Call { func (_e *MockConn_Expecter) SetWriteDeadline(t interface{}) *MockConn_SetWriteDeadline_Call {
return &MockConn_SetWriteDeadline_Call{Call: _e.mock.On("SetWriteDeadline", t)} return &MockConn_SetWriteDeadline_Call{Call: _e.mock.On("SetWriteDeadline", t)}
} }
@@ -391,7 +391,7 @@ type MockConn_Write_Call struct {
// Write is a helper method to define mock.On call // Write is a helper method to define mock.On call
// - b []byte // - b []byte
func (_e *MockConn_Expecter) Write(b any) *MockConn_Write_Call { func (_e *MockConn_Expecter) Write(b interface{}) *MockConn_Write_Call {
return &MockConn_Write_Call{Call: _e.mock.On("Write", b)} return &MockConn_Write_Call{Call: _e.mock.On("Write", b)}
} }

View File

@@ -45,7 +45,7 @@ type MockBackend_ActivateWiredConnection_Call struct {
// ActivateWiredConnection is a helper method to define mock.On call // ActivateWiredConnection is a helper method to define mock.On call
// - uuid string // - uuid string
func (_e *MockBackend_Expecter) ActivateWiredConnection(uuid any) *MockBackend_ActivateWiredConnection_Call { func (_e *MockBackend_Expecter) ActivateWiredConnection(uuid interface{}) *MockBackend_ActivateWiredConnection_Call {
return &MockBackend_ActivateWiredConnection_Call{Call: _e.mock.On("ActivateWiredConnection", uuid)} return &MockBackend_ActivateWiredConnection_Call{Call: _e.mock.On("ActivateWiredConnection", uuid)}
} }
@@ -91,7 +91,7 @@ type MockBackend_CancelCredentials_Call struct {
// CancelCredentials is a helper method to define mock.On call // CancelCredentials is a helper method to define mock.On call
// - token string // - token string
func (_e *MockBackend_Expecter) CancelCredentials(token any) *MockBackend_CancelCredentials_Call { func (_e *MockBackend_Expecter) CancelCredentials(token interface{}) *MockBackend_CancelCredentials_Call {
return &MockBackend_CancelCredentials_Call{Call: _e.mock.On("CancelCredentials", token)} return &MockBackend_CancelCredentials_Call{Call: _e.mock.On("CancelCredentials", token)}
} }
@@ -137,7 +137,7 @@ type MockBackend_ClearVPNCredentials_Call struct {
// ClearVPNCredentials is a helper method to define mock.On call // ClearVPNCredentials is a helper method to define mock.On call
// - uuidOrName string // - uuidOrName string
func (_e *MockBackend_Expecter) ClearVPNCredentials(uuidOrName any) *MockBackend_ClearVPNCredentials_Call { func (_e *MockBackend_Expecter) ClearVPNCredentials(uuidOrName interface{}) *MockBackend_ClearVPNCredentials_Call {
return &MockBackend_ClearVPNCredentials_Call{Call: _e.mock.On("ClearVPNCredentials", uuidOrName)} return &MockBackend_ClearVPNCredentials_Call{Call: _e.mock.On("ClearVPNCredentials", uuidOrName)}
} }
@@ -261,7 +261,7 @@ type MockBackend_ConnectVPN_Call struct {
// ConnectVPN is a helper method to define mock.On call // ConnectVPN is a helper method to define mock.On call
// - uuidOrName string // - uuidOrName string
// - singleActive bool // - singleActive bool
func (_e *MockBackend_Expecter) ConnectVPN(uuidOrName any, singleActive any) *MockBackend_ConnectVPN_Call { func (_e *MockBackend_Expecter) ConnectVPN(uuidOrName interface{}, singleActive interface{}) *MockBackend_ConnectVPN_Call {
return &MockBackend_ConnectVPN_Call{Call: _e.mock.On("ConnectVPN", uuidOrName, singleActive)} return &MockBackend_ConnectVPN_Call{Call: _e.mock.On("ConnectVPN", uuidOrName, singleActive)}
} }
@@ -307,7 +307,7 @@ type MockBackend_ConnectWiFi_Call struct {
// ConnectWiFi is a helper method to define mock.On call // ConnectWiFi is a helper method to define mock.On call
// - req network.ConnectionRequest // - req network.ConnectionRequest
func (_e *MockBackend_Expecter) ConnectWiFi(req any) *MockBackend_ConnectWiFi_Call { func (_e *MockBackend_Expecter) ConnectWiFi(req interface{}) *MockBackend_ConnectWiFi_Call {
return &MockBackend_ConnectWiFi_Call{Call: _e.mock.On("ConnectWiFi", req)} return &MockBackend_ConnectWiFi_Call{Call: _e.mock.On("ConnectWiFi", req)}
} }
@@ -353,7 +353,7 @@ type MockBackend_DeleteVPN_Call struct {
// DeleteVPN is a helper method to define mock.On call // DeleteVPN is a helper method to define mock.On call
// - uuidOrName string // - uuidOrName string
func (_e *MockBackend_Expecter) DeleteVPN(uuidOrName any) *MockBackend_DeleteVPN_Call { func (_e *MockBackend_Expecter) DeleteVPN(uuidOrName interface{}) *MockBackend_DeleteVPN_Call {
return &MockBackend_DeleteVPN_Call{Call: _e.mock.On("DeleteVPN", uuidOrName)} return &MockBackend_DeleteVPN_Call{Call: _e.mock.On("DeleteVPN", uuidOrName)}
} }
@@ -489,7 +489,7 @@ type MockBackend_DisconnectEthernetDevice_Call struct {
// DisconnectEthernetDevice is a helper method to define mock.On call // DisconnectEthernetDevice is a helper method to define mock.On call
// - device string // - device string
func (_e *MockBackend_Expecter) DisconnectEthernetDevice(device any) *MockBackend_DisconnectEthernetDevice_Call { func (_e *MockBackend_Expecter) DisconnectEthernetDevice(device interface{}) *MockBackend_DisconnectEthernetDevice_Call {
return &MockBackend_DisconnectEthernetDevice_Call{Call: _e.mock.On("DisconnectEthernetDevice", device)} return &MockBackend_DisconnectEthernetDevice_Call{Call: _e.mock.On("DisconnectEthernetDevice", device)}
} }
@@ -535,7 +535,7 @@ type MockBackend_DisconnectVPN_Call struct {
// DisconnectVPN is a helper method to define mock.On call // DisconnectVPN is a helper method to define mock.On call
// - uuidOrName string // - uuidOrName string
func (_e *MockBackend_Expecter) DisconnectVPN(uuidOrName any) *MockBackend_DisconnectVPN_Call { func (_e *MockBackend_Expecter) DisconnectVPN(uuidOrName interface{}) *MockBackend_DisconnectVPN_Call {
return &MockBackend_DisconnectVPN_Call{Call: _e.mock.On("DisconnectVPN", uuidOrName)} return &MockBackend_DisconnectVPN_Call{Call: _e.mock.On("DisconnectVPN", uuidOrName)}
} }
@@ -626,7 +626,7 @@ type MockBackend_DisconnectWiFiDevice_Call struct {
// DisconnectWiFiDevice is a helper method to define mock.On call // DisconnectWiFiDevice is a helper method to define mock.On call
// - device string // - device string
func (_e *MockBackend_Expecter) DisconnectWiFiDevice(device any) *MockBackend_DisconnectWiFiDevice_Call { func (_e *MockBackend_Expecter) DisconnectWiFiDevice(device interface{}) *MockBackend_DisconnectWiFiDevice_Call {
return &MockBackend_DisconnectWiFiDevice_Call{Call: _e.mock.On("DisconnectWiFiDevice", device)} return &MockBackend_DisconnectWiFiDevice_Call{Call: _e.mock.On("DisconnectWiFiDevice", device)}
} }
@@ -672,7 +672,7 @@ type MockBackend_ForgetWiFiNetwork_Call struct {
// ForgetWiFiNetwork is a helper method to define mock.On call // ForgetWiFiNetwork is a helper method to define mock.On call
// - ssid string // - ssid string
func (_e *MockBackend_Expecter) ForgetWiFiNetwork(ssid any) *MockBackend_ForgetWiFiNetwork_Call { func (_e *MockBackend_Expecter) ForgetWiFiNetwork(ssid interface{}) *MockBackend_ForgetWiFiNetwork_Call {
return &MockBackend_ForgetWiFiNetwork_Call{Call: _e.mock.On("ForgetWiFiNetwork", ssid)} return &MockBackend_ForgetWiFiNetwork_Call{Call: _e.mock.On("ForgetWiFiNetwork", ssid)}
} }
@@ -881,7 +881,7 @@ type MockBackend_GetVPNConfig_Call struct {
// GetVPNConfig is a helper method to define mock.On call // GetVPNConfig is a helper method to define mock.On call
// - uuidOrName string // - uuidOrName string
func (_e *MockBackend_Expecter) GetVPNConfig(uuidOrName any) *MockBackend_GetVPNConfig_Call { func (_e *MockBackend_Expecter) GetVPNConfig(uuidOrName interface{}) *MockBackend_GetVPNConfig_Call {
return &MockBackend_GetVPNConfig_Call{Call: _e.mock.On("GetVPNConfig", uuidOrName)} return &MockBackend_GetVPNConfig_Call{Call: _e.mock.On("GetVPNConfig", uuidOrName)}
} }
@@ -1041,7 +1041,7 @@ type MockBackend_GetWiFiNetworkDetails_Call struct {
// GetWiFiNetworkDetails is a helper method to define mock.On call // GetWiFiNetworkDetails is a helper method to define mock.On call
// - ssid string // - ssid string
func (_e *MockBackend_Expecter) GetWiFiNetworkDetails(ssid any) *MockBackend_GetWiFiNetworkDetails_Call { func (_e *MockBackend_Expecter) GetWiFiNetworkDetails(ssid interface{}) *MockBackend_GetWiFiNetworkDetails_Call {
return &MockBackend_GetWiFiNetworkDetails_Call{Call: _e.mock.On("GetWiFiNetworkDetails", ssid)} return &MockBackend_GetWiFiNetworkDetails_Call{Call: _e.mock.On("GetWiFiNetworkDetails", ssid)}
} }
@@ -1156,7 +1156,7 @@ type MockBackend_GetWiredNetworkDetails_Call struct {
// GetWiredNetworkDetails is a helper method to define mock.On call // GetWiredNetworkDetails is a helper method to define mock.On call
// - uuid string // - uuid string
func (_e *MockBackend_Expecter) GetWiredNetworkDetails(uuid any) *MockBackend_GetWiredNetworkDetails_Call { func (_e *MockBackend_Expecter) GetWiredNetworkDetails(uuid interface{}) *MockBackend_GetWiredNetworkDetails_Call {
return &MockBackend_GetWiredNetworkDetails_Call{Call: _e.mock.On("GetWiredNetworkDetails", uuid)} return &MockBackend_GetWiredNetworkDetails_Call{Call: _e.mock.On("GetWiredNetworkDetails", uuid)}
} }
@@ -1215,7 +1215,7 @@ type MockBackend_ImportVPN_Call struct {
// ImportVPN is a helper method to define mock.On call // ImportVPN is a helper method to define mock.On call
// - filePath string // - filePath string
// - name string // - name string
func (_e *MockBackend_Expecter) ImportVPN(filePath any, name any) *MockBackend_ImportVPN_Call { func (_e *MockBackend_Expecter) ImportVPN(filePath interface{}, name interface{}) *MockBackend_ImportVPN_Call {
return &MockBackend_ImportVPN_Call{Call: _e.mock.On("ImportVPN", filePath, name)} return &MockBackend_ImportVPN_Call{Call: _e.mock.On("ImportVPN", filePath, name)}
} }
@@ -1522,7 +1522,7 @@ type MockBackend_ScanWiFiDevice_Call struct {
// ScanWiFiDevice is a helper method to define mock.On call // ScanWiFiDevice is a helper method to define mock.On call
// - device string // - device string
func (_e *MockBackend_Expecter) ScanWiFiDevice(device any) *MockBackend_ScanWiFiDevice_Call { func (_e *MockBackend_Expecter) ScanWiFiDevice(device interface{}) *MockBackend_ScanWiFiDevice_Call {
return &MockBackend_ScanWiFiDevice_Call{Call: _e.mock.On("ScanWiFiDevice", device)} return &MockBackend_ScanWiFiDevice_Call{Call: _e.mock.On("ScanWiFiDevice", device)}
} }
@@ -1568,7 +1568,7 @@ type MockBackend_SetPromptBroker_Call struct {
// SetPromptBroker is a helper method to define mock.On call // SetPromptBroker is a helper method to define mock.On call
// - broker network.PromptBroker // - broker network.PromptBroker
func (_e *MockBackend_Expecter) SetPromptBroker(broker any) *MockBackend_SetPromptBroker_Call { func (_e *MockBackend_Expecter) SetPromptBroker(broker interface{}) *MockBackend_SetPromptBroker_Call {
return &MockBackend_SetPromptBroker_Call{Call: _e.mock.On("SetPromptBroker", broker)} return &MockBackend_SetPromptBroker_Call{Call: _e.mock.On("SetPromptBroker", broker)}
} }
@@ -1617,7 +1617,7 @@ type MockBackend_SetVPNCredentials_Call struct {
// - username string // - username string
// - password string // - password string
// - save bool // - save bool
func (_e *MockBackend_Expecter) SetVPNCredentials(uuid any, username any, password any, save any) *MockBackend_SetVPNCredentials_Call { func (_e *MockBackend_Expecter) SetVPNCredentials(uuid interface{}, username interface{}, password interface{}, save interface{}) *MockBackend_SetVPNCredentials_Call {
return &MockBackend_SetVPNCredentials_Call{Call: _e.mock.On("SetVPNCredentials", uuid, username, password, save)} return &MockBackend_SetVPNCredentials_Call{Call: _e.mock.On("SetVPNCredentials", uuid, username, password, save)}
} }
@@ -1664,7 +1664,7 @@ type MockBackend_SetWiFiAutoconnect_Call struct {
// SetWiFiAutoconnect is a helper method to define mock.On call // SetWiFiAutoconnect is a helper method to define mock.On call
// - ssid string // - ssid string
// - autoconnect bool // - autoconnect bool
func (_e *MockBackend_Expecter) SetWiFiAutoconnect(ssid any, autoconnect any) *MockBackend_SetWiFiAutoconnect_Call { func (_e *MockBackend_Expecter) SetWiFiAutoconnect(ssid interface{}, autoconnect interface{}) *MockBackend_SetWiFiAutoconnect_Call {
return &MockBackend_SetWiFiAutoconnect_Call{Call: _e.mock.On("SetWiFiAutoconnect", ssid, autoconnect)} return &MockBackend_SetWiFiAutoconnect_Call{Call: _e.mock.On("SetWiFiAutoconnect", ssid, autoconnect)}
} }
@@ -1710,7 +1710,7 @@ type MockBackend_SetWiFiEnabled_Call struct {
// SetWiFiEnabled is a helper method to define mock.On call // SetWiFiEnabled is a helper method to define mock.On call
// - enabled bool // - enabled bool
func (_e *MockBackend_Expecter) SetWiFiEnabled(enabled any) *MockBackend_SetWiFiEnabled_Call { func (_e *MockBackend_Expecter) SetWiFiEnabled(enabled interface{}) *MockBackend_SetWiFiEnabled_Call {
return &MockBackend_SetWiFiEnabled_Call{Call: _e.mock.On("SetWiFiEnabled", enabled)} return &MockBackend_SetWiFiEnabled_Call{Call: _e.mock.On("SetWiFiEnabled", enabled)}
} }
@@ -1756,7 +1756,7 @@ type MockBackend_StartMonitoring_Call struct {
// StartMonitoring is a helper method to define mock.On call // StartMonitoring is a helper method to define mock.On call
// - onStateChange func() // - onStateChange func()
func (_e *MockBackend_Expecter) StartMonitoring(onStateChange any) *MockBackend_StartMonitoring_Call { func (_e *MockBackend_Expecter) StartMonitoring(onStateChange interface{}) *MockBackend_StartMonitoring_Call {
return &MockBackend_StartMonitoring_Call{Call: _e.mock.On("StartMonitoring", onStateChange)} return &MockBackend_StartMonitoring_Call{Call: _e.mock.On("StartMonitoring", onStateChange)}
} }
@@ -1836,7 +1836,7 @@ type MockBackend_SubmitCredentials_Call struct {
// - token string // - token string
// - secrets map[string]string // - secrets map[string]string
// - save bool // - save bool
func (_e *MockBackend_Expecter) SubmitCredentials(token any, secrets any, save any) *MockBackend_SubmitCredentials_Call { func (_e *MockBackend_Expecter) SubmitCredentials(token interface{}, secrets interface{}, save interface{}) *MockBackend_SubmitCredentials_Call {
return &MockBackend_SubmitCredentials_Call{Call: _e.mock.On("SubmitCredentials", token, secrets, save)} return &MockBackend_SubmitCredentials_Call{Call: _e.mock.On("SubmitCredentials", token, secrets, save)}
} }
@@ -1858,7 +1858,7 @@ func (_c *MockBackend_SubmitCredentials_Call) RunAndReturn(run func(string, map[
} }
// UpdateVPNConfig provides a mock function with given fields: uuid, updates // UpdateVPNConfig provides a mock function with given fields: uuid, updates
func (_m *MockBackend) UpdateVPNConfig(uuid string, updates map[string]any) error { func (_m *MockBackend) UpdateVPNConfig(uuid string, updates map[string]interface{}) error {
ret := _m.Called(uuid, updates) ret := _m.Called(uuid, updates)
if len(ret) == 0 { if len(ret) == 0 {
@@ -1866,7 +1866,7 @@ func (_m *MockBackend) UpdateVPNConfig(uuid string, updates map[string]any) erro
} }
var r0 error var r0 error
if rf, ok := ret.Get(0).(func(string, map[string]any) error); ok { if rf, ok := ret.Get(0).(func(string, map[string]interface{}) error); ok {
r0 = rf(uuid, updates) r0 = rf(uuid, updates)
} else { } else {
r0 = ret.Error(0) r0 = ret.Error(0)
@@ -1882,14 +1882,14 @@ type MockBackend_UpdateVPNConfig_Call struct {
// UpdateVPNConfig is a helper method to define mock.On call // UpdateVPNConfig is a helper method to define mock.On call
// - uuid string // - uuid string
// - updates map[string]any // - updates map[string]interface{}
func (_e *MockBackend_Expecter) UpdateVPNConfig(uuid any, updates any) *MockBackend_UpdateVPNConfig_Call { func (_e *MockBackend_Expecter) UpdateVPNConfig(uuid interface{}, updates interface{}) *MockBackend_UpdateVPNConfig_Call {
return &MockBackend_UpdateVPNConfig_Call{Call: _e.mock.On("UpdateVPNConfig", uuid, updates)} return &MockBackend_UpdateVPNConfig_Call{Call: _e.mock.On("UpdateVPNConfig", uuid, updates)}
} }
func (_c *MockBackend_UpdateVPNConfig_Call) Run(run func(uuid string, updates map[string]any)) *MockBackend_UpdateVPNConfig_Call { func (_c *MockBackend_UpdateVPNConfig_Call) Run(run func(uuid string, updates map[string]interface{})) *MockBackend_UpdateVPNConfig_Call {
_c.Call.Run(func(args mock.Arguments) { _c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(map[string]any)) run(args[0].(string), args[1].(map[string]interface{}))
}) })
return _c return _c
} }
@@ -1899,7 +1899,7 @@ func (_c *MockBackend_UpdateVPNConfig_Call) Return(_a0 error) *MockBackend_Updat
return _c return _c
} }
func (_c *MockBackend_UpdateVPNConfig_Call) RunAndReturn(run func(string, map[string]any) error) *MockBackend_UpdateVPNConfig_Call { func (_c *MockBackend_UpdateVPNConfig_Call) RunAndReturn(run func(string, map[string]interface{}) error) *MockBackend_UpdateVPNConfig_Call {
_c.Call.Return(run) _c.Call.Return(run)
return _c return _c
} }

View File

@@ -52,7 +52,7 @@ type MockVersionFetcher_GetCurrentVersion_Call struct {
// GetCurrentVersion is a helper method to define mock.On call // GetCurrentVersion is a helper method to define mock.On call
// - dmsPath string // - dmsPath string
func (_e *MockVersionFetcher_Expecter) GetCurrentVersion(dmsPath any) *MockVersionFetcher_GetCurrentVersion_Call { func (_e *MockVersionFetcher_Expecter) GetCurrentVersion(dmsPath interface{}) *MockVersionFetcher_GetCurrentVersion_Call {
return &MockVersionFetcher_GetCurrentVersion_Call{Call: _e.mock.On("GetCurrentVersion", dmsPath)} return &MockVersionFetcher_GetCurrentVersion_Call{Call: _e.mock.On("GetCurrentVersion", dmsPath)}
} }
@@ -108,7 +108,7 @@ type MockVersionFetcher_GetLatestVersion_Call struct {
// GetLatestVersion is a helper method to define mock.On call // GetLatestVersion is a helper method to define mock.On call
// - dmsPath string // - dmsPath string
func (_e *MockVersionFetcher_Expecter) GetLatestVersion(dmsPath any) *MockVersionFetcher_GetLatestVersion_Call { func (_e *MockVersionFetcher_Expecter) GetLatestVersion(dmsPath interface{}) *MockVersionFetcher_GetLatestVersion_Call {
return &MockVersionFetcher_GetLatestVersion_Call{Call: _e.mock.On("GetLatestVersion", dmsPath)} return &MockVersionFetcher_GetLatestVersion_Call{Call: _e.mock.On("GetLatestVersion", dmsPath)}
} }

View File

@@ -8,9 +8,9 @@ import (
) )
type Request struct { type Request struct {
ID int `json:"id"` ID int `json:"id"`
Method string `json:"method"` Method string `json:"method"`
Params map[string]interface{} `json:"params"` Params map[string]any `json:"params"`
} }
func HandleRequest(conn net.Conn, req Request, manager *Manager) { func HandleRequest(conn net.Conn, req Request, manager *Manager) {
@@ -44,7 +44,7 @@ func handleOpen(conn net.Conn, req Request, manager *Manager) {
event.MimeType = mimeType event.MimeType = mimeType
} }
if categories, ok := req.Params["categories"].([]interface{}); ok { if categories, ok := req.Params["categories"].([]any); ok {
event.Categories = make([]string, 0, len(categories)) event.Categories = make([]string, 0, len(categories))
for _, cat := range categories { for _, cat := range categories {
if catStr, ok := cat.(string); ok { if catStr, ok := cat.(string); ok {

View File

@@ -37,25 +37,18 @@ func NewDDCBackend() (*DDCBackend, error) {
} }
func (b *DDCBackend) scanI2CDevices() error { func (b *DDCBackend) scanI2CDevices() error {
b.scanMutex.Lock() return b.scanI2CDevicesInternal(false)
lastScan := b.lastScan }
b.scanMutex.Unlock()
if time.Since(lastScan) < b.scanInterval {
return nil
}
func (b *DDCBackend) scanI2CDevicesInternal(force bool) error {
b.scanMutex.Lock() b.scanMutex.Lock()
defer b.scanMutex.Unlock() defer b.scanMutex.Unlock()
if time.Since(b.lastScan) < b.scanInterval { if !force && time.Since(b.lastScan) < b.scanInterval {
return nil return nil
} }
b.devices.Range(func(key string, value *ddcDevice) bool { activeBuses := make(map[int]bool)
b.devices.Delete(key)
return true
})
for i := 0; i < 32; i++ { for i := 0; i < 32; i++ {
busPath := fmt.Sprintf("/dev/i2c-%d", i) busPath := fmt.Sprintf("/dev/i2c-%d", i)
@@ -68,17 +61,31 @@ func (b *DDCBackend) scanI2CDevices() error {
continue continue
} }
activeBuses[i] = true
id := fmt.Sprintf("ddc:i2c-%d", i)
if _, exists := b.devices.Load(id); exists {
continue
}
dev, err := b.probeDDCDevice(i) dev, err := b.probeDDCDevice(i)
if err != nil || dev == nil { if err != nil || dev == nil {
continue continue
} }
id := fmt.Sprintf("ddc:i2c-%d", i)
dev.id = id dev.id = id
b.devices.Store(id, dev) b.devices.Store(id, dev)
log.Debugf("found DDC device on i2c-%d", i) log.Debugf("found DDC device on i2c-%d", i)
} }
b.devices.Range(func(id string, dev *ddcDevice) bool {
if !activeBuses[dev.bus] {
b.devices.Delete(id)
log.Debugf("removed DDC device %s (bus no longer exists)", id)
}
return true
})
b.lastScan = time.Now() b.lastScan = time.Now()
return nil return nil
@@ -187,6 +194,13 @@ func (b *DDCBackend) SetBrightness(id string, value int, exponential bool, callb
func (b *DDCBackend) SetBrightnessWithExponent(id string, value int, exponential bool, exponent float64, callback func()) error { func (b *DDCBackend) SetBrightnessWithExponent(id string, value int, exponential bool, exponent float64, callback func()) error {
_, ok := b.devices.Load(id) _, ok := b.devices.Load(id)
if !ok {
if err := b.scanI2CDevicesInternal(true); err != nil {
log.Debugf("rescan failed for %s: %v", id, err)
}
_, ok = b.devices.Load(id)
}
if !ok { if !ok {
return fmt.Errorf("device not found: %s", id) return fmt.Errorf("device not found: %s", id)
} }
@@ -234,6 +248,13 @@ func (b *DDCBackend) SetBrightnessWithExponent(id string, value int, exponential
func (b *DDCBackend) setBrightnessImmediateWithExponent(id string, value int) error { func (b *DDCBackend) setBrightnessImmediateWithExponent(id string, value int) error {
dev, ok := b.devices.Load(id) dev, ok := b.devices.Load(id)
if !ok {
if err := b.scanI2CDevicesInternal(true); err != nil {
log.Debugf("rescan failed for %s: %v", id, err)
}
dev, ok = b.devices.Load(id)
}
if !ok { if !ok {
return fmt.Errorf("device not found: %s", id) return fmt.Errorf("device not found: %s", id)
} }

View File

@@ -54,6 +54,7 @@ func (m *Manager) initSysfs() {
m.sysfsBackend = sysfs m.sysfsBackend = sysfs
m.sysfsReady = true m.sysfsReady = true
m.updateState() m.updateState()
m.initUdev()
return return
} }
@@ -65,6 +66,11 @@ func (m *Manager) initSysfs() {
m.sysfsBackend = sysfs m.sysfsBackend = sysfs
m.sysfsReady = true m.sysfsReady = true
m.updateState() m.updateState()
m.initUdev()
}
func (m *Manager) initUdev() {
m.udevMonitor = NewUdevMonitor(m)
} }
func (m *Manager) initDDC() { func (m *Manager) initDDC() {

View File

@@ -43,6 +43,7 @@ type Manager struct {
logindBackend *LogindBackend logindBackend *LogindBackend
sysfsBackend *SysfsBackend sysfsBackend *SysfsBackend
ddcBackend *DDCBackend ddcBackend *DDCBackend
udevMonitor *UdevMonitor
logindReady bool logindReady bool
sysfsReady bool sysfsReady bool
@@ -181,6 +182,10 @@ func (m *Manager) Close() {
return true return true
}) })
if m.udevMonitor != nil {
m.udevMonitor.Close()
}
if m.logindBackend != nil { if m.logindBackend != nil {
m.logindBackend.Close() m.logindBackend.Close()
} }

View File

@@ -0,0 +1,151 @@
package brightness
import (
"os"
"path/filepath"
"strconv"
"strings"
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
"github.com/pilebones/go-udev/netlink"
)
type UdevMonitor struct {
stop chan struct{}
}
func NewUdevMonitor(manager *Manager) *UdevMonitor {
m := &UdevMonitor{
stop: make(chan struct{}),
}
go m.run(manager)
return m
}
func (m *UdevMonitor) run(manager *Manager) {
conn := &netlink.UEventConn{}
if err := conn.Connect(netlink.UdevEvent); err != nil {
log.Errorf("Failed to connect to udev netlink: %v", err)
return
}
defer conn.Close()
matcher := &netlink.RuleDefinitions{
Rules: []netlink.RuleDefinition{
{Env: map[string]string{"SUBSYSTEM": "backlight"}},
// ! TODO: most drivers dont emit this for leds?
// ! inotify brightness_hw_changed works, but thn some devices dont do that...
// ! So for now the GUI just shows OSDs for leds, without reflecting actual HW value
// {Env: map[string]string{"SUBSYSTEM": "leds"}},
},
}
if err := matcher.Compile(); err != nil {
log.Errorf("Failed to compile udev matcher: %v", err)
return
}
events := make(chan netlink.UEvent)
errs := make(chan error)
conn.Monitor(events, errs, matcher)
log.Info("Udev monitor started for backlight/leds events")
for {
select {
case <-m.stop:
return
case err := <-errs:
log.Errorf("Udev monitor error: %v", err)
return
case event := <-events:
m.handleEvent(manager, event)
}
}
}
func (m *UdevMonitor) handleEvent(manager *Manager, event netlink.UEvent) {
subsystem := event.Env["SUBSYSTEM"]
devpath := event.Env["DEVPATH"]
if subsystem == "" || devpath == "" {
return
}
sysname := filepath.Base(devpath)
action := string(event.Action)
switch action {
case "change":
m.handleChange(manager, subsystem, sysname)
case "add", "remove":
log.Debugf("Udev %s event: %s:%s - triggering rescan", action, subsystem, sysname)
manager.Rescan()
}
}
func (m *UdevMonitor) handleChange(manager *Manager, subsystem, sysname string) {
deviceID := subsystem + ":" + sysname
if manager.sysfsBackend == nil {
return
}
brightnessPath := filepath.Join(manager.sysfsBackend.basePath, subsystem, sysname, "brightness")
data, err := os.ReadFile(brightnessPath)
if err != nil {
log.Debugf("Udev change event for %s but failed to read brightness: %v", deviceID, err)
return
}
brightness, err := strconv.Atoi(strings.TrimSpace(string(data)))
if err != nil {
log.Debugf("Failed to parse brightness for %s: %v", deviceID, err)
return
}
manager.handleUdevBrightnessChange(deviceID, brightness)
}
func (m *UdevMonitor) Close() {
close(m.stop)
}
func (m *Manager) handleUdevBrightnessChange(deviceID string, rawBrightness int) {
if m.sysfsBackend == nil {
return
}
dev, err := m.sysfsBackend.GetDevice(deviceID)
if err != nil {
log.Debugf("Udev event for unknown device %s: %v", deviceID, err)
return
}
percent := m.sysfsBackend.ValueToPercent(rawBrightness, dev, false)
m.stateMutex.Lock()
var found bool
for i, d := range m.state.Devices {
if d.ID != deviceID {
continue
}
found = true
if d.Current == rawBrightness {
m.stateMutex.Unlock()
return
}
m.state.Devices[i].Current = rawBrightness
m.state.Devices[i].CurrentPercent = percent
break
}
m.stateMutex.Unlock()
if !found {
log.Debugf("Udev event for device not in state: %s", deviceID)
return
}
log.Debugf("Udev brightness change: %s -> %d (%d%%)", deviceID, rawBrightness, percent)
m.broadcastDeviceUpdate(deviceID)
}

View File

@@ -0,0 +1,260 @@
package brightness
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/pilebones/go-udev/netlink"
)
func setupTestManager(t *testing.T) (*Manager, string) {
tmpDir := t.TempDir()
backlightDir := filepath.Join(tmpDir, "backlight", "intel_backlight")
if err := os.MkdirAll(backlightDir, 0755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(backlightDir, "max_brightness"), []byte("1000\n"), 0644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(backlightDir, "brightness"), []byte("500\n"), 0644); err != nil {
t.Fatal(err)
}
sysfs := &SysfsBackend{
basePath: tmpDir,
classes: []string{"backlight"},
}
if err := sysfs.scanDevices(); err != nil {
t.Fatal(err)
}
m := &Manager{
sysfsBackend: sysfs,
sysfsReady: true,
stopChan: make(chan struct{}),
}
m.state = State{
Devices: []Device{
{
Class: ClassBacklight,
ID: "backlight:intel_backlight",
Name: "intel_backlight",
Current: 500,
Max: 1000,
CurrentPercent: 50,
Backend: "sysfs",
},
},
}
return m, tmpDir
}
func TestHandleUdevBrightnessChange_UpdatesState(t *testing.T) {
m, _ := setupTestManager(t)
m.handleUdevBrightnessChange("backlight:intel_backlight", 750)
state := m.GetState()
if len(state.Devices) != 1 {
t.Fatalf("expected 1 device, got %d", len(state.Devices))
}
dev := state.Devices[0]
if dev.Current != 750 {
t.Errorf("expected Current=750, got %d", dev.Current)
}
if dev.CurrentPercent != 75 {
t.Errorf("expected CurrentPercent=75, got %d", dev.CurrentPercent)
}
}
func TestHandleUdevBrightnessChange_NoChangeWhenSameValue(t *testing.T) {
m, _ := setupTestManager(t)
updateCh := m.SubscribeUpdates("test")
defer m.UnsubscribeUpdates("test")
m.handleUdevBrightnessChange("backlight:intel_backlight", 500)
select {
case <-updateCh:
t.Error("should not broadcast when brightness unchanged")
case <-time.After(50 * time.Millisecond):
}
}
func TestHandleUdevBrightnessChange_BroadcastsOnChange(t *testing.T) {
m, _ := setupTestManager(t)
updateCh := m.SubscribeUpdates("test")
defer m.UnsubscribeUpdates("test")
m.handleUdevBrightnessChange("backlight:intel_backlight", 750)
select {
case update := <-updateCh:
if update.Device.Current != 750 {
t.Errorf("broadcast had wrong Current: got %d, want 750", update.Device.Current)
}
case <-time.After(100 * time.Millisecond):
t.Error("expected broadcast on brightness change")
}
}
func TestHandleUdevBrightnessChange_UnknownDevice(t *testing.T) {
m, _ := setupTestManager(t)
m.handleUdevBrightnessChange("backlight:unknown_device", 500)
state := m.GetState()
if len(state.Devices) != 1 {
t.Errorf("state should be unchanged, got %d devices", len(state.Devices))
}
}
func TestHandleUdevBrightnessChange_NilSysfsBackend(t *testing.T) {
m := &Manager{
sysfsBackend: nil,
stopChan: make(chan struct{}),
}
m.handleUdevBrightnessChange("backlight:test", 500)
}
func TestHandleUdevBrightnessChange_DeviceNotInState(t *testing.T) {
m, _ := setupTestManager(t)
m.sysfsBackend.deviceCache.Store("backlight:other_device", &sysfsDevice{
class: ClassBacklight,
id: "backlight:other_device",
name: "other_device",
maxBrightness: 100,
minValue: 1,
})
m.handleUdevBrightnessChange("backlight:other_device", 50)
state := m.GetState()
for _, d := range state.Devices {
if d.ID == "backlight:other_device" {
t.Error("device should not be added to state via udev change event")
}
}
}
func TestHandleEvent_ChangeAction(t *testing.T) {
m, tmpDir := setupTestManager(t)
um := &UdevMonitor{stop: make(chan struct{})}
brightnessPath := filepath.Join(tmpDir, "backlight", "intel_backlight", "brightness")
if err := os.WriteFile(brightnessPath, []byte("800\n"), 0644); err != nil {
t.Fatal(err)
}
event := netlink.UEvent{
Action: netlink.CHANGE,
Env: map[string]string{
"SUBSYSTEM": "backlight",
"DEVPATH": "/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight",
},
}
um.handleEvent(m, event)
state := m.GetState()
if state.Devices[0].Current != 800 {
t.Errorf("expected Current=800 after change event, got %d", state.Devices[0].Current)
}
}
func TestHandleEvent_MissingEnvVars(t *testing.T) {
m, _ := setupTestManager(t)
um := &UdevMonitor{stop: make(chan struct{})}
event := netlink.UEvent{
Action: netlink.CHANGE,
Env: map[string]string{},
}
um.handleEvent(m, event)
state := m.GetState()
if state.Devices[0].Current != 500 {
t.Error("state should be unchanged with missing env vars")
}
}
func TestHandleEvent_MissingSubsystem(t *testing.T) {
m, _ := setupTestManager(t)
um := &UdevMonitor{stop: make(chan struct{})}
event := netlink.UEvent{
Action: netlink.CHANGE,
Env: map[string]string{
"DEVPATH": "/devices/foo/bar",
},
}
um.handleEvent(m, event)
state := m.GetState()
if state.Devices[0].Current != 500 {
t.Error("state should be unchanged with missing SUBSYSTEM")
}
}
func TestHandleChange_BrightnessFileNotFound(t *testing.T) {
m, _ := setupTestManager(t)
um := &UdevMonitor{stop: make(chan struct{})}
um.handleChange(m, "backlight", "nonexistent_device")
state := m.GetState()
if state.Devices[0].Current != 500 {
t.Error("state should be unchanged when brightness file not found")
}
}
func TestHandleChange_InvalidBrightnessValue(t *testing.T) {
m, tmpDir := setupTestManager(t)
um := &UdevMonitor{stop: make(chan struct{})}
brightnessPath := filepath.Join(tmpDir, "backlight", "intel_backlight", "brightness")
if err := os.WriteFile(brightnessPath, []byte("not_a_number\n"), 0644); err != nil {
t.Fatal(err)
}
um.handleChange(m, "backlight", "intel_backlight")
state := m.GetState()
if state.Devices[0].Current != 500 {
t.Error("state should be unchanged with invalid brightness value")
}
}
func TestUdevMonitor_Close(t *testing.T) {
um := &UdevMonitor{stop: make(chan struct{})}
um.Close()
select {
case <-um.stop:
default:
t.Error("stop channel should be closed")
}
}
func TestHandleChange_NilSysfsBackend(t *testing.T) {
m := &Manager{
sysfsBackend: nil,
stopChan: make(chan struct{}),
}
um := &UdevMonitor{stop: make(chan struct{})}
um.handleChange(m, "backlight", "test_device")
}

View File

@@ -7,9 +7,9 @@ import (
) )
type Request struct { type Request struct {
ID int `json:"id"` ID int `json:"id"`
Method string `json:"method"` Method string `json:"method"`
Params map[string]interface{} `json:"params"` Params map[string]any `json:"params"`
} }
func HandleRequest(conn net.Conn, req Request, manager *Manager) { func HandleRequest(conn net.Conn, req Request, manager *Manager) {

View File

@@ -356,7 +356,7 @@ func TestHandleCreatePrinter(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.createPrinter", Method: "cups.createPrinter",
Params: map[string]interface{}{ Params: map[string]any{
"name": "newprinter", "name": "newprinter",
"deviceURI": "usb://HP", "deviceURI": "usb://HP",
"ppd": "generic.ppd", "ppd": "generic.ppd",
@@ -377,10 +377,10 @@ func TestHandleCreatePrinter_MissingParams(t *testing.T) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
conn := &mockConn{Buffer: buf} conn := &mockConn{Buffer: buf}
req := Request{ID: 1, Method: "cups.createPrinter", Params: map[string]interface{}{}} req := Request{ID: 1, Method: "cups.createPrinter", Params: map[string]any{}}
handleCreatePrinter(conn, req, m) handleCreatePrinter(conn, req, m)
var resp models.Response[interface{}] var resp models.Response[any]
err := json.NewDecoder(buf).Decode(&resp) err := json.NewDecoder(buf).Decode(&resp)
assert.NoError(t, err) assert.NoError(t, err)
assert.Nil(t, resp.Result) assert.Nil(t, resp.Result)
@@ -399,7 +399,7 @@ func TestHandleDeletePrinter(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.deletePrinter", Method: "cups.deletePrinter",
Params: map[string]interface{}{"printerName": "printer1"}, Params: map[string]any{"printerName": "printer1"},
} }
handleDeletePrinter(conn, req, m) handleDeletePrinter(conn, req, m)
@@ -422,7 +422,7 @@ func TestHandleAcceptJobs(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.acceptJobs", Method: "cups.acceptJobs",
Params: map[string]interface{}{"printerName": "printer1"}, Params: map[string]any{"printerName": "printer1"},
} }
handleAcceptJobs(conn, req, m) handleAcceptJobs(conn, req, m)
@@ -445,7 +445,7 @@ func TestHandleRejectJobs(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.rejectJobs", Method: "cups.rejectJobs",
Params: map[string]interface{}{"printerName": "printer1"}, Params: map[string]any{"printerName": "printer1"},
} }
handleRejectJobs(conn, req, m) handleRejectJobs(conn, req, m)
@@ -468,7 +468,7 @@ func TestHandleSetPrinterShared(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.setPrinterShared", Method: "cups.setPrinterShared",
Params: map[string]interface{}{"printerName": "printer1", "shared": true}, Params: map[string]any{"printerName": "printer1", "shared": true},
} }
handleSetPrinterShared(conn, req, m) handleSetPrinterShared(conn, req, m)
@@ -491,7 +491,7 @@ func TestHandleSetPrinterLocation(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.setPrinterLocation", Method: "cups.setPrinterLocation",
Params: map[string]interface{}{"printerName": "printer1", "location": "Office"}, Params: map[string]any{"printerName": "printer1", "location": "Office"},
} }
handleSetPrinterLocation(conn, req, m) handleSetPrinterLocation(conn, req, m)
@@ -514,7 +514,7 @@ func TestHandleSetPrinterInfo(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.setPrinterInfo", Method: "cups.setPrinterInfo",
Params: map[string]interface{}{"printerName": "printer1", "info": "Main Printer"}, Params: map[string]any{"printerName": "printer1", "info": "Main Printer"},
} }
handleSetPrinterInfo(conn, req, m) handleSetPrinterInfo(conn, req, m)
@@ -537,7 +537,7 @@ func TestHandleMoveJob(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.moveJob", Method: "cups.moveJob",
Params: map[string]interface{}{"jobID": float64(1), "destPrinter": "printer2"}, Params: map[string]any{"jobID": float64(1), "destPrinter": "printer2"},
} }
handleMoveJob(conn, req, m) handleMoveJob(conn, req, m)
@@ -560,7 +560,7 @@ func TestHandlePrintTestPage(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.printTestPage", Method: "cups.printTestPage",
Params: map[string]interface{}{"printerName": "printer1"}, Params: map[string]any{"printerName": "printer1"},
} }
handlePrintTestPage(conn, req, m) handlePrintTestPage(conn, req, m)
@@ -584,7 +584,7 @@ func TestHandleAddPrinterToClass(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.addPrinterToClass", Method: "cups.addPrinterToClass",
Params: map[string]interface{}{"className": "office", "printerName": "printer1"}, Params: map[string]any{"className": "office", "printerName": "printer1"},
} }
handleAddPrinterToClass(conn, req, m) handleAddPrinterToClass(conn, req, m)
@@ -607,7 +607,7 @@ func TestHandleRemovePrinterFromClass(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.removePrinterFromClass", Method: "cups.removePrinterFromClass",
Params: map[string]interface{}{"className": "office", "printerName": "printer1"}, Params: map[string]any{"className": "office", "printerName": "printer1"},
} }
handleRemovePrinterFromClass(conn, req, m) handleRemovePrinterFromClass(conn, req, m)
@@ -630,7 +630,7 @@ func TestHandleDeleteClass(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.deleteClass", Method: "cups.deleteClass",
Params: map[string]interface{}{"className": "office"}, Params: map[string]any{"className": "office"},
} }
handleDeleteClass(conn, req, m) handleDeleteClass(conn, req, m)
@@ -653,7 +653,7 @@ func TestHandleRestartJob(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.restartJob", Method: "cups.restartJob",
Params: map[string]interface{}{"jobID": float64(1)}, Params: map[string]any{"jobID": float64(1)},
} }
handleRestartJob(conn, req, m) handleRestartJob(conn, req, m)
@@ -676,7 +676,7 @@ func TestHandleHoldJob(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.holdJob", Method: "cups.holdJob",
Params: map[string]interface{}{"jobID": float64(1)}, Params: map[string]any{"jobID": float64(1)},
} }
handleHoldJob(conn, req, m) handleHoldJob(conn, req, m)
@@ -699,7 +699,7 @@ func TestHandleHoldJob_WithHoldUntil(t *testing.T) {
req := Request{ req := Request{
ID: 1, ID: 1,
Method: "cups.holdJob", Method: "cups.holdJob",
Params: map[string]interface{}{"jobID": float64(1), "holdUntil": "no-hold"}, Params: map[string]any{"jobID": float64(1), "holdUntil": "no-hold"},
} }
handleHoldJob(conn, req, m) handleHoldJob(conn, req, m)

View File

@@ -167,7 +167,7 @@ func (p *DBusPkHelper) JobSetHoldUntil(jobID int, holdUntil string) error {
return p.callSimple("JobSetHoldUntil", int32(jobID), holdUntil) return p.callSimple("JobSetHoldUntil", int32(jobID), holdUntil)
} }
func (p *DBusPkHelper) callSimple(method string, args ...interface{}) error { func (p *DBusPkHelper) callSimple(method string, args ...any) error {
var errStr string var errStr string
call := p.obj.Call(pkHelperInterface+"."+method, 0, args...) call := p.obj.Call(pkHelperInterface+"."+method, 0, args...)

View File

@@ -1346,7 +1346,7 @@ func Start(printDocs bool) error {
if wlContext != nil { if wlContext != nil {
go func() { go func() {
err := <-wlContext.FatalError() err := <-wlContext.FatalError()
fatalErrChan <- fmt.Errorf("Wayland context fatal error: %w", err) fatalErrChan <- fmt.Errorf("wayland context fatal error: %w", err)
}() }()
} }

View File

@@ -78,7 +78,7 @@ func NewManager(display *wlclient.Display, config Config) (*Manager, error) {
log.Info("Gamma control enabled at startup, initializing controls") log.Info("Gamma control enabled at startup, initializing controls")
gammaMgr := m.gammaControl.(*wlr_gamma_control.ZwlrGammaControlManagerV1) gammaMgr := m.gammaControl.(*wlr_gamma_control.ZwlrGammaControlManagerV1)
if err := func() error { if err := func() error {
var outputs []*wlclient.Output = m.availableOutputs outputs := m.availableOutputs
return m.setupOutputControls(outputs, gammaMgr) return m.setupOutputControls(outputs, gammaMgr)
}(); err != nil { }(); err != nil {
log.Errorf("Failed to initialize gamma controls: %v", err) log.Errorf("Failed to initialize gamma controls: %v", err)
@@ -573,6 +573,7 @@ func (m *Manager) transitionWorker() {
log.Debugf("Starting smooth transition: %dK -> %dK over %v", currentTemp, targetTemp, dur) log.Debugf("Starting smooth transition: %dK -> %dK over %v", currentTemp, targetTemp, dur)
stepLoop:
for i := 0; i <= steps; i++ { for i := 0; i <= steps; i++ {
select { select {
case newTarget := <-m.transitionChan: case newTarget := <-m.transitionChan:
@@ -580,7 +581,7 @@ func (m *Manager) transitionWorker() {
m.targetTemp = newTarget m.targetTemp = newTarget
m.transitionMutex.Unlock() m.transitionMutex.Unlock()
log.Debugf("Transition %dK -> %dK aborted (newer transition started)", currentTemp, targetTemp) log.Debugf("Transition %dK -> %dK aborted (newer transition started)", currentTemp, targetTemp)
break break stepLoop
default: default:
} }
@@ -1214,7 +1215,7 @@ func (m *Manager) SetEnabled(enabled bool) {
log.Info("Creating gamma controls") log.Info("Creating gamma controls")
gammaMgr := m.gammaControl.(*wlr_gamma_control.ZwlrGammaControlManagerV1) gammaMgr := m.gammaControl.(*wlr_gamma_control.ZwlrGammaControlManagerV1)
if err := func() error { if err := func() error {
var outputs []*wlclient.Output = m.availableOutputs outputs := m.availableOutputs
return m.setupOutputControls(outputs, gammaMgr) return m.setupOutputControls(outputs, gammaMgr)
}(); err != nil { }(); err != nil {
log.Errorf("Failed to create gamma controls: %v", err) log.Errorf("Failed to create gamma controls: %v", err)

View File

@@ -122,7 +122,7 @@ func (h *HttpAdapter) GetHttpUri(namespace string, object any) string {
} }
func (h *HttpAdapter) TestConnection() error { func (h *HttpAdapter) TestConnection() error {
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", h.host, h.port)) conn, err := net.Dial("tcp", net.JoinHostPort(h.host, fmt.Sprintf("%d", h.port)))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -59,7 +59,9 @@ override_dh_auto_install:
mkdir -p debian/dms-git/usr/share/quickshell/dms debian/dms-git/usr/lib/systemd/user mkdir -p debian/dms-git/usr/share/quickshell/dms debian/dms-git/usr/lib/systemd/user
if [ -d quickshell ]; then \ if [ -d quickshell ]; then \
cp -r quickshell/* debian/dms-git/usr/share/quickshell/dms/; \ cp -r quickshell/* debian/dms-git/usr/share/quickshell/dms/; \
install -Dm644 quickshell/assets/systemd/dms.service debian/dms-git/usr/lib/systemd/user/dms.service; \ install -Dm644 assets/systemd/dms.service debian/dms-git/usr/lib/systemd/user/dms.service; \
install -Dm644 assets/dms-open.desktop debian/dms-git/usr/share/applications/dms-open.desktop; \
install -Dm644 assets/danklogo.svg debian/dms-git/usr/share/icons/hicolor/scalable/apps/danklogo.svg; \
else \ else \
echo "ERROR: quickshell directory not found!" && \ echo "ERROR: quickshell directory not found!" && \
echo "Contents of current directory:" && ls -la && \ echo "Contents of current directory:" && ls -la && \

View File

@@ -55,7 +55,9 @@ override_dh_auto_install:
fi fi
if [ -d DankMaterialShell-$(UPSTREAM_VERSION) ]; then \ if [ -d DankMaterialShell-$(UPSTREAM_VERSION) ]; then \
cp -r DankMaterialShell-$(UPSTREAM_VERSION)/quickshell/* debian/dms/usr/share/quickshell/dms/; \ cp -r DankMaterialShell-$(UPSTREAM_VERSION)/quickshell/* debian/dms/usr/share/quickshell/dms/; \
install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/quickshell/assets/systemd/dms.service debian/dms/usr/lib/systemd/user/dms.service; \ install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/systemd/dms.service debian/dms/usr/lib/systemd/user/dms.service; \
install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/dms-open.desktop debian/dms/usr/share/applications/dms-open.desktop; \
install -Dm644 DankMaterialShell-$(UPSTREAM_VERSION)/assets/danklogo.svg debian/dms/usr/share/icons/hicolor/scalable/apps/danklogo.svg; \
else \ else \
echo "ERROR: DankMaterialShell-$(UPSTREAM_VERSION) directory not found!" && \ echo "ERROR: DankMaterialShell-$(UPSTREAM_VERSION) directory not found!" && \
echo "Contents of current directory:" && ls -la && \ echo "Contents of current directory:" && ls -la && \

View File

@@ -97,12 +97,12 @@ gunzip -c %{_builddir}/dgop.gz > %{_builddir}/dgop
chmod +x %{_builddir}/dgop chmod +x %{_builddir}/dgop
%build %build
# Build DMS CLI from source (core/ subdirectory in monorepo) # Build DMS CLI from source (core/subdirectory)
cd core cd core
make dist make dist
%install %install
# Install dms-cli binary (built from source) - use architecture-specific path # Install dms-cli binary (built from source)
case "%{_arch}" in case "%{_arch}" in
x86_64) x86_64)
DMS_BINARY="dms-linux-amd64" DMS_BINARY="dms-linux-amd64"
@@ -129,8 +129,12 @@ core/bin/${DMS_BINARY} completion fish > %{buildroot}%{_datadir}/fish/vendor_com
# Install dgop binary # Install dgop binary
install -Dm755 %{_builddir}/dgop %{buildroot}%{_bindir}/dgop install -Dm755 %{_builddir}/dgop %{buildroot}%{_bindir}/dgop
# Install systemd user service (from quickshell/ subdirectory) # Install systemd user service
install -Dm644 quickshell/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service
# Install desktop file and icon
install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop
install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
# Install shell files to shared data location (from quickshell/ subdirectory) # Install shell files to shared data location (from quickshell/ subdirectory)
install -dm755 %{buildroot}%{_datadir}/quickshell/dms install -dm755 %{buildroot}%{_datadir}/quickshell/dms
@@ -143,9 +147,8 @@ rm -rf %{buildroot}%{_datadir}/quickshell/dms/.github
rm -rf %{buildroot}%{_datadir}/quickshell/dms/distro rm -rf %{buildroot}%{_datadir}/quickshell/dms/distro
%posttrans %posttrans
# Clean up old installation path from previous versions (only if empty) # Clean up old installation path from previous versions
if [ -d "%{_sysconfdir}/xdg/quickshell/dms" ]; then if [ -d "%{_sysconfdir}/xdg/quickshell/dms" ]; then
# Remove directories only if empty (preserves any user-added files)
rmdir "%{_sysconfdir}/xdg/quickshell/dms" 2>/dev/null || true rmdir "%{_sysconfdir}/xdg/quickshell/dms" 2>/dev/null || true
rmdir "%{_sysconfdir}/xdg/quickshell" 2>/dev/null || true rmdir "%{_sysconfdir}/xdg/quickshell" 2>/dev/null || true
rmdir "%{_sysconfdir}/xdg" 2>/dev/null || true rmdir "%{_sysconfdir}/xdg" 2>/dev/null || true
@@ -162,6 +165,8 @@ fi
%doc quickshell/README.md %doc quickshell/README.md
%{_datadir}/quickshell/dms/ %{_datadir}/quickshell/dms/
%{_userunitdir}/dms.service %{_userunitdir}/dms.service
%{_datadir}/applications/dms-open.desktop
%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
%files -n dms-cli %files -n dms-cli
%{_bindir}/dms %{_bindir}/dms

View File

@@ -89,7 +89,10 @@ install -d %{buildroot}%{_datadir}/fish/vendor_completions.d
./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : ./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || :
./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : ./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || :
install -Dm644 quickshell/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service
install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop
install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
install -dm755 %{buildroot}%{_datadir}/quickshell/dms install -dm755 %{buildroot}%{_datadir}/quickshell/dms
cp -r quickshell/* %{buildroot}%{_datadir}/quickshell/dms/ cp -r quickshell/* %{buildroot}%{_datadir}/quickshell/dms/
@@ -125,6 +128,8 @@ fi
%dir %{_datadir}/quickshell %dir %{_datadir}/quickshell
%{_datadir}/quickshell/dms/ %{_datadir}/quickshell/dms/
%{_userunitdir}/dms.service %{_userunitdir}/dms.service
%{_datadir}/applications/dms-open.desktop
%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
%changelog %changelog
* Tue Nov 25 2025 Avenge Media <AvengeMedia.US@gmail.com> - 0.6.2+git2147.03073f68-1 * Tue Nov 25 2025 Avenge Media <AvengeMedia.US@gmail.com> - 0.6.2+git2147.03073f68-1

View File

@@ -63,7 +63,10 @@ install -d %{buildroot}%{_datadir}/fish/vendor_completions.d
./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || : ./dms completion zsh > %{buildroot}%{_datadir}/zsh/site-functions/_dms || :
./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || : ./dms completion fish > %{buildroot}%{_datadir}/fish/vendor_completions.d/dms.fish || :
install -Dm644 quickshell/assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service install -Dm644 assets/systemd/dms.service %{buildroot}%{_userunitdir}/dms.service
install -Dm644 assets/dms-open.desktop %{buildroot}%{_datadir}/applications/dms-open.desktop
install -Dm644 assets/danklogo.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
install -dm755 %{buildroot}%{_datadir}/quickshell/dms install -dm755 %{buildroot}%{_datadir}/quickshell/dms
cp -r quickshell/* %{buildroot}%{_datadir}/quickshell/dms/ cp -r quickshell/* %{buildroot}%{_datadir}/quickshell/dms/
@@ -100,6 +103,8 @@ fi
%dir %{_datadir}/quickshell %dir %{_datadir}/quickshell
%{_datadir}/quickshell/dms/ %{_datadir}/quickshell/dms/
%{_userunitdir}/dms.service %{_userunitdir}/dms.service
%{_datadir}/applications/dms-open.desktop
%{_datadir}/icons/hicolor/scalable/apps/danklogo.svg
%changelog %changelog
* Fri Nov 22 2025 AvengeMedia <maintainer@avengemedia.com> - 0.6.2-1 * Fri Nov 22 2025 AvengeMedia <maintainer@avengemedia.com> - 0.6.2-1

View File

@@ -53,9 +53,15 @@ override_dh_auto_install:
rm -rf debian/dms-git/usr/share/quickshell/dms/distro rm -rf debian/dms-git/usr/share/quickshell/dms/distro
# Install systemd user service # Install systemd user service
install -Dm644 dms-git-repo/quickshell/assets/systemd/dms.service \ install -Dm644 dms-git-repo/assets/systemd/dms.service \
debian/dms-git/usr/lib/systemd/user/dms.service debian/dms-git/usr/lib/systemd/user/dms.service
# Install desktop file and icon
install -Dm644 dms-git-repo/assets/dms-open.desktop \
debian/dms-git/usr/share/applications/dms-open.desktop
install -Dm644 dms-git-repo/assets/danklogo.svg \
debian/dms-git/usr/share/icons/hicolor/scalable/apps/danklogo.svg
override_dh_auto_clean: override_dh_auto_clean:
# Don't delete dms-git-repo directory - it's part of the source package (native format) # Don't delete dms-git-repo directory - it's part of the source package (native format)
# Clean up build artifacts # Clean up build artifacts

View File

@@ -45,9 +45,15 @@ override_dh_auto_install:
rm -rf debian/dms/usr/share/quickshell/dms/distro rm -rf debian/dms/usr/share/quickshell/dms/distro
# Install systemd user service # Install systemd user service
install -Dm644 DankMaterialShell-$(BASE_VERSION)/quickshell/assets/systemd/dms.service \ install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/systemd/dms.service \
debian/dms/usr/lib/systemd/user/dms.service debian/dms/usr/lib/systemd/user/dms.service
# Install desktop file and icon
install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/dms-open.desktop \
debian/dms/usr/share/applications/dms-open.desktop
install -Dm644 DankMaterialShell-$(BASE_VERSION)/assets/danklogo.svg \
debian/dms/usr/share/icons/hicolor/scalable/apps/danklogo.svg
# Generate and install shell completions (if applicable) # Generate and install shell completions (if applicable)
# Uncomment if dms supports completion generation # Uncomment if dms supports completion generation
# ./dms completion bash > dms.bash # ./dms completion bash > dms.bash

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env bash
# Build script wrapper for dms-cli core binaries
# Forwards make commands to core/Makefile
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CORE_DIR="$SCRIPT_DIR/core"
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Check if core directory exists
if [ ! -d "$CORE_DIR" ]; then
echo "Error: core directory not found at $CORE_DIR"
exit 1
fi
# If no arguments provided, build and install
if [ $# -eq 0 ]; then
echo -e "${BLUE}Building and installing DMS CLI binary...${NC}"
cd "$CORE_DIR"
make && sudo make install
exit 0
fi
# Forward all arguments to make in core directory
echo -e "${GREEN}Building in core directory...${NC}"
cd "$CORE_DIR"
make "$@"

View File

@@ -51,7 +51,7 @@
pname = "dmsCli"; pname = "dmsCli";
src = ./core; src = ./core;
vendorHash = "sha256-wruiGaQaixqYst/zkdxjOhjKCbj6GvSaM3IdtNTeo50="; vendorHash = "sha256-2PCqiW4frxME8IlmwWH5ktznhd/G1bah5Ae4dp0HPTQ=";
subPackages = ["cmd/dms"]; subPackages = ["cmd/dms"];

View File

@@ -0,0 +1,373 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import qs.Services
import qs.Widgets
Singleton {
id: root
property var activeModal: null
property bool windowsVisible: false
property var targetScreen: null
readonly property bool hasActiveModal: activeModal !== null
readonly property bool shouldShowModal: hasActiveModal
readonly property var screen: backgroundWindow.screen
readonly property real dpr: screen ? CompositorService.getScreenScale(screen) : 1
readonly property real shadowBuffer: 5
property bool wantsToHide: false
property real cachedModalWidth: 400
property real cachedModalHeight: 300
property real cachedModalX: 0
property real cachedModalY: 0
property var cachedModal: null
property int cachedAnimationDuration: Theme.shortDuration
property var cachedEnterCurve: Theme.expressiveCurves.expressiveFastSpatial
property var cachedExitCurve: Theme.expressiveCurves.expressiveFastSpatial
property real cachedScaleCollapsed: 0.96
readonly property real modalWidth: cachedModalWidth
readonly property real modalHeight: cachedModalHeight
readonly property real modalX: cachedModalX
readonly property real modalY: cachedModalY
Connections {
target: root.cachedModal
function onModalWidthChanged() {
if (!root.hasActiveModal)
return;
root.cachedModalWidth = Theme.px(root.cachedModal.modalWidth, root.dpr);
root.cachedModalX = root.calculateX(root.cachedModal);
}
function onModalHeightChanged() {
if (!root.hasActiveModal)
return;
root.cachedModalHeight = Theme.px(root.cachedModal.modalHeight, root.dpr);
root.cachedModalY = root.calculateY(root.cachedModal);
}
}
onScreenChanged: {
if (!cachedModal || !screen)
return;
cachedModalWidth = Theme.px(cachedModal.modalWidth, dpr);
cachedModalHeight = Theme.px(cachedModal.modalHeight, dpr);
cachedModalX = calculateX(cachedModal);
cachedModalY = calculateY(cachedModal);
}
function showModal(modal) {
wantsToHide = false;
targetScreen = CompositorService.focusedScreen;
activeModal = modal;
cachedModal = modal;
windowsVisible = true;
cachedModalWidth = Theme.px(modal.modalWidth, dpr);
cachedModalHeight = Theme.px(modal.modalHeight, dpr);
cachedModalX = calculateX(modal);
cachedModalY = calculateY(modal);
cachedAnimationDuration = modal.animationDuration ?? Theme.shortDuration;
cachedEnterCurve = modal.animationEnterCurve ?? Theme.expressiveCurves.expressiveFastSpatial;
cachedExitCurve = modal.animationExitCurve ?? Theme.expressiveCurves.expressiveFastSpatial;
cachedScaleCollapsed = modal.animationScaleCollapsed ?? 0.96;
if (modal.directContent)
Qt.callLater(focusDirectContent);
}
function focusDirectContent() {
if (!hasActiveModal)
return;
if (!cachedModal?.directContent)
return;
cachedModal.directContent.forceActiveFocus();
}
function hideModal() {
wantsToHide = true;
Qt.callLater(completeHide);
}
function completeHide() {
if (!wantsToHide)
return;
activeModal = null;
wantsToHide = false;
}
function hideModalInstant() {
wantsToHide = false;
activeModal = null;
windowsVisible = false;
cleanupInputMethod();
}
function onCloseAnimationFinished() {
if (hasActiveModal)
return;
if (cachedModal && typeof cachedModal.onFullyClosed === "function")
cachedModal.onFullyClosed();
cleanupInputMethod();
windowsVisible = false;
}
function cleanupInputMethod() {
if (!Qt.inputMethod)
return;
Qt.inputMethod.hide();
Qt.inputMethod.reset();
}
function calculateX(m) {
const screen = backgroundWindow.screen;
if (!screen)
return 0;
const w = Theme.px(m.modalWidth, dpr);
switch (m.positioning) {
case "center":
return Theme.snap((screen.width - w) / 2, dpr);
case "top-right":
return Theme.snap(Math.max(Theme.spacingL, screen.width - w - Theme.spacingL), dpr);
case "custom":
return Theme.snap(m.customPosition.x, dpr);
default:
return 0;
}
}
function calculateY(m) {
const screen = backgroundWindow.screen;
if (!screen)
return 0;
const h = Theme.px(m.modalHeight, dpr);
switch (m.positioning) {
case "center":
return Theme.snap((screen.height - h) / 2, dpr);
case "top-right":
return Theme.snap(Theme.barHeight + Theme.spacingXS, dpr);
case "custom":
return Theme.snap(m.customPosition.y, dpr);
default:
return 0;
}
}
PanelWindow {
id: backgroundWindow
visible: root.windowsVisible
screen: root.targetScreen
color: "transparent"
WlrLayershell.namespace: "dms:modal:background"
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
anchors {
top: true
left: true
right: true
bottom: true
}
mask: Region {
item: backgroundMaskRect
intersection: Intersection.Xor
}
Item {
id: backgroundMaskRect
x: root.shouldShowModal ? root.modalX : 0
y: root.shouldShowModal ? root.modalY : 0
width: root.shouldShowModal ? root.modalWidth : (backgroundWindow.screen?.width ?? 1920)
height: root.shouldShowModal ? root.modalHeight : (backgroundWindow.screen?.height ?? 1080)
}
MouseArea {
anchors.fill: parent
enabled: root.windowsVisible
onClicked: mouse => {
if (!root.cachedModal || !root.shouldShowModal)
return;
if (!(root.cachedModal.closeOnBackgroundClick ?? true))
return;
const outside = mouse.x < root.modalX || mouse.x > root.modalX + root.modalWidth || mouse.y < root.modalY || mouse.y > root.modalY + root.modalHeight;
if (!outside)
return;
root.cachedModal.backgroundClicked();
}
}
Rectangle {
anchors.fill: parent
color: "black"
opacity: root.shouldShowModal && SettingsData.modalDarkenBackground ? (root.cachedModal?.backgroundOpacity ?? 0.5) : 0
visible: SettingsData.modalDarkenBackground
Behavior on opacity {
NumberAnimation {
duration: root.cachedAnimationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldShowModal ? root.cachedEnterCurve : root.cachedExitCurve
}
}
}
}
PanelWindow {
id: contentWindow
visible: root.windowsVisible
screen: root.targetScreen
color: "transparent"
WlrLayershell.namespace: root.cachedModal?.layerNamespace ?? "dms:modal"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: {
if (!root.hasActiveModal)
return WlrKeyboardFocus.None;
if (root.cachedModal?.customKeyboardFocus !== null && root.cachedModal?.customKeyboardFocus !== undefined)
return root.cachedModal.customKeyboardFocus;
if (CompositorService.isHyprland)
return WlrKeyboardFocus.OnDemand;
return WlrKeyboardFocus.Exclusive;
}
anchors {
left: true
top: true
}
WlrLayershell.margins {
left: Math.max(0, Theme.snap(root.modalX - root.shadowBuffer, root.dpr))
top: Math.max(0, Theme.snap(root.modalY - root.shadowBuffer, root.dpr))
}
implicitWidth: root.modalWidth + (root.shadowBuffer * 2)
implicitHeight: root.modalHeight + (root.shadowBuffer * 2)
mask: Region {
item: contentMaskRect
}
Item {
id: contentMaskRect
x: root.shadowBuffer
y: root.shadowBuffer
width: root.shouldShowModal ? root.modalWidth : 0
height: root.shouldShowModal ? root.modalHeight : 0
}
HyprlandFocusGrab {
windows: [contentWindow]
active: CompositorService.isHyprland && root.hasActiveModal && (root.cachedModal?.shouldHaveFocus ?? false)
}
Item {
id: contentContainer
x: root.shadowBuffer
y: root.shadowBuffer
width: root.modalWidth
height: root.modalHeight
readonly property bool hasDirectContent: root.cachedModal ? (root.cachedModal.directContent !== null && root.cachedModal.directContent !== undefined) : false
opacity: root.shouldShowModal ? 1 : 0
scale: root.shouldShowModal ? 1 : root.cachedScaleCollapsed
onHasDirectContentChanged: {
if (!hasDirectContent)
return;
const dc = root.cachedModal.directContent;
if (dc.parent === directContentWrapper)
return;
dc.parent = directContentWrapper;
dc.anchors.fill = directContentWrapper;
}
Behavior on opacity {
NumberAnimation {
id: opacityAnimation
duration: root.cachedAnimationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldShowModal ? root.cachedEnterCurve : root.cachedExitCurve
onRunningChanged: {
if (running || root.shouldShowModal)
return;
root.onCloseAnimationFinished();
}
}
}
Behavior on scale {
NumberAnimation {
id: scaleAnimation
duration: root.cachedAnimationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldShowModal ? root.cachedEnterCurve : root.cachedExitCurve
}
}
DankRectangle {
anchors.fill: parent
color: root.cachedModal?.backgroundColor ?? Theme.surfaceContainer
borderColor: root.cachedModal?.borderColor ?? Theme.outlineMedium
borderWidth: root.cachedModal?.borderWidth ?? 1
radius: root.cachedModal?.cornerRadius ?? Theme.cornerRadius
z: -1
}
FocusScope {
id: modalFocusScope
anchors.fill: parent
focus: root.hasActiveModal
Keys.onEscapePressed: event => {
if (!root.cachedModal?.closeOnEscapeKey)
return;
root.cachedModal.close();
event.accepted = true;
}
Keys.forwardTo: contentContainer.hasDirectContent ? [directContentWrapper] : (contentLoader.item ? [contentLoader.item] : [])
Item {
id: directContentWrapper
anchors.fill: parent
visible: contentContainer.hasDirectContent
focus: contentContainer.hasDirectContent && root.hasActiveModal
}
Loader {
id: contentLoader
anchors.fill: parent
active: !contentContainer.hasDirectContent && root.windowsVisible
asynchronous: false
sourceComponent: root.cachedModal?.content ?? null
visible: !contentContainer.hasDirectContent
focus: !contentContainer.hasDirectContent && root.hasActiveModal
onLoaded: {
if (!item)
return;
if (root.cachedModal)
root.cachedModal.loadedContent = item;
if (root.hasActiveModal)
item.forceActiveFocus();
}
onActiveChanged: {
if (active || !root.cachedModal)
return;
root.cachedModal.loadedContent = null;
}
}
}
}
}
}

View File

@@ -30,6 +30,11 @@ Singleton {
onTriggered: root.suppressOSD = false onTriggered: root.suppressOSD = false
} }
function suppressOSDTemporarily() {
suppressOSD = true;
osdSuppressTimer.restart();
}
Connections { Connections {
target: SessionService target: SessionService
function onSessionResumed() { function onSessionResumed() {
@@ -856,6 +861,13 @@ Singleton {
return brightnessUserSetValues[deviceName]; return brightnessUserSetValues[deviceName];
} }
function clearBrightnessUserSetValue(deviceName) {
var newValues = Object.assign({}, brightnessUserSetValues);
delete newValues[deviceName];
brightnessUserSetValues = newValues;
saveSettings();
}
function setBrightnessExponent(deviceName, exponent) { function setBrightnessExponent(deviceName, exponent) {
var newValues = Object.assign({}, brightnessExponentValues); var newValues = Object.assign({}, brightnessExponentValues);
if (exponent !== undefined && exponent !== null) { if (exponent !== undefined && exponent !== null) {

View File

@@ -25,6 +25,8 @@ import qs.Services
Item { Item {
id: root id: root
readonly property bool _forceDisplayService: DisplayService.brightnessAvailable !== undefined
Instantiator { Instantiator {
id: daemonPluginInstantiator id: daemonPluginInstantiator
asynchronous: true asynchronous: true

View File

@@ -1,5 +1,4 @@
import QtQuick import QtQuick
import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services import qs.Services
@@ -10,11 +9,6 @@ DankModal {
layerNamespace: "dms:bluetooth-pairing" layerNamespace: "dms:bluetooth-pairing"
HyprlandFocusGrab {
windows: [root.contentWindow]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property string deviceName: "" property string deviceName: ""
property string deviceAddress: "" property string deviceAddress: ""
property string requestType: "" property string requestType: ""

View File

@@ -1,10 +1,9 @@
import QtQuick import QtQuick
import qs.Common import qs.Common
import qs.Services
import qs.Widgets import qs.Widgets
import qs.Modals.Clipboard import qs.Modals.Clipboard
Item { FocusScope {
id: clipboardContent id: clipboardContent
required property var modal required property var modal
@@ -15,6 +14,7 @@ Item {
property alias clipboardListView: clipboardListView property alias clipboardListView: clipboardListView
anchors.fill: parent anchors.fill: parent
focus: true
Column { Column {
anchors.fill: parent anchors.fill: parent
@@ -31,14 +31,13 @@ Item {
onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints
onClearAllClicked: { onClearAllClicked: {
clearConfirmDialog.show(I18n.tr("Clear All History?"), I18n.tr("This will permanently delete all clipboard history."), function () { clearConfirmDialog.show(I18n.tr("Clear All History?"), I18n.tr("This will permanently delete all clipboard history."), function () {
modal.clearAll() modal.clearAll();
modal.hide() modal.hide();
}, function () {}) }, function () {});
} }
onCloseClicked: modal.hide() onCloseClicked: modal.hide()
} }
// Search Field
DankTextField { DankTextField {
id: searchField id: searchField
width: parent.width width: parent.width
@@ -47,27 +46,24 @@ Item {
showClearButton: true showClearButton: true
focus: true focus: true
ignoreTabKeys: true ignoreTabKeys: true
keyForwardTargets: [modal.modalFocusScope]
onTextChanged: { onTextChanged: {
modal.searchText = text modal.searchText = text;
modal.updateFilteredModel() modal.updateFilteredModel();
} }
Keys.onEscapePressed: function (event) { Keys.onPressed: event => {
modal.hide() if (event.key === Qt.Key_Escape) {
event.accepted = true modal.hide();
} event.accepted = true;
Component.onCompleted: { return;
Qt.callLater(function () { }
forceActiveFocus() modal.keyboardController?.handleKey(event);
})
} }
Component.onCompleted: Qt.callLater(() => forceActiveFocus())
Connections { Connections {
target: modal target: modal
function onOpened() { function onOpened() {
Qt.callLater(function () { Qt.callLater(() => searchField.forceActiveFocus());
searchField.forceActiveFocus()
})
} }
} }
} }
@@ -97,21 +93,21 @@ Item {
function ensureVisible(index) { function ensureVisible(index) {
if (index < 0 || index >= count) { if (index < 0 || index >= count) {
return return;
} }
const itemHeight = ClipboardConstants.itemHeight + spacing const itemHeight = ClipboardConstants.itemHeight + spacing;
const itemY = index * itemHeight const itemY = index * itemHeight;
const itemBottom = itemY + itemHeight const itemBottom = itemY + itemHeight;
if (itemY < contentY) { if (itemY < contentY) {
contentY = itemY contentY = itemY;
} else if (itemBottom > contentY + height) { } else if (itemBottom > contentY + height) {
contentY = itemBottom - height contentY = itemBottom - height;
} }
} }
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (clipboardContent.modal && clipboardContent.modal.keyboardNavigationActive && currentIndex >= 0) { if (clipboardContent.modal && clipboardContent.modal.keyboardNavigationActive && currentIndex >= 0) {
ensureVisible(currentIndex) ensureVisible(currentIndex);
} }
} }

View File

@@ -2,7 +2,6 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
@@ -13,11 +12,6 @@ DankModal {
layerNamespace: "dms:clipboard" layerNamespace: "dms:clipboard"
HyprlandFocusGrab {
windows: [clipboardHistoryModal.contentWindow]
active: CompositorService.isHyprland && clipboardHistoryModal.shouldHaveFocus
}
property int totalCount: 0 property int totalCount: 0
property var clipboardEntries: [] property var clipboardEntries: []
property string searchText: "" property string searchText: ""
@@ -148,11 +142,10 @@ DankModal {
borderWidth: 1 borderWidth: 1
enableShadow: true enableShadow: true
onBackgroundClicked: hide() onBackgroundClicked: hide()
modalFocusScope.Keys.onPressed: function (event) {
keyboardController.handleKey(event);
}
content: clipboardContent content: clipboardContent
property alias keyboardController: keyboardController
ClipboardKeyboardController { ClipboardKeyboardController {
id: keyboardController id: keyboardController
modal: clipboardHistoryModal modal: clipboardHistoryModal
@@ -165,13 +158,11 @@ DankModal {
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) {
clipboardHistoryModal.shouldHaveFocus = false; clipboardHistoryModal.shouldHaveFocus = false;
} else if (clipboardHistoryModal.shouldBeVisible) { return;
clipboardHistoryModal.shouldHaveFocus = true;
clipboardHistoryModal.modalFocusScope.forceActiveFocus();
if (clipboardHistoryModal.contentLoader.item && clipboardHistoryModal.contentLoader.item.searchField) {
clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus();
}
} }
if (!clipboardHistoryModal.shouldBeVisible)
return;
clipboardHistoryModal.shouldHaveFocus = true;
} }
} }

View File

@@ -61,29 +61,21 @@ DankModal {
shouldBeVisible: false shouldBeVisible: false
allowStacking: true allowStacking: true
modalWidth: 350 modalWidth: 350
modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 160 modalHeight: 160
enableShadow: true enableShadow: true
shouldHaveFocus: true shouldHaveFocus: true
onBackgroundClicked: { onBackgroundClicked: {
close(); close();
if (onCancel) { if (onCancel)
onCancel(); onCancel();
}
} }
onOpened: {
Qt.callLater(function () { function handleKey(event) {
modalFocusScope.forceActiveFocus();
modalFocusScope.focus = true;
shouldHaveFocus = true;
});
}
modalFocusScope.Keys.onPressed: function (event) {
switch (event.key) { switch (event.key) {
case Qt.Key_Escape: case Qt.Key_Escape:
close(); close();
if (onCancel) { if (onCancel)
onCancel(); onCancel();
}
event.accepted = true; event.accepted = true;
break; break;
case Qt.Key_Left: case Qt.Key_Left:
@@ -99,46 +91,46 @@ DankModal {
event.accepted = true; event.accepted = true;
break; break;
case Qt.Key_N: case Qt.Key_N:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = (selectedButton + 1) % 2; keyboardNavigation = true;
event.accepted = true; selectedButton = (selectedButton + 1) % 2;
} event.accepted = true;
break; break;
case Qt.Key_P: case Qt.Key_P:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = selectedButton === -1 ? 1 : (selectedButton - 1 + 2) % 2; keyboardNavigation = true;
event.accepted = true; selectedButton = selectedButton === -1 ? 1 : (selectedButton - 1 + 2) % 2;
} event.accepted = true;
break; break;
case Qt.Key_J: case Qt.Key_J:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = 1; keyboardNavigation = true;
event.accepted = true; selectedButton = 1;
} event.accepted = true;
break; break;
case Qt.Key_K: case Qt.Key_K:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = 0; keyboardNavigation = true;
event.accepted = true; selectedButton = 0;
} event.accepted = true;
break; break;
case Qt.Key_H: case Qt.Key_H:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = 0; keyboardNavigation = true;
event.accepted = true; selectedButton = 0;
} event.accepted = true;
break; break;
case Qt.Key_L: case Qt.Key_L:
if (event.modifiers & Qt.ControlModifier) { if (!(event.modifiers & Qt.ControlModifier))
keyboardNavigation = true; return;
selectedButton = 1; keyboardNavigation = true;
event.accepted = true; selectedButton = 1;
} event.accepted = true;
break; break;
case Qt.Key_Tab: case Qt.Key_Tab:
keyboardNavigation = true; keyboardNavigation = true;
@@ -147,9 +139,9 @@ DankModal {
break; break;
case Qt.Key_Return: case Qt.Key_Return:
case Qt.Key_Enter: case Qt.Key_Enter:
if (selectedButton !== -1) { if (selectedButton !== -1)
selectButton(); selectButton();
} else { else {
selectedButton = 1; selectedButton = 1;
selectButton(); selectButton();
} }
@@ -159,10 +151,13 @@ DankModal {
} }
content: Component { content: Component {
Item { FocusScope {
anchors.fill: parent anchors.fill: parent
focus: true
implicitHeight: mainColumn.implicitHeight implicitHeight: mainColumn.implicitHeight
Keys.onPressed: event => root.handleKey(event)
Column { Column {
id: mainColumn id: mainColumn
anchors.left: parent.left anchors.left: parent.left

View File

@@ -1,24 +1,19 @@
import QtQuick import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Common import qs.Common
import qs.Services
import qs.Widgets
Item { Item {
id: root id: root
property string layerNamespace: "dms:modal" property string layerNamespace: "dms:modal"
property alias content: contentLoader.sourceComponent property Component content: null
property alias contentLoader: contentLoader
property Item directContent: null property Item directContent: null
property Item loadedContent: null
readonly property var contentLoader: QtObject {
readonly property var item: root.directContent ?? root.loadedContent
}
property real modalWidth: 400 property real modalWidth: 400
property real modalHeight: 300 property real modalHeight: 300
property var targetScreen property var targetScreen: null
readonly property var effectiveScreen: targetScreen || contentWindow.screen
readonly property real screenWidth: effectiveScreen?.width
readonly property real screenHeight: effectiveScreen?.height
readonly property real dpr: effectiveScreen ? CompositorService.getScreenScale(effectiveScreen) : 1
property bool showBackground: true property bool showBackground: true
property real backgroundOpacity: 0.5 property real backgroundOpacity: 0.5
property string positioning: "center" property string positioning: "center"
@@ -36,7 +31,6 @@ Item {
property real borderWidth: 1 property real borderWidth: 1
property real cornerRadius: Theme.cornerRadius property real cornerRadius: Theme.cornerRadius
property bool enableShadow: false property bool enableShadow: false
property alias modalFocusScope: focusScope
property bool shouldBeVisible: false property bool shouldBeVisible: false
property bool shouldHaveFocus: shouldBeVisible property bool shouldHaveFocus: shouldBeVisible
property bool allowFocusOverride: false property bool allowFocusOverride: false
@@ -45,48 +39,41 @@ Item {
property bool keepPopoutsOpen: false property bool keepPopoutsOpen: false
property var customKeyboardFocus: null property var customKeyboardFocus: null
property bool useOverlayLayer: false property bool useOverlayLayer: false
readonly property alias contentWindow: contentWindow
readonly property alias backgroundWindow: backgroundWindow
signal opened signal opened
signal dialogClosed signal dialogClosed
signal backgroundClicked signal backgroundClicked
property bool animationsEnabled: true onBackgroundClicked: {
readonly property bool useBackgroundWindow: true if (closeOnBackgroundClick)
close();
}
function open() { function open() {
ModalManager.openModal(root); ModalManager.openModal(root);
closeTimer.stop();
shouldBeVisible = true; shouldBeVisible = true;
contentWindow.visible = false; shouldHaveFocus = true;
if (useBackgroundWindow) DankModalWindow.showModal(root);
backgroundWindow.visible = true; opened();
Qt.callLater(() => { }
contentWindow.visible = true;
shouldHaveFocus = false; function openCentered() {
Qt.callLater(() => { positioning = "center";
shouldHaveFocus = Qt.binding(() => shouldBeVisible); open();
});
});
} }
function close() { function close() {
shouldBeVisible = false; shouldBeVisible = false;
shouldHaveFocus = false; shouldHaveFocus = false;
closeTimer.restart(); DankModalWindow.hideModal();
dialogClosed();
} }
function instantClose() { function instantClose() {
animationsEnabled = false;
shouldBeVisible = false; shouldBeVisible = false;
shouldHaveFocus = false; shouldHaveFocus = false;
closeTimer.stop(); DankModalWindow.hideModalInstant();
contentWindow.visible = false;
if (useBackgroundWindow)
backgroundWindow.visible = false;
dialogClosed(); dialogClosed();
Qt.callLater(() => animationsEnabled = true);
} }
function toggle() { function toggle() {
@@ -96,322 +83,9 @@ Item {
Connections { Connections {
target: ModalManager target: ModalManager
function onCloseAllModalsExcept(excludedModal) { function onCloseAllModalsExcept(excludedModal) {
if (excludedModal !== root && !allowStacking && shouldBeVisible) { if (excludedModal === root || allowStacking || !shouldBeVisible)
close(); return;
} close();
}
}
Timer {
id: closeTimer
interval: animationDuration + 120
onTriggered: {
if (!shouldBeVisible) {
contentWindow.visible = false;
if (useBackgroundWindow)
backgroundWindow.visible = false;
dialogClosed();
}
}
}
readonly property real shadowBuffer: 5
readonly property real alignedWidth: Theme.px(modalWidth, dpr)
readonly property real alignedHeight: Theme.px(modalHeight, dpr)
readonly property real alignedX: Theme.snap((() => {
switch (positioning) {
case "center":
return (screenWidth - alignedWidth) / 2;
case "top-right":
return Math.max(Theme.spacingL, screenWidth - alignedWidth - Theme.spacingL);
case "custom":
return customPosition.x;
default:
return 0;
}
})(), dpr)
readonly property real alignedY: Theme.snap((() => {
switch (positioning) {
case "center":
return (screenHeight - alignedHeight) / 2;
case "top-right":
return Theme.barHeight + Theme.spacingXS;
case "custom":
return customPosition.y;
default:
return 0;
}
})(), dpr)
PanelWindow {
id: backgroundWindow
visible: false
color: "transparent"
WlrLayershell.namespace: root.layerNamespace + ":background"
WlrLayershell.layer: WlrLayershell.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
anchors {
top: true
left: true
right: true
bottom: true
}
mask: Region {
item: Rectangle {
x: root.alignedX
y: root.alignedY
width: root.shouldBeVisible ? root.alignedWidth : 0
height: root.shouldBeVisible ? root.alignedHeight : 0
}
intersection: Intersection.Xor
}
MouseArea {
anchors.fill: parent
enabled: root.closeOnBackgroundClick && root.shouldBeVisible
onClicked: mouse => {
const clickX = mouse.x;
const clickY = mouse.y;
const outsideContent = clickX < root.alignedX || clickX > root.alignedX + root.alignedWidth || clickY < root.alignedY || clickY > root.alignedY + root.alignedHeight;
if (!outsideContent)
return;
root.backgroundClicked();
}
}
Rectangle {
id: background
anchors.fill: parent
color: "black"
opacity: root.showBackground && SettingsData.modalDarkenBackground ? (root.shouldBeVisible ? root.backgroundOpacity : 0) : 0
visible: root.showBackground && SettingsData.modalDarkenBackground
Behavior on opacity {
enabled: root.animationsEnabled
NumberAnimation {
duration: root.animationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
}
}
}
}
PanelWindow {
id: contentWindow
visible: false
color: "transparent"
WlrLayershell.namespace: root.layerNamespace
WlrLayershell.layer: {
if (root.useOverlayLayer)
return WlrLayershell.Overlay;
switch (Quickshell.env("DMS_MODAL_LAYER")) {
case "bottom":
console.error("DankModal: 'bottom' layer is not valid for modals. Defaulting to 'top' layer.");
return WlrLayershell.Top;
case "background":
console.error("DankModal: 'background' layer is not valid for modals. Defaulting to 'top' layer.");
return WlrLayershell.Top;
case "overlay":
return WlrLayershell.Overlay;
default:
return WlrLayershell.Top;
}
}
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: {
if (customKeyboardFocus !== null)
return customKeyboardFocus;
if (!shouldHaveFocus)
return WlrKeyboardFocus.None;
if (CompositorService.isHyprland)
return WlrKeyboardFocus.OnDemand;
return WlrKeyboardFocus.Exclusive;
}
anchors {
left: true
top: true
}
WlrLayershell.margins {
left: Math.max(0, Theme.snap(root.alignedX - shadowBuffer, dpr))
top: Math.max(0, Theme.snap(root.alignedY - shadowBuffer, dpr))
}
implicitWidth: root.alignedWidth + (shadowBuffer * 2)
implicitHeight: root.alignedHeight + (shadowBuffer * 2)
onVisibleChanged: {
if (visible) {
opened();
} else {
if (Qt.inputMethod) {
Qt.inputMethod.hide();
Qt.inputMethod.reset();
}
}
}
Item {
id: modalContainer
x: shadowBuffer
y: shadowBuffer
width: root.alignedWidth
height: root.alignedHeight
readonly property bool slide: root.animationType === "slide"
readonly property real offsetX: slide ? 15 : 0
readonly property real offsetY: slide ? -30 : root.animationOffset
property real animX: 0
property real animY: 0
property real scaleValue: root.animationScaleCollapsed
onOffsetXChanged: animX = Theme.snap(root.shouldBeVisible ? 0 : offsetX, root.dpr)
onOffsetYChanged: animY = Theme.snap(root.shouldBeVisible ? 0 : offsetY, root.dpr)
Connections {
target: root
function onShouldBeVisibleChanged() {
modalContainer.animX = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetX, root.dpr);
modalContainer.animY = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetY, root.dpr);
modalContainer.scaleValue = root.shouldBeVisible ? 1.0 : root.animationScaleCollapsed;
}
}
Behavior on animX {
enabled: root.animationsEnabled
NumberAnimation {
duration: root.animationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
}
}
Behavior on animY {
enabled: root.animationsEnabled
NumberAnimation {
duration: root.animationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
}
}
Behavior on scaleValue {
enabled: root.animationsEnabled
NumberAnimation {
duration: root.animationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
}
}
Item {
id: contentContainer
anchors.centerIn: parent
width: parent.width
height: parent.height
clip: false
Item {
id: animatedContent
anchors.fill: parent
clip: false
opacity: root.shouldBeVisible ? 1 : 0
scale: modalContainer.scaleValue
x: Theme.snap(modalContainer.animX, root.dpr) + (parent.width - width) * (1 - modalContainer.scaleValue) * 0.5
y: Theme.snap(modalContainer.animY, root.dpr) + (parent.height - height) * (1 - modalContainer.scaleValue) * 0.5
Behavior on opacity {
enabled: root.animationsEnabled
NumberAnimation {
duration: animationDuration
easing.type: Easing.BezierSpline
easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve
}
}
DankRectangle {
anchors.fill: parent
color: root.backgroundColor
borderColor: root.borderColor
borderWidth: root.borderWidth
radius: root.cornerRadius
}
FocusScope {
anchors.fill: parent
focus: root.shouldBeVisible
clip: false
Item {
id: directContentWrapper
anchors.fill: parent
visible: root.directContent !== null
focus: true
clip: false
Component.onCompleted: {
if (root.directContent) {
root.directContent.parent = directContentWrapper;
root.directContent.anchors.fill = directContentWrapper;
Qt.callLater(() => root.directContent.forceActiveFocus());
}
}
Connections {
target: root
function onDirectContentChanged() {
if (root.directContent) {
root.directContent.parent = directContentWrapper;
root.directContent.anchors.fill = directContentWrapper;
Qt.callLater(() => root.directContent.forceActiveFocus());
}
}
}
}
Loader {
id: contentLoader
anchors.fill: parent
active: root.directContent === null && (root.keepContentLoaded || root.shouldBeVisible || contentWindow.visible)
asynchronous: false
focus: true
clip: false
visible: root.directContent === null
onLoaded: {
if (item) {
Qt.callLater(() => item.forceActiveFocus());
}
}
}
}
}
}
}
FocusScope {
id: focusScope
objectName: "modalFocusScope"
anchors.fill: parent
visible: root.shouldBeVisible || contentWindow.visible
focus: root.shouldBeVisible
Keys.onEscapePressed: event => {
if (root.closeOnEscapeKey && shouldHaveFocus) {
root.close();
event.accepted = true;
}
}
} }
} }
} }

View File

@@ -1,6 +1,5 @@
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services import qs.Services
@@ -11,11 +10,6 @@ DankModal {
layerNamespace: "dms:color-picker" layerNamespace: "dms:color-picker"
HyprlandFocusGrab {
windows: [root.contentWindow]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property string pickerTitle: I18n.tr("Choose Color") property string pickerTitle: I18n.tr("Choose Color")
property color selectedColor: SessionData.recentColors.length > 0 ? SessionData.recentColors[0] : Theme.primary property color selectedColor: SessionData.recentColors.length > 0 ? SessionData.recentColors[0] : Theme.primary
property var onColorSelectedCallback: null property var onColorSelectedCallback: null

View File

@@ -1,5 +1,4 @@
import QtQuick import QtQuick
import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services import qs.Services
@@ -17,12 +16,6 @@ DankModal {
modalWidth: _maxW modalWidth: _maxW
modalHeight: _maxH modalHeight: _maxH
onBackgroundClicked: close() onBackgroundClicked: close()
onOpened: () => Qt.callLater(() => modalFocusScope.forceActiveFocus())
HyprlandFocusGrab {
windows: [root.contentWindow]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
function scrollDown() { function scrollDown() {
if (!root.activeFlickable) if (!root.activeFlickable)
@@ -40,25 +33,35 @@ DankModal {
root.activeFlickable.contentY = newY; root.activeFlickable.contentY = newY;
} }
modalFocusScope.Keys.onPressed: event => {
if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
scrollDown();
event.accepted = true;
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
scrollUp();
event.accepted = true;
} else if (event.key === Qt.Key_Down) {
scrollDown();
event.accepted = true;
} else if (event.key === Qt.Key_Up) {
scrollUp();
event.accepted = true;
}
}
content: Component { content: Component {
Item { FocusScope {
anchors.fill: parent anchors.fill: parent
focus: true
Keys.onPressed: event => {
switch (event.key) {
case Qt.Key_J:
if (!(event.modifiers & Qt.ControlModifier))
return;
root.scrollDown();
event.accepted = true;
break;
case Qt.Key_K:
if (!(event.modifiers & Qt.ControlModifier))
return;
root.scrollUp();
event.accepted = true;
break;
case Qt.Key_Down:
root.scrollDown();
event.accepted = true;
break;
case Qt.Key_Up:
root.scrollUp();
event.accepted = true;
break;
}
}
Column { Column {
anchors.fill: parent anchors.fill: parent

View File

@@ -1,5 +1,4 @@
import QtQuick import QtQuick
import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
@@ -11,11 +10,6 @@ DankModal {
layerNamespace: "dms:notification-center-modal" layerNamespace: "dms:notification-center-modal"
HyprlandFocusGrab {
windows: [notificationModal.contentWindow]
active: CompositorService.isHyprland && notificationModal.shouldHaveFocus
}
property bool notificationModalOpen: false property bool notificationModalOpen: false
property var notificationListRef: null property var notificationListRef: null
@@ -61,9 +55,6 @@ DankModal {
modalHeight: 700 modalHeight: 700
visible: false visible: false
onBackgroundClicked: hide() onBackgroundClicked: hide()
onOpened: () => {
Qt.callLater(() => modalFocusScope.forceActiveFocus());
}
onShouldBeVisibleChanged: shouldBeVisible => { onShouldBeVisibleChanged: shouldBeVisible => {
if (!shouldBeVisible) { if (!shouldBeVisible) {
notificationModalOpen = false; notificationModalOpen = false;
@@ -71,7 +62,6 @@ DankModal {
NotificationService.onOverlayClose(); NotificationService.onOverlayClose();
} }
} }
modalFocusScope.Keys.onPressed: event => modalKeyboardController.handleKey(event)
NotificationKeyboardController { NotificationKeyboardController {
id: modalKeyboardController id: modalKeyboardController
@@ -101,10 +91,12 @@ DankModal {
} }
content: Component { content: Component {
Item { FocusScope {
id: notificationKeyHandler id: notificationKeyHandler
anchors.fill: parent anchors.fill: parent
focus: true
Keys.onPressed: event => modalKeyboardController.handleKey(event)
Column { Column {
anchors.fill: parent anchors.fill: parent

View File

@@ -1,7 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Effects import QtQuick.Effects
import Quickshell import Quickshell
import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services import qs.Services
@@ -13,11 +12,6 @@ DankModal {
layerNamespace: "dms:power-menu" layerNamespace: "dms:power-menu"
keepPopoutsOpen: true keepPopoutsOpen: true
HyprlandFocusGrab {
windows: [root.contentWindow]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property int selectedIndex: 0 property int selectedIndex: 0
property int selectedRow: 0 property int selectedRow: 0
property int selectedCol: 0 property int selectedCol: 0
@@ -275,34 +269,11 @@ DankModal {
} else { } else {
selectedIndex = defaultIndex; selectedIndex = defaultIndex;
} }
Qt.callLater(() => modalFocusScope.forceActiveFocus());
} }
onDialogClosed: () => { onDialogClosed: () => {
cancelHold(); cancelHold();
} }
Component.onCompleted: updateVisibleActions() Component.onCompleted: updateVisibleActions()
modalFocusScope.Keys.onPressed: event => {
if (event.isAutoRepeat) {
event.accepted = true;
return;
}
if (SettingsData.powerMenuGridLayout) {
handleGridNavigation(event, true);
} else {
handleListNavigation(event, true);
}
}
modalFocusScope.Keys.onReleased: event => {
if (event.isAutoRepeat) {
event.accepted = true;
return;
}
if (SettingsData.powerMenuGridLayout) {
handleGridNavigation(event, false);
} else {
handleListNavigation(event, false);
}
}
function handleListNavigation(event, isPressed) { function handleListNavigation(event, isPressed) {
if (!isPressed) { if (!isPressed) {
@@ -481,10 +452,33 @@ DankModal {
} }
content: Component { content: Component {
Item { FocusScope {
anchors.fill: parent anchors.fill: parent
focus: true
implicitHeight: (SettingsData.powerMenuGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight) + Theme.spacingL * 2 + (root.needsConfirmation ? hintRow.height + Theme.spacingM : 0) implicitHeight: (SettingsData.powerMenuGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight) + Theme.spacingL * 2 + (root.needsConfirmation ? hintRow.height + Theme.spacingM : 0)
Keys.onPressed: event => {
if (event.isAutoRepeat) {
event.accepted = true;
return;
}
if (SettingsData.powerMenuGridLayout)
root.handleGridNavigation(event, true);
else
root.handleListNavigation(event, true);
}
Keys.onReleased: event => {
if (event.isAutoRepeat) {
event.accepted = true;
return;
}
if (SettingsData.powerMenuGridLayout)
root.handleGridNavigation(event, false);
else
root.handleListNavigation(event, false);
}
Grid { Grid {
id: buttonGrid id: buttonGrid
visible: SettingsData.powerMenuGridLayout visible: SettingsData.powerMenuGridLayout

View File

@@ -51,7 +51,21 @@ Item {
anchors.fill: parent anchors.fill: parent
focus: true focus: true
clip: false clip: false
onActiveFocusChanged: {
if (!activeFocus)
return;
if (!searchField)
return;
searchField.forceActiveFocus();
}
Keys.onPressed: event => { Keys.onPressed: event => {
const menu = usePopupContextMenu ? popupContextMenu : layerContextMenuLoader.item;
if (menu?.visible) {
menu.handleKey(event);
return;
}
if (event.key === Qt.Key_Escape) { if (event.key === Qt.Key_Escape) {
if (parentModal) if (parentModal)
parentModal.hide(); parentModal.hide();
@@ -197,7 +211,6 @@ Item {
parent: spotlightKeyHandler parent: spotlightKeyHandler
appLauncher: spotlightKeyHandler.appLauncher appLauncher: spotlightKeyHandler.appLauncher
parentHandler: spotlightKeyHandler
searchField: spotlightKeyHandler.searchField searchField: spotlightKeyHandler.searchField
visible: false visible: false
z: 1000 z: 1000
@@ -218,8 +231,6 @@ Item {
sourceComponent: Component { sourceComponent: Component {
SpotlightContextMenu { SpotlightContextMenu {
appLauncher: spotlightKeyHandler.appLauncher appLauncher: spotlightKeyHandler.appLauncher
parentHandler: spotlightKeyHandler
parentModal: spotlightKeyHandler.parentModal
} }
} }
} }
@@ -280,6 +291,12 @@ Item {
updateSearchMode(); updateSearchMode();
} }
Keys.onPressed: event => { Keys.onPressed: event => {
const menu = spotlightKeyHandler.usePopupContextMenu ? popupContextMenu : layerContextMenuLoader.item;
if (menu?.visible) {
menu.handleKey(event);
return;
}
if (event.key === Qt.Key_Escape) { if (event.key === Qt.Key_Escape) {
if (parentModal) if (parentModal)
parentModal.hide(); parentModal.hide();
@@ -312,7 +329,7 @@ Item {
Row { Row {
id: viewModeButtons id: viewModeButtons
spacing: Theme.spacingXS spacing: Theme.spacingXS
visible: searchMode === "apps" && appLauncher.model.count > 0 visible: searchMode === "apps"
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View File

@@ -1,7 +1,6 @@
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common import qs.Common
import qs.Modals.Spotlight import qs.Modals.Spotlight
@@ -11,54 +10,66 @@ PanelWindow {
WlrLayershell.namespace: "dms:spotlight-context-menu" WlrLayershell.namespace: "dms:spotlight-context-menu"
WlrLayershell.layer: WlrLayershell.Overlay WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1 WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
property var appLauncher: null property var appLauncher: null
property var parentHandler: null
property var parentModal: null
property real menuPositionX: 0 property real menuPositionX: 0
property real menuPositionY: 0 property real menuPositionY: 0
readonly property real shadowBuffer: 5 readonly property real shadowBuffer: 5
screen: parentModal?.effectiveScreen screen: DankModalWindow.targetScreen
function show(x, y, app, fromKeyboard) { function show(x, y, app, fromKeyboard) {
fromKeyboard = fromKeyboard || false; fromKeyboard = fromKeyboard || false;
menuContent.currentApp = app; menuContent.currentApp = app;
let screenX = x; let screenX = x;
let screenY = y; let screenY = y;
if (parentModal) { const modalX = DankModalWindow.modalX;
if (fromKeyboard) { const modalY = DankModalWindow.modalY;
screenX = x + parentModal.alignedX;
screenY = y + parentModal.alignedY; if (fromKeyboard) {
} else { screenX = x + modalX;
screenX = x + (parentModal.alignedX - shadowBuffer); screenY = y + modalY;
screenY = y + (parentModal.alignedY - shadowBuffer); } else {
} screenX = x + (modalX - shadowBuffer);
screenY = y + (modalY - shadowBuffer);
} }
menuPositionX = screenX; menuPositionX = screenX;
menuPositionY = screenY; menuPositionY = screenY;
menuContent.selectedMenuIndex = fromKeyboard ? 0 : -1; menuContent.selectedMenuIndex = fromKeyboard ? 0 : -1;
menuContent.keyboardNavigation = true; menuContent.keyboardNavigation = true;
visible = true; visible = true;
}
if (parentHandler) {
parentHandler.enabled = false; function handleKey(event) {
switch (event.key) {
case Qt.Key_Down:
menuContent.selectNext();
event.accepted = true;
break;
case Qt.Key_Up:
menuContent.selectPrevious();
event.accepted = true;
break;
case Qt.Key_Return:
case Qt.Key_Enter:
menuContent.activateSelected();
event.accepted = true;
break;
case Qt.Key_Escape:
case Qt.Key_Menu:
hide();
event.accepted = true;
break;
} }
Qt.callLater(() => {
menuContent.keyboardHandler.forceActiveFocus();
});
} }
function hide() { function hide() {
if (parentHandler) {
parentHandler.enabled = true;
}
visible = false; visible = false;
} }
@@ -71,11 +82,6 @@ PanelWindow {
bottom: true bottom: true
} }
onVisibleChanged: {
if (!visible && parentHandler) {
parentHandler.enabled = true;
}
}
SpotlightContextMenuContent { SpotlightContextMenuContent {
id: menuContent id: menuContent

View File

@@ -8,51 +8,57 @@ Popup {
id: root id: root
property var appLauncher: null property var appLauncher: null
property var parentHandler: null
property var searchField: null property var searchField: null
function show(x, y, app, fromKeyboard) { function show(x, y, app, fromKeyboard) {
fromKeyboard = fromKeyboard || false; fromKeyboard = fromKeyboard || false;
menuContent.currentApp = app; menuContent.currentApp = app;
root.x = x + 4; root.x = x + 4;
root.y = y + 4; root.y = y + 4;
menuContent.selectedMenuIndex = fromKeyboard ? 0 : -1; menuContent.selectedMenuIndex = fromKeyboard ? 0 : -1;
menuContent.keyboardNavigation = true; menuContent.keyboardNavigation = true;
if (parentHandler) {
parentHandler.enabled = false;
}
open(); open();
} }
onOpened: { function handleKey(event) {
Qt.callLater(() => { switch (event.key) {
menuContent.keyboardHandler.forceActiveFocus(); case Qt.Key_Down:
}); menuContent.selectNext();
event.accepted = true;
break;
case Qt.Key_Up:
menuContent.selectPrevious();
event.accepted = true;
break;
case Qt.Key_Return:
case Qt.Key_Enter:
menuContent.activateSelected();
event.accepted = true;
break;
case Qt.Key_Escape:
case Qt.Key_Menu:
hide();
event.accepted = true;
break;
}
} }
function hide() { function hide() {
if (parentHandler) {
parentHandler.enabled = true;
}
close(); close();
} }
width: menuContent.implicitWidth width: menuContent.implicitWidth
height: menuContent.implicitHeight height: menuContent.implicitHeight
padding: 0 padding: 0
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside closePolicy: Popup.CloseOnPressOutside
modal: true modal: true
dim: false dim: false
background: Item {} background: Item {}
onClosed: { onClosed: {
if (parentHandler) {
parentHandler.enabled = true;
}
if (searchField) { if (searchField) {
Qt.callLater(() => { Qt.callLater(() => {
searchField.forceActiveFocus(); searchField.forceActiveFocus();

View File

@@ -1,20 +1,13 @@
import QtQuick import QtQuick
import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import qs.Common import qs.Common
import qs.Modals.Common import qs.Modals.Common
import qs.Services
DankModal { DankModal {
id: spotlightModal id: spotlightModal
layerNamespace: "dms:spotlight" layerNamespace: "dms:spotlight"
HyprlandFocusGrab {
windows: [spotlightModal.contentWindow]
active: CompositorService.isHyprland && spotlightModal.shouldHaveFocus
}
property bool spotlightOpen: false property bool spotlightOpen: false
property alias spotlightContent: spotlightContentInstance property alias spotlightContent: spotlightContentInstance
property bool openedFromOverview: false property bool openedFromOverview: false
@@ -23,32 +16,18 @@ DankModal {
openedFromOverview = false; openedFromOverview = false;
spotlightOpen = true; spotlightOpen = true;
open(); open();
Qt.callLater(() => {
if (spotlightContent && spotlightContent.searchField) {
spotlightContent.searchField.forceActiveFocus();
}
});
} }
function showWithQuery(query) { function showWithQuery(query) {
if (spotlightContent) { if (spotlightContent) {
if (spotlightContent.appLauncher) { if (spotlightContent.appLauncher)
spotlightContent.appLauncher.searchQuery = query; spotlightContent.appLauncher.searchQuery = query;
} if (spotlightContent.searchField)
if (spotlightContent.searchField) {
spotlightContent.searchField.text = query; spotlightContent.searchField.text = query;
}
} }
spotlightOpen = true; spotlightOpen = true;
open(); open();
Qt.callLater(() => {
if (spotlightContent && spotlightContent.searchField) {
spotlightContent.searchField.forceActiveFocus();
}
});
} }
function hide() { function hide() {
@@ -57,23 +36,24 @@ DankModal {
close(); close();
} }
onDialogClosed: { function onFullyClosed() {
if (spotlightContent) { resetContent();
if (spotlightContent.appLauncher) { }
spotlightContent.appLauncher.searchQuery = "";
spotlightContent.appLauncher.selectedIndex = 0; function resetContent() {
spotlightContent.appLauncher.setCategory(I18n.tr("All")); if (!spotlightContent)
} return;
if (spotlightContent.fileSearchController) { if (spotlightContent.appLauncher) {
spotlightContent.fileSearchController.reset(); spotlightContent.appLauncher.searchQuery = "";
} spotlightContent.appLauncher.selectedIndex = 0;
if (spotlightContent.resetScroll) { spotlightContent.appLauncher.setCategory(I18n.tr("All"));
spotlightContent.resetScroll();
}
if (spotlightContent.searchField) {
spotlightContent.searchField.text = "";
}
} }
if (spotlightContent.fileSearchController)
spotlightContent.fileSearchController.reset();
if (spotlightContent.resetScroll)
spotlightContent.resetScroll();
if (spotlightContent.searchField)
spotlightContent.searchField.text = "";
} }
function toggle() { function toggle() {
@@ -94,16 +74,10 @@ DankModal {
enableShadow: true enableShadow: true
keepContentLoaded: true keepContentLoaded: true
onVisibleChanged: () => { onVisibleChanged: () => {
if (visible && !spotlightOpen) { if (!visible)
return;
if (!spotlightOpen)
show(); show();
}
if (visible && spotlightContent) {
Qt.callLater(() => {
if (spotlightContent.searchField) {
spotlightContent.searchField.forceActiveFocus();
}
});
}
} }
onBackgroundClicked: () => { onBackgroundClicked: () => {
return hide(); return hide();

View File

@@ -89,6 +89,8 @@ Variants {
property bool isInitialized: false property bool isInitialized: false
property real transitionProgress: 0 property real transitionProgress: 0
readonly property bool transitioning: transitionAnimation.running readonly property bool transitioning: transitionAnimation.running
property bool effectActive: false
property bool useNextForEffect: false
onSourceChanged: { onSourceChanged: {
const isColor = source.startsWith("#"); const isColor = source.startsWith("#");
@@ -112,10 +114,21 @@ Variants {
function setWallpaperImmediate(newSource) { function setWallpaperImmediate(newSource) {
transitionAnimation.stop(); transitionAnimation.stop();
root.transitionProgress = 0.0; root.transitionProgress = 0.0;
root.effectActive = false;
currentWallpaper.source = newSource; currentWallpaper.source = newSource;
nextWallpaper.source = ""; nextWallpaper.source = "";
currentWallpaper.opacity = 1; }
nextWallpaper.opacity = 0;
function startTransition() {
currentWallpaper.cache = true;
nextWallpaper.cache = true;
root.useNextForEffect = true;
root.effectActive = true;
if (srcNext.scheduleUpdate)
srcNext.scheduleUpdate();
Qt.callLater(() => {
transitionAnimation.start();
});
} }
function changeWallpaper(newPath) { function changeWallpaper(newPath) {
@@ -126,6 +139,7 @@ Variants {
if (root.transitioning) { if (root.transitioning) {
transitionAnimation.stop(); transitionAnimation.stop();
root.transitionProgress = 0; root.transitionProgress = 0;
root.effectActive = false;
currentWallpaper.source = nextWallpaper.source; currentWallpaper.source = nextWallpaper.source;
nextWallpaper.source = ""; nextWallpaper.source = "";
} }
@@ -138,7 +152,7 @@ Variants {
nextWallpaper.source = newPath; nextWallpaper.source = newPath;
if (nextWallpaper.status === Image.Ready) { if (nextWallpaper.status === Image.Ready) {
transitionAnimation.start(); root.startTransition();
} }
} }
@@ -152,6 +166,10 @@ Variants {
} }
} }
property real screenScale: CompositorService.getScreenScale(modelData)
property int physicalWidth: Math.round(modelData.width * screenScale)
property int physicalHeight: Math.round(modelData.height * screenScale)
Image { Image {
id: currentWallpaper id: currentWallpaper
anchors.fill: parent anchors.fill: parent
@@ -160,7 +178,7 @@ Variants {
asynchronous: true asynchronous: true
smooth: true smooth: true
cache: true cache: true
sourceSize: Qt.size(modelData.width, modelData.height) sourceSize: Qt.size(root.physicalWidth, root.physicalHeight)
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SettingsData.wallpaperFillMode) fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SettingsData.wallpaperFillMode)
} }
@@ -171,19 +189,46 @@ Variants {
opacity: 0 opacity: 0
asynchronous: true asynchronous: true
smooth: true smooth: true
cache: true cache: false
sourceSize: Qt.size(modelData.width, modelData.height) sourceSize: Qt.size(root.physicalWidth, root.physicalHeight)
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SettingsData.wallpaperFillMode) fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SettingsData.wallpaperFillMode)
onStatusChanged: { onStatusChanged: {
if (status !== Image.Ready) if (status !== Image.Ready)
return; return;
if (!root.transitioning) { if (!root.transitioning) {
transitionAnimation.start(); root.startTransition();
} }
} }
} }
ShaderEffectSource {
id: srcNext
sourceItem: root.effectActive ? nextWallpaper : null
hideSource: root.effectActive
live: root.effectActive
mipmap: false
recursive: false
textureSize: root.effectActive ? Qt.size(root.physicalWidth, root.physicalHeight) : Qt.size(1, 1)
}
Rectangle {
id: dummyRect
width: 1
height: 1
visible: false
color: "transparent"
}
ShaderEffectSource {
id: srcDummy
sourceItem: dummyRect
hideSource: true
live: false
mipmap: false
recursive: false
}
Item { Item {
id: blurredLayer id: blurredLayer
anchors.fill: parent anchors.fill: parent
@@ -201,8 +246,8 @@ Variants {
MultiEffect { MultiEffect {
anchors.fill: parent anchors.fill: parent
source: nextWallpaper source: root.useNextForEffect ? srcNext : srcDummy
visible: nextWallpaper.source !== "" visible: nextWallpaper.source !== "" && root.useNextForEffect
blurEnabled: true blurEnabled: true
blur: 0.8 blur: 0.8
blurMax: 75 blurMax: 75
@@ -220,16 +265,18 @@ Variants {
duration: 1000 duration: 1000
easing.type: Easing.InOutCubic easing.type: Easing.InOutCubic
onFinished: { onFinished: {
const tempSource = nextWallpaper.source; if (nextWallpaper.source && nextWallpaper.status === Image.Ready) {
if (tempSource && nextWallpaper.status === Image.Ready && !tempSource.toString().startsWith("#")) { currentWallpaper.source = nextWallpaper.source;
currentWallpaper.source = tempSource;
} }
root.transitionProgress = 0.0; root.useNextForEffect = false;
currentWallpaper.opacity = 1;
nextWallpaper.opacity = 0;
Qt.callLater(() => { Qt.callLater(() => {
nextWallpaper.source = ""; nextWallpaper.source = "";
Qt.callLater(() => {
root.effectActive = false;
currentWallpaper.cache = true;
nextWallpaper.cache = false;
root.transitionProgress = 0.0;
});
}); });
} }
} }

View File

@@ -402,9 +402,8 @@ Rectangle {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
if (modelData) { if (modelData) {
AudioService.suppressOSD = true; SessionData.suppressOSDTemporarily();
modelData.audio.muted = !modelData.audio.muted; modelData.audio.muted = !modelData.audio.muted;
AudioService.suppressOSD = false;
} }
} }
} }
@@ -446,18 +445,9 @@ Rectangle {
thumbOutlineColor: Theme.surfaceContainer thumbOutlineColor: Theme.surfaceContainer
trackColor: appVolumeRow.sliderTrackColor.a > 0 ? appVolumeRow.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) trackColor: appVolumeRow.sliderTrackColor.a > 0 ? appVolumeRow.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
onIsDraggingChanged: {
if (isDragging) {
AudioService.suppressOSD = true;
} else {
Qt.callLater(() => {
AudioService.suppressOSD = false;
});
}
}
onSliderValueChanged: function (newValue) { onSliderValueChanged: function (newValue) {
if (modelData) { if (modelData) {
SessionData.suppressOSDTemporarily();
modelData.audio.volume = newValue / 100.0; modelData.audio.volume = newValue / 100.0;
if (newValue > 0 && modelData.audio.muted) { if (newValue > 0 && modelData.audio.muted) {
modelData.audio.muted = false; modelData.audio.muted = false;

View File

@@ -1,7 +1,4 @@
import QtQuick import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Services.Pipewire
import qs.Common import qs.Common
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
@@ -30,9 +27,8 @@ Row {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
if (defaultSink) { if (defaultSink) {
AudioService.suppressOSD = true SessionData.suppressOSDTemporarily();
defaultSink.audio.muted = !defaultSink.audio.muted defaultSink.audio.muted = !defaultSink.audio.muted;
AudioService.suppressOSD = false
} }
} }
} }
@@ -40,15 +36,19 @@ Row {
DankIcon { DankIcon {
anchors.centerIn: parent anchors.centerIn: parent
name: { name: {
if (!defaultSink) return "volume_off" if (!defaultSink)
return "volume_off";
let volume = defaultSink.audio.volume let volume = defaultSink.audio.volume;
let muted = defaultSink.audio.muted let muted = defaultSink.audio.muted;
if (muted || volume === 0.0) return "volume_off" if (muted || volume === 0.0)
if (volume <= 0.33) return "volume_down" return "volume_off";
if (volume <= 0.66) return "volume_up" if (volume <= 0.33)
return "volume_up" return "volume_down";
if (volume <= 0.66)
return "volume_up";
return "volume_up";
} }
size: Theme.iconSize size: Theme.iconSize
color: defaultSink && !defaultSink.audio.muted && defaultSink.audio.volume > 0 ? Theme.primary : Theme.surfaceText color: defaultSink && !defaultSink.audio.muted && defaultSink.audio.volume > 0 ? Theme.primary : Theme.surfaceText
@@ -70,22 +70,15 @@ Row {
thumbOutlineColor: Theme.surfaceContainer thumbOutlineColor: Theme.surfaceContainer
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
onIsDraggingChanged: { onSliderValueChanged: function (newValue) {
if (isDragging) {
AudioService.suppressOSD = true
} else {
Qt.callLater(() => { AudioService.suppressOSD = false })
}
}
onSliderValueChanged: function(newValue) {
if (defaultSink) { if (defaultSink) {
defaultSink.audio.volume = newValue / 100.0 SessionData.suppressOSDTemporarily();
defaultSink.audio.volume = newValue / 100.0;
if (newValue > 0 && defaultSink.audio.muted) { if (newValue > 0 && defaultSink.audio.muted) {
defaultSink.audio.muted = false defaultSink.audio.muted = false;
} }
AudioService.playVolumeChangeSoundIfEnabled() AudioService.playVolumeChangeSoundIfEnabled();
} }
} }
} }
} }

View File

@@ -159,7 +159,6 @@ Row {
} }
return targetDevice.displayMax || 100; return targetDevice.displayMax || 100;
} }
value: !isDragging ? targetBrightness : value
showValue: true showValue: true
unit: { unit: {
if (!targetDevice) if (!targetDevice)
@@ -177,5 +176,10 @@ Row {
} }
thumbOutlineColor: Theme.surfaceContainer thumbOutlineColor: Theme.surfaceContainer
trackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) trackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
Binding on value {
value: root.targetBrightness
when: !brightnessSlider.isDragging
}
} }
} }

View File

@@ -1,7 +1,4 @@
import QtQuick import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Services.Pipewire
import qs.Common import qs.Common
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
@@ -30,9 +27,8 @@ Row {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
if (defaultSource) { if (defaultSource) {
AudioService.suppressOSD = true SessionData.suppressOSDTemporarily();
defaultSource.audio.muted = !defaultSource.audio.muted defaultSource.audio.muted = !defaultSource.audio.muted;
AudioService.suppressOSD = false
} }
} }
} }
@@ -40,13 +36,15 @@ Row {
DankIcon { DankIcon {
anchors.centerIn: parent anchors.centerIn: parent
name: { name: {
if (!defaultSource) return "mic_off" if (!defaultSource)
return "mic_off";
let volume = defaultSource.audio.volume let volume = defaultSource.audio.volume;
let muted = defaultSource.audio.muted let muted = defaultSource.audio.muted;
if (muted || volume === 0.0) return "mic_off" if (muted || volume === 0.0)
return "mic" return "mic_off";
return "mic";
} }
size: Theme.iconSize size: Theme.iconSize
color: defaultSource && !defaultSource.audio.muted && defaultSource.audio.volume > 0 ? Theme.primary : Theme.surfaceText color: defaultSource && !defaultSource.audio.muted && defaultSource.audio.volume > 0 ? Theme.primary : Theme.surfaceText
@@ -67,16 +65,14 @@ Row {
valueOverride: actualVolumePercent valueOverride: actualVolumePercent
thumbOutlineColor: Theme.surfaceContainer thumbOutlineColor: Theme.surfaceContainer
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
onIsDraggingChanged: { onSliderValueChanged: function (newValue) {
AudioService.suppressOSD = isDragging
}
onSliderValueChanged: function(newValue) {
if (defaultSource) { if (defaultSource) {
defaultSource.audio.volume = newValue / 100.0 SessionData.suppressOSDTemporarily();
defaultSource.audio.volume = newValue / 100.0;
if (newValue > 0 && defaultSource.audio.muted) { if (newValue > 0 && defaultSource.audio.muted) {
defaultSource.audio.muted = false defaultSource.audio.muted = false;
} }
} }
} }
} }
} }

View File

@@ -134,11 +134,12 @@ BasePill {
function handleBrightnessWheel(delta) { function handleBrightnessWheel(delta) {
const deviceName = getPinnedBrightnessDevice(); const deviceName = getPinnedBrightnessDevice();
if (!deviceName) if (!deviceName) {
return; return;
}
const currentBrightness = DisplayService.getDeviceBrightness(deviceName); const currentBrightness = DisplayService.getDeviceBrightness(deviceName);
const newBrightness = delta > 0 ? Math.min(100, currentBrightness + 5) : Math.max(1, currentBrightness - 5); const newBrightness = delta > 0 ? Math.min(100, currentBrightness + 5) : Math.max(1, currentBrightness - 5);
DisplayService.setBrightness(newBrightness, deviceName, false); DisplayService.setBrightness(newBrightness, deviceName);
} }
function getBatteryIconColor() { function getBatteryIconColor() {

View File

@@ -205,6 +205,7 @@ Item {
const current = Math.round(currentVolume * 100); const current = Math.round(currentVolume * 100);
const newVolume = Math.min(100, Math.max(0, current + step)); const newVolume = Math.min(100, Math.max(0, current + step));
SessionData.suppressOSDTemporarily();
if (usePlayerVolume) { if (usePlayerVolume) {
activePlayer.volume = newVolume / 100; activePlayer.volume = newVolume / 100;
} else if (AudioService.sink?.audio) { } else if (AudioService.sink?.audio) {
@@ -790,6 +791,7 @@ Item {
volumeButtonExited(); volumeButtonExited();
} }
onClicked: { onClicked: {
SessionData.suppressOSDTemporarily();
if (currentVolume > 0) { if (currentVolume > 0) {
volumeButton.previousVolume = currentVolume; volumeButton.previousVolume = currentVolume;
if (usePlayerVolume) { if (usePlayerVolume) {
@@ -807,6 +809,7 @@ Item {
} }
} }
onWheel: wheelEvent => { onWheel: wheelEvent => {
SessionData.suppressOSDTemporarily();
const delta = wheelEvent.angleDelta.y; const delta = wheelEvent.angleDelta.y;
const current = (currentVolume * 100) || 0; const current = (currentVolume * 100) || 0;
const newVolume = delta > 0 ? Math.min(100, current + 5) : Math.max(0, current - 5); const newVolume = delta > 0 ? Math.min(100, current + 5) : Math.max(0, current - 5);

View File

@@ -107,7 +107,6 @@ DankOSD {
} }
thumbOutlineColor: Theme.surfaceContainer thumbOutlineColor: Theme.surfaceContainer
alwaysShowValue: SettingsData.osdAlwaysShowValue alwaysShowValue: SettingsData.osdAlwaysShowValue
value: !isDragging ? root.targetBrightness : value
onSliderValueChanged: newValue => { onSliderValueChanged: newValue => {
if (DisplayService.brightnessAvailable) { if (DisplayService.brightnessAvailable) {
@@ -119,6 +118,11 @@ DankOSD {
onContainsMouseChanged: { onContainsMouseChanged: {
setChildHovered(containsMouse); setChildHovered(containsMouse);
} }
Binding on value {
value: root.targetBrightness
when: !brightnessSlider.isDragging
}
} }
} }
} }
@@ -163,7 +167,12 @@ DankOSD {
y: gap * 2 + Theme.iconSize y: gap * 2 + Theme.iconSize
property bool dragging: false property bool dragging: false
property int value: !dragging ? root.targetBrightness : value property int value: 50
Binding on value {
value: root.targetBrightness
when: !vertSlider.dragging
}
readonly property int minimum: { readonly property int minimum: {
const deviceInfo = DisplayService.getCurrentDeviceInfo(); const deviceInfo = DisplayService.getCurrentDeviceInfo();
@@ -255,12 +264,14 @@ DankOSD {
} }
function updateBrightness(mouse) { function updateBrightness(mouse) {
if (DisplayService.brightnessAvailable) { if (!DisplayService.brightnessAvailable) {
const ratio = 1.0 - (mouse.y / height); return;
const newValue = Math.round(vertSlider.minimum + ratio * (vertSlider.maximum - vertSlider.minimum));
DisplayService.setBrightness(newValue, DisplayService.lastIpcDevice, true);
resetHideTimer();
} }
const ratio = 1.0 - (mouse.y / height);
const newValue = Math.round(vertSlider.minimum + ratio * (vertSlider.maximum - vertSlider.minimum));
vertSlider.value = newValue;
DisplayService.setBrightness(newValue, DisplayService.lastIpcDevice, true);
resetHideTimer();
} }
} }
} }

View File

@@ -17,14 +17,14 @@ DankOSD {
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() { function onVolumeChanged() {
if (!AudioService.suppressOSD && SettingsData.osdVolumeEnabled) { if (SettingsData.osdVolumeEnabled) {
root.show() root.show();
} }
} }
function onMutedChanged() { function onMutedChanged() {
if (!AudioService.suppressOSD && SettingsData.osdVolumeEnabled) { if (SettingsData.osdVolumeEnabled) {
root.show() root.show();
} }
} }
} }
@@ -34,7 +34,7 @@ DankOSD {
function onSinkChanged() { function onSinkChanged() {
if (root.shouldBeVisible && SettingsData.osdVolumeEnabled) { if (root.shouldBeVisible && SettingsData.osdVolumeEnabled) {
root.show() root.show();
} }
} }
} }
@@ -76,10 +76,10 @@ DankOSD {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
AudioService.toggleMute() AudioService.toggleMute();
} }
onContainsMouseChanged: { onContainsMouseChanged: {
setChildHovered(containsMouse || volumeSlider.containsMouse) setChildHovered(containsMouse || volumeSlider.containsMouse);
} }
} }
} }
@@ -105,21 +105,20 @@ DankOSD {
Component.onCompleted: { Component.onCompleted: {
if (AudioService.sink && AudioService.sink.audio) { if (AudioService.sink && AudioService.sink.audio) {
value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100)) value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
} }
} }
onSliderValueChanged: newValue => { onSliderValueChanged: newValue => {
if (AudioService.sink && AudioService.sink.audio) { if (AudioService.sink && AudioService.sink.audio) {
AudioService.suppressOSD = true SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = newValue / 100 AudioService.sink.audio.volume = newValue / 100;
AudioService.suppressOSD = false resetHideTimer();
resetHideTimer() }
} }
}
onContainsMouseChanged: { onContainsMouseChanged: {
setChildHovered(containsMouse || muteButton.containsMouse) setChildHovered(containsMouse || muteButton.containsMouse);
} }
Connections { Connections {
@@ -127,7 +126,7 @@ DankOSD {
function onVolumeChanged() { function onVolumeChanged() {
if (volumeSlider && !volumeSlider.pressed) { if (volumeSlider && !volumeSlider.pressed) {
volumeSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100)) volumeSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
} }
} }
} }
@@ -164,10 +163,10 @@ DankOSD {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
AudioService.toggleMute() AudioService.toggleMute();
} }
onContainsMouseChanged: { onContainsMouseChanged: {
setChildHovered(containsMouse || vertSliderArea.containsMouse) setChildHovered(containsMouse || vertSliderArea.containsMouse);
} }
} }
} }
@@ -207,9 +206,9 @@ DankOSD {
height: 8 height: 8
radius: Theme.cornerRadius radius: Theme.cornerRadius
y: { y: {
const ratio = vertSlider.value / 100 const ratio = vertSlider.value / 100;
const travel = parent.height - height const travel = parent.height - height;
return Math.max(0, Math.min(travel, travel * (1 - ratio))) return Math.max(0, Math.min(travel, travel * (1 - ratio)));
} }
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
color: Theme.primary color: Theme.primary
@@ -226,36 +225,35 @@ DankOSD {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onContainsMouseChanged: { onContainsMouseChanged: {
setChildHovered(containsMouse || muteButtonVert.containsMouse) setChildHovered(containsMouse || muteButtonVert.containsMouse);
} }
onPressed: mouse => { onPressed: mouse => {
vertSlider.dragging = true vertSlider.dragging = true;
updateVolume(mouse) updateVolume(mouse);
} }
onReleased: { onReleased: {
vertSlider.dragging = false vertSlider.dragging = false;
} }
onPositionChanged: mouse => { onPositionChanged: mouse => {
if (pressed) { if (pressed) {
updateVolume(mouse) updateVolume(mouse);
} }
} }
onClicked: mouse => { onClicked: mouse => {
updateVolume(mouse) updateVolume(mouse);
} }
function updateVolume(mouse) { function updateVolume(mouse) {
if (AudioService.sink && AudioService.sink.audio) { if (AudioService.sink && AudioService.sink.audio) {
const ratio = 1.0 - (mouse.y / height) const ratio = 1.0 - (mouse.y / height);
const volume = Math.max(0, Math.min(100, Math.round(ratio * 100))) const volume = Math.max(0, Math.min(100, Math.round(ratio * 100)));
AudioService.suppressOSD = true SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = volume / 100 AudioService.sink.audio.volume = volume / 100;
AudioService.suppressOSD = false resetHideTimer();
resetHideTimer()
} }
} }
} }
@@ -265,7 +263,7 @@ DankOSD {
function onVolumeChanged() { function onVolumeChanged() {
if (!vertSlider.dragging) { if (!vertSlider.dragging) {
vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100)) vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
} }
} }
} }
@@ -286,9 +284,9 @@ DankOSD {
onOsdShown: { onOsdShown: {
if (AudioService.sink && AudioService.sink.audio && contentLoader.item && contentLoader.item.item) { if (AudioService.sink && AudioService.sink.audio && contentLoader.item && contentLoader.item.item) {
if (!useVertical) { if (!useVertical) {
const slider = contentLoader.item.item.children[0].children[1] const slider = contentLoader.item.item.children[0].children[1];
if (slider && slider.value !== undefined) { if (slider && slider.value !== undefined) {
slider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100)) slider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
} }
} }
} }

View File

@@ -95,10 +95,6 @@ FloatingWindow {
if (!parentModal) if (!parentModal)
return; return;
parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
Qt.callLater(() => {
if (parentModal.modalFocusScope)
parentModal.modalFocusScope.forceActiveFocus();
});
} }
objectName: "pluginBrowser" objectName: "pluginBrowser"

View File

@@ -82,10 +82,6 @@ FloatingWindow {
if (!parentModal) if (!parentModal)
return; return;
parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
Qt.callLater(() => {
if (parentModal && parentModal.modalFocusScope)
parentModal.modalFocusScope.forceActiveFocus();
});
} }
objectName: "widgetSelectionPopup" objectName: "widgetSelectionPopup"
@@ -112,10 +108,6 @@ FloatingWindow {
if (!parentModal) if (!parentModal)
return; return;
parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible);
Qt.callLater(() => {
if (parentModal && parentModal.modalFocusScope)
parentModal.modalFocusScope.forceActiveFocus();
});
} }
FocusScope { FocusScope {

View File

@@ -68,12 +68,6 @@ Variants {
} }
} }
onActualTransitionTypeChanged: {
if (actualTransitionType === "none") {
currentWallpaper.visible = true;
nextWallpaper.visible = false;
}
}
property real transitionProgress: 0 property real transitionProgress: 0
property real shaderFillMode: getFillMode(SettingsData.wallpaperFillMode) property real shaderFillMode: getFillMode(SettingsData.wallpaperFillMode)
property vector4d fillColor: Qt.vector4d(0, 0, 0, 1) property vector4d fillColor: Qt.vector4d(0, 0, 0, 1)
@@ -86,9 +80,8 @@ Variants {
property real stripesAngle: 0 property real stripesAngle: 0
readonly property bool transitioning: transitionAnimation.running readonly property bool transitioning: transitionAnimation.running
property bool effectActive: false
property bool hasCurrent: currentWallpaper.status === Image.Ready && !!currentWallpaper.source property bool useNextForEffect: false
property bool booting: !hasCurrent && nextWallpaper.status === Image.Ready
function getFillMode(modeName) { function getFillMode(modeName) {
switch (modeName) { switch (modeName) {
@@ -143,10 +136,25 @@ Variants {
function setWallpaperImmediate(newSource) { function setWallpaperImmediate(newSource) {
transitionAnimation.stop(); transitionAnimation.stop();
root.transitionProgress = 0.0; root.transitionProgress = 0.0;
root.effectActive = false;
currentWallpaper.source = newSource; currentWallpaper.source = newSource;
nextWallpaper.source = ""; nextWallpaper.source = "";
currentWallpaper.visible = true; }
nextWallpaper.visible = false;
function startTransition() {
currentWallpaper.cache = true;
nextWallpaper.cache = true;
currentWallpaper.layer.enabled = true;
nextWallpaper.layer.enabled = true;
root.useNextForEffect = true;
root.effectActive = true;
if (srcCurrent.scheduleUpdate)
srcCurrent.scheduleUpdate();
if (srcNext.scheduleUpdate)
srcNext.scheduleUpdate();
Qt.callLater(() => {
transitionAnimation.start();
});
} }
function changeWallpaper(newPath, force) { function changeWallpaper(newPath, force) {
@@ -157,17 +165,16 @@ Variants {
if (root.transitioning) { if (root.transitioning) {
transitionAnimation.stop(); transitionAnimation.stop();
root.transitionProgress = 0; root.transitionProgress = 0;
root.effectActive = false;
currentWallpaper.source = nextWallpaper.source; currentWallpaper.source = nextWallpaper.source;
nextWallpaper.source = ""; nextWallpaper.source = "";
} }
// If no current wallpaper, set immediately to avoid scaling issues
if (!currentWallpaper.source) { if (!currentWallpaper.source) {
setWallpaperImmediate(newPath); setWallpaperImmediate(newPath);
return; return;
} }
// If transition is "none", set immediately
if (root.transitionType === "random") { if (root.transitionType === "random") {
if (SessionData.includedTransitions.length === 0) { if (SessionData.includedTransitions.length === 0) {
root.actualTransitionType = "none"; root.actualTransitionType = "none";
@@ -183,7 +190,7 @@ Variants {
if (root.actualTransitionType === "wipe") { if (root.actualTransitionType === "wipe") {
root.wipeDirection = Math.random() * 4; root.wipeDirection = Math.random() * 4;
} else if (root.actualTransitionType === "disc") { } else if (root.actualTransitionType === "disc" || root.actualTransitionType === "pixelate" || root.actualTransitionType === "portal") {
root.discCenterX = Math.random(); root.discCenterX = Math.random();
root.discCenterY = Math.random(); root.discCenterY = Math.random();
} else if (root.actualTransitionType === "stripes") { } else if (root.actualTransitionType === "stripes") {
@@ -194,7 +201,7 @@ Variants {
nextWallpaper.source = newPath; nextWallpaper.source = newPath;
if (nextWallpaper.status === Image.Ready) { if (nextWallpaper.status === Image.Ready) {
transitionAnimation.start(); root.startTransition();
} }
} }
@@ -208,41 +215,33 @@ Variants {
} }
} }
Rectangle { property real screenScale: CompositorService.getScreenScale(modelData)
id: transparentRect property int physicalWidth: Math.round(modelData.width * screenScale)
anchors.fill: parent property int physicalHeight: Math.round(modelData.height * screenScale)
color: "transparent"
visible: false
}
ShaderEffectSource {
id: transparentSource
sourceItem: transparentRect
hideSource: true
live: false
}
Image { Image {
id: currentWallpaper id: currentWallpaper
anchors.fill: parent anchors.fill: parent
visible: root.actualTransitionType === "none" visible: true
opacity: 1 opacity: 1
layer.enabled: false layer.enabled: false
asynchronous: true asynchronous: true
smooth: true smooth: true
cache: true cache: true
sourceSize: Qt.size(root.physicalWidth, root.physicalHeight)
fillMode: root.getFillMode(SettingsData.wallpaperFillMode) fillMode: root.getFillMode(SettingsData.wallpaperFillMode)
} }
Image { Image {
id: nextWallpaper id: nextWallpaper
anchors.fill: parent anchors.fill: parent
visible: false visible: true
opacity: 0 opacity: 0
layer.enabled: false layer.enabled: false
asynchronous: true asynchronous: true
smooth: true smooth: true
cache: true cache: false
sourceSize: Qt.size(root.physicalWidth, root.physicalHeight)
fillMode: root.getFillMode(SettingsData.wallpaperFillMode) fillMode: root.getFillMode(SettingsData.wallpaperFillMode)
onStatusChanged: { onStatusChanged: {
@@ -252,19 +251,53 @@ Variants {
currentWallpaper.source = source; currentWallpaper.source = source;
nextWallpaper.source = ""; nextWallpaper.source = "";
root.transitionProgress = 0.0; root.transitionProgress = 0.0;
} else { } else if (!root.transitioning) {
visible = true; root.startTransition();
if (!root.transitioning) {
transitionAnimation.start();
}
} }
} }
} }
ShaderEffectSource {
id: srcCurrent
sourceItem: root.effectActive ? currentWallpaper : null
hideSource: root.effectActive
live: root.effectActive
mipmap: false
recursive: false
textureSize: root.effectActive ? Qt.size(root.physicalWidth, root.physicalHeight) : Qt.size(1, 1)
}
ShaderEffectSource {
id: srcNext
sourceItem: root.effectActive ? nextWallpaper : null
hideSource: root.effectActive
live: root.effectActive
mipmap: false
recursive: false
textureSize: root.effectActive ? Qt.size(root.physicalWidth, root.physicalHeight) : Qt.size(1, 1)
}
Rectangle {
id: dummyRect
width: 1
height: 1
visible: false
color: "transparent"
}
ShaderEffectSource {
id: srcDummy
sourceItem: dummyRect
hideSource: true
live: false
mipmap: false
recursive: false
}
Loader { Loader {
id: effectLoader id: effectLoader
anchors.fill: parent anchors.fill: parent
active: root.actualTransitionType !== "none" && (root.hasCurrent || root.booting) active: root.effectActive
sourceComponent: { sourceComponent: {
switch (root.actualTransitionType) { switch (root.actualTransitionType) {
case "fade": case "fade":
@@ -291,15 +324,15 @@ Variants {
id: fadeComp id: fadeComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_fade.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_fade.frag.qsb")
@@ -310,17 +343,17 @@ Variants {
id: wipeComp id: wipeComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real direction: root.wipeDirection property real direction: root.wipeDirection
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_wipe.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_wipe.frag.qsb")
@@ -331,8 +364,8 @@ Variants {
id: discComp id: discComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real aspectRatio: root.width / root.height property real aspectRatio: root.width / root.height
@@ -340,10 +373,10 @@ Variants {
property real centerY: root.discCenterY property real centerY: root.discCenterY
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_disc.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_disc.frag.qsb")
@@ -354,8 +387,8 @@ Variants {
id: stripesComp id: stripesComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real aspectRatio: root.width / root.height property real aspectRatio: root.width / root.height
@@ -363,10 +396,10 @@ Variants {
property real angle: root.stripesAngle property real angle: root.stripesAngle
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_stripes.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_stripes.frag.qsb")
@@ -377,8 +410,8 @@ Variants {
id: irisComp id: irisComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real centerX: 0.5 property real centerX: 0.5
@@ -386,10 +419,10 @@ Variants {
property real aspectRatio: root.width / root.height property real aspectRatio: root.width / root.height
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_iris_bloom.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_iris_bloom.frag.qsb")
@@ -400,16 +433,16 @@ Variants {
id: pixelateComp id: pixelateComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
property real centerX: root.discCenterX property real centerX: root.discCenterX
@@ -423,8 +456,8 @@ Variants {
id: portalComp id: portalComp
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
property variant source1: root.hasCurrent ? currentWallpaper : transparentSource property variant source1: srcCurrent
property variant source2: nextWallpaper property variant source2: root.useNextForEffect ? srcNext : srcDummy
property real progress: root.transitionProgress property real progress: root.transitionProgress
property real smoothness: root.edgeSmoothness property real smoothness: root.edgeSmoothness
property real aspectRatio: root.width / root.height property real aspectRatio: root.width / root.height
@@ -432,10 +465,10 @@ Variants {
property real centerY: root.discCenterY property real centerY: root.discCenterY
property real fillMode: root.shaderFillMode property real fillMode: root.shaderFillMode
property vector4d fillColor: root.fillColor property vector4d fillColor: root.fillColor
property real imageWidth1: Math.max(1, root.hasCurrent ? source1.sourceSize.width : modelData.width) property real imageWidth1: modelData.width
property real imageHeight1: Math.max(1, root.hasCurrent ? source1.sourceSize.height : modelData.height) property real imageHeight1: modelData.height
property real imageWidth2: Math.max(1, source2.sourceSize.width) property real imageWidth2: modelData.width
property real imageHeight2: Math.max(1, source2.sourceSize.height) property real imageHeight2: modelData.height
property real screenWidth: modelData.width property real screenWidth: modelData.width
property real screenHeight: modelData.height property real screenHeight: modelData.height
fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_portal.frag.qsb") fragmentShader: Qt.resolvedUrl("../Shaders/qsb/wp_portal.frag.qsb")
@@ -451,14 +484,20 @@ Variants {
duration: root.actualTransitionType === "none" ? 0 : 1000 duration: root.actualTransitionType === "none" ? 0 : 1000
easing.type: Easing.InOutCubic easing.type: Easing.InOutCubic
onFinished: { onFinished: {
if (nextWallpaper.source && nextWallpaper.status === Image.Ready) {
currentWallpaper.source = nextWallpaper.source;
}
root.useNextForEffect = false;
Qt.callLater(() => { Qt.callLater(() => {
if (nextWallpaper.source && nextWallpaper.status === Image.Ready && !nextWallpaper.source.toString().startsWith("#")) {
currentWallpaper.source = nextWallpaper.source;
}
nextWallpaper.source = ""; nextWallpaper.source = "";
nextWallpaper.visible = false; Qt.callLater(() => {
currentWallpaper.visible = root.actualTransitionType === "none"; root.effectActive = false;
root.transitionProgress = 0.0; currentWallpaper.layer.enabled = false;
nextWallpaper.layer.enabled = false;
currentWallpaper.cache = true;
nextWallpaper.cache = false;
root.transitionProgress = 0.0;
});
}); });
} }
} }

View File

@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.I3
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Hyprland import Quickshell.Hyprland
import qs.Common import qs.Common
@@ -23,6 +24,31 @@ Singleton {
readonly property string labwcPid: Quickshell.env("LABWC_PID") readonly property string labwcPid: Quickshell.env("LABWC_PID")
property bool useNiriSorting: isNiri && NiriService property bool useNiriSorting: isNiri && NiriService
readonly property string focusedScreenName: {
if (isHyprland && Hyprland.focusedMonitor)
return Hyprland.focusedMonitor.name;
if (isNiri && NiriService.currentOutput)
return NiriService.currentOutput;
if (isDwl && DwlService.activeOutput)
return DwlService.activeOutput;
if (isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
if (focusedWs?.monitor?.name)
return focusedWs.monitor.name;
}
return Quickshell.screens[0]?.name ?? "";
}
readonly property var focusedScreen: {
if (!focusedScreenName)
return Quickshell.screens[0] ?? null;
for (const s of Quickshell.screens) {
if (s.name === focusedScreenName)
return s;
}
return Quickshell.screens[0] ?? null;
}
property var sortedToplevels: [] property var sortedToplevels: []
property bool _sortScheduled: false property bool _sortScheduled: false

View File

@@ -14,6 +14,8 @@ Singleton {
property var deviceBrightness: ({}) property var deviceBrightness: ({})
property var deviceBrightnessUserSet: ({}) property var deviceBrightnessUserSet: ({})
property var deviceMaxCache: ({}) property var deviceMaxCache: ({})
property var userControlledDevices: ({})
property var pendingOsdDevices: ({})
property int brightnessVersion: 0 property int brightnessVersion: 0
property string currentDevice: "" property string currentDevice: ""
property string lastIpcDevice: "" property string lastIpcDevice: ""
@@ -28,6 +30,7 @@ Singleton {
} }
property int maxBrightness: 100 property int maxBrightness: 100
property bool brightnessInitialized: false property bool brightnessInitialized: false
property bool suppressOsd: true
signal brightnessChanged(bool showOsd) signal brightnessChanged(bool showOsd)
signal deviceSwitched signal deviceSwitched
@@ -38,11 +41,51 @@ Singleton {
property bool automationAvailable: false property bool automationAvailable: false
property bool gammaControlAvailable: false property bool gammaControlAvailable: false
function markDeviceUserControlled(deviceId) {
const newControlled = Object.assign({}, userControlledDevices);
newControlled[deviceId] = Date.now();
userControlledDevices = newControlled;
}
function isDeviceUserControlled(deviceId) {
const controlTime = userControlledDevices[deviceId];
if (!controlTime) {
return false;
}
return (Date.now() - controlTime) < 1000;
}
function clearDeviceUserControlled(deviceId) {
const newControlled = Object.assign({}, userControlledDevices);
delete newControlled[deviceId];
userControlledDevices = newControlled;
}
function markDevicePendingOsd(deviceId) {
const newPending = Object.assign({}, pendingOsdDevices);
newPending[deviceId] = true;
pendingOsdDevices = newPending;
}
function clearDevicePendingOsd(deviceId) {
const newPending = Object.assign({}, pendingOsdDevices);
delete newPending[deviceId];
pendingOsdDevices = newPending;
}
function updateSingleDevice(device) { function updateSingleDevice(device) {
if (device.class === "leds") {
return;
}
const isUserControlled = isDeviceUserControlled(device.id);
if (isUserControlled) {
return;
}
const deviceIndex = devices.findIndex(d => d.id === device.id); const deviceIndex = devices.findIndex(d => d.id === device.id);
if (deviceIndex !== -1) { if (deviceIndex !== -1) {
const newDevices = [...devices]; const newDevices = [...devices];
const existingDevice = devices[deviceIndex];
const cachedMax = deviceMaxCache[device.id]; const cachedMax = deviceMaxCache[device.id];
let displayMax = cachedMax || (device.class === "ddc" ? device.max : 100); let displayMax = cachedMax || (device.class === "ddc" ? device.max : 100);
@@ -71,7 +114,17 @@ Singleton {
let displayValue = device.currentPercent; let displayValue = device.currentPercent;
if (isExponential) { if (isExponential) {
if (userSetValue !== undefined) { if (userSetValue !== undefined) {
displayValue = userSetValue; const exponent = SessionData.getBrightnessExponent(device.id);
const expectedHardware = Math.round(Math.pow(userSetValue / 100.0, exponent) * 100.0);
if (Math.abs(device.currentPercent - expectedHardware) > 2) {
const newUserSet = Object.assign({}, deviceBrightnessUserSet);
delete newUserSet[device.id];
deviceBrightnessUserSet = newUserSet;
SessionData.clearBrightnessUserSetValue(device.id);
displayValue = linearToExponential(device.currentPercent, device.id);
} else {
displayValue = userSetValue;
}
} else { } else {
displayValue = linearToExponential(device.currentPercent, device.id); displayValue = linearToExponential(device.currentPercent, device.id);
} }
@@ -83,9 +136,22 @@ Singleton {
deviceBrightness = newBrightness; deviceBrightness = newBrightness;
brightnessVersion++; brightnessVersion++;
if (oldValue !== undefined && oldValue !== displayValue && brightnessInitialized) { const isPendingOsd = pendingOsdDevices[device.id] === true;
brightnessChanged(true); if (isPendingOsd) {
clearDevicePendingOsd(device.id);
if (!suppressOsd) {
brightnessChanged(true);
}
return;
} }
if (!brightnessInitialized || oldValue === displayValue) {
return;
}
if (suppressOsd) {
return;
}
brightnessChanged(true);
} }
function updateFromBrightnessState(state) { function updateFromBrightnessState(state) {
@@ -167,13 +233,12 @@ Singleton {
function setBrightness(percentage, device, suppressOsd) { function setBrightness(percentage, device, suppressOsd) {
const actualDevice = device === "" ? getDefaultDevice() : (device || currentDevice || getDefaultDevice()); const actualDevice = device === "" ? getDefaultDevice() : (device || currentDevice || getDefaultDevice());
if (!actualDevice) { if (!actualDevice) {
console.warn("DisplayService: No device selected for brightness change"); console.warn("DisplayService: No device selected for brightness change");
return; return;
} }
if (actualDevice && actualDevice !== lastIpcDevice) { if (actualDevice !== lastIpcDevice) {
lastIpcDevice = actualDevice; lastIpcDevice = actualDevice;
} }
@@ -183,12 +248,15 @@ Singleton {
let minValue = 0; let minValue = 0;
let maxValue = 100; let maxValue = 100;
if (isExponential) { switch (true) {
case isExponential:
minValue = 1; minValue = 1;
maxValue = 100; maxValue = 100;
} else { break;
default:
minValue = (deviceInfo && (deviceInfo.class === "backlight" || deviceInfo.class === "ddc")) ? 1 : 0; minValue = (deviceInfo && (deviceInfo.class === "backlight" || deviceInfo.class === "ddc")) ? 1 : 0;
maxValue = deviceInfo?.displayMax || 100; maxValue = deviceInfo?.displayMax || 100;
break;
} }
if (maxValue <= 0) { if (maxValue <= 0) {
@@ -203,11 +271,23 @@ Singleton {
return; return;
} }
const isLedDevice = deviceInfo?.class === "leds";
if (suppressOsd) {
markDeviceUserControlled(actualDevice);
} else if (!isLedDevice) {
markDevicePendingOsd(actualDevice);
}
const newBrightness = Object.assign({}, deviceBrightness); const newBrightness = Object.assign({}, deviceBrightness);
newBrightness[actualDevice] = clampedValue; newBrightness[actualDevice] = clampedValue;
deviceBrightness = newBrightness; deviceBrightness = newBrightness;
brightnessVersion++; brightnessVersion++;
if (isLedDevice && !suppressOsd) {
brightnessChanged(true);
}
if (isExponential) { if (isExponential) {
const newUserSet = Object.assign({}, deviceBrightnessUserSet); const newUserSet = Object.assign({}, deviceBrightnessUserSet);
newUserSet[actualDevice] = clampedValue; newUserSet[actualDevice] = clampedValue;
@@ -215,10 +295,6 @@ Singleton {
SessionData.setBrightnessUserSetValue(actualDevice, clampedValue); SessionData.setBrightnessUserSetValue(actualDevice, clampedValue);
} }
if (!suppressOsd) {
brightnessChanged(true);
}
const params = { const params = {
"device": actualDevice, "device": actualDevice,
"percent": clampedValue "percent": clampedValue
@@ -590,11 +666,7 @@ Singleton {
return; return;
} }
if (SessionData.nightModeAutoEnabled) { evaluateNightMode();
startAutomation();
} else {
applyNightModeDirectly();
}
}); });
} }
} }
@@ -604,7 +676,7 @@ Singleton {
Timer { Timer {
id: restartTimer id: restartTimer
property string nextAction: "" property string nextAction: ""
interval: 100 interval: 250
repeat: false repeat: false
onTriggered: { onTriggered: {
@@ -634,6 +706,13 @@ Singleton {
brightnessChanged(); brightnessChanged();
} }
Timer {
id: osdSuppressTimer
interval: 2000
running: true
onTriggered: suppressOsd = false
}
Component.onCompleted: { Component.onCompleted: {
nightModeEnabled = SessionData.nightModeEnabled; nightModeEnabled = SessionData.nightModeEnabled;
deviceBrightnessUserSet = Object.assign({}, SessionData.brightnessUserSetValues); deviceBrightnessUserSet = Object.assign({}, SessionData.brightnessUserSetValues);
@@ -674,6 +753,13 @@ Singleton {
function onBrightnessDeviceUpdate(device) { function onBrightnessDeviceUpdate(device) {
updateSingleDevice(device); updateSingleDevice(device);
} }
function onLoginctlEvent(event) {
if (event.event === "unlock" || event.event === "resume") {
suppressOsd = true;
osdSuppressTimer.restart();
}
}
} }
// Session Data Connections // Session Data Connections
@@ -746,7 +832,7 @@ Singleton {
if (targetDevice && targetDevice !== root.currentDevice) { if (targetDevice && targetDevice !== root.currentDevice) {
root.setCurrentDevice(targetDevice, false); root.setCurrentDevice(targetDevice, false);
} }
root.setBrightness(clampedValue, targetDevice, false); root.setBrightness(clampedValue, targetDevice);
if (targetDevice) { if (targetDevice) {
return "Brightness set to " + clampedValue + "% on " + targetDevice; return "Brightness set to " + clampedValue + "% on " + targetDevice;
@@ -787,7 +873,7 @@ Singleton {
const newBrightness = Math.min(maxValue, currentBrightness + stepValue); const newBrightness = Math.min(maxValue, currentBrightness + stepValue);
root.setBrightness(newBrightness, actualDevice, false); root.setBrightness(newBrightness, actualDevice);
return "Brightness increased by " + stepValue + "%" + (targetDevice ? " on " + targetDevice : ""); return "Brightness increased by " + stepValue + "%" + (targetDevice ? " on " + targetDevice : "");
} }
@@ -824,7 +910,7 @@ Singleton {
const newBrightness = Math.max(minValue, currentBrightness - stepValue); const newBrightness = Math.max(minValue, currentBrightness - stepValue);
root.setBrightness(newBrightness, actualDevice, false); root.setBrightness(newBrightness, actualDevice);
return "Brightness decreased by " + stepValue + "%" + (targetDevice ? " on " + targetDevice : ""); return "Brightness decreased by " + stepValue + "%" + (targetDevice ? " on " + targetDevice : "");
} }

View File

@@ -1,16 +1,13 @@
pragma Singleton pragma Singleton
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.Io
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
Singleton { Singleton {
id: root id: root
readonly property list<MprisPlayer> availablePlayers: Mpris.players.values readonly property list<MprisPlayer> availablePlayers: Mpris.players.values
property MprisPlayer activePlayer: availablePlayers.find(p => p.isPlaying) ?? availablePlayers.find(p => p.canControl && p.canPlay) ?? null property MprisPlayer activePlayer: availablePlayers.find(p => p.isPlaying) ?? availablePlayers.find(p => p.canControl && p.canPlay) ?? null
} }