1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-05-03 11:02:08 -04:00

Compare commits

..

8 Commits

Author SHA1 Message Date
bbedward
3d35af2a87 cc: fix plugin reloading in bar position changes 2026-02-17 17:24:22 -05:00
bbedward
fed3c36f84 popout: anchor height changing popout surfaces to top and bottom 2026-02-17 17:18:07 -05:00
bbedward
414d81aa40 workspaces: fix named workspace icons 2026-02-17 16:02:13 -05:00
bbedward
d548803769 dankinstall: no_anim on dms layers 2026-02-17 15:32:08 -05:00
bbedward
1180258394 system updater: fix hide no update option 2026-02-17 13:53:17 -05:00
bbedward
48a566a24b launcher: fix kb navigation not always showing last delegate in view 2026-02-17 13:07:43 -05:00
bbedward
3bc5d1df81 doctor: add qt6-imageformats check 2026-02-17 12:58:09 -05:00
bbedward
c7222e2e86 bump version, codename, disable changelog 2026-02-17 12:02:36 -05:00
28 changed files with 413 additions and 493 deletions

View File

@@ -13,16 +13,16 @@ import (
)
var (
ssOutputName string
ssCursor string
ssFormat string
ssQuality int
ssOutputDir string
ssFilename string
ssNoClipboard bool
ssNoFile bool
ssNoNotify bool
ssStdout bool
ssOutputName string
ssIncludeCursor bool
ssFormat string
ssQuality int
ssOutputDir string
ssFilename string
ssNoClipboard bool
ssNoFile bool
ssNoNotify bool
ssStdout bool
)
var screenshotCmd = &cobra.Command{
@@ -52,7 +52,7 @@ Examples:
dms screenshot last # Last region (pre-selected)
dms screenshot --no-clipboard # Save file only
dms screenshot --no-file # Clipboard only
dms screenshot --cursor=on # Include cursor
dms screenshot --cursor # Include cursor
dms screenshot -f jpg -q 85 # JPEG with quality 85`,
}
@@ -111,7 +111,7 @@ var notifyActionCmd = &cobra.Command{
func init() {
screenshotCmd.PersistentFlags().StringVarP(&ssOutputName, "output", "o", "", "Output name for 'output' mode")
screenshotCmd.PersistentFlags().StringVar(&ssCursor, "cursor", "off", "Include cursor in screenshot (on/off)")
screenshotCmd.PersistentFlags().BoolVar(&ssIncludeCursor, "cursor", false, "Include cursor in screenshot")
screenshotCmd.PersistentFlags().StringVarP(&ssFormat, "format", "f", "png", "Output format (png, jpg, ppm)")
screenshotCmd.PersistentFlags().IntVarP(&ssQuality, "quality", "q", 90, "JPEG quality (1-100)")
screenshotCmd.PersistentFlags().StringVarP(&ssOutputDir, "dir", "d", "", "Output directory")
@@ -136,9 +136,7 @@ func getScreenshotConfig(mode screenshot.Mode) screenshot.Config {
config := screenshot.DefaultConfig()
config.Mode = mode
config.OutputName = ssOutputName
if strings.EqualFold(ssCursor, "on") {
config.Cursor = screenshot.CursorOn
}
config.IncludeCursor = ssIncludeCursor
config.Clipboard = !ssNoClipboard
config.SaveFile = !ssNoFile
config.Notify = !ssNoNotify

View File

@@ -430,7 +430,7 @@ func (d *DebianDistribution) enableOBSRepos(ctx context.Context, obsPkgs []Packa
}
// Add repository
repoLine := fmt.Sprintf("deb [signed-by=%s arch=%s] %s/ /", keyringPath, runtime.GOARCH, baseURL)
repoLine := fmt.Sprintf("deb [signed-by=%s, arch=%s] %s/ /", keyringPath, runtime.GOARCH, baseURL)
progressChan <- InstallProgressMsg{
Phase: PhaseSystemPackages,

View File

@@ -33,7 +33,6 @@ const (
TemplateKindTerminal
TemplateKindGTK
TemplateKindVSCode
TemplateKindEmacs
)
type TemplateDef struct {
@@ -66,7 +65,7 @@ var templateRegistry = []TemplateDef{
{ID: "dgop", Commands: []string{"dgop"}, ConfigFile: "dgop.toml"},
{ID: "kcolorscheme", ConfigFile: "kcolorscheme.toml", RunUnconditionally: true},
{ID: "vscode", Kind: TemplateKindVSCode},
{ID: "emacs", Commands: []string{"emacs"}, ConfigFile: "emacs.toml", Kind: TemplateKindEmacs},
{ID: "emacs", Commands: []string{"emacs"}, ConfigFile: "emacs.toml"},
}
func (c *ColorMode) GTKTheme() string {
@@ -79,8 +78,7 @@ func (c *ColorMode) GTKTheme() string {
}
var (
matugenVersionMu sync.Mutex
matugenVersionOK bool
matugenVersionOnce sync.Once
matugenSupportsCOE bool
matugenIsV4 bool
)
@@ -336,10 +334,6 @@ output_path = '%s'
appendVSCodeConfig(cfgFile, "cursor", filepath.Join(homeDir, ".cursor/extensions"), opts.ShellDir)
appendVSCodeConfig(cfgFile, "windsurf", filepath.Join(homeDir, ".windsurf/extensions"), opts.ShellDir)
appendVSCodeConfig(cfgFile, "vscode-insiders", filepath.Join(homeDir, ".vscode-insiders/extensions"), opts.ShellDir)
case TemplateKindEmacs:
if utils.EmacsConfigDir() != "" {
appendConfig(opts, cfgFile, tmpl.Commands, tmpl.Flatpaks, tmpl.ConfigFile)
}
default:
appendConfig(opts, cfgFile, tmpl.Commands, tmpl.Flatpaks, tmpl.ConfigFile)
}
@@ -497,9 +491,6 @@ func substituteVars(content, shellDir string) string {
result = strings.ReplaceAll(result, "'CONFIG_DIR/", "'"+utils.XDGConfigHome()+"/")
result = strings.ReplaceAll(result, "'DATA_DIR/", "'"+utils.XDGDataHome()+"/")
result = strings.ReplaceAll(result, "'CACHE_DIR/", "'"+utils.XDGCacheHome()+"/")
if emacsDir := utils.EmacsConfigDir(); emacsDir != "" {
result = strings.ReplaceAll(result, "'EMACS_DIR/", "'"+emacsDir+"/")
}
return result
}
@@ -520,159 +511,78 @@ func extractTOMLSection(content, startMarker, endMarker string) string {
return content[startIdx : startIdx+endIdx]
}
type matugenFlags struct {
supportsCOE bool
isV4 bool
func checkMatugenVersion() {
matugenVersionOnce.Do(func() {
cmd := exec.Command("matugen", "--version")
output, err := cmd.Output()
if err != nil {
return
}
versionStr := strings.TrimSpace(string(output))
versionStr = strings.TrimPrefix(versionStr, "matugen ")
parts := strings.Split(versionStr, ".")
if len(parts) < 2 {
return
}
major, err := strconv.Atoi(parts[0])
if err != nil {
return
}
minor, err := strconv.Atoi(parts[1])
if err != nil {
return
}
matugenSupportsCOE = major > 3 || (major == 3 && minor >= 1)
matugenIsV4 = major >= 4
if matugenSupportsCOE {
log.Infof("Matugen %s supports --continue-on-error", versionStr)
}
if matugenIsV4 {
log.Infof("Matugen %s: using v4 flags", versionStr)
}
})
}
func detectMatugenVersion() (matugenFlags, error) {
matugenVersionMu.Lock()
defer matugenVersionMu.Unlock()
if matugenVersionOK {
return matugenFlags{matugenSupportsCOE, matugenIsV4}, nil
}
return detectMatugenVersionLocked()
}
func redetectMatugenVersion(old matugenFlags) (matugenFlags, bool) {
matugenVersionMu.Lock()
defer matugenVersionMu.Unlock()
matugenVersionOK = false
flags, err := detectMatugenVersionLocked()
if err != nil {
return old, false
}
changed := flags.supportsCOE != old.supportsCOE || flags.isV4 != old.isV4
return flags, changed
}
func detectMatugenVersionLocked() (matugenFlags, error) {
cmd := exec.Command("matugen", "--version")
output, err := cmd.Output()
if err != nil {
return matugenFlags{}, fmt.Errorf("failed to get matugen version: %w", err)
}
versionStr := strings.TrimSpace(string(output))
versionStr = strings.TrimPrefix(versionStr, "matugen ")
parts := strings.Split(versionStr, ".")
if len(parts) < 2 {
return matugenFlags{}, fmt.Errorf("unexpected matugen version format: %q", versionStr)
}
major, err := strconv.Atoi(parts[0])
if err != nil {
return matugenFlags{}, fmt.Errorf("failed to parse matugen major version %q: %w", parts[0], err)
}
minor, err := strconv.Atoi(parts[1])
if err != nil {
return matugenFlags{}, fmt.Errorf("failed to parse matugen minor version %q: %w", parts[1], err)
}
matugenSupportsCOE = major > 3 || (major == 3 && minor >= 1)
matugenIsV4 = major >= 4
matugenVersionOK = true
func runMatugen(args []string) error {
checkMatugenVersion()
if matugenSupportsCOE {
log.Infof("Matugen %s supports --continue-on-error", versionStr)
args = append([]string{"--continue-on-error"}, args...)
}
if matugenIsV4 {
log.Infof("Matugen %s: using v4 flags", versionStr)
}
return matugenFlags{matugenSupportsCOE, matugenIsV4}, nil
}
func buildMatugenArgs(baseArgs []string, flags matugenFlags) []string {
args := make([]string, 0, len(baseArgs)+4)
if flags.supportsCOE {
args = append(args, "--continue-on-error")
}
args = append(args, baseArgs...)
if flags.isV4 {
args = append(args, "--source-color-index", "0")
}
return args
}
func runMatugen(baseArgs []string) error {
flags, err := detectMatugenVersion()
if err != nil {
return err
}
args := buildMatugenArgs(baseArgs, flags)
cmd := exec.Command("matugen", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
runErr := cmd.Run()
if runErr == nil {
return nil
}
log.Warnf("Matugen failed (v4=%v): %v", flags.isV4, runErr)
newFlags, changed := redetectMatugenVersion(flags)
if !changed {
return runErr
}
log.Warnf("Matugen version changed (v4: %v -> %v), retrying", flags.isV4, newFlags.isV4)
args = buildMatugenArgs(baseArgs, newFlags)
retryCmd := exec.Command("matugen", args...)
retryCmd.Stdout = os.Stdout
retryCmd.Stderr = os.Stderr
return retryCmd.Run()
return cmd.Run()
}
func runMatugenDryRun(opts *Options) (string, error) {
flags, err := detectMatugenVersion()
if err != nil {
return "", err
}
checkMatugenVersion()
output, dryErr := execDryRun(opts, flags)
if dryErr == nil {
return output, nil
}
log.Warnf("Matugen dry-run failed (v4=%v): %v", flags.isV4, dryErr)
newFlags, changed := redetectMatugenVersion(flags)
if !changed {
return "", dryErr
}
log.Warnf("Matugen version changed (v4: %v -> %v), retrying dry-run", flags.isV4, newFlags.isV4)
return execDryRun(opts, newFlags)
}
func execDryRun(opts *Options, flags matugenFlags) (string, error) {
var baseArgs []string
var args []string
switch opts.Kind {
case "hex":
baseArgs = []string{"color", "hex", opts.Value}
args = []string{"color", "hex", opts.Value}
default:
baseArgs = []string{opts.Kind, opts.Value}
args = []string{opts.Kind, opts.Value}
}
baseArgs = append(baseArgs, "-m", "dark", "-t", opts.MatugenType, "--json", "hex", "--dry-run")
if flags.isV4 {
baseArgs = append(baseArgs, "--source-color-index", "0", "--old-json-output")
args = append(args, "-m", "dark", "-t", opts.MatugenType, "--json", "hex", "--dry-run")
if matugenIsV4 {
args = append(args, "--source-color-index", "0", "--old-json-output")
}
cmd := exec.Command("matugen", baseArgs...)
var stderr strings.Builder
cmd.Stderr = &stderr
cmd := exec.Command("matugen", args...)
output, err := cmd.Output()
if err != nil {
if stderr.Len() > 0 {
return "", fmt.Errorf("matugen %v failed (v4=%v): %s", baseArgs, flags.isV4, strings.TrimSpace(stderr.String()))
}
return "", fmt.Errorf("matugen %v failed (v4=%v): %w", baseArgs, flags.isV4, err)
return "", err
}
return strings.ReplaceAll(string(output), "\n", ""), nil
}
@@ -909,8 +819,6 @@ func CheckTemplates(checker utils.AppChecker) []TemplateCheck {
detected = true
case tmpl.Kind == TemplateKindVSCode:
detected = checkVSCodeExtension(homeDir)
case tmpl.Kind == TemplateKindEmacs:
detected = appExists(checker, tmpl.Commands, tmpl.Flatpaks) && utils.EmacsConfigDir() != ""
default:
detected = appExists(checker, tmpl.Commands, tmpl.Flatpaks)
}

View File

@@ -108,7 +108,7 @@ func NewRegionSelector(s *Screenshoter) *RegionSelector {
screenshoter: s,
outputs: make(map[uint32]*WaylandOutput),
preCapture: make(map[*WaylandOutput]*PreCapture),
showCapturedCursor: s.config.Cursor == CursorOn,
showCapturedCursor: true,
}
}

View File

@@ -453,7 +453,10 @@ func (s *Screenshoter) blitBuffer(dst, src *ShmBuffer, dstX, dstY int, yInverted
}
func (s *Screenshoter) captureWholeOutput(output *WaylandOutput) (*CaptureResult, error) {
cursor := int32(s.config.Cursor)
cursor := int32(0)
if s.config.IncludeCursor {
cursor = 1
}
frame, err := s.screencopy.CaptureOutput(cursor, output.wlOutput)
if err != nil {
@@ -621,7 +624,10 @@ func (s *Screenshoter) captureRegionOnOutput(output *WaylandOutput, region Regio
}
}
cursor := int32(s.config.Cursor)
cursor := int32(0)
if s.config.IncludeCursor {
cursor = 1
}
frame, err := s.screencopy.CaptureOutputRegion(cursor, output.wlOutput, localX, localY, w, h)
if err != nil {

View File

@@ -19,13 +19,6 @@ const (
FormatPPM
)
type CursorMode int
const (
CursorOff CursorMode = iota
CursorOn
)
type Region struct {
X int32 `json:"x"`
Y int32 `json:"y"`
@@ -49,29 +42,29 @@ type Output struct {
}
type Config struct {
Mode Mode
OutputName string
Cursor CursorMode
Format Format
Quality int
OutputDir string
Filename string
Clipboard bool
SaveFile bool
Notify bool
Stdout bool
Mode Mode
OutputName string
IncludeCursor bool
Format Format
Quality int
OutputDir string
Filename string
Clipboard bool
SaveFile bool
Notify bool
Stdout bool
}
func DefaultConfig() Config {
return Config{
Mode: ModeRegion,
Cursor: CursorOff,
Format: FormatPNG,
Quality: 90,
OutputDir: "",
Filename: "",
Clipboard: true,
SaveFile: true,
Notify: true,
Mode: ModeRegion,
IncludeCursor: false,
Format: FormatPNG,
Quality: 90,
OutputDir: "",
Filename: "",
Clipboard: true,
SaveFile: true,
Notify: true,
}
}

View File

@@ -38,22 +38,6 @@ func XDGConfigHome() string {
return filepath.Join(home, ".config")
}
func EmacsConfigDir() string {
home, _ := os.UserHomeDir()
emacsD := filepath.Join(home, ".emacs.d")
if info, err := os.Stat(emacsD); err == nil && info.IsDir() {
return emacsD
}
xdgEmacs := filepath.Join(XDGConfigHome(), "emacs")
if info, err := os.Stat(xdgEmacs); err == nil && info.IsDir() {
return xdgEmacs
}
return ""
}
func ExpandPath(path string) (string, error) {
expanded := os.ExpandEnv(path)
expanded = filepath.Clean(expanded)

View File

@@ -1 +1 @@
Saffron Bloom
The Wolverine

View File

@@ -60,7 +60,6 @@ Singleton {
property bool _hasLoaded: false
property bool _isReadOnly: false
property bool _hasUnsavedChanges: false
property bool _selfWrite: false
property var _loadedSettingsSnapshot: null
property var pluginSettings: ({})
property var builtInPluginSettings: ({})
@@ -1244,7 +1243,6 @@ Singleton {
function saveSettings() {
if (_loading || _parseError || !_hasLoaded)
return;
_selfWrite = true;
settingsFile.setText(JSON.stringify(Store.toJson(root), null, 2));
if (_isReadOnly)
_checkSettingsWritable();
@@ -2591,13 +2589,7 @@ Singleton {
blockWrites: true
atomicWrites: true
watchChanges: true
onFileChanged: {
if (_selfWrite) {
_selfWrite = false;
return;
}
settingsFileReloadDebounce.restart();
}
onFileChanged: settingsFileReloadDebounce.restart()
onLoaded: {
if (isGreeterMode)
return;

View File

@@ -83,9 +83,9 @@ FloatingWindow {
objectName: "processListModal"
title: I18n.tr("System Monitor", "sysmon window title")
minimumSize: Qt.size(Math.min(Math.round(Theme.fontSizeMedium * 48), Screen.width), Math.min(Math.round(Theme.fontSizeMedium * 34), Screen.height))
implicitWidth: Math.round(Theme.fontSizeMedium * 71)
implicitHeight: Math.round(Theme.fontSizeMedium * 51)
minimumSize: Qt.size(750, 550)
implicitWidth: 1000
implicitHeight: 720
color: Theme.surfaceContainer
visible: false
@@ -236,7 +236,7 @@ FloatingWindow {
Item {
Layout.fillWidth: true
Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.4)
Layout.preferredHeight: 48
MouseArea {
anchors.fill: parent
@@ -293,10 +293,10 @@ FloatingWindow {
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.7)
Layout.preferredHeight: 52
Layout.leftMargin: Theme.spacingL
Layout.rightMargin: Theme.spacingL
spacing: Theme.spacingM
spacing: Theme.spacingL
Row {
spacing: 2
@@ -322,15 +322,14 @@ FloatingWindow {
]
Rectangle {
width: tabRowContent.implicitWidth + Theme.spacingM * 2
height: Math.round(Theme.fontSizeMedium * 3.1)
width: 120
height: 44
radius: Theme.cornerRadius
color: currentTab === index ? Theme.primaryPressed : (tabMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent")
border.color: currentTab === index ? Theme.primary : "transparent"
border.width: currentTab === index ? 1 : 0
Row {
id: tabRowContent
anchors.centerIn: parent
spacing: Theme.spacingXS
@@ -374,13 +373,11 @@ FloatingWindow {
DankButtonGroup {
id: processFilterGroup
Layout.minimumWidth: implicitWidth + 8
model: [I18n.tr("All"), I18n.tr("User"), I18n.tr("System")]
currentIndex: 0
checkEnabled: false
buttonHeight: Math.round(Theme.fontSizeSmall * 2.6)
minButtonWidth: 0
buttonPadding: Theme.spacingS
textSize: Theme.fontSizeSmall
buttonHeight: 36
visible: currentTab === 0
onSelectionChanged: (index, selected) => {
if (!selected)
@@ -403,9 +400,9 @@ FloatingWindow {
DankTextField {
id: searchField
Layout.fillWidth: true
Layout.maximumWidth: Math.round(Theme.fontSizeMedium * 18)
Layout.minimumWidth: Theme.fontSizeMedium * 4
Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 2.8)
Layout.maximumWidth: 250
Layout.minimumWidth: 120
Layout.preferredHeight: 40
placeholderText: I18n.tr("Search processes...", "process search placeholder")
leftIconName: "search"
showClearButton: true
@@ -473,7 +470,7 @@ FloatingWindow {
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: Math.round(Theme.fontSizeSmall * 2.7)
Layout.preferredHeight: 32
Layout.leftMargin: Theme.spacingL
Layout.rightMargin: Theme.spacingL
Layout.bottomMargin: Theme.spacingM

View File

@@ -155,7 +155,6 @@ BasePill {
property real touchpadThreshold: 500
onWheel: function (wheelEvent) {
wheelEvent.accepted = true;
const deltaY = wheelEvent.angleDelta.y;
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0;

View File

@@ -278,7 +278,7 @@ Item {
Behavior on x {
enabled: !swipeDragHandler.active && delegateRoot.__delegateInitialized
NumberAnimation {
duration: Theme.notificationExitDuration
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
@@ -286,7 +286,7 @@ Item {
Behavior on opacity {
enabled: delegateRoot.__delegateInitialized
NumberAnimation {
duration: delegateRoot.__delegateInitialized ? Theme.notificationExitDuration : 0
duration: delegateRoot.__delegateInitialized ? Theme.shortDuration : 0
}
}
}

View File

@@ -257,7 +257,7 @@ DankListView {
target: delegateRoot
property: "swipeOffset"
to: 0
duration: Theme.notificationExitDuration
duration: Theme.shortDuration
easing.type: Easing.OutCubic
onStopped: NotificationService.dismissGroup(delegateRoot.modelData?.key || "")
}

View File

@@ -764,7 +764,7 @@ Rectangle {
target: expandedDelegateWrapper
property: "swipeOffset"
to: expandedDelegateWrapper.swipeOffset > 0 ? expandedDelegateWrapper.width : -expandedDelegateWrapper.width
duration: Theme.notificationExitDuration
duration: Theme.shortDuration
easing.type: Easing.OutCubic
onStopped: NotificationService.dismissNotification(modelData)
}

View File

@@ -35,9 +35,9 @@ DankPopout {
popupWidth: triggerScreen ? Math.min(500, Math.max(380, triggerScreen.width - 48)) : 400
popupHeight: stablePopupHeight
positioning: ""
animationScaleCollapsed: 0.94
animationScaleCollapsed: 1.0
animationOffset: 0
suspendShadowWhileResizing: false
suspendShadowWhileResizing: true
screen: triggerScreen
shouldBeVisible: notificationHistoryVisible

View File

@@ -22,8 +22,6 @@ PanelWindow {
property bool _isDestroying: false
property bool _finalized: false
property real _lastReportedAlignedHeight: -1
property real _storedTopMargin: 0
property real _storedBottomMargin: 0
readonly property string clearText: I18n.tr("Dismiss")
property bool descriptionExpanded: false
readonly property bool hasExpandableBody: (notificationData?.htmlBody || "").replace(/<[^>]*>/g, "").trim().length > 0
@@ -148,8 +146,6 @@ PanelWindow {
}
Component.onCompleted: {
_lastReportedAlignedHeight = Theme.px(implicitHeight, dpr);
_storedTopMargin = getTopMargin();
_storedBottomMargin = getBottomMargin();
if (SettingsData.notificationPopupPrivacyMode)
descriptionExpanded = false;
if (hasValidData) {
@@ -183,30 +179,14 @@ PanelWindow {
property bool isBottomCenter: SettingsData.notificationPopupPosition === SettingsData.Position.BottomCenter
property bool isCenterPosition: isTopCenter || isBottomCenter
anchors.top: true
anchors.bottom: true
anchors.top: isTopCenter || SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Left
anchors.bottom: isBottomCenter || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom || SettingsData.notificationPopupPosition === SettingsData.Position.Right
anchors.left: SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
anchors.right: SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Right
mask: contentInputMask
Region {
id: contentInputMask
item: contentMaskRect
}
Item {
id: contentMaskRect
visible: false
x: content.x
y: content.y
width: alignedWidth
height: alignedHeight
}
margins {
top: _storedTopMargin
bottom: _storedBottomMargin
top: getTopMargin()
bottom: getBottomMargin()
left: getLeftMargin()
right: getRightMargin()
}
@@ -283,14 +263,7 @@ PanelWindow {
id: content
x: Theme.snap((win.width - alignedWidth) / 2, dpr)
y: {
const isTop = isTopCenter || SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Left;
if (isTop) {
return Theme.snap(screenY, dpr);
} else {
return Theme.snap(win.height - alignedHeight - screenY, dpr);
}
}
y: Theme.snap((win.height - alignedHeight) / 2, dpr)
width: alignedWidth
height: alignedHeight
visible: !win._finalized
@@ -338,7 +311,7 @@ PanelWindow {
id: bgShadowLayer
anchors.fill: parent
anchors.margins: Theme.snap(4, win.dpr)
layer.enabled: !win._isDestroying && win.screenValid
layer.enabled: !win._isDestroying && win.screenValid && !implicitHeightAnim.running
layer.smooth: false
layer.textureSize: Qt.size(Math.round(width * win.dpr), Math.round(height * win.dpr))
layer.textureMirroring: ShaderEffectSource.MirrorVertically
@@ -841,7 +814,7 @@ PanelWindow {
Behavior on swipeOffset {
enabled: !content.swipeActive && !content.swipeDismissing
NumberAnimation {
duration: Theme.notificationExitDuration
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
@@ -851,7 +824,7 @@ PanelWindow {
target: content
property: "swipeOffset"
to: isTopCenter ? -content.height : isBottomCenter ? content.height : (SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom ? -content.width : content.width)
duration: Theme.notificationExitDuration
duration: Theme.shortDuration
easing.type: Easing.OutCubic
onStopped: {
NotificationService.dismissNotification(notificationData);

View File

@@ -7,10 +7,9 @@ DankOSD {
id: root
readonly property bool useVertical: isVerticalLayout
property int _displayBrightness: 0
function _syncBrightness() {
_displayBrightness = DisplayService.brightnessLevel;
property int targetBrightness: {
DisplayService.brightnessVersion;
return DisplayService.brightnessLevel;
}
osdWidth: useVertical ? (40 + Theme.spacingS * 2) : Math.min(260, Screen.width - Theme.spacingM * 2)
@@ -21,9 +20,9 @@ DankOSD {
Connections {
target: DisplayService
function onBrightnessChanged(showOsd) {
root._syncBrightness();
if (showOsd && SettingsData.osdBrightnessEnabled)
if (showOsd && SettingsData.osdBrightnessEnabled) {
root.show();
}
}
}
@@ -54,11 +53,13 @@ DankOSD {
anchors.centerIn: parent
name: {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc")
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc") {
return "brightness_medium";
if (deviceInfo.name.includes("kbd"))
} else if (deviceInfo.name.includes("kbd")) {
return "keyboard";
return "lightbulb";
} else {
return "lightbulb";
}
}
size: Theme.iconSize
color: Theme.primary
@@ -76,16 +77,20 @@ DankOSD {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo)
return 1;
if (SessionData.getBrightnessExponential(deviceInfo.id))
const isExponential = SessionData.getBrightnessExponential(deviceInfo.id);
if (isExponential) {
return 1;
}
return (deviceInfo.class === "backlight" || deviceInfo.class === "ddc") ? 1 : 0;
}
maximum: {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo)
return 100;
if (SessionData.getBrightnessExponential(deviceInfo.id))
const isExponential = SessionData.getBrightnessExponential(deviceInfo.id);
if (isExponential) {
return 100;
}
return deviceInfo.displayMax || 100;
}
enabled: DisplayService.brightnessAvailable
@@ -94,24 +99,28 @@ DankOSD {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo)
return "%";
if (SessionData.getBrightnessExponential(deviceInfo.id))
const isExponential = SessionData.getBrightnessExponential(deviceInfo.id);
if (isExponential) {
return "%";
}
return deviceInfo.class === "ddc" ? "" : "%";
}
thumbOutlineColor: Theme.surfaceContainer
alwaysShowValue: SettingsData.osdAlwaysShowValue
onSliderValueChanged: newValue => {
if (!DisplayService.brightnessAvailable)
return;
DisplayService.setBrightness(newValue, DisplayService.lastIpcDevice, true);
resetHideTimer();
if (DisplayService.brightnessAvailable) {
DisplayService.setBrightness(newValue, DisplayService.lastIpcDevice, true);
resetHideTimer();
}
}
onContainsMouseChanged: setChildHovered(containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse);
}
Binding on value {
value: root._displayBrightness
value: root.targetBrightness
when: !brightnessSlider.isDragging
}
}
@@ -137,11 +146,13 @@ DankOSD {
anchors.centerIn: parent
name: {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc")
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc") {
return "brightness_medium";
if (deviceInfo.name.includes("kbd"))
} else if (deviceInfo.name.includes("kbd")) {
return "keyboard";
return "lightbulb";
} else {
return "lightbulb";
}
}
size: Theme.iconSize
color: Theme.primary
@@ -159,7 +170,7 @@ DankOSD {
property int value: 50
Binding on value {
value: root._displayBrightness
value: root.targetBrightness
when: !vertSlider.dragging
}
@@ -167,7 +178,8 @@ DankOSD {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo)
return 1;
if (SessionData.getBrightnessExponential(deviceInfo.id))
const isExponential = SessionData.getBrightnessExponential(deviceInfo.id);
if (isExponential)
return 1;
return (deviceInfo.class === "backlight" || deviceInfo.class === "ddc") ? 1 : 0;
}
@@ -176,7 +188,8 @@ DankOSD {
const deviceInfo = DisplayService.getCurrentDeviceInfo();
if (!deviceInfo)
return 100;
if (SessionData.getBrightnessExponential(deviceInfo.id))
const isExponential = SessionData.getBrightnessExponential(deviceInfo.id);
if (isExponential)
return 100;
return deviceInfo.displayMax || 100;
}
@@ -227,25 +240,33 @@ DankOSD {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onContainsMouseChanged: setChildHovered(containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse);
}
onPressed: mouse => {
vertSlider.dragging = true;
updateBrightness(mouse);
}
onReleased: vertSlider.dragging = false
onPositionChanged: mouse => {
if (pressed)
updateBrightness(mouse);
onReleased: {
vertSlider.dragging = false;
}
onClicked: mouse => updateBrightness(mouse)
onPositionChanged: mouse => {
if (pressed) {
updateBrightness(mouse);
}
}
onClicked: mouse => {
updateBrightness(mouse);
}
function updateBrightness(mouse) {
if (!DisplayService.brightnessAvailable)
if (!DisplayService.brightnessAvailable) {
return;
}
const ratio = 1.0 - (mouse.y / height);
const newValue = Math.round(vertSlider.minimum + ratio * (vertSlider.maximum - vertSlider.minimum));
vertSlider.value = newValue;

View File

@@ -8,20 +8,13 @@ DankOSD {
readonly property bool useVertical: isVerticalLayout
readonly property var player: MprisController.activePlayer
readonly property int currentVolume: player ? Math.min(100, Math.round(player.volume * 100)) : 0
readonly property bool volumeSupported: player?.volumeSupported ?? false
property bool _suppressNewPlayer: false
property int _displayVolume: 0
function _syncVolume() {
if (!player)
return;
_displayVolume = Math.min(100, Math.round(player.volume * 100));
}
onPlayerChanged: {
_suppressNewPlayer = true;
_suppressTimer.restart();
_syncVolume();
}
Timer {
@@ -44,25 +37,25 @@ DankOSD {
}
function toggleMute() {
if (!player)
return;
player.volume = player.volume > 0 ? 0 : 1;
if (player) {
player.volume = player.volume > 0 ? 0 : 1;
}
}
function setVolume(volumePercent) {
if (!player)
return;
player.volume = volumePercent / 100;
resetHideTimer();
if (player) {
player.volume = volumePercent / 100;
resetHideTimer();
}
}
Connections {
target: player
function onVolumeChanged() {
root._syncVolume();
if (SettingsData.osdMediaVolumeEnabled && volumeSupported && !_suppressNewPlayer)
if (SettingsData.osdMediaVolumeEnabled && volumeSupported && !_suppressNewPlayer) {
root.show();
}
}
}
@@ -103,7 +96,9 @@ DankOSD {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: toggleMute()
onContainsMouseChanged: setChildHovered(containsMouse || volumeSlider.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || volumeSlider.containsMouse);
}
}
}
@@ -120,21 +115,29 @@ DankOSD {
showValue: true
unit: "%"
thumbOutlineColor: Theme.surfaceContainer
valueOverride: root._displayVolume
valueOverride: currentVolume
alwaysShowValue: SettingsData.osdAlwaysShowValue
Component.onCompleted: {
root._syncVolume();
value = root._displayVolume;
value = currentVolume;
}
onSliderValueChanged: newValue => setVolume(newValue)
onSliderValueChanged: newValue => {
setVolume(newValue);
}
onContainsMouseChanged: setChildHovered(containsMouse || muteButton.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || muteButton.containsMouse);
}
Binding on value {
value: root._displayVolume
when: !volumeSlider.pressed
Connections {
target: player
function onVolumeChanged() {
if (volumeSlider && !volumeSlider.pressed) {
volumeSlider.value = currentVolume;
}
}
}
}
}
@@ -169,7 +172,9 @@ DankOSD {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: toggleMute()
onContainsMouseChanged: setChildHovered(containsMouse || vertSliderArea.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || vertSliderArea.containsMouse);
}
}
}
@@ -181,7 +186,7 @@ DankOSD {
y: gap * 2 + Theme.iconSize
property bool dragging: false
property int value: root._displayVolume
property int value: currentVolume
Rectangle {
id: vertTrack
@@ -226,21 +231,28 @@ DankOSD {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onContainsMouseChanged: setChildHovered(containsMouse || muteButtonVert.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || muteButtonVert.containsMouse);
}
onPressed: mouse => {
vertSlider.dragging = true;
updateVolume(mouse);
}
onReleased: vertSlider.dragging = false
onPositionChanged: mouse => {
if (pressed)
updateVolume(mouse);
onReleased: {
vertSlider.dragging = false;
}
onClicked: mouse => updateVolume(mouse)
onPositionChanged: mouse => {
if (pressed) {
updateVolume(mouse);
}
}
onClicked: mouse => {
updateVolume(mouse);
}
function updateVolume(mouse) {
const ratio = 1.0 - (mouse.y / height);
@@ -248,6 +260,16 @@ DankOSD {
setVolume(volume);
}
}
Connections {
target: player
function onVolumeChanged() {
if (!vertSlider.dragging) {
vertSlider.value = currentVolume;
}
}
}
}
StyledText {
@@ -261,4 +283,15 @@ DankOSD {
}
}
}
onOsdShown: {
if (player && contentLoader.item && contentLoader.item.item) {
if (!useVertical) {
const slider = contentLoader.item.item.children[0].children[1];
if (slider && slider.value !== undefined) {
slider.value = currentVolume;
}
}
}
}
}

View File

@@ -7,13 +7,6 @@ DankOSD {
id: root
readonly property bool useVertical: isVerticalLayout
property int _displayVolume: 0
function _syncVolume() {
if (!AudioService.sink?.audio)
return;
_displayVolume = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
}
osdWidth: useVertical ? (40 + Theme.spacingS * 2) : Math.min(260, Screen.width - Theme.spacingM * 2)
osdHeight: useVertical ? Math.min(260, Screen.height - Theme.spacingM * 2) : (40 + Theme.spacingS * 2)
@@ -21,17 +14,18 @@ DankOSD {
enableMouseInteraction: true
Connections {
target: AudioService.sink?.audio ?? null
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() {
root._syncVolume();
if (SettingsData.osdVolumeEnabled)
if (SettingsData.osdVolumeEnabled) {
root.show();
}
}
function onMutedChanged() {
if (SettingsData.osdVolumeEnabled)
if (SettingsData.osdVolumeEnabled) {
root.show();
}
}
}
@@ -39,9 +33,9 @@ DankOSD {
target: AudioService
function onSinkChanged() {
root._syncVolume();
if (root.shouldBeVisible && SettingsData.osdVolumeEnabled)
if (root.shouldBeVisible && SettingsData.osdVolumeEnabled) {
root.show();
}
}
}
@@ -70,7 +64,7 @@ DankOSD {
DankIcon {
anchors.centerIn: parent
name: AudioService.sink?.audio?.muted ? "volume_off" : "volume_up"
name: AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.muted ? "volume_off" : "volume_up"
size: Theme.iconSize
color: muteButton.containsMouse ? Theme.primary : Theme.surfaceText
}
@@ -81,45 +75,60 @@ DankOSD {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: AudioService.toggleMute()
onContainsMouseChanged: setChildHovered(containsMouse || volumeSlider.containsMouse)
onClicked: {
AudioService.toggleMute();
}
onContainsMouseChanged: {
setChildHovered(containsMouse || volumeSlider.containsMouse);
}
}
}
DankSlider {
id: volumeSlider
readonly property real actualVolumePercent: AudioService.sink && AudioService.sink.audio ? Math.round(AudioService.sink.audio.volume * 100) : 0
readonly property real displayPercent: actualVolumePercent
width: parent.width - Theme.iconSize - parent.gap * 3
height: 40
x: parent.gap * 2 + Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
minimum: 0
maximum: AudioService.sinkMaxVolume
enabled: AudioService.sink?.audio
enabled: AudioService.sink && AudioService.sink.audio
showValue: true
unit: "%"
thumbOutlineColor: Theme.surfaceContainer
valueOverride: root._displayVolume
valueOverride: displayPercent
alwaysShowValue: SettingsData.osdAlwaysShowValue
Component.onCompleted: {
root._syncVolume();
value = root._displayVolume;
if (AudioService.sink && AudioService.sink.audio) {
value = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
}
}
onSliderValueChanged: newValue => {
if (!AudioService.sink?.audio)
return;
SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = newValue / 100;
resetHideTimer();
if (AudioService.sink && AudioService.sink.audio) {
SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = newValue / 100;
resetHideTimer();
}
}
onContainsMouseChanged: setChildHovered(containsMouse || muteButton.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || muteButton.containsMouse);
}
Binding on value {
value: root._displayVolume
when: !volumeSlider.pressed
Connections {
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() {
if (volumeSlider && !volumeSlider.pressed) {
volumeSlider.value = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
}
}
}
}
}
@@ -142,7 +151,7 @@ DankOSD {
DankIcon {
anchors.centerIn: parent
name: AudioService.sink?.audio?.muted ? "volume_off" : "volume_up"
name: AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.muted ? "volume_off" : "volume_up"
size: Theme.iconSize
color: muteButtonVert.containsMouse ? Theme.primary : Theme.surfaceText
}
@@ -153,8 +162,12 @@ DankOSD {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: AudioService.toggleMute()
onContainsMouseChanged: setChildHovered(containsMouse || vertSliderArea.containsMouse)
onClicked: {
AudioService.toggleMute();
}
onContainsMouseChanged: {
setChildHovered(containsMouse || vertSliderArea.containsMouse);
}
}
}
@@ -166,7 +179,7 @@ DankOSD {
y: gap * 2 + Theme.iconSize
property bool dragging: false
property int value: root._displayVolume
property int value: AudioService.sink && AudioService.sink.audio ? Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100)) : 0
Rectangle {
id: vertTrack
@@ -207,35 +220,50 @@ DankOSD {
id: vertSliderArea
anchors.fill: parent
anchors.margins: -12
enabled: AudioService.sink?.audio
enabled: AudioService.sink && AudioService.sink.audio
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onContainsMouseChanged: setChildHovered(containsMouse || muteButtonVert.containsMouse)
onContainsMouseChanged: {
setChildHovered(containsMouse || muteButtonVert.containsMouse);
}
onPressed: mouse => {
vertSlider.dragging = true;
updateVolume(mouse);
}
onReleased: vertSlider.dragging = false
onPositionChanged: mouse => {
if (pressed)
updateVolume(mouse);
onReleased: {
vertSlider.dragging = false;
}
onClicked: mouse => updateVolume(mouse)
onPositionChanged: mouse => {
if (pressed) {
updateVolume(mouse);
}
}
onClicked: mouse => {
updateVolume(mouse);
}
function updateVolume(mouse) {
if (!AudioService.sink?.audio)
return;
const maxVol = AudioService.sinkMaxVolume;
const ratio = 1.0 - (mouse.y / height);
const volume = Math.max(0, Math.min(maxVol, Math.round(ratio * maxVol)));
SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = volume / 100;
resetHideTimer();
if (AudioService.sink && AudioService.sink.audio) {
const maxVol = AudioService.sinkMaxVolume;
const ratio = 1.0 - (mouse.y / height);
const volume = Math.max(0, Math.min(maxVol, Math.round(ratio * maxVol)));
SessionData.suppressOSDTemporarily();
AudioService.sink.audio.volume = volume / 100;
resetHideTimer();
}
}
}
Connections {
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() {
vertSlider.value = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
}
}
}
@@ -251,4 +279,15 @@ DankOSD {
}
}
}
onOsdShown: {
if (AudioService.sink && AudioService.sink.audio && contentLoader.item && contentLoader.item.item) {
if (!useVertical) {
const slider = contentLoader.item.item.children[0].children[1];
if (slider && slider.value !== undefined) {
slider.value = Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100));
}
}
}
}
}

View File

@@ -18,41 +18,36 @@ Column {
property bool isInitialized: false
function loadValue() {
const settings = findSettings();
const settings = findSettings()
if (settings && settings.pluginService) {
const loadedValue = settings.loadValue(settingKey, defaultValue);
if (textField.activeFocus && isInitialized)
return;
value = loadedValue;
textField.text = loadedValue;
isInitialized = true;
const loadedValue = settings.loadValue(settingKey, defaultValue)
value = loadedValue
textField.text = loadedValue
isInitialized = true
}
}
Component.onCompleted: {
Qt.callLater(loadValue);
Qt.callLater(loadValue)
}
function commit() {
if (!isInitialized)
return;
if (textField.text === value)
return;
value = textField.text;
const settings = findSettings();
if (settings)
settings.saveValue(settingKey, value);
onValueChanged: {
if (!isInitialized) return
const settings = findSettings()
if (settings) {
settings.saveValue(settingKey, value)
}
}
function findSettings() {
let item = parent;
let item = parent
while (item) {
if (item.saveValue !== undefined && item.loadValue !== undefined) {
return item;
return item
}
item = item.parent;
item = item.parent
}
return null;
return null
}
StyledText {
@@ -75,10 +70,16 @@ Column {
id: textField
width: parent.width
placeholderText: root.placeholder
onEditingFinished: root.commit()
onTextEdited: {
root.value = text
}
onEditingFinished: {
root.value = text
}
onActiveFocusChanged: {
if (!activeFocus)
root.commit();
if (!activeFocus) {
root.value = text
}
}
}
}

View File

@@ -26,8 +26,8 @@ DankPopout {
open();
}
popupWidth: Math.round(Theme.fontSizeMedium * 46)
popupHeight: Math.round(Theme.fontSizeMedium * 39)
popupWidth: 650
popupHeight: 550
triggerWidth: 55
positioning: ""
screen: triggerScreen
@@ -151,13 +151,11 @@ DankPopout {
DankButtonGroup {
id: processFilterGroup
Layout.minimumWidth: implicitWidth
Layout.minimumWidth: implicitWidth + 8
model: [I18n.tr("All"), I18n.tr("User"), I18n.tr("System")]
currentIndex: 0
checkEnabled: false
buttonHeight: Math.round(Theme.fontSizeSmall * 2.4)
minButtonWidth: 0
buttonPadding: Theme.spacingM
buttonHeight: Math.round(Theme.fontSizeMedium * 2.2)
textSize: Theme.fontSizeSmall
onSelectionChanged: (index, selected) => {
if (!selected)
@@ -179,8 +177,7 @@ DankPopout {
DankTextField {
id: searchField
Layout.fillWidth: true
Layout.minimumWidth: Theme.fontSizeMedium * 8
Layout.preferredWidth: Theme.fontSizeMedium * 14
Layout.preferredHeight: Theme.fontSizeMedium * 2.5
placeholderText: I18n.tr("Search...")
leftIconName: "search"

View File

@@ -375,20 +375,8 @@ FocusScope {
if (!plugin || !PluginService.isPluginLoaded(pluginId))
return;
var isLauncher = plugin.type === "launcher" || (plugin.capabilities && plugin.capabilities.includes("launcher"));
if (isLauncher) {
pluginReloadTimer.pendingPluginId = pluginId;
pluginReloadTimer.restart();
}
}
}
Timer {
id: pluginReloadTimer
property string pendingPluginId: ""
interval: 500
onTriggered: {
if (pendingPluginId)
PluginService.reloadPlugin(pendingPluginId);
if (isLauncher)
PluginService.reloadPlugin(pluginId);
}
}

View File

@@ -16,7 +16,7 @@ Item {
property var cachedCursorThemes: SettingsData.availableCursorThemes
property var cachedMatugenSchemes: Theme.availableMatugenSchemes.map(option => option.label)
property var installedRegistryThemes: []
property var templateDetection: []
property var templateDetection: ({})
property var cursorIncludeStatus: ({
"exists": false,
@@ -106,10 +106,9 @@ Item {
}
function isTemplateDetected(templateId) {
if (!templateDetection || templateDetection.length === 0)
if (!templateDetection || Object.keys(templateDetection).length === 0)
return true;
var item = templateDetection.find(i => i.id === templateId);
return !item || item.detected !== false;
return templateDetection[templateId] !== false;
}
function getTemplateDescription(templateId, baseDescription) {
@@ -146,17 +145,30 @@ Item {
DMSService.listInstalledThemes();
if (PopoutService.pendingThemeInstall)
Qt.callLater(() => showThemeBrowser());
Proc.runCommand("template-check", ["dms", "matugen", "check"], (output, exitCode) => {
if (exitCode !== 0)
return;
try {
themeColorsTab.templateDetection = JSON.parse(output.trim());
} catch (e) {}
});
templateCheckProcess.running = true;
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl)
checkCursorIncludeStatus();
}
Process {
id: templateCheckProcess
command: ["dms", "matugen", "check"]
running: false
stdout: StdioCollector {
onStreamFinished: {
try {
const results = JSON.parse(text);
const detection = {};
for (const item of results) {
detection[item.id] = item.detected;
}
themeColorsTab.templateDetection = detection;
} catch (e) {}
}
}
}
Connections {
target: DMSService
function onInstalledThemesReceived(themes) {

View File

@@ -11,7 +11,7 @@ Singleton {
id: root
readonly property string currentVersion: "1.4"
readonly property bool changelogEnabled: true
readonly property bool changelogEnabled: false
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) + "/DankMaterialShell"
readonly property string changelogMarkerPath: configDir + "/.changelog-" + currentVersion

View File

@@ -1 +1 @@
v1.4.1
v1.5-beta

View File

@@ -28,10 +28,6 @@ PanelWindow {
function show() {
if (SessionData.suppressOSD)
return;
if (shouldBeVisible) {
hideTimer.restart();
return;
}
OSDManager.showOSD(root);
closeTimer.stop();
shouldBeVisible = true;
@@ -261,7 +257,7 @@ PanelWindow {
property real shadowSpreadPx: 0
property real shadowBaseAlpha: 0.60
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
readonly property real effectiveShadowAlpha: shouldBeVisible ? Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha)) : 0
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha * osdContainer.opacity))
Rectangle {
id: background

View File

@@ -469,44 +469,6 @@ Item {
}
}
Rectangle {
id: shadowSource
anchors.centerIn: parent
width: parent.width
height: parent.height
radius: Theme.cornerRadius
color: "black"
visible: false
opacity: contentWrapper.opacity
scale: contentWrapper.scale
x: contentWrapper.x
y: contentWrapper.y
property real shadowBlurPx: 10
property real shadowSpreadPx: 0
property real shadowBaseAlpha: 0.60
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
readonly property int blurMax: 64
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive)
layer.smooth: false
layer.effect: MultiEffect {
id: shadowFx
autoPaddingEnabled: true
shadowEnabled: true
blurEnabled: false
maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, shadowSource.shadowBlurPx / shadowSource.blurMax))
shadowScale: 1 + (2 * shadowSource.shadowSpreadPx) / Math.max(1, Math.min(shadowSource.width, shadowSource.height))
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
return Theme.withAlpha(baseColor, shadowSource.effectiveShadowAlpha);
}
}
}
Item {
id: contentWrapper
anchors.centerIn: parent
@@ -518,10 +480,31 @@ Item {
x: Theme.snap(contentContainer.animX + (parent.width - width) * (1 - contentContainer.scaleValue) * 0.5, root.dpr)
y: Theme.snap(contentContainer.animY + (parent.height - height) * (1 - contentContainer.scaleValue) * 0.5, root.dpr)
layer.enabled: contentWrapper.opacity < 1
property real shadowBlurPx: 10
property real shadowSpreadPx: 0
property real shadowBaseAlpha: 0.60
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
readonly property int blurMax: 64
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive)
layer.smooth: false
layer.textureSize: root.dpr > 1 ? Qt.size(Math.ceil(width * root.dpr), Math.ceil(height * root.dpr)) : Qt.size(0, 0)
layer.effect: MultiEffect {
id: shadowFx
autoPaddingEnabled: true
shadowEnabled: true
blurEnabled: false
maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, contentWrapper.shadowBlurPx / contentWrapper.blurMax))
shadowScale: 1 + (2 * contentWrapper.shadowSpreadPx) / Math.max(1, Math.min(contentWrapper.width, contentWrapper.height))
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
return Theme.withAlpha(baseColor, contentWrapper.effectiveShadowAlpha);
}
}
Behavior on opacity {
NumberAnimation {
duration: animationDuration

View File

@@ -1,3 +1,3 @@
[templates.dmsemacs]
input_path = 'SHELL_DIR/matugen/templates/dank-emacs.el'
output_path = 'EMACS_DIR/themes/dank-emacs-theme.el'
output_path = "~/.emacs.d/themes/dank-emacs-theme.el"