1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-05-02 10:32:07 -04:00

Compare commits

...

28 Commits

Author SHA1 Message Date
bbedward
bcfa508da5 weather: fix fahrenheit conversion 2025-11-21 22:07:44 -05:00
mbpowers
c0ae3ef58b fix: bar and dock flickering autohide (#784) 2025-11-21 21:49:31 -05:00
mbpowers
1e70d7b4c3 fix: remove useFahrenheit refresh, fetch Celcius convert locally (#785)
* fix: remove useFahrenheit refresh, fetch Celcius convert locally

* fix: typo in change unit button
2025-11-21 21:41:12 -05:00
bbedward
f8dc6ad2bc update CONTRIBUTING 2025-11-21 17:30:54 -05:00
bbedward
e22482988f weather: fix display when 0 temp
fixes #782
2025-11-21 17:06:57 -05:00
bbedward
4eb896629d net: fix VPN prompting for password 2025-11-21 12:59:12 -05:00
bbedward
b310e66275 themes: shift catpuccin palete 2025-11-21 09:30:58 -05:00
bbedward
b39da1bea7 cc: bit of extra height for some detail items 2025-11-21 09:15:59 -05:00
Pi Home Server
fa575d0574 Fix background color of the privacy widget (#779) 2025-11-21 09:05:56 -05:00
bbedward
dfe2f3771b theme: add colorful bar widget option 2025-11-21 00:07:23 -05:00
bbedward
46caeb0445 sounds: only play audio changed when trigger by us 2025-11-20 23:38:06 -05:00
bbedward
59cc9c7006 niri: ensure overview spotlight is hidden when main window is brought up 2025-11-20 21:23:56 -05:00
bbedward
12e91534eb niri: empty input region & disable spotlight content when not open 2025-11-20 16:44:46 -05:00
bbedward
d9da88ceb5 niri: embed spotlight to same window as overview layer 2025-11-20 16:28:26 -05:00
bbedward
2dbfec0307 niri: close spotlight when closing overview 2025-11-20 13:56:35 -05:00
Lucas
09cf8c9641 niri: add spotlight on overview typing functionality (#774) 2025-11-20 13:48:30 -05:00
Pi Home Server
f1bed4d6a3 Feature/privacy widget fix (#772)
* Fix active camera icon

* Fix active camera icon
2025-11-20 12:30:23 -05:00
bbedward
2ed6c33c83 missing import 2025-11-19 19:14:47 -05:00
bbedward
7ad532ed17 dankinstall: add ultramarine 2025-11-19 18:53:41 -05:00
bbedward
92fe8c5b14 hyprland: restore focus grab to tray menus 2025-11-19 17:24:14 -05:00
bbedward
8e95572589 modals: move HyprFocusGrab out of common Modal 2025-11-19 17:16:51 -05:00
bbedward
62da862a66 modal: round textureSize pixels 2025-11-19 14:36:08 -05:00
bbedward
993e34f548 dankinstall: weakdeps for niri/system 2025-11-19 09:35:22 -05:00
github-actions[bot]
e39465aece chore: bump version to v0.6.2 2025-11-19 13:54:50 +00:00
bbedward
8fd616b680 osd: suppression fix from cc 2025-11-19 08:52:37 -05:00
bbedward
cc054b27de filebrowser: fix auto closing from ddash 2025-11-19 08:33:07 -05:00
github-actions[bot]
dfdaa82245 chore: bump version to v0.6.1 2025-11-19 03:16:35 +00:00
bbedward
99a307e0ad dankbar: hot fix color moda & systm tray item positions 2025-11-18 22:13:06 -05:00
75 changed files with 1032 additions and 370 deletions

View File

@@ -2,28 +2,42 @@
Contributions are welcome and encouraged.
## Formatting
To contribute fork this repository, make your changes, and open a pull request.
The preferred tool for formatting files is [qmlfmt](https://github.com/jesperhh/qmlfmt) (also available on aur as qmlfmt-git). It actually kinda sucks, but `qmlformat` doesn't work with null safe operators and ternarys and pragma statements and a bunch of other things that are supported.
## VSCode Setup
We need some consistent style, so this at least gives the same formatter that Qt Creator uses.
This is a monorepo, the easiest thing to do is to open an editor in either `quickshell`, `core`, or both depending on which part of the project you are working on.
You can configure it to format on save in vscode by configuring the "custom local formatters" extension then adding this to settings json.
### QML (`quickshell` directory)
1. Install the [QML Extension](https://doc.qt.io/vscodeext/)
2. Configure `ctrl+shift+p` -> user preferences (json) with qmlls path
```json
"customLocalFormatters.formatters": [
{
"command": "sh -c \"qmlfmt -t 4 -i 4 -b 250 | sed 's/pragma ComponentBehavior$/pragma ComponentBehavior: Bound/g'\"",
"languages": ["qml"]
}
],
"[qml]": {
"editor.defaultFormatter": "jkillian.custom-local-formatters",
"editor.formatOnSave": true
},
{
"qt-qml.doNotAskForQmllsDownload": true,
"qt-qml.qmlls.customExePath": "/usr/lib/qt6/bin/qmlls"
}
```
Sometimes it just breaks code though. Like turning `"_\""` into `"_""`, so you may not want to do formatOnSave.
3. Create empty `.qmlls.ini` file in `quickshell/` directory
```bash
cd quickshell
touch .qmlls.ini
```
4. Restart dms to generate the `.qmlls.ini` file
5. Make your changes, test, and open a pull request.
### GO (`core` directory)
1. Install the [Go Extension](https://code.visualstudio.com/docs/languages/go)
2. Ensure code is formatted with `make fmt`
3. Add appropriate test coverage and ensure tests pass with `make test`
4. Run `go mod tidy`
5. Open pull request
## Pull request

View File

@@ -19,10 +19,12 @@ func init() {
Register("fedora-asahi-remix", "#0B57A4", FamilyFedora, func(config DistroConfig, logChan chan<- string) Distribution {
return NewFedoraDistribution(config, logChan)
})
Register("bluefin", "#0B57A4", FamilyFedora, func(config DistroConfig, logChan chan<- string) Distribution {
return NewFedoraDistribution(config, logChan)
})
Register("ultramarine", "#00078b", FamilyFedora, func(config DistroConfig, logChan chan<- string) Distribution {
return NewFedoraDistribution(config, logChan)
})
}
type FedoraDistribution struct {
@@ -506,6 +508,14 @@ func (f *FedoraDistribution) installDNFPackages(ctx context.Context, packages []
f.log(fmt.Sprintf("Installing DNF packages: %s", strings.Join(packages, ", ")))
args := []string{"dnf", "install", "-y"}
for _, pkg := range packages {
if pkg == "niri" || pkg == "niri-git" {
args = append(args, "--setopt=install_weak_deps=False")
break
}
}
args = append(args, packages...)
progressChan <- InstallProgressMsg{

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strconv"
"time"
"github.com/AvengeMedia/DankMaterialShell/core/internal/errdefs"
@@ -125,8 +126,9 @@ func (a *SecretAgent) GetSecrets(
connType, displayName, vpnSvc := readConnTypeAndName(conn)
ssid := readSSID(conn)
fields := fieldsNeeded(settingName, hints)
vpnPasswordFlags := readVPNPasswordFlags(conn, settingName)
log.Infof("[SecretAgent] connType=%s, name=%s, vpnSvc=%s, fields=%v, flags=%d", connType, displayName, vpnSvc, fields, flags)
log.Infof("[SecretAgent] connType=%s, name=%s, vpnSvc=%s, fields=%v, flags=%d, vpnPasswordFlags=%d", connType, displayName, vpnSvc, fields, flags, vpnPasswordFlags)
if a.backend != nil {
a.backend.stateMutex.RLock()
@@ -163,57 +165,70 @@ func (a *SecretAgent) GetSecrets(
}
if len(fields) == 0 {
// For VPN connections with no hints, we can't provide a proper UI.
// Defer to other agents (like nm-applet or VPN-specific auth dialogs)
// that can handle the VPN type properly (e.g., OpenConnect with SAML, etc.)
if settingName == "vpn" {
log.Infof("[SecretAgent] VPN with empty hints - deferring to other agents for %s", vpnSvc)
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
}
if a.backend != nil {
a.backend.stateMutex.RLock()
isConnectingVPN := a.backend.state.IsConnectingVPN
a.backend.stateMutex.RUnlock()
const (
NM_SETTING_SECRET_FLAG_NONE = 0
NM_SETTING_SECRET_FLAG_AGENT_OWNED = 1
NM_SETTING_SECRET_FLAG_NOT_SAVED = 2
NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 4
)
if !isConnectingVPN {
log.Infof("[SecretAgent] VPN with empty hints - deferring to other agents for %s", vpnSvc)
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
}
var passwordFlags uint32 = 0xFFFF
switch settingName {
case "802-11-wireless-security":
if wifiSecSettings, ok := conn["802-11-wireless-security"]; ok {
if flagsVariant, ok := wifiSecSettings["psk-flags"]; ok {
if pwdFlags, ok := flagsVariant.Value().(uint32); ok {
passwordFlags = pwdFlags
}
}
}
case "802-1x":
if dot1xSettings, ok := conn["802-1x"]; ok {
if flagsVariant, ok := dot1xSettings["password-flags"]; ok {
if pwdFlags, ok := flagsVariant.Value().(uint32); ok {
passwordFlags = pwdFlags
}
}
log.Infof("[SecretAgent] VPN with empty hints but we're connecting - prompting for password")
fields = []string{"password"}
} else {
log.Infof("[SecretAgent] VPN with empty hints - deferring to other agents for %s", vpnSvc)
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
}
}
if passwordFlags == 0xFFFF {
log.Warnf("[SecretAgent] Could not determine password-flags for empty hints - returning NoSecrets error")
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
} else if passwordFlags&NM_SETTING_SECRET_FLAG_NOT_REQUIRED != 0 {
log.Infof("[SecretAgent] Secrets not required (flags=%d)", passwordFlags)
out := nmSettingMap{}
out[settingName] = nmVariantMap{}
return out, nil
} else if passwordFlags&NM_SETTING_SECRET_FLAG_AGENT_OWNED != 0 {
log.Warnf("[SecretAgent] Secrets are agent-owned but we don't store secrets (flags=%d) - returning NoSecrets error", passwordFlags)
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
} else {
log.Infof("[SecretAgent] No secrets needed, using system stored secrets (flags=%d)", passwordFlags)
out := nmSettingMap{}
out[settingName] = nmVariantMap{}
return out, nil
if len(fields) == 0 {
const (
NM_SETTING_SECRET_FLAG_NONE = 0
NM_SETTING_SECRET_FLAG_AGENT_OWNED = 1
NM_SETTING_SECRET_FLAG_NOT_SAVED = 2
NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 4
)
var passwordFlags uint32 = 0xFFFF
switch settingName {
case "802-11-wireless-security":
if wifiSecSettings, ok := conn["802-11-wireless-security"]; ok {
if flagsVariant, ok := wifiSecSettings["psk-flags"]; ok {
if pwdFlags, ok := flagsVariant.Value().(uint32); ok {
passwordFlags = pwdFlags
}
}
}
case "802-1x":
if dot1xSettings, ok := conn["802-1x"]; ok {
if flagsVariant, ok := dot1xSettings["password-flags"]; ok {
if pwdFlags, ok := flagsVariant.Value().(uint32); ok {
passwordFlags = pwdFlags
}
}
}
}
if passwordFlags == 0xFFFF {
log.Warnf("[SecretAgent] Could not determine password-flags for empty hints - returning NoSecrets error")
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
} else if passwordFlags&NM_SETTING_SECRET_FLAG_NOT_REQUIRED != 0 {
log.Infof("[SecretAgent] Secrets not required (flags=%d)", passwordFlags)
out := nmSettingMap{}
out[settingName] = nmVariantMap{}
return out, nil
} else if passwordFlags&NM_SETTING_SECRET_FLAG_AGENT_OWNED != 0 {
log.Warnf("[SecretAgent] Secrets are agent-owned but we don't store secrets (flags=%d) - returning NoSecrets error", passwordFlags)
return nil, dbus.NewError("org.freedesktop.NetworkManager.SecretAgent.Error.NoSecrets", nil)
} else {
log.Infof("[SecretAgent] No secrets needed, using system stored secrets (flags=%d)", passwordFlags)
out := nmSettingMap{}
out[settingName] = nmVariantMap{}
return out, nil
}
}
}
@@ -343,13 +358,11 @@ func (a *SecretAgent) GetSecrets(
// Update settings based on type
switch settingName {
case "vpn":
// Set password-flags=0 and add secrets to vpn section
vpn, ok := existingSettings["vpn"]
if !ok {
vpn = make(map[string]dbus.Variant)
}
// Get existing data map (vpn.data is string->string)
var data map[string]string
if dataVariant, ok := vpn["data"]; ok {
if dm, ok := dataVariant.Value().(map[string]string); ok {
@@ -364,11 +377,9 @@ func (a *SecretAgent) GetSecrets(
data = make(map[string]string)
}
// Update password-flags to 0 (system-stored)
data["password-flags"] = "0"
vpn["data"] = dbus.MakeVariant(data)
// Add secrets (vpn.secrets is string->string)
secs := make(map[string]string)
for k, v := range reply.Secrets {
secs[k] = v
@@ -379,14 +390,12 @@ func (a *SecretAgent) GetSecrets(
log.Infof("[SecretAgent] Updated VPN settings: password-flags=0, secrets with %d fields", len(secs))
case "802-11-wireless-security":
// Set psk-flags=0 for WiFi
wifiSec, ok := existingSettings["802-11-wireless-security"]
if !ok {
wifiSec = make(map[string]dbus.Variant)
}
wifiSec["psk-flags"] = dbus.MakeVariant(uint32(0))
// Add PSK secret
if psk, ok := reply.Secrets["psk"]; ok {
wifiSec["psk"] = dbus.MakeVariant(psk)
log.Infof("[SecretAgent] Updated WiFi settings: psk-flags=0")
@@ -394,14 +403,12 @@ func (a *SecretAgent) GetSecrets(
settings["802-11-wireless-security"] = wifiSec
case "802-1x":
// Set password-flags=0 for 802.1x
dot1x, ok := existingSettings["802-1x"]
if !ok {
dot1x = make(map[string]dbus.Variant)
}
dot1x["password-flags"] = dbus.MakeVariant(uint32(0))
// Add password secret
if password, ok := reply.Secrets["password"]; ok {
dot1x["password"] = dbus.MakeVariant(password)
log.Infof("[SecretAgent] Updated 802.1x settings: password-flags=0")
@@ -507,6 +514,39 @@ func fieldsNeeded(setting string, hints []string) []string {
}
}
func readVPNPasswordFlags(conn map[string]nmVariantMap, settingName string) uint32 {
if settingName != "vpn" {
return 0xFFFF
}
vpnSettings, ok := conn["vpn"]
if !ok {
return 0xFFFF
}
dataVariant, ok := vpnSettings["data"]
if !ok {
return 0xFFFF
}
dataMap, ok := dataVariant.Value().(map[string]string)
if !ok {
return 0xFFFF
}
flagsStr, ok := dataMap["password-flags"]
if !ok {
return 0xFFFF
}
flags64, err := strconv.ParseUint(flagsStr, 10, 32)
if err != nil {
return 0xFFFF
}
return uint32(flags64)
}
func reasonFromFlags(flags uint32) string {
const (
NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0

View File

@@ -235,7 +235,7 @@ func (b *NetworkManagerBackend) ConnectVPN(uuidOrName string, singleActive bool)
}
nm := b.nmConn.(gonetworkmanager.NetworkManager)
activeConn, err := nm.ActivateConnection(targetConn, nil, nil)
_, err = nm.ActivateConnection(targetConn, nil, nil)
if err != nil {
b.stateMutex.Lock()
b.state.IsConnectingVPN = false
@@ -249,20 +249,6 @@ func (b *NetworkManagerBackend) ConnectVPN(uuidOrName string, singleActive bool)
return fmt.Errorf("failed to activate VPN: %w", err)
}
if activeConn != nil {
state, _ := activeConn.GetPropertyState()
if state == 2 {
b.stateMutex.Lock()
b.state.IsConnectingVPN = false
b.state.ConnectingVPNUUID = ""
b.stateMutex.Unlock()
b.ListActiveVPN()
if b.onStateChange != nil {
b.onStateChange()
}
}
}
return nil
}

View File

@@ -44,6 +44,11 @@ Singleton {
SuspendThenHibernate
}
enum WidgetColorMode {
Default,
Colorful
}
readonly property string defaultFontFamily: "Inter Variable"
readonly property string defaultMonoFontFamily: "Fira Code"
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
@@ -70,6 +75,7 @@ Singleton {
property real popupTransparency: 1.0
property real dockTransparency: 1
property string widgetBackgroundColor: "sch"
property string widgetColorMode: "default"
property real cornerRadius: 12
property bool use24HourClock: true
@@ -171,6 +177,7 @@ Singleton {
property string spotlightModalViewMode: "list"
property bool sortAppsAlphabetically: false
property int appLauncherGridColumns: 4
property bool spotlightCloseNiriOverview: true
property string weatherLocation: "New York, NY"
property string weatherCoordinates: "40.7128,-74.0060"

View File

@@ -2,16 +2,16 @@
// Separated from Theme.qml to keep that file clean
const CatppuccinMocha = {
surface: "#313244",
surface: "#181825",
surfaceText: "#cdd6f4",
surfaceVariant: "#313244",
surfaceVariant: "#1e1e2e",
surfaceVariantText: "#a6adc8",
background: "#1e1e2e",
background: "#181825",
backgroundText: "#cdd6f4",
outline: "#6c7086",
surfaceContainer: "#45475a",
surfaceContainerHigh: "#585b70",
surfaceContainerHighest: "#6c7086"
surfaceContainer: "#1e1e2e",
surfaceContainerHigh: "#313244",
surfaceContainerHighest: "#45475a"
}
const CatppuccinLatte = {

View File

@@ -665,6 +665,34 @@ Singleton {
}
}
property color widgetIconColor: {
if (typeof SettingsData === "undefined") {
return surfaceText
}
switch (SettingsData.widgetColorMode) {
case "colorful":
return surfaceText
case "default":
default:
return surfaceText
}
}
property color widgetTextColor: {
if (typeof SettingsData === "undefined") {
return surfaceText
}
switch (SettingsData.widgetColorMode) {
case "colorful":
return primary
case "default":
default:
return surfaceText
}
}
function isColorDark(c) {
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) < 0.5

View File

@@ -18,6 +18,7 @@ var SPEC = {
dockTransparency: { def: 1.0, coerce: percentToUnit },
widgetBackgroundColor: { def: "sch" },
widgetColorMode: { def: "default" },
cornerRadius: { def: 12, onChange: "updateNiriLayout" },
use24HourClock: { def: true },
@@ -97,6 +98,7 @@ var SPEC = {
spotlightModalViewMode: { def: "list" },
sortAppsAlphabetically: { def: false },
appLauncherGridColumns: { def: 4 },
spotlightCloseNiriOverview: { def: true },
weatherLocation: { def: "New York, NY" },
weatherCoordinates: { def: "40.7128,-74.0060" },

View File

@@ -22,7 +22,7 @@ import qs.Modules.ProcessList
import qs.Modules.Settings
import qs.Modules.DankBar
import qs.Modules.DankBar.Popouts
import qs.Modules.HyprWorkspaces
import qs.Modules.WorkspaceOverlays
import qs.Modules.Plugins
import qs.Services
@@ -581,4 +581,12 @@ Item {
id: hyprlandOverview
}
}
LazyLoader {
id: niriOverviewOverlayLoader
active: CompositorService.isNiri
component: NiriOverviewOverlay {
id: niriOverviewOverlay
}
}
}

View File

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

View File

@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Common
import qs.Modals.Common
@@ -14,6 +15,11 @@ DankModal {
layerNamespace: "dms:clipboard"
HyprlandFocusGrab {
windows: [clipboardHistoryModal]
active: CompositorService.isHyprland && clipboardHistoryModal.shouldHaveFocus
}
property int totalCount: 0
property var clipboardEntries: []
property string searchText: ""

View File

@@ -95,11 +95,6 @@ PanelWindow {
return WlrKeyboardFocus.Exclusive
}
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && shouldHaveFocus
}
onVisibleChanged: {
if (root.visible) {
opened()
@@ -245,7 +240,7 @@ PanelWindow {
clip: false
layer.enabled: true
layer.smooth: false
layer.textureSize: Qt.size(width * root.dpr, height * root.dpr)
layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr))
opacity: root.shouldBeVisible ? 1 : 0
scale: modalContainer.scaleValue
x: Theme.snap(modalContainer.animX + (parent.width - width) * (1 - modalContainer.scaleValue) * 0.5, root.dpr)

View File

@@ -1,6 +1,7 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Common
import qs.Modals.Common
@@ -12,6 +13,11 @@ DankModal {
layerNamespace: "dms:color-picker"
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property string pickerTitle: "Choose Color"
property color selectedColor: SessionData.recentColors.length > 0 ? SessionData.recentColors[0] : Theme.primary
property var onColorSelectedCallback: null

View File

@@ -2,10 +2,13 @@ import Qt.labs.folderlistmodel
import QtCore
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Common
import qs.Modals.Common
import qs.Modals.FileBrowser
import qs.Services
import qs.Widgets
DankModal {
@@ -13,6 +16,13 @@ DankModal {
layerNamespace: "dms:file-browser"
HyprlandFocusGrab {
windows: [fileBrowserModal]
active: CompositorService.isHyprland && fileBrowserModal.shouldHaveFocus
}
keepPopoutsOpen: true
property string homeDir: StandardPaths.writableLocation(StandardPaths.HomeLocation)
property string docsDir: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
property string musicDir: StandardPaths.writableLocation(StandardPaths.MusicLocation)

View File

@@ -1,4 +1,6 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Common
import qs.Modals.Common
@@ -11,6 +13,11 @@ DankModal {
layerNamespace: "dms:notification-center-modal"
HyprlandFocusGrab {
windows: [notificationModal]
active: CompositorService.isHyprland && notificationModal.shouldHaveFocus
}
property bool notificationModalOpen: false
property var notificationListRef: null

View File

@@ -1,4 +1,6 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import qs.Common
import qs.Modals.Common
import qs.Services
@@ -9,6 +11,11 @@ DankModal {
layerNamespace: "dms:polkit"
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property string passwordInput: ""
property var currentFlow: PolkitService.agent?.flow
property bool isLoading: false

View File

@@ -1,5 +1,6 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import qs.Common
import qs.Modals.Common
import qs.Services
@@ -10,6 +11,11 @@ DankModal {
layerNamespace: "dms:power-menu"
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property int selectedIndex: 0
property int selectedRow: 0
property int selectedCol: 0

View File

@@ -22,7 +22,7 @@ Item {
width: parent.width
height: lockScreenSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 0
@@ -106,7 +106,7 @@ Item {
width: parent.width
height: timeoutSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 0
@@ -329,7 +329,7 @@ Item {
width: parent.width
height: powerMenuCustomSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 0
@@ -516,7 +516,7 @@ Item {
width: parent.width
height: powerCommandConfirmSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 0
@@ -560,7 +560,7 @@ Item {
width: parent.width
height: powerCommandCustomization.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 0

View File

@@ -1,5 +1,7 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Common
import qs.Modals.Common
@@ -13,6 +15,11 @@ DankModal {
layerNamespace: "dms:settings"
HyprlandFocusGrab {
windows: [settingsModal]
active: CompositorService.isHyprland && settingsModal.shouldHaveFocus
}
property Component settingsContent
property alias profileBrowser: profileBrowser
property int currentTabIndex: 0

View File

@@ -158,6 +158,10 @@ Item {
onAppLaunched: () => {
if (parentModal)
parentModal.hide()
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview()
}
}
onViewModeSelected: mode => {
SettingsData.set("spotlightModalViewMode", mode)
@@ -170,6 +174,10 @@ Item {
onFileOpened: () => {
if (parentModal)
parentModal.hide()
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview()
}
}
}

View File

@@ -1,6 +1,7 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
@@ -14,10 +15,17 @@ DankModal {
layerNamespace: "dms:spotlight"
HyprlandFocusGrab {
windows: [spotlightModal]
active: CompositorService.isHyprland && spotlightModal.shouldHaveFocus
}
property bool spotlightOpen: false
property alias spotlightContent: spotlightContentInstance
property bool openedFromOverview: false
function show() {
openedFromOverview = false
spotlightOpen = true
open()
@@ -49,6 +57,7 @@ DankModal {
}
function hide() {
openedFromOverview = false
spotlightOpen = false
close()
}

View File

@@ -1,4 +1,6 @@
import QtQuick
import Quickshell
import Quickshell.Hyprland
import qs.Common
import qs.Modals.Common
import qs.Services
@@ -8,6 +10,12 @@ DankModal {
id: root
layerNamespace: "dms:wifi-password"
keepPopoutsOpen: true
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && root.shouldHaveFocus
}
property string wifiPasswordSSID: ""
property string wifiPasswordInput: ""
@@ -101,7 +109,11 @@ DankModal {
shouldBeVisible: false
width: 420
height: requiresEnterprise ? 430 : 230
height: {
if (requiresEnterprise) return 430
if (isVpnPrompt) return 260
return 230
}
onShouldBeVisibleChanged: () => {
if (!shouldBeVisible) {
wifiPasswordInput = ""
@@ -314,7 +326,7 @@ DankModal {
if (passwordInput.text) secrets["password"] = passwordInput.text
if (wifiAnonymousIdentityInput) secrets["anonymous-identity"] = wifiAnonymousIdentityInput
}
NetworkService.submitCredentials(promptToken, secrets, true)
NetworkService.submitCredentials(promptToken, secrets, savePasswordCheckbox.checked)
} else {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(
@@ -429,44 +441,91 @@ DankModal {
}
}
Row {
Column {
spacing: Theme.spacingS
width: parent.width
Rectangle {
id: showPasswordCheckbox
Row {
spacing: Theme.spacingS
property bool checked: false
Rectangle {
id: showPasswordCheckbox
width: 20
height: 20
radius: 4
color: checked ? Theme.primary : "transparent"
border.color: checked ? Theme.primary : Theme.outlineButton
border.width: 2
property bool checked: false
DankIcon {
anchors.centerIn: parent
name: "check"
size: 12
color: Theme.background
visible: parent.checked
width: 20
height: 20
radius: 4
color: checked ? Theme.primary : "transparent"
border.color: checked ? Theme.primary : Theme.outlineButton
border.width: 2
DankIcon {
anchors.centerIn: parent
name: "check"
size: 12
color: Theme.background
visible: parent.checked
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
showPasswordCheckbox.checked = !showPasswordCheckbox.checked
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
showPasswordCheckbox.checked = !showPasswordCheckbox.checked
}
StyledText {
text: I18n.tr("Show password")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
StyledText {
text: I18n.tr("Show password")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
Row {
spacing: Theme.spacingS
visible: isVpnPrompt
Rectangle {
id: savePasswordCheckbox
property bool checked: false
width: 20
height: 20
radius: 4
color: checked ? Theme.primary : "transparent"
border.color: checked ? Theme.primary : Theme.outlineButton
border.width: 2
DankIcon {
anchors.centerIn: parent
name: "check"
size: 12
color: Theme.background
visible: parent.checked
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
savePasswordCheckbox.checked = !savePasswordCheckbox.checked
}
}
}
StyledText {
text: I18n.tr("Save password")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
}
@@ -558,7 +617,7 @@ DankModal {
if (passwordInput.text) secrets["password"] = passwordInput.text
if (wifiAnonymousIdentityInput) secrets["anonymous-identity"] = wifiAnonymousIdentityInput
}
NetworkService.submitCredentials(promptToken, secrets, true)
NetworkService.submitCredentials(promptToken, secrets, savePasswordCheckbox.checked)
} else {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(

View File

@@ -2,19 +2,16 @@ import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import Quickshell.Io
import qs.Common
import qs.Widgets
import qs.Modules
import qs.Services
Variants {
model: {
if (SessionData.isGreeterMode) {
return Quickshell.screens
return Quickshell.screens;
}
return SettingsData.getFilteredScreens("wallpaper")
return SettingsData.getFilteredScreens("wallpaper");
}
PanelWindow {
@@ -50,9 +47,9 @@ Variants {
target: SessionData
function onIsLightModeChanged() {
if (SessionData.perModeWallpaper) {
var newSource = SessionData.getMonitorWallpaper(modelData.name) || ""
var newSource = SessionData.getMonitorWallpaper(modelData.name) || "";
if (newSource !== root.source) {
root.source = newSource
root.source = newSource;
}
}
}
@@ -61,32 +58,32 @@ Variants {
function getFillMode(modeName) {
switch (modeName) {
case "Stretch":
return Image.Stretch
return Image.Stretch;
case "Fit":
case "PreserveAspectFit":
return Image.PreserveAspectFit
return Image.PreserveAspectFit;
case "Fill":
case "PreserveAspectCrop":
return Image.PreserveAspectCrop
return Image.PreserveAspectCrop;
case "Tile":
return Image.Tile
return Image.Tile;
case "TileVertically":
return Image.TileVertically
return Image.TileVertically;
case "TileHorizontally":
return Image.TileHorizontally
return Image.TileHorizontally;
case "Pad":
return Image.Pad
return Image.Pad;
default:
return Image.PreserveAspectCrop
return Image.PreserveAspectCrop;
}
}
Component.onCompleted: {
if (source) {
const formattedSource = source.startsWith("file://") ? source : "file://" + source
setWallpaperImmediate(formattedSource)
const formattedSource = source.startsWith("file://") ? source : "file://" + source;
setWallpaperImmediate(formattedSource);
}
isInitialized = true
isInitialized = true;
}
property bool isInitialized: false
@@ -94,55 +91,54 @@ Variants {
readonly property bool transitioning: transitionAnimation.running
onSourceChanged: {
const isColor = source.startsWith("#")
const isColor = source.startsWith("#");
if (!source) {
setWallpaperImmediate("")
setWallpaperImmediate("");
} else if (isColor) {
setWallpaperImmediate("")
setWallpaperImmediate("");
} else {
if (!isInitialized || !currentWallpaper.source) {
setWallpaperImmediate(source.startsWith("file://") ? source : "file://" + source)
isInitialized = true
setWallpaperImmediate(source.startsWith("file://") ? source : "file://" + source);
isInitialized = true;
} else if (CompositorService.isNiri && SessionData.isSwitchingMode) {
setWallpaperImmediate(source.startsWith("file://") ? source : "file://" + source)
setWallpaperImmediate(source.startsWith("file://") ? source : "file://" + source);
} else {
changeWallpaper(source.startsWith("file://") ? source : "file://" + source)
changeWallpaper(source.startsWith("file://") ? source : "file://" + source);
}
}
}
function setWallpaperImmediate(newSource) {
transitionAnimation.stop()
root.transitionProgress = 0.0
currentWallpaper.source = newSource
nextWallpaper.source = ""
currentWallpaper.opacity = 1
nextWallpaper.opacity = 0
transitionAnimation.stop();
root.transitionProgress = 0.0;
currentWallpaper.source = newSource;
nextWallpaper.source = "";
currentWallpaper.opacity = 1;
nextWallpaper.opacity = 0;
}
function changeWallpaper(newPath) {
if (newPath === currentWallpaper.source)
return
return;
if (!newPath || newPath.startsWith("#"))
return
return;
if (root.transitioning) {
transitionAnimation.stop()
root.transitionProgress = 0
currentWallpaper.source = nextWallpaper.source
nextWallpaper.source = ""
transitionAnimation.stop();
root.transitionProgress = 0;
currentWallpaper.source = nextWallpaper.source;
nextWallpaper.source = "";
}
if (!currentWallpaper.source) {
setWallpaperImmediate(newPath)
return
setWallpaperImmediate(newPath);
return;
}
nextWallpaper.source = newPath
nextWallpaper.source = newPath;
if (nextWallpaper.status === Image.Ready) {
transitionAnimation.start()
transitionAnimation.start();
}
}
@@ -179,10 +175,9 @@ Variants {
onStatusChanged: {
if (status !== Image.Ready)
return
return;
if (!root.transitioning) {
transitionAnimation.start()
transitionAnimation.start();
}
}
}
@@ -222,14 +217,14 @@ Variants {
easing.type: Easing.InOutCubic
onFinished: {
Qt.callLater(() => {
if (nextWallpaper.source && nextWallpaper.status === Image.Ready && !nextWallpaper.source.toString().startsWith("#")) {
currentWallpaper.source = nextWallpaper.source
}
nextWallpaper.source = ""
currentWallpaper.opacity = 1
nextWallpaper.opacity = 0
root.transitionProgress = 0.0
})
if (nextWallpaper.source && nextWallpaper.status === Image.Ready && !nextWallpaper.source.toString().startsWith("#")) {
currentWallpaper.source = nextWallpaper.source;
}
nextWallpaper.source = "";
currentWallpaper.opacity = 1;
nextWallpaper.opacity = 0;
root.transitionProgress = 0.0;
});
}
}
}

View File

@@ -16,10 +16,18 @@ Item {
property var widgetModel: null
property var collapseCallback: null
function getDetailHeight(section) {
const maxAvailable = parent ? parent.height - Theme.spacingS : 9999
if (section === "wifi") return Math.min(350, maxAvailable)
if (section === "bluetooth") return Math.min(350, maxAvailable)
if (section.startsWith("brightnessSlider_")) return Math.min(400, maxAvailable)
return Math.min(250, maxAvailable)
}
Loader {
id: pluginDetailLoader
width: parent.width
height: 250
height: parent.height - Theme.spacingS
y: Theme.spacingS
active: false
sourceComponent: null
@@ -28,7 +36,7 @@ Item {
Loader {
id: coreDetailLoader
width: parent.width
height: 250
height: parent.height - Theme.spacingS
y: Theme.spacingS
active: false
sourceComponent: null

View File

@@ -160,8 +160,9 @@ Column {
}
DetailHost {
id: detailHost
width: parent.width
height: active ? (250 + Theme.spacingS) : 0
height: active ? (getDetailHeight(root.expandedSection) + Theme.spacingS) : 0
property bool active: {
if (root.expandedSection === "")
return false
@@ -593,13 +594,13 @@ Column {
text: {
switch (widgetData.id || "") {
case "nightMode":
return "Night Mode"
return I18n.tr("Night Mode")
case "darkMode":
return SessionData.isLightMode ? "Light Mode" : "Dark Mode"
return I18n.tr("Dark Mode")
case "doNotDisturb":
return "Do Not Disturb"
return I18n.tr("Do Not Disturb")
case "idleInhibitor":
return SessionService.idleInhibited ? "Keeping Awake" : "Keep Awake"
return SessionService.idleInhibited ? I18n.tr("Keeping Awake") : I18n.tr("Keep Awake")
default:
return "Unknown"
}
@@ -619,7 +620,7 @@ Column {
case "nightMode":
return DisplayService.nightModeEnabled || false
case "darkMode":
return SessionData.isLightMode
return !SessionData.isLightMode
case "doNotDisturb":
return SessionData.doNotDisturb || false
case "idleInhibitor":
@@ -700,7 +701,7 @@ Column {
case "nightMode":
return DisplayService.nightModeEnabled || false
case "darkMode":
return SessionData.isLightMode
return !SessionData.isLightMode
case "doNotDisturb":
return SessionData.doNotDisturb || false
case "idleInhibitor":

View File

@@ -64,7 +64,12 @@ DankPopout {
}
popupWidth: 550
popupHeight: Math.min((triggerScreen?.height ?? 1080) - 100, contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400)
popupHeight: {
const screenHeight = (triggerScreen?.height ?? 1080)
const maxHeight = screenHeight - 100
const contentHeight = contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400
return Math.min(maxHeight, contentHeight)
}
triggerX: (triggerScreen?.width ?? 1920) - 600 - Theme.spacingL
triggerY: Theme.barHeight - 4 + SettingsData.dankBarSpacing
triggerWidth: 80
@@ -72,9 +77,12 @@ DankPopout {
screen: triggerScreen
shouldBeVisible: false
property bool credentialsPromptOpen: NetworkService.credentialsRequested
WlrLayershell.keyboardFocus: {
if (!shouldBeVisible) return WlrKeyboardFocus.None
if (powerMenuOpen) return WlrKeyboardFocus.None
if (credentialsPromptOpen) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}

View File

@@ -180,7 +180,11 @@ Rectangle {
Column {
anchors.verticalCenter: parent.verticalCenter
width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM
width: {
const iconWidth = Theme.iconSize
const pinButtonWidth = pinInputRow.width + Theme.spacingS * 4 + Theme.spacingM
return parent.parent.width - iconWidth - parent.spacing - pinButtonWidth - Theme.spacingM * 2
}
StyledText {
text: AudioService.displayName(modelData)

View File

@@ -187,7 +187,11 @@ Rectangle {
Column {
anchors.verticalCenter: parent.verticalCenter
width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM
width: {
const iconWidth = Theme.iconSize
const pinButtonWidth = pinOutputRow.width + Theme.spacingS * 4 + Theme.spacingM
return parent.parent.width - iconWidth - parent.spacing - pinButtonWidth - Theme.spacingM * 2
}
StyledText {
text: AudioService.displayName(modelData)

View File

@@ -10,7 +10,12 @@ import qs.Modals
Rectangle {
id: root
implicitHeight: BluetoothService.adapter && BluetoothService.adapter.enabled ? headerRow.height + bluetoothContent.height + Theme.spacingM : headerRow.height
implicitHeight: {
if (height > 0) {
return height
}
return BluetoothService.adapter && BluetoothService.adapter.enabled ? headerRow.height + bluetoothContent.height + Theme.spacingM : headerRow.height
}
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)

View File

@@ -88,7 +88,12 @@ Rectangle {
SettingsData.set("brightnessDevicePins", pins)
}
implicitHeight: brightnessContent.height + Theme.spacingM
implicitHeight: {
if (height > 0) {
return height
}
return brightnessContent.height + Theme.spacingM
}
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)

View File

@@ -10,6 +10,9 @@ Rectangle {
id: root
implicitHeight: {
if (height > 0) {
return height
}
if (NetworkService.wifiToggling) {
return headerRow.height + wifiToggleContent.height + Theme.spacingM
}

View File

@@ -69,12 +69,22 @@ Row {
valueOverride: actualVolumePercent
thumbOutlineColor: Theme.surfaceContainer
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
onIsDraggingChanged: {
if (isDragging) {
AudioService.suppressOSD = true
} else {
Qt.callLater(() => { AudioService.suppressOSD = false })
}
}
onSliderValueChanged: function(newValue) {
if (defaultSink) {
defaultSink.audio.volume = newValue / 100.0
if (newValue > 0 && defaultSink.audio.muted) {
defaultSink.audio.muted = false
}
AudioService.playVolumeChangeSoundIfEnabled()
}
}
}

View File

@@ -143,6 +143,8 @@ Row {
}
DankSlider {
id: brightnessSlider
anchors.verticalCenter: parent.verticalCenter
width: parent.width - (Theme.iconSize + Theme.spacingS * 2)
enabled: DisplayService.brightnessAvailable && targetDeviceName.length > 0
@@ -162,7 +164,7 @@ Row {
}
return targetDevice.displayMax || 100
}
value: targetBrightness
value: !isDragging ? targetBrightness : value
showValue: true
unit: {
if (!targetDevice) return "%"

View File

@@ -635,7 +635,7 @@ Item {
id: systemTrayComponent
SystemTrayBar {
parentWindow: rootWindow
parentWindow: barWindow
parentScreen: barWindow.screen
widgetThickness: barWindow.widgetThickness
isAtBottom: SettingsData.dankBarPosition === SettingsData.Position.Bottom
@@ -981,7 +981,7 @@ Item {
section: topBarContent.getWidgetSection(parent) || "right"
parentScreen: barWindow.screen
onColorPickerRequested: {
rootWindow.colorPickerRequested()
barWindow.colorPickerRequested()
}
}
}

View File

@@ -430,9 +430,9 @@ PanelWindow {
bottom: barWindow.isVertical ? parent.bottom : undefined
}
readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
hoverEnabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview
hoverEnabled: SettingsData.dankBarAutoHide && !inOverview
acceptedButtons: Qt.NoButton
enabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview
enabled: SettingsData.dankBarAutoHide && !inOverview
Item {
id: topBarContainer

View File

@@ -31,7 +31,7 @@ BasePill {
size: Theme.barIconSize(battery.barThickness)
color: {
if (!BatteryService.batteryAvailable) {
return Theme.surfaceText
return Theme.widgetIconColor
}
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
@@ -42,7 +42,7 @@ BasePill {
return Theme.primary
}
return Theme.surfaceText
return Theme.widgetIconColor
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -50,7 +50,7 @@ BasePill {
StyledText {
text: BatteryService.batteryLevel.toString()
font.pixelSize: Theme.barTextSize(battery.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
visible: BatteryService.batteryAvailable
}
@@ -67,7 +67,7 @@ BasePill {
size: Theme.barIconSize(battery.barThickness, -4)
color: {
if (!BatteryService.batteryAvailable) {
return Theme.surfaceText;
return Theme.widgetIconColor;
}
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
@@ -78,7 +78,7 @@ BasePill {
return Theme.primary;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -86,7 +86,7 @@ BasePill {
StyledText {
text: `${BatteryService.batteryLevel}%`
font.pixelSize: Theme.barTextSize(battery.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
visible: BatteryService.batteryAvailable
}

View File

@@ -18,7 +18,7 @@ BasePill {
anchors.centerIn: parent
name: "content_paste"
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetIconColor
}
}
}

View File

@@ -36,7 +36,7 @@ BasePill {
}
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -52,7 +52,7 @@ BasePill {
}
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -65,7 +65,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -73,7 +73,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -87,7 +87,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -95,7 +95,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
}
@@ -193,7 +193,7 @@ BasePill {
return systemClock?.date?.toLocaleTimeString(Qt.locale(), SettingsData.getEffectiveTimeFormat())
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.baseline: dateText.baseline
}
@@ -215,7 +215,7 @@ BasePill {
return systemClock?.date?.toLocaleDateString(Qt.locale(), "ddd d")
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
visible: !SettingsData.clockCompactMode
}

View File

@@ -85,7 +85,7 @@ BasePill {
return "volume_up"
}
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetIconColor
anchors.centerIn: parent
}
@@ -104,6 +104,7 @@ BasePill {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.muted = false
AudioService.sink.audio.volume = newVolume / 100
AudioService.playVolumeChangeSoundIfEnabled()
}
wheelEvent.accepted = true
}
@@ -113,7 +114,7 @@ BasePill {
DankIcon {
name: "settings"
size: Theme.barIconSize(root.barThickness)
color: root.isActive ? Theme.primary : Theme.surfaceText
color: root.isActive ? Theme.primary : Theme.widgetIconColor
anchors.horizontalCenter: parent.horizontalCenter
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
}
@@ -189,7 +190,7 @@ BasePill {
return "volume_up";
}
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetIconColor
anchors.centerIn: parent
}
@@ -210,6 +211,7 @@ BasePill {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.muted = false;
AudioService.sink.audio.volume = newVolume / 100;
AudioService.playVolumeChangeSoundIfEnabled();
}
wheelEvent.accepted = true;
}
@@ -227,7 +229,7 @@ BasePill {
DankIcon {
name: "settings"
size: Theme.barIconSize(root.barThickness)
color: root.isActive ? Theme.primary : Theme.surfaceText
color: root.isActive ? Theme.primary : Theme.widgetIconColor
anchors.verticalCenter: parent.verticalCenter
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
}

View File

@@ -45,7 +45,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -59,7 +59,7 @@ BasePill {
return DgopService.cpuUsage.toFixed(0);
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -82,7 +82,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -96,7 +96,7 @@ BasePill {
return DgopService.cpuUsage.toFixed(0) + "%";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -45,7 +45,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -59,7 +59,7 @@ BasePill {
return Math.round(DgopService.cpuTemperature).toString();
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -82,7 +82,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -96,7 +96,7 @@ BasePill {
return Math.round(DgopService.cpuTemperature) + "°";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -58,14 +58,14 @@ BasePill {
DankIcon {
name: layout.getLayoutIcon(layout.currentLayoutSymbol)
size: Theme.barIconSize(layout.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: layout.currentLayoutSymbol
font.pixelSize: Theme.barTextSize(layout.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -79,14 +79,14 @@ BasePill {
DankIcon {
name: layout.getLayoutIcon(layout.currentLayoutSymbol)
size: Theme.barIconSize(layout.barThickness, -4)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: layout.currentLayoutSymbol
font.pixelSize: Theme.barTextSize(layout.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
}

View File

@@ -115,7 +115,7 @@ BasePill {
return root.diskUsagePercent.toFixed(0)
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -149,7 +149,7 @@ BasePill {
return root.selectedMount.mount
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone
@@ -163,7 +163,7 @@ BasePill {
return root.diskUsagePercent.toFixed(0) + "%"
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -124,7 +124,7 @@ BasePill {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.surfaceText
color: Theme.widgetTextColor
visible: {
if (!root.isVerticalOrientation || !activeWindow || !activeWindow.appId) return false
const moddedId = Paths.moddedAppId(activeWindow.appId)
@@ -148,7 +148,7 @@ BasePill {
return activeWindow.appId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
Row {
@@ -168,7 +168,7 @@ BasePill {
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1
@@ -204,7 +204,7 @@ BasePill {
return title;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1

View File

@@ -109,7 +109,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -123,7 +123,7 @@ BasePill {
return Math.round(root.displayTemp).toString();
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -146,7 +146,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -160,7 +160,7 @@ BasePill {
return Math.round(root.displayTemp) + "°";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -18,7 +18,7 @@ BasePill {
anchors.centerIn: parent
name: SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
size: Theme.barIconSize(root.barThickness, -4)
color: Theme.surfaceText
color: Theme.widgetTextColor
}
}
}

View File

@@ -37,7 +37,7 @@ BasePill {
DankIcon {
name: "keyboard"
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -51,7 +51,7 @@ BasePill {
return root.currentLayout.substring(0, 2).toUpperCase()
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -65,7 +65,7 @@ BasePill {
StyledText {
text: root.currentLayout
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
}

View File

@@ -23,7 +23,7 @@ BasePill {
anchors.centerIn: parent
name: "apps"
size: Theme.barIconSize(root.barThickness, -4)
color: Theme.surfaceText
color: Theme.widgetIconColor
}
SystemLogo {

View File

@@ -175,7 +175,7 @@ BasePill {
anchors.verticalCenter: parent.verticalCenter
text: textContainer.displayText
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
wrapMode: Text.NoWrap
x: needsScrolling ? -scrollOffset : 0
onTextChanged: {
@@ -249,7 +249,7 @@ BasePill {
anchors.centerIn: parent
name: "skip_previous"
size: 12
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {
@@ -306,7 +306,7 @@ BasePill {
anchors.centerIn: parent
name: "skip_next"
size: 12
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {

View File

@@ -42,7 +42,7 @@ BasePill {
DankIcon {
name: "network_check"
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -80,7 +80,7 @@ BasePill {
DankIcon {
name: "network_check"
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
@@ -97,7 +97,7 @@ BasePill {
StyledText {
text: DgopService.networkRxRate > 0 ? root.formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s"
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone
@@ -133,7 +133,7 @@ BasePill {
StyledText {
text: DgopService.networkTxRate > 0 ? root.formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s"
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -19,7 +19,7 @@ BasePill {
anchors.centerIn: parent
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
size: Theme.barIconSize(root.barThickness, -4)
color: SessionData.doNotDisturb ? Theme.error : (root.isActive ? Theme.primary : Theme.surfaceText)
color: SessionData.doNotDisturb ? Theme.error : (root.isActive ? Theme.primary : Theme.widgetIconColor)
}
Rectangle {

View File

@@ -44,7 +44,8 @@ Item {
return "transparent"
}
return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : Theme.errorHover.r, privacyArea.containsMouse ? Theme.errorPressed.g : Theme.errorHover.g, privacyArea.containsMouse ? Theme.errorPressed.b : Theme.errorHover.b, (privacyArea.containsMouse ? Theme.errorPressed.a : Theme.errorHover.a) * Theme.widgetTransparency)
const baseColor = Theme.widgetBaseBackgroundColor
return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : baseColor.r, privacyArea.containsMouse ? Theme.errorPressed.g : baseColor.g, privacyArea.containsMouse ? Theme.errorPressed.b : baseColor.b, (privacyArea.containsMouse ? Theme.errorPressed.a : baseColor.a) * Theme.widgetTransparency)
}
Column {
@@ -81,7 +82,7 @@ Item {
DankIcon {
name: "camera_video"
size: Theme.iconSizeSmall
color: Theme.surfaceText
color: Theme.widgetTextColor
filled: true
anchors.centerIn: parent
}
@@ -213,7 +214,7 @@ Item {
anchors.centerIn: parent
text: PrivacyService.getPrivacySummary()
font.pixelSize: Theme.barTextSize(barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
}
Rectangle {

View File

@@ -47,7 +47,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -61,7 +61,7 @@ BasePill {
return DgopService.memoryUsage.toFixed(0);
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -92,7 +92,7 @@ BasePill {
return Theme.tempWarning;
}
return Theme.surfaceText;
return Theme.widgetIconColor;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -110,7 +110,7 @@ BasePill {
return ramText;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
elide: Text.ElideNone

View File

@@ -292,7 +292,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
size: Theme.barIconSize(root.barThickness)
name: "sports_esports"
color: Theme.surfaceText
color: Theme.widgetTextColor
visible: {
const moddedId = Paths.moddedAppId(appId)
return moddedId.toLowerCase().includes("steam_app")
@@ -321,7 +321,7 @@ Item {
return appId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
Rectangle {
@@ -354,7 +354,7 @@ Item {
visible: !SettingsData.runningAppsCompactMode
text: windowTitle
font.pixelSize: Theme.barTextSize(barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
elide: Text.ElideRight
maximumLineCount: 1
}
@@ -527,7 +527,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
size: Theme.barIconSize(root.barThickness)
name: "sports_esports"
color: Theme.surfaceText
color: Theme.widgetTextColor
visible: {
const moddedId = Paths.moddedAppId(appId)
return moddedId.toLowerCase().includes("steam_app")
@@ -555,7 +555,7 @@ Item {
return appId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
Rectangle {
@@ -587,7 +587,7 @@ Item {
visible: !SettingsData.runningAppsCompactMode
text: windowTitle
font.pixelSize: Theme.barTextSize(barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
elide: Text.ElideRight
maximumLineCount: 1
}
@@ -777,7 +777,7 @@ Item {
anchors.centerIn: parent
text: I18n.tr("Close")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {

View File

@@ -161,7 +161,7 @@ Item {
return itemId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
}
@@ -206,7 +206,7 @@ Item {
anchors.centerIn: parent
name: root.menuOpen ? "expand_less" : "expand_more"
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {
@@ -294,7 +294,7 @@ Item {
return itemId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
}
@@ -346,7 +346,7 @@ Item {
}
}
size: Theme.barIconSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {
@@ -530,6 +530,7 @@ Item {
Item {
id: menuContainer
objectName: "overflowMenuContainer"
readonly property real rawWidth: {
const itemCount = root.hiddenBarItems.length
@@ -704,7 +705,7 @@ Item {
return itemId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {
@@ -724,8 +725,7 @@ Item {
if (!trayItem.hasMenu) return
root.menuOpen = false
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
root.showForTrayItem(trayItem, menuContainer, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
}
@@ -911,10 +911,10 @@ Item {
onVisibleChanged: {
if (visible) {
updatePosition()
root.menuOpen = false
PopoutManager.closeAllPopouts()
ModalManager.closeAllModalsExcept(null)
updatePosition()
}
}
@@ -954,11 +954,20 @@ Item {
function updatePosition() {
const targetItem = (typeof menuRoot !== "undefined" && menuRoot.anchorItem) ? menuRoot.anchorItem : root
const globalPos = targetItem.mapToGlobal(0, 0)
const screenX = screen.x || 0
const screenY = screen.y || 0
const relativeX = globalPos.x - screenX
const relativeY = globalPos.y - screenY
const isFromOverflowMenu = targetItem.objectName === "overflowMenuContainer"
let relativeX, relativeY
if (isFromOverflowMenu) {
relativeX = targetItem.x
relativeY = targetItem.y
} else {
const globalPos = targetItem.mapToGlobal(0, 0)
const screenX = screen.x || 0
const screenY = screen.y || 0
relativeX = globalPos.x - screenX
relativeY = globalPos.y - screenY
}
const widgetThickness = Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
const effectiveBarThickness = Math.max(widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
@@ -1129,7 +1138,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
name: SessionData.isHiddenTrayId(menuRoot.trayItem?.id || "") ? "visibility" : "visibility_off"
size: 16
color: Theme.surfaceText
color: Theme.widgetTextColor
}
MouseArea {
@@ -1174,14 +1183,14 @@ Item {
DankIcon {
name: "arrow_back"
size: 16
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Back")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
}
@@ -1317,7 +1326,7 @@ Item {
anchors.centerIn: parent
name: "chevron_right"
size: 14
color: Theme.surfaceText
color: Theme.widgetTextColor
visible: menuEntry?.hasChildren ?? false
}
}

View File

@@ -112,7 +112,7 @@ BasePill {
anchors.verticalCenter: parent.verticalCenter
text: SystemUpdateService.updateCount.toString()
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
visible: root.hasUpdates && !root.isChecking
}
}

View File

@@ -31,20 +31,20 @@ BasePill {
DankIcon {
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
size: Theme.barIconSize(root.barThickness, -6)
color: Theme.primary
color: Theme.widgetIconColor
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
if (temp === undefined || temp === null || temp === 0) {
if (!WeatherService.weather.available) {
return "--";
}
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
}
@@ -58,21 +58,20 @@ BasePill {
DankIcon {
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
size: Theme.barIconSize(root.barThickness, -6)
color: Theme.primary
color: Theme.widgetIconColor
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
if (temp === undefined || temp === null || temp === 0) {
if (!WeatherService.weather.available) {
return "--°" + (SettingsData.useFahrenheit ? "F" : "C");
}
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
}
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
}

View File

@@ -727,7 +727,7 @@ Item {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.surfaceText
color: Theme.widgetTextColor
opacity: modelData.active ? 1.0 : appMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp
}
@@ -798,7 +798,7 @@ Item {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.surfaceText
color: Theme.widgetTextColor
opacity: modelData.active ? 1.0 : appMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp
}

View File

@@ -292,6 +292,7 @@ DankPopout {
tabBarItem: tabBar
keyForwardTarget: mainContainer
targetScreen: root.triggerScreen
parentPopout: root
}
WeatherTab {

View File

@@ -165,6 +165,7 @@ Item {
if (newVolume > 0 && defaultSink.audio.muted) {
defaultSink.audio.muted = false
}
AudioService.playVolumeChangeSoundIfEnabled()
}
Process {
@@ -1392,6 +1393,7 @@ Item {
if (volume > 0 && defaultSink.audio.muted) {
defaultSink.audio.muted = false
}
AudioService.playVolumeChangeSoundIfEnabled()
}
}
}

View File

@@ -5,6 +5,7 @@ import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import qs.Common
import qs.Modals.FileBrowser
import qs.Services
@@ -25,6 +26,7 @@ Item {
property Item tabBarItem: null
property int gridIndex: 0
property Item keyForwardTarget: null
property var parentPopout: null
property int lastPage: 0
property bool enableAnimation: false
property string homeDir: StandardPaths.writableLocation(StandardPaths.HomeLocation)
@@ -293,6 +295,12 @@ Item {
active: false
asynchronous: true
onActiveChanged: {
if (active && parentPopout) {
parentPopout.WlrLayershell.keyboardFocus = WlrKeyboardFocus.None
}
}
sourceComponent: FileBrowserModal {
Component.onCompleted: {
open()
@@ -318,6 +326,13 @@ Item {
}
onDialogClosed: {
if (parentPopout) {
if (CompositorService.isHyprland) {
parentPopout.WlrLayershell.keyboardFocus = WlrKeyboardFocus.OnDemand
} else {
parentPopout.WlrLayershell.keyboardFocus = WlrKeyboardFocus.Exclusive
}
}
Qt.callLater(() => wallpaperBrowserLoader.active = false)
}
}

View File

@@ -139,7 +139,7 @@ Item {
cursorShape: Qt.PointingHandCursor
onClicked: {
if (WeatherService.weather.available) {
SettingsData.set("temperatureUnit", !SettingsData.useFahrenheit)
SettingsData.set("useFahrenheit", !SettingsData.useFahrenheit)
}
}
enabled: WeatherService.weather.available
@@ -656,4 +656,4 @@ Item {
}
}
}
}
}

View File

@@ -257,7 +257,8 @@ Variants {
height: {
if (dock.isVertical) {
return dock.reveal ? Math.min(dockBackground.implicitHeight + 4, maxDockHeight) : Math.min(Math.max(dockBackground.implicitHeight + 64, 200), screenHeight * 0.5)
const hiddenHeight = Math.min(Math.max(dockBackground.implicitHeight + 64, 200), screenHeight * 0.5)
return dock.reveal ? Math.max(Math.min(dockBackground.implicitHeight + 4, maxDockHeight), hiddenHeight) : hiddenHeight
} else {
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1
}
@@ -266,7 +267,8 @@ Variants {
if (dock.isVertical) {
return dock.reveal ? px(dock.effectiveBarHeight + SettingsData.dockSpacing + SettingsData.dockBottomGap + SettingsData.dockMargin) : 1
} else {
return dock.reveal ? Math.min(dockBackground.implicitWidth + 4, maxDockWidth) : Math.min(Math.max(dockBackground.implicitWidth + 64, 200), screenWidth * 0.5)
const hiddenWidth = Math.min(Math.max(dockBackground.implicitWidth + 64, 200), screenWidth * 0.5)
return dock.reveal ? Math.max(Math.min(dockBackground.implicitWidth + 4, maxDockWidth), hiddenWidth) : hiddenWidth
}
}
anchors {

View File

@@ -591,6 +591,72 @@ Item {
}
}
StyledRect {
width: parent.width
height: niriOverviewSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.2)
border.width: 0
visible: CompositorService.isNiri
Column {
id: niriOverviewSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "open_in_new"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Close Overview on Launch")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - parent.children[0].width
- parent.children[1].width
- niriOverviewToggle.width - Theme.spacingM * 3
height: 1
}
DankToggle {
id: niriOverviewToggle
width: 32
height: 18
checked: SettingsData.spotlightCloseNiriOverview
anchors.verticalCenter: parent.verticalCenter
onToggled: checked => {
SettingsData.set("spotlightCloseNiriOverview", checked)
}
}
}
StyledText {
width: parent.width
text: I18n.tr("When enabled, launching an app from the launcher will automatically close the Niri overview if it's open.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
}
}
}
StyledRect {
width: parent.width
height: recentlyUsedSection.implicitHeight + Theme.spacingL * 2

View File

@@ -704,6 +704,57 @@ Item {
}
}
Row {
width: parent.width
height: 40
spacing: Theme.spacingM
Column {
width: parent.width - widgetColorModeGroup.width - parent.spacing
anchors.verticalCenter: parent.verticalCenter
spacing: 2
StyledText {
text: I18n.tr("Widget Style")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
elide: Text.ElideRight
width: parent.width
}
StyledText {
text: I18n.tr("Change bar appearance")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
width: parent.width
}
}
DankButtonGroup {
id: widgetColorModeGroup
property int currentColorModeIndex: {
switch (SettingsData.widgetColorMode) {
case "default": return 0
case "colorful": return 1
default: return 0
}
}
model: ["default", "colorful"]
currentIndex: currentColorModeIndex
selectionMode: "single"
anchors.verticalCenter: parent.verticalCenter
onSelectionChanged: (index, selected) => {
if (!selected) return
const colorModeOptions = ["default", "colorful"]
SettingsData.set("widgetColorMode", colorModeOptions[index])
}
}
}
Column {
width: parent.width
spacing: Theme.spacingS

View File

@@ -1,9 +1,4 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
@@ -42,7 +37,7 @@ DankPopout {
onShouldBeVisibleChanged: {
if (shouldBeVisible) {
if (SystemUpdateService.updateCount === 0 && !SystemUpdateService.isChecking) {
SystemUpdateService.checkForUpdates()
SystemUpdateService.checkForUpdates();
}
}
}
@@ -57,19 +52,23 @@ DankPopout {
smooth: true
Repeater {
model: [{
model: [
{
"margin": -3,
"color": Qt.rgba(0, 0, 0, 0.05),
"z": -3
}, {
},
{
"margin": -2,
"color": Qt.rgba(0, 0, 0, 0.08),
"z": -2
}, {
},
{
"margin": 0,
"color": Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12),
"z": -1
}]
}
]
Rectangle {
anchors.fill: parent
anchors.margins: modelData.margin
@@ -109,14 +108,18 @@ DankPopout {
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: {
if (SystemUpdateService.isChecking) return "Checking...";
if (SystemUpdateService.hasError) return "Error";
if (SystemUpdateService.updateCount === 0) return "Up to date";
if (SystemUpdateService.isChecking)
return "Checking...";
if (SystemUpdateService.hasError)
return "Error";
if (SystemUpdateService.updateCount === 0)
return "Up to date";
return SystemUpdateService.updateCount + " updates";
}
font.pixelSize: Theme.fontSizeMedium
color: {
if (SystemUpdateService.hasError) return Theme.error;
if (SystemUpdateService.hasError)
return Theme.error;
return Theme.surfaceText;
}
}
@@ -131,7 +134,7 @@ DankPopout {
enabled: !SystemUpdateService.isChecking
opacity: enabled ? 1.0 : 0.5
onClicked: {
SystemUpdateService.checkForUpdates()
SystemUpdateService.checkForUpdates();
}
RotationAnimation {
@@ -145,7 +148,7 @@ DankPopout {
onRunningChanged: {
if (!running) {
checkForUpdatesButton.rotation = 0
checkForUpdatesButton.rotation = 0;
}
}
}
@@ -156,9 +159,9 @@ DankPopout {
Rectangle {
width: parent.width
height: {
let usedHeight = 40 + Theme.spacingL
usedHeight += 48 + Theme.spacingL
return parent.height - usedHeight
let usedHeight = 40 + Theme.spacingL;
usedHeight += 48 + Theme.spacingL;
return parent.height - usedHeight;
}
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.1)
@@ -190,7 +193,8 @@ DankPopout {
}
font.pixelSize: Theme.fontSizeMedium
color: {
if (SystemUpdateService.hasError) return Theme.errorText;
if (SystemUpdateService.hasError)
return Theme.errorText;
return Theme.surfaceText;
}
wrapMode: Text.WordWrap
@@ -246,7 +250,9 @@ DankPopout {
}
Behavior on color {
ColorAnimation { duration: Theme.shortDuration }
ColorAnimation {
duration: Theme.shortDuration
}
}
MouseArea {
@@ -274,7 +280,9 @@ DankPopout {
opacity: SystemUpdateService.updateCount > 0 ? 1.0 : 0.5
Behavior on color {
ColorAnimation { duration: Theme.shortDuration }
ColorAnimation {
duration: Theme.shortDuration
}
}
Row {
@@ -304,13 +312,12 @@ DankPopout {
cursorShape: Qt.PointingHandCursor
enabled: SystemUpdateService.updateCount > 0
onClicked: {
SystemUpdateService.runUpdates()
systemUpdatePopout.close()
SystemUpdateService.runUpdates();
systemUpdatePopout.close();
}
}
}
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: parent.height
@@ -318,7 +325,9 @@ DankPopout {
color: closeMouseArea.containsMouse ? Theme.errorPressed : Theme.secondaryHover
Behavior on color {
ColorAnimation { duration: Theme.shortDuration }
ColorAnimation {
duration: Theme.shortDuration
}
}
Row {
@@ -347,13 +356,12 @@ DankPopout {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
systemUpdatePopout.close()
systemUpdatePopout.close();
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,229 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import qs.Common
import qs.Modals.Spotlight
import qs.Services
Scope {
id: niriOverviewScope
property bool searchActive: false
property string searchActiveScreen: ""
property bool overlayActive: NiriService.inOverview && !(PopoutService.spotlightModal?.spotlightOpen ?? false)
function showSpotlight(screenName) {
searchActive = true
searchActiveScreen = screenName
}
function hideSpotlight() {
searchActive = false
searchActiveScreen = ""
}
Connections {
target: NiriService
function onInOverviewChanged() {
if (!NiriService.inOverview) {
hideSpotlight()
} else {
searchActive = false
searchActiveScreen = ""
}
}
function onCurrentOutputChanged() {
if (NiriService.inOverview && searchActive && searchActiveScreen !== "" && searchActiveScreen !== NiriService.currentOutput) {
hideSpotlight()
}
}
}
Connections {
target: PopoutService.spotlightModal
function onSpotlightOpenChanged() {
if (PopoutService.spotlightModal?.spotlightOpen && searchActive) {
hideSpotlight()
}
}
}
Loader {
id: niriOverlayLoader
active: overlayActive
asynchronous: false
sourceComponent: Variants {
id: overlayVariants
model: Quickshell.screens
PanelWindow {
id: overlayWindow
required property var modelData
readonly property real dpr: CompositorService.getScreenScale(screen)
readonly property bool isActiveScreen: screen.name === NiriService.currentOutput
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen
screen: modelData
visible: NiriService.inOverview
color: "transparent"
WlrLayershell.namespace: "dms:niri-overview-spotlight"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: {
if (!NiriService.inOverview) return WlrKeyboardFocus.None
if (!isActiveScreen) return WlrKeyboardFocus.None
return WlrKeyboardFocus.Exclusive
}
mask: Region {
item: shouldShowSpotlight ? spotlightContainer : null
}
onShouldShowSpotlightChanged: {
if (!shouldShowSpotlight && isActiveScreen) {
Qt.callLater(() => keyboardFocusScope.forceActiveFocus())
}
}
anchors {
top: true
left: true
right: true
bottom: true
}
FocusScope {
id: keyboardFocusScope
anchors.fill: parent
focus: true
Keys.onPressed: event => {
if (!overlayWindow.shouldShowSpotlight) {
if ([Qt.Key_Escape, Qt.Key_Return].includes(event.key)) {
NiriService.toggleOverview()
event.accepted = true
return
}
if (event.key === Qt.Key_Left) {
NiriService.moveColumnLeft()
event.accepted = true
return
}
if (event.key === Qt.Key_Right) {
NiriService.moveColumnRight()
event.accepted = true
return
}
if (event.key === Qt.Key_Up) {
NiriService.moveWorkspaceUp()
event.accepted = true
return
}
if (event.key === Qt.Key_Down) {
NiriService.moveWorkspaceDown()
event.accepted = true
return
}
if (event.modifiers & (Qt.ControlModifier | Qt.MetaModifier) || [Qt.Key_Delete, Qt.Key_Backspace].includes(event.key)) {
event.accepted = false
return
}
if (!event.isAutoRepeat && event.text) {
niriOverviewScope.showSpotlight(overlayWindow.screen.name)
if (spotlightContent?.searchField) {
spotlightContent.searchField.text = event.text.trim()
if (spotlightContent.appLauncher) {
spotlightContent.appLauncher.searchQuery = event.text.trim()
}
Qt.callLater(() => spotlightContent.searchField.forceActiveFocus())
}
event.accepted = true
}
}
}
}
Item {
id: spotlightContainer
x: Theme.snap((parent.width - width) / 2, overlayWindow.dpr)
y: Theme.snap((parent.height - height) / 2, overlayWindow.dpr)
width: Theme.px(500, overlayWindow.dpr)
height: Theme.px(600, overlayWindow.dpr)
property real scaleValue: 0.96
scale: scaleValue
opacity: overlayWindow.shouldShowSpotlight ? 1 : 0
enabled: overlayWindow.shouldShowSpotlight
layer.enabled: true
layer.smooth: false
layer.textureSize: Qt.size(Math.round(width * overlayWindow.dpr), Math.round(height * overlayWindow.dpr))
Connections {
target: overlayWindow
function onShouldShowSpotlightChanged() {
spotlightContainer.scaleValue = overlayWindow.shouldShowSpotlight ? 1.0 : 0.96
}
}
Behavior on scaleValue {
NumberAnimation {
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.type: Easing.BezierSpline
easing.bezierCurve: niriOverviewScope.searchActive ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.type: Easing.BezierSpline
easing.bezierCurve: niriOverviewScope.searchActive ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
}
}
Rectangle {
anchors.fill: parent
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
border.color: Theme.outlineMedium
border.width: 1
}
SpotlightContent {
id: spotlightContent
anchors.fill: parent
anchors.margins: 0
property var fakeParentModal: QtObject {
property bool spotlightOpen: overlayWindow.shouldShowSpotlight
function hide() {
niriOverviewScope.hideSpotlight()
if (overlayWindow.isActiveScreen) {
Qt.callLater(() => keyboardFocusScope.forceActiveFocus())
}
}
}
Component.onCompleted: {
parentModal = fakeParentModal
}
}
}
}
}
}
}

View File

@@ -407,24 +407,9 @@ Singleton {
}
}
Timer {
id: volumeSoundDebounce
interval: 50
repeat: false
onTriggered: {
if (!root.suppressOSD && SettingsData.soundsEnabled && SettingsData.soundVolumeChanged) {
root.playVolumeChangeSound()
}
}
}
Connections {
target: root.sink && root.sink.audio ? root.sink.audio : null
enabled: root.sink && root.sink.audio
ignoreUnknownSignals: true
function onVolumeChanged() {
volumeSoundDebounce.restart()
function playVolumeChangeSoundIfEnabled() {
if (SettingsData.soundsEnabled && SettingsData.soundVolumeChanged) {
playVolumeChangeSound()
}
}
@@ -559,6 +544,7 @@ Singleton {
const newVolume = Math.max(0, Math.min(100, currentVolume + stepValue))
root.sink.audio.volume = newVolume / 100
root.playVolumeChangeSoundIfEnabled()
return `Volume increased to ${newVolume}%`
}
@@ -576,6 +562,7 @@ Singleton {
const newVolume = Math.max(0, Math.min(100, currentVolume - stepValue))
root.sink.audio.volume = newVolume / 100
root.playVolumeChangeSoundIfEnabled()
return `Volume decreased to ${newVolume}%`
}

View File

@@ -606,6 +606,38 @@ Singleton {
})
}
function moveColumnLeft() {
return send({
"Action": {
"FocusColumnLeft": {}
}
})
}
function moveColumnRight() {
return send({
"Action": {
"FocusColumnRight": {}
}
})
}
function moveWorkspaceDown() {
return send({
"Action": {
"FocusWorkspaceDown": {}
}
})
}
function moveWorkspaceUp() {
return send({
"Action": {
"FocusWorkspaceUp": {}
}
})
}
function switchToWorkspace(workspaceIndex) {
return send({
"Action": {

View File

@@ -34,7 +34,7 @@ Singleton {
}
PwObjectTracker {
objects: Pipewire.nodes.values.filter(node => node.audio && !node.isStream)
objects: Pipewire.nodes.values.filter(node => !node.isStream)
}
readonly property bool cameraActive: {
@@ -47,7 +47,7 @@ Singleton {
if (!node || !node.ready) {
continue
}
if (node.properties && node.properties["media.class"] === "Stream/Input/Video") {
if (node.properties["stream.is-live"] === "true") {
return true

View File

@@ -190,10 +190,6 @@ Singleton {
"forecast_days=7"
]
if (SettingsData.useFahrenheit) {
params.push("temperature_unit=fahrenheit")
}
return "https://api.open-meteo.com/v1/forecast?" + params.join('&')
}
@@ -471,17 +467,17 @@ Singleton {
const currentUnits = data.current_units || {}
const tempC = current.temperature_2m || 0
const tempF = SettingsData.useFahrenheit ? tempC : (tempC * 9/5 + 32)
const tempF = (tempC * 9/5 + 32)
const feelsLikeC = current.apparent_temperature || tempC
const feelsLikeF = SettingsData.useFahrenheit ? feelsLikeC : (feelsLikeC * 9/5 + 32)
const feelsLikeF = (feelsLikeC * 9/5 + 32)
const forecast = []
if (daily.time && daily.time.length > 0) {
for (let i = 0; i < Math.min(daily.time.length, 7); i++) {
const tempMinC = daily.temperature_2m_min?.[i] || 0
const tempMaxC = daily.temperature_2m_max?.[i] || 0
const tempMinF = SettingsData.useFahrenheit ? tempMinC : (tempMinC * 9/5 + 32)
const tempMaxF = SettingsData.useFahrenheit ? tempMaxC : (tempMaxC * 9/5 + 32)
const tempMinF = (tempMinC * 9/5 + 32)
const tempMaxF = (tempMaxC * 9/5 + 32)
forecast.push({
"day": formatForecastDay(daily.time[i], i),
@@ -630,11 +626,6 @@ Singleton {
root.forceRefresh()
})
SettingsData.useFahrenheitChanged.connect(() => {
root.lastFetchTime = 0
root.forceRefresh()
})
SettingsData.weatherEnabledChanged.connect(() => {
if (SettingsData.weatherEnabled && root.refCount > 0 && !root.weather.available) {
root.forceRefresh()

View File

@@ -1 +1 @@
v0.6.0
v0.6.2