1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-31 00:42:50 -05:00

Compare commits

..

21 Commits

Author SHA1 Message Date
bbedward
e022c04519 bump version 2026-01-15 23:45:21 -05:00
bbedward
f534384e5e cc: wrap icons in fixed size containers
maybe #1376
2026-01-15 23:45:09 -05:00
bbedward
a25cdb43d5 controlcenter: fix visibility condition of no icons fixes #1377 2026-01-15 23:45:09 -05:00
purian23
4e9b4ca400 Fix fedora version format 2026-01-15 23:44:19 -05:00
bbedward
5bab1c98b1 plugins: fix plugin confirm third part repo window 2026-01-15 23:44:19 -05:00
purian23
2284bb002f distro: Update Fedora dynamic versioning 2026-01-15 23:44:19 -05:00
purian23
b0611d6104 feat: Allow more pinned services in Control Center/Settings 2026-01-15 23:44:19 -05:00
purian23
27965862d6 core: Update ghostty on dankinstall 2026-01-15 23:44:19 -05:00
Abhinav Chalise
e74a901e05 fix volume osd sliding ui update for vertical layout (#1382) 2026-01-15 23:44:19 -05:00
bbedward
77794deb2c widgets: add fallback for steam apps 2026-01-15 23:44:19 -05:00
Lucas
1c10746e50 doctor: use dbus for checking on services (#1384)
* doctor: use dbus for checking on services

* doctor: show docs URL for failed checks

* core: remove unused function
2026-01-15 23:44:19 -05:00
bbedward
8ecb7282b9 dankdash: fix weather open IPC fixes #1367 2026-01-15 23:44:19 -05:00
bbedward
9b3fa804ab matugen: fix nvim ID in skipTemplates 2026-01-15 23:44:19 -05:00
purian23
b2ad31a27e dankdash: Center Media Art & Controls 2026-01-15 23:44:19 -05:00
bbedward
db17e4cb14 i18n: update terms 2026-01-15 23:44:02 -05:00
bbedward
1b7dcf56a8 bump VERSION 2026-01-14 08:00:15 -05:00
bbedward
502bb88e92 modals: fix wifi passowrd, polkit, and VPN import 2026-01-14 08:00:05 -05:00
bbedward
b76d0ce97d settings: fix child windows on newer quickshell-git 2026-01-13 16:58:08 -05:00
bbedward
fa66d330cf bump VERSION 2026-01-13 16:42:49 -05:00
Lucas
157eab2d07 settings: fix modal not opening on latest quickshell (#1357) 2026-01-13 16:42:38 -05:00
Lucas
f50ad2dc22 nix: escape version string (#1353) 2026-01-13 16:42:38 -05:00
26 changed files with 575 additions and 349 deletions

View File

@@ -4,14 +4,13 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
package: package:
description: "Package to update" description: "Package to update (dms, dms-git, or all)"
required: true required: false
type: choice default: "all"
options: tag_version:
- dms description: "Specific tag version for dms stable (e.g., v1.0.2). Leave empty to auto-detect latest release."
- dms-git required: false
- all default: ""
default: "dms"
rebuild_release: rebuild_release:
description: "Release number for rebuilds (e.g., 2, 3, 4 to increment spec Release)" description: "Release number for rebuilds (e.g., 2, 3, 4 to increment spec Release)"
required: false required: false
@@ -57,9 +56,8 @@ jobs:
} }
# Helper function to check dms stable tag # Helper function to check dms stable tag
# Sets LATEST_TAG variable in parent scope if update needed
check_dms_stable() { check_dms_stable() {
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "") local LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "v\?\([^"]*\)".*/\1/' || echo "")
local OBS_SPEC=$(curl -s -u "$OBS_USERNAME:$OBS_PASSWORD" "https://api.opensuse.org/source/home:AvengeMedia:dms/dms/dms.spec" 2>/dev/null || echo "") local OBS_SPEC=$(curl -s -u "$OBS_USERNAME:$OBS_PASSWORD" "https://api.opensuse.org/source/home:AvengeMedia:dms/dms/dms.spec" 2>/dev/null || echo "")
local OBS_VERSION=$(echo "$OBS_SPEC" | grep "^Version:" | awk '{print $2}' | xargs || echo "") local OBS_VERSION=$(echo "$OBS_SPEC" | grep "^Version:" | awk '{print $2}' | xargs || echo "")
@@ -75,8 +73,8 @@ jobs:
# Main logic # Main logic
REBUILD="${{ github.event.inputs.rebuild_release }}" REBUILD="${{ github.event.inputs.rebuild_release }}"
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" =~ ^refs/tags/ ]]; then
# Tag selected or pushed - always update stable package # Tag push - always update stable package
echo "packages=dms" >> $GITHUB_OUTPUT echo "packages=dms" >> $GITHUB_OUTPUT
VERSION="${GITHUB_REF#refs/tags/}" VERSION="${GITHUB_REF#refs/tags/}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
@@ -106,12 +104,7 @@ jobs:
# Check each package and build list of those needing updates # Check each package and build list of those needing updates
PACKAGES_TO_UPDATE=() PACKAGES_TO_UPDATE=()
check_dms_git && PACKAGES_TO_UPDATE+=("dms-git") check_dms_git && PACKAGES_TO_UPDATE+=("dms-git")
if check_dms_stable; then check_dms_stable && PACKAGES_TO_UPDATE+=("dms")
PACKAGES_TO_UPDATE+=("dms")
if [[ -n "$LATEST_TAG" ]]; then
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
fi
fi
if [[ ${#PACKAGES_TO_UPDATE[@]} -gt 0 ]]; then if [[ ${#PACKAGES_TO_UPDATE[@]} -gt 0 ]]; then
echo "packages=${PACKAGES_TO_UPDATE[*]}" >> $GITHUB_OUTPUT echo "packages=${PACKAGES_TO_UPDATE[*]}" >> $GITHUB_OUTPUT
@@ -136,9 +129,6 @@ jobs:
if check_dms_stable; then if check_dms_stable; then
echo "packages=$PKG" >> $GITHUB_OUTPUT echo "packages=$PKG" >> $GITHUB_OUTPUT
echo "has_updates=true" >> $GITHUB_OUTPUT echo "has_updates=true" >> $GITHUB_OUTPUT
if [[ -n "$LATEST_TAG" ]]; then
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
fi
else else
echo "packages=" >> $GITHUB_OUTPUT echo "packages=" >> $GITHUB_OUTPUT
echo "has_updates=false" >> $GITHUB_OUTPUT echo "has_updates=false" >> $GITHUB_OUTPUT
@@ -171,19 +161,12 @@ jobs:
- name: Determine packages to update - name: Determine packages to update
id: packages id: packages
run: | run: |
# Check if GITHUB_REF points to a tag (works for both push events and workflow_dispatch with tag selected) if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" =~ ^refs/tags/ ]]; then
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then # Tag push event - use the pushed tag
# Tag selected or pushed - use the tag from GITHUB_REF
echo "packages=dms" >> $GITHUB_OUTPUT echo "packages=dms" >> $GITHUB_OUTPUT
VERSION="${GITHUB_REF#refs/tags/}" VERSION="${GITHUB_REF#refs/tags/}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Using tag from GITHUB_REF: $VERSION" echo "Triggered by tag: $VERSION"
# Check if check-updates already determined a version (from auto-detection)
elif [[ -n "${{ needs.check-updates.outputs.version }}" ]]; then
# Use version from check-updates job
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
echo "version=${{ needs.check-updates.outputs.version }}" >> $GITHUB_OUTPUT
echo "Using version from check-updates: ${{ needs.check-updates.outputs.version }}"
elif [[ "${{ github.event_name }}" == "schedule" ]]; then elif [[ "${{ github.event_name }}" == "schedule" ]]; then
# Scheduled run - dms-git only # Scheduled run - dms-git only
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
@@ -193,28 +176,22 @@ jobs:
# Determine version for dms stable # Determine version for dms stable
if [[ "${{ github.event.inputs.package }}" == "dms" ]]; then if [[ "${{ github.event.inputs.package }}" == "dms" ]]; then
# Use github.ref if tag selected, otherwise auto-detect latest # For explicit dms selection, require tag_version
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then if [[ -n "${{ github.event.inputs.tag_version }}" ]]; then
VERSION="${GITHUB_REF#refs/tags/}" VERSION="${{ github.event.inputs.tag_version }}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Using tag from GITHUB_REF: $VERSION" echo "Using specified tag: $VERSION"
else else
# Auto-detect latest release for dms echo "ERROR: tag_version is required when package=dms"
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "") echo "Please specify a tag version (e.g., v1.0.2) or use package=all for auto-detection"
if [[ -n "$LATEST_TAG" ]]; then exit 1
echo "version=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "Auto-detected latest release: $LATEST_TAG"
else
echo "ERROR: Could not auto-detect latest release"
exit 1
fi
fi fi
elif [[ "${{ github.event.inputs.package }}" == "all" ]]; then elif [[ "${{ github.event.inputs.package }}" == "all" ]]; then
# Use github.ref if tag selected, otherwise auto-detect latest # For "all", auto-detect if tag_version not specified
if [[ "${{ github.ref }}" =~ ^refs/tags/ ]]; then if [[ -n "${{ github.event.inputs.tag_version }}" ]]; then
VERSION="${GITHUB_REF#refs/tags/}" VERSION="${{ github.event.inputs.tag_version }}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Using tag from GITHUB_REF: $VERSION" echo "Using specified tag: $VERSION"
else else
# Auto-detect latest release for "all" # Auto-detect latest release for "all"
LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "") LATEST_TAG=$(curl -s https://api.github.com/repos/AvengeMedia/DankMaterialShell/releases/latest | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/' || echo "")
@@ -229,7 +206,7 @@ jobs:
fi fi
# Use filtered packages from check-updates when package="all" and no rebuild/tag specified # Use filtered packages from check-updates when package="all" and no rebuild/tag specified
if [[ "${{ github.event.inputs.package }}" == "all" ]] && [[ -z "${{ github.event.inputs.rebuild_release }}" ]] && [[ ! "${{ github.ref }}" =~ ^refs/tags/ ]]; then if [[ "${{ github.event.inputs.package }}" == "all" ]] && [[ -z "${{ github.event.inputs.rebuild_release }}" ]] && [[ -z "${{ github.event.inputs.tag_version }}" ]]; then
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
echo "Manual trigger: all (filtered to: ${{ needs.check-updates.outputs.packages }})" echo "Manual trigger: all (filtered to: ${{ needs.check-updates.outputs.packages }})"
else else
@@ -238,9 +215,6 @@ jobs:
fi fi
else else
echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT echo "packages=${{ needs.check-updates.outputs.packages }}" >> $GITHUB_OUTPUT
if [[ -n "${{ needs.check-updates.outputs.version }}" ]]; then
echo "version=${{ needs.check-updates.outputs.version }}" >> $GITHUB_OUTPUT
fi
fi fi
- name: Update dms-git spec version - name: Update dms-git spec version

View File

@@ -108,7 +108,6 @@ func (o *OpenSUSEDistribution) GetPackageMappingWithVariants(wm deps.WindowManag
packages := map[string]PackageMapping{ packages := map[string]PackageMapping{
// Standard zypper packages // Standard zypper packages
"git": {Name: "git", Repository: RepoTypeSystem}, "git": {Name: "git", Repository: RepoTypeSystem},
"ghostty": {Name: "ghostty", Repository: RepoTypeSystem},
"kitty": {Name: "kitty", Repository: RepoTypeSystem}, "kitty": {Name: "kitty", Repository: RepoTypeSystem},
"alacritty": {Name: "alacritty", Repository: RepoTypeSystem}, "alacritty": {Name: "alacritty", Repository: RepoTypeSystem},
"xdg-desktop-portal-gtk": {Name: "xdg-desktop-portal-gtk", Repository: RepoTypeSystem}, "xdg-desktop-portal-gtk": {Name: "xdg-desktop-portal-gtk", Repository: RepoTypeSystem},
@@ -117,6 +116,7 @@ func (o *OpenSUSEDistribution) GetPackageMappingWithVariants(wm deps.WindowManag
// DMS packages from OBS // DMS packages from OBS
"dms (DankMaterialShell)": o.getDmsMapping(variants["dms (DankMaterialShell)"]), "dms (DankMaterialShell)": o.getDmsMapping(variants["dms (DankMaterialShell)"]),
"quickshell": o.getQuickshellMapping(variants["quickshell"]), "quickshell": o.getQuickshellMapping(variants["quickshell"]),
"ghostty": {Name: "ghostty", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
"matugen": {Name: "matugen", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"}, "matugen": {Name: "matugen", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
"dgop": {Name: "dgop", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"}, "dgop": {Name: "dgop", Repository: RepoTypeOBS, RepoURL: "home:AvengeMedia:danklinux"},
} }

View File

@@ -1 +1 @@
Saffron Bloom Spicy Miso

View File

@@ -45,6 +45,10 @@ Singleton {
Quickshell.execDetached(["cp", strip(from), strip(to)]); Quickshell.execDetached(["cp", strip(from), strip(to)]);
} }
function isSteamApp(appId: string): bool {
return appId && /^steam_app_\d+$/.test(appId);
}
function moddedAppId(appId: string): string { function moddedAppId(appId: string): string {
const subs = SettingsData.appIdSubstitutions || []; const subs = SettingsData.appIdSubstitutions || [];
for (let i = 0; i < subs.length; i++) { for (let i = 0; i < subs.length; i++) {
@@ -60,6 +64,9 @@ Singleton {
} }
} }
} }
const steamMatch = appId.match(/^steam_app_(\d+)$/);
if (steamMatch)
return `steam_icon_${steamMatch[1]}`;
return appId; return appId;
} }

View File

@@ -145,7 +145,6 @@ Singleton {
property bool controlCenterShowMicPercent: true property bool controlCenterShowMicPercent: true
property bool controlCenterShowBatteryIcon: false property bool controlCenterShowBatteryIcon: false
property bool controlCenterShowPrinterIcon: false property bool controlCenterShowPrinterIcon: false
property bool controlCenterShowScreenSharingIcon: true
property bool showPrivacyButton: true property bool showPrivacyButton: true
property bool privacyShowMicIcon: false property bool privacyShowMicIcon: false
property bool privacyShowCameraIcon: false property bool privacyShowCameraIcon: false

View File

@@ -28,8 +28,7 @@ Singleton {
showMicIcon: false, showMicIcon: false,
showMicPercent: true, showMicPercent: true,
showBatteryIcon: false, showBatteryIcon: false,
showPrinterIcon: false, showPrinterIcon: false
showScreenSharingIcon: true
}; };
leftModel.append(dummy); leftModel.append(dummy);
centerModel.append(dummy); centerModel.append(dummy);
@@ -85,8 +84,6 @@ Singleton {
item.showBatteryIcon = order[i].showBatteryIcon; item.showBatteryIcon = order[i].showBatteryIcon;
if (isObj && order[i].showPrinterIcon !== undefined) if (isObj && order[i].showPrinterIcon !== undefined)
item.showPrinterIcon = order[i].showPrinterIcon; item.showPrinterIcon = order[i].showPrinterIcon;
if (isObj && order[i].showScreenSharingIcon !== undefined)
item.showScreenSharingIcon = order[i].showScreenSharingIcon;
model.append(item); model.append(item);
} }

View File

@@ -70,7 +70,6 @@ var SPEC = {
controlCenterShowMicPercent: { def: false }, controlCenterShowMicPercent: { def: false },
controlCenterShowBatteryIcon: { def: false }, controlCenterShowBatteryIcon: { def: false },
controlCenterShowPrinterIcon: { def: false }, controlCenterShowPrinterIcon: { def: false },
controlCenterShowScreenSharingIcon: { def: true },
showPrivacyButton: { def: true }, showPrivacyButton: { def: true },
privacyShowMicIcon: { def: false }, privacyShowMicIcon: { def: false },

View File

@@ -122,6 +122,21 @@ Rectangle {
contentHeight: audioColumn.height contentHeight: audioColumn.height
clip: true clip: true
property int maxPinnedInputs: 3
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
if (typeof value === "string" && value.length > 0)
return [value]
return []
}
function getPinnedInputs() {
const pins = SettingsData.audioInputDevicePins || {}
return normalizePinList(pins["preferredInput"])
}
Column { Column {
id: audioColumn id: audioColumn
width: parent.width width: parent.width
@@ -133,16 +148,20 @@ Rectangle {
const nodes = Pipewire.nodes.values.filter(node => { const nodes = Pipewire.nodes.values.filter(node => {
return node.audio && !node.isSink && !node.isStream; return node.audio && !node.isSink && !node.isStream;
}); });
const pins = SettingsData.audioInputDevicePins || {}; const pinnedList = audioContent.getPinnedInputs();
const pinnedName = pins["preferredInput"];
let sorted = [...nodes]; let sorted = [...nodes];
sorted.sort((a, b) => { sorted.sort((a, b) => {
// Pinned device first // Pinned device first
if (a.name === pinnedName && b.name !== pinnedName) const aPinnedIndex = pinnedList.indexOf(a.name)
return -1; const bPinnedIndex = pinnedList.indexOf(b.name)
if (b.name === pinnedName && a.name !== pinnedName) if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
return 1; if (aPinnedIndex === -1)
return 1
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
}
// Then active device // Then active device
if (a === AudioService.source && b !== AudioService.source) if (a === AudioService.source && b !== AudioService.source)
return -1; return -1;
@@ -224,7 +243,7 @@ Rectangle {
height: 28 height: 28
radius: height / 2 radius: height / 2
color: { color: {
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05); return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
} }
@@ -237,7 +256,7 @@ Rectangle {
name: "push_pin" name: "push_pin"
size: 16 size: 16
color: { color: {
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
return isThisDevicePinned ? Theme.primary : Theme.surfaceText; return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -245,12 +264,12 @@ Rectangle {
StyledText { StyledText {
text: { text: {
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin"); return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
} }
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: { color: {
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
return isThisDevicePinned ? Theme.primary : Theme.surfaceText; return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -261,16 +280,24 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {})); const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}))
const isCurrentlyPinned = pins["preferredInput"] === modelData.name; let pinnedList = audioContent.normalizePinList(pins["preferredInput"])
const pinIndex = pinnedList.indexOf(modelData.name)
if (isCurrentlyPinned) { if (pinIndex !== -1) {
delete pins["preferredInput"]; pinnedList.splice(pinIndex, 1)
} else { } else {
pins["preferredInput"] = modelData.name; pinnedList.unshift(modelData.name)
if (pinnedList.length > audioContent.maxPinnedInputs)
pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs)
} }
SettingsData.set("audioInputDevicePins", pins); if (pinnedList.length > 0)
pins["preferredInput"] = pinnedList
else
delete pins["preferredInput"]
SettingsData.set("audioInputDevicePins", pins)
} }
} }
} }

View File

@@ -132,6 +132,21 @@ Rectangle {
contentHeight: audioColumn.height contentHeight: audioColumn.height
clip: true clip: true
property int maxPinnedOutputs: 3
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
if (typeof value === "string" && value.length > 0)
return [value]
return []
}
function getPinnedOutputs() {
const pins = SettingsData.audioOutputDevicePins || {}
return normalizePinList(pins["preferredOutput"])
}
Column { Column {
id: audioColumn id: audioColumn
width: parent.width width: parent.width
@@ -143,16 +158,20 @@ Rectangle {
const nodes = Pipewire.nodes.values.filter(node => { const nodes = Pipewire.nodes.values.filter(node => {
return node.audio && node.isSink && !node.isStream; return node.audio && node.isSink && !node.isStream;
}); });
const pins = SettingsData.audioOutputDevicePins || {}; const pinnedList = audioContent.getPinnedOutputs();
const pinnedName = pins["preferredOutput"];
let sorted = [...nodes]; let sorted = [...nodes];
sorted.sort((a, b) => { sorted.sort((a, b) => {
// Pinned device first // Pinned device first
if (a.name === pinnedName && b.name !== pinnedName) const aPinnedIndex = pinnedList.indexOf(a.name)
return -1; const bPinnedIndex = pinnedList.indexOf(b.name)
if (b.name === pinnedName && a.name !== pinnedName) if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
return 1; if (aPinnedIndex === -1)
return 1
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
}
// Then active device // Then active device
if (a === AudioService.sink && b !== AudioService.sink) if (a === AudioService.sink && b !== AudioService.sink)
return -1; return -1;
@@ -236,7 +255,7 @@ Rectangle {
height: 28 height: 28
radius: height / 2 radius: height / 2
color: { color: {
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05); return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
} }
@@ -249,7 +268,7 @@ Rectangle {
name: "push_pin" name: "push_pin"
size: 16 size: 16
color: { color: {
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
return isThisDevicePinned ? Theme.primary : Theme.surfaceText; return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -257,12 +276,12 @@ Rectangle {
StyledText { StyledText {
text: { text: {
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin"); return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
} }
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: { color: {
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name; const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
return isThisDevicePinned ? Theme.primary : Theme.surfaceText; return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -273,16 +292,24 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {})); const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}))
const isCurrentlyPinned = pins["preferredOutput"] === modelData.name; let pinnedList = audioContent.normalizePinList(pins["preferredOutput"])
const pinIndex = pinnedList.indexOf(modelData.name)
if (isCurrentlyPinned) { if (pinIndex !== -1) {
delete pins["preferredOutput"]; pinnedList.splice(pinIndex, 1)
} else { } else {
pins["preferredOutput"] = modelData.name; pinnedList.unshift(modelData.name)
if (pinnedList.length > audioContent.maxPinnedOutputs)
pinnedList = pinnedList.slice(0, audioContent.maxPinnedOutputs)
} }
SettingsData.set("audioOutputDevicePins", pins); if (pinnedList.length > 0)
pins["preferredOutput"] = pinnedList
else
delete pins["preferredOutput"]
SettingsData.set("audioOutputDevicePins", pins)
} }
} }
} }

View File

@@ -150,6 +150,21 @@ Rectangle {
contentHeight: bluetoothColumn.height contentHeight: bluetoothColumn.height
clip: true clip: true
property int maxPinnedDevices: 3
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
if (typeof value === "string" && value.length > 0)
return [value]
return []
}
function getPinnedDevices() {
const pins = SettingsData.bluetoothDevicePins || {}
return normalizePinList(pins["preferredDevice"])
}
Column { Column {
id: bluetoothColumn id: bluetoothColumn
width: parent.width width: parent.width
@@ -162,14 +177,18 @@ Rectangle {
if (!BluetoothService.adapter || !BluetoothService.adapter.devices) if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
return [] return []
const pins = SettingsData.bluetoothDevicePins || {} const pinnedList = bluetoothContent.getPinnedDevices()
const pinnedAddr = pins["preferredDevice"]
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))] let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
devices.sort((a, b) => { devices.sort((a, b) => {
// Pinned device first // Pinned device first
if (a.address === pinnedAddr && b.address !== pinnedAddr) return -1 const aPinnedIndex = pinnedList.indexOf(a.address)
if (b.address === pinnedAddr && a.address !== pinnedAddr) return 1 const bPinnedIndex = pinnedList.indexOf(b.address)
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
if (aPinnedIndex === -1) return 1
if (bPinnedIndex === -1) return -1
return aPinnedIndex - bPinnedIndex
}
// Then connected devices // Then connected devices
if (a.connected && !b.connected) return -1 if (a.connected && !b.connected) return -1
if (!a.connected && b.connected) return 1 if (!a.connected && b.connected) return 1
@@ -302,7 +321,7 @@ Rectangle {
height: 28 height: 28
radius: height / 2 radius: height / 2
color: { color: {
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05) return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
} }
@@ -315,7 +334,7 @@ Rectangle {
name: "push_pin" name: "push_pin"
size: 16 size: 16
color: { color: {
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
return isThisDevicePinned ? Theme.primary : Theme.surfaceText return isThisDevicePinned ? Theme.primary : Theme.surfaceText
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -323,12 +342,12 @@ Rectangle {
StyledText { StyledText {
text: { text: {
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin") return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin")
} }
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: { color: {
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
return isThisDevicePinned ? Theme.primary : Theme.surfaceText return isThisDevicePinned ? Theme.primary : Theme.surfaceText
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -340,14 +359,22 @@ Rectangle {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {})) const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {}))
const isCurrentlyPinned = pins["preferredDevice"] === modelData.address let pinnedList = bluetoothContent.normalizePinList(pins["preferredDevice"])
const pinIndex = pinnedList.indexOf(modelData.address)
if (isCurrentlyPinned) { if (pinIndex !== -1) {
delete pins["preferredDevice"] pinnedList.splice(pinIndex, 1)
} else { } else {
pins["preferredDevice"] = modelData.address pinnedList.unshift(modelData.address)
if (pinnedList.length > bluetoothContent.maxPinnedDevices)
pinnedList = pinnedList.slice(0, bluetoothContent.maxPinnedDevices)
} }
if (pinnedList.length > 0)
pins["preferredDevice"] = pinnedList
else
delete pins["preferredDevice"]
SettingsData.set("bluetoothDevicePins", pins) SettingsData.set("bluetoothDevicePins", pins)
} }
} }

View File

@@ -463,20 +463,39 @@ Rectangle {
contentHeight: wifiColumn.height contentHeight: wifiColumn.height
clip: true clip: true
property int maxPinnedNetworks: 3
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
if (typeof value === "string" && value.length > 0)
return [value]
return []
}
function getPinnedNetworks() {
const pins = SettingsData.wifiNetworkPins || {}
return normalizePinList(pins["preferredWifi"])
}
property var frozenNetworks: [] property var frozenNetworks: []
property bool menuOpen: false property bool menuOpen: false
property var sortedNetworks: { property var sortedNetworks: {
const ssid = NetworkService.currentWifiSSID; const ssid = NetworkService.currentWifiSSID;
const networks = NetworkService.wifiNetworks; const networks = NetworkService.wifiNetworks;
const pins = SettingsData.wifiNetworkPins || {}; const pinnedList = getPinnedNetworks()
const pinnedSSID = pins["preferredWifi"];
let sorted = [...networks]; let sorted = [...networks];
sorted.sort((a, b) => { sorted.sort((a, b) => {
if (a.ssid === pinnedSSID && b.ssid !== pinnedSSID) const aPinnedIndex = pinnedList.indexOf(a.ssid)
return -1; const bPinnedIndex = pinnedList.indexOf(b.ssid)
if (b.ssid === pinnedSSID && a.ssid !== pinnedSSID) if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
return 1; if (aPinnedIndex === -1)
return 1
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
}
if (a.ssid === ssid) if (a.ssid === ssid)
return -1; return -1;
if (b.ssid === ssid) if (b.ssid === ssid)
@@ -625,7 +644,7 @@ Rectangle {
height: 28 height: 28
radius: height / 2 radius: height / 2
color: { color: {
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid; const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
return isThisNetworkPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05); return isThisNetworkPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
} }
@@ -638,7 +657,7 @@ Rectangle {
name: "push_pin" name: "push_pin"
size: 16 size: 16
color: { color: {
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid; const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText; return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -646,12 +665,12 @@ Rectangle {
StyledText { StyledText {
text: { text: {
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid; const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
return isThisNetworkPinned ? I18n.tr("Pinned") : I18n.tr("Pin"); return isThisNetworkPinned ? I18n.tr("Pinned") : I18n.tr("Pin");
} }
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: { color: {
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid; const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText; return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -662,16 +681,24 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {})); const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
const isCurrentlyPinned = pins["preferredWifi"] === modelData.ssid; let pinnedList = wifiContent.normalizePinList(pins["preferredWifi"])
const pinIndex = pinnedList.indexOf(modelData.ssid)
if (isCurrentlyPinned) { if (pinIndex !== -1) {
delete pins["preferredWifi"]; pinnedList.splice(pinIndex, 1)
} else { } else {
pins["preferredWifi"] = modelData.ssid; pinnedList.unshift(modelData.ssid)
if (pinnedList.length > wifiContent.maxPinnedNetworks)
pinnedList = pinnedList.slice(0, wifiContent.maxPinnedNetworks)
} }
SettingsData.set("wifiNetworkPins", pins); if (pinnedList.length > 0)
pins["preferredWifi"] = pinnedList
else
delete pins["preferredWifi"]
SettingsData.set("wifiNetworkPins", pins)
} }
} }
} }

View File

@@ -29,6 +29,7 @@ BasePill {
property real micAccumulator: 0 property real micAccumulator: 0
property real volumeAccumulator: 0 property real volumeAccumulator: 0
property real brightnessAccumulator: 0 property real brightnessAccumulator: 0
readonly property real vIconSize: Theme.barIconSize(root.barThickness, -4)
Loader { Loader {
active: root.showPrinterIcon active: root.showPrinterIcon
@@ -214,7 +215,25 @@ BasePill {
} }
function hasNoVisibleIcons() { function hasNoVisibleIcons() {
return !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon && !root.showVpnIcon && !root.showBrightnessIcon && !root.showMicIcon && !root.showBatteryIcon && !root.showPrinterIcon && !root.showScreenSharingIcon; if (root.showScreenSharingIcon && NiriService.hasCasts)
return false;
if (root.showNetworkIcon && NetworkService.networkAvailable)
return false;
if (root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected)
return false;
if (root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled)
return false;
if (root.showAudioIcon)
return false;
if (root.showMicIcon)
return false;
if (root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice())
return false;
if (root.showBatteryIcon && BatteryService.batteryAvailable)
return false;
if (root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs())
return false;
return true;
} }
content: Component { content: Component {
@@ -228,53 +247,75 @@ BasePill {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingXS spacing: Theme.spacingXS
DankIcon { Item {
name: "screen_record" width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: NiriService.hasActiveCast ? Theme.primary : Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showScreenSharingIcon && NiriService.hasCasts visible: root.showScreenSharingIcon && NiriService.hasCasts
DankIcon {
name: "screen_record"
size: root.vIconSize
color: NiriService.hasActiveCast ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent
}
} }
DankIcon { Item {
name: root.getNetworkIconName() width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: root.getNetworkIconColor()
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showNetworkIcon && NetworkService.networkAvailable visible: root.showNetworkIcon && NetworkService.networkAvailable
DankIcon {
name: root.getNetworkIconName()
size: root.vIconSize
color: root.getNetworkIconColor()
anchors.centerIn: parent
}
} }
DankIcon { Item {
name: "vpn_lock" width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: NetworkService.vpnConnected ? Theme.primary : Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected
DankIcon {
name: "vpn_lock"
size: root.vIconSize
color: NetworkService.vpnConnected ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent
}
} }
DankIcon { Item {
name: "bluetooth" width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: BluetoothService.connected ? Theme.primary : Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
DankIcon {
name: "bluetooth"
size: root.vIconSize
color: BluetoothService.connected ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent
}
} }
Rectangle { Item {
width: audioIconV.implicitWidth + 4 width: root.vIconSize
height: audioIconV.implicitHeight + (root.showAudioPercent ? audioPercentV.implicitHeight : 0) + 4 height: root.vIconSize + (root.showAudioPercent ? audioPercentV.implicitHeight + 2 : 0)
color: "transparent"
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showAudioIcon visible: root.showAudioIcon
DankIcon { DankIcon {
id: audioIconV id: audioIconV
name: root.getVolumeIconName() name: root.getVolumeIconName()
size: Theme.barIconSize(root.barThickness, -4) size: root.vIconSize
color: Theme.widgetIconColor color: Theme.widgetIconColor
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 2
} }
StyledText { StyledText {
@@ -301,21 +342,19 @@ BasePill {
} }
} }
Rectangle { Item {
width: micIconV.implicitWidth + 4 width: root.vIconSize
height: micIconV.implicitHeight + (root.showAudioPercent ? micPercentV.implicitHeight : 0) + 4 height: root.vIconSize + (root.showMicPercent ? micPercentV.implicitHeight + 2 : 0)
color: "transparent"
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showMicIcon visible: root.showMicIcon
DankIcon { DankIcon {
id: micIconV id: micIconV
name: root.getMicIconName() name: root.getMicIconName()
size: Theme.barIconSize(root.barThickness, -4) size: root.vIconSize
color: root.getMicIconColor() color: root.getMicIconColor()
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 2
} }
StyledText { StyledText {
@@ -342,21 +381,19 @@ BasePill {
} }
} }
Rectangle { Item {
width: brightnessIconV.implicitWidth + 4 width: root.vIconSize
height: brightnessIconV.implicitHeight + (root.showBrightnessPercent ? brightnessPercentV.implicitHeight : 0) + 4 height: root.vIconSize + (root.showBrightnessPercent ? brightnessPercentV.implicitHeight + 2 : 0)
color: "transparent"
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice() visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice()
DankIcon { DankIcon {
id: brightnessIconV id: brightnessIconV
name: root.getBrightnessIconName() name: root.getBrightnessIconName()
size: Theme.barIconSize(root.barThickness, -4) size: root.vIconSize
color: Theme.widgetIconColor color: Theme.widgetIconColor
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 2
} }
StyledText { StyledText {
@@ -380,28 +417,46 @@ BasePill {
} }
} }
DankIcon { Item {
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable) width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: root.getBatteryIconColor()
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showBatteryIcon && BatteryService.batteryAvailable visible: root.showBatteryIcon && BatteryService.batteryAvailable
DankIcon {
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable)
size: root.vIconSize
color: root.getBatteryIconColor()
anchors.centerIn: parent
}
} }
DankIcon { Item {
name: "print" width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: Theme.primary
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs() visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs()
DankIcon {
name: "print"
size: root.vIconSize
color: Theme.primary
anchors.centerIn: parent
}
} }
DankIcon { Item {
name: "settings" width: root.vIconSize
size: Theme.barIconSize(root.barThickness, -4) height: root.vIconSize
color: root.isActive ? Theme.primary : Theme.widgetIconColor
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: root.hasNoVisibleIcons() visible: root.hasNoVisibleIcons()
DankIcon {
name: "settings"
size: root.vIconSize
color: root.isActive ? Theme.primary : Theme.widgetIconColor
anchors.centerIn: parent
}
} }
} }

View File

@@ -155,9 +155,17 @@ BasePill {
} }
} }
DankIcon {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.widgetTextColor
visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready && Paths.isSteamApp(activeWindow.appId)
}
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready visible: root.isVerticalOrientation && activeWindow && activeWindow.appId && appIcon.status !== Image.Ready && !Paths.isSteamApp(activeWindow.appId)
text: { text: {
if (!activeWindow || !activeWindow.appId) if (!activeWindow || !activeWindow.appId)
return "?"; return "?";

View File

@@ -393,9 +393,19 @@ Item {
} }
} }
DankIcon {
anchors.left: parent.left
anchors.leftMargin: (widgetData?.runningAppsCompactMode !== undefined ? widgetData.runningAppsCompactMode : SettingsData.runningAppsCompactMode) ? Math.round((parent.width - Theme.barIconSize(root.barThickness)) / 2) : Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
size: Theme.barIconSize(root.barThickness)
name: "sports_esports"
color: Theme.widgetTextColor
visible: !iconImg.visible && Paths.isSteamApp(appId)
}
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
visible: !iconImg.visible visible: !iconImg.visible && !Paths.isSteamApp(appId)
text: { text: {
root._desktopEntriesUpdateTrigger; root._desktopEntriesUpdateTrigger;
if (!appId) if (!appId)
@@ -628,9 +638,19 @@ Item {
} }
} }
DankIcon {
anchors.left: parent.left
anchors.leftMargin: (widgetData?.runningAppsCompactMode !== undefined ? widgetData.runningAppsCompactMode : SettingsData.runningAppsCompactMode) ? Math.round((parent.width - Theme.barIconSize(root.barThickness)) / 2) : Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
size: Theme.barIconSize(root.barThickness)
name: "sports_esports"
color: Theme.widgetTextColor
visible: !iconImg.visible && Paths.isSteamApp(appId)
}
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
visible: !iconImg.visible visible: !iconImg.visible && !Paths.isSteamApp(appId)
text: { text: {
root._desktopEntriesUpdateTrigger; root._desktopEntriesUpdateTrigger;
if (!appId) if (!appId)

View File

@@ -265,6 +265,7 @@ Item {
if (!byApp[key]) { if (!byApp[key]) {
const isQuickshell = keyBase === "org.quickshell"; const isQuickshell = keyBase === "org.quickshell";
const isSteamApp = Paths.isSteamApp(keyBase);
const moddedId = Paths.moddedAppId(keyBase); const moddedId = Paths.moddedAppId(keyBase);
const desktopEntry = DesktopEntries.heuristicLookup(moddedId); const desktopEntry = DesktopEntries.heuristicLookup(moddedId);
const icon = Paths.getAppIcon(keyBase, desktopEntry); const icon = Paths.getAppIcon(keyBase, desktopEntry);
@@ -272,6 +273,7 @@ Item {
"type": "icon", "type": "icon",
"icon": icon, "icon": icon,
"isQuickshell": isQuickshell, "isQuickshell": isQuickshell,
"isSteamApp": isSteamApp,
"active": !!((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)), "active": !!((w.activated || w.is_focused) || (CompositorService.isNiri && w.is_focused)),
"count": 1, "count": 1,
"windowId": w.address || w.id, "windowId": w.address || w.id,
@@ -1135,7 +1137,7 @@ Item {
anchors.fill: parent anchors.fill: parent
source: modelData.icon source: modelData.icon
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6 opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
visible: !modelData.isQuickshell visible: !modelData.isQuickshell && !modelData.isSteamApp
} }
IconImage { IconImage {
@@ -1151,6 +1153,22 @@ Item {
} }
} }
IconImage {
anchors.fill: parent
source: modelData.icon
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp && modelData.icon
}
DankIcon {
anchors.centerIn: parent
size: root.appIconSize
name: "sports_esports"
color: Theme.widgetTextColor
opacity: modelData.active ? 1.0 : rowAppMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp && !modelData.icon
}
MouseArea { MouseArea {
id: rowAppMouseArea id: rowAppMouseArea
anchors.fill: parent anchors.fill: parent
@@ -1229,7 +1247,7 @@ Item {
anchors.fill: parent anchors.fill: parent
source: modelData.icon source: modelData.icon
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6 opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
visible: !modelData.isQuickshell visible: !modelData.isQuickshell && !modelData.isSteamApp
} }
IconImage { IconImage {
@@ -1245,6 +1263,22 @@ Item {
} }
} }
IconImage {
anchors.fill: parent
source: modelData.icon
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp && modelData.icon
}
DankIcon {
anchors.centerIn: parent
size: root.appIconSize
name: "sports_esports"
color: Theme.widgetTextColor
opacity: modelData.active ? 1.0 : colAppMouseArea.containsMouse ? 0.8 : 0.6
visible: modelData.isSteamApp && !modelData.icon
}
MouseArea { MouseArea {
id: colAppMouseArea id: colAppMouseArea
anchors.fill: parent anchors.fill: parent

View File

@@ -403,7 +403,7 @@ Item {
width: actualIconSize width: actualIconSize
height: actualIconSize height: actualIconSize
anchors.centerIn: parent anchors.centerIn: parent
visible: iconImg.status !== Image.Ready visible: iconImg.status !== Image.Ready && appData && appData.appId && !Paths.isSteamApp(appData.appId)
color: Theme.surfaceLight color: Theme.surfaceLight
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 1 border.width: 1
@@ -425,6 +425,14 @@ Item {
} }
} }
DankIcon {
anchors.centerIn: parent
size: actualIconSize
name: "sports_esports"
color: Theme.surfaceText
visible: iconImg.status !== Image.Ready && appData && appData.appId && Paths.isSteamApp(appData.appId)
}
Loader { Loader {
anchors.horizontalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.horizontalCenter anchors.horizontalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.horizontalCenter
anchors.verticalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? parent.verticalCenter : undefined anchors.verticalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? parent.verticalCenter : undefined

View File

@@ -1406,14 +1406,6 @@ Item {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio) visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
DankIcon {
name: "screen_record"
size: Theme.iconSize - 2
color: NiriService.hasActiveCast ? "white" : Qt.rgba(255, 255, 255, 0.5)
anchors.verticalCenter: parent.verticalCenter
visible: NiriService.hasCasts
}
DankIcon { DankIcon {
name: { name: {
if (NetworkService.wifiToggling) if (NetworkService.wifiToggling)

View File

@@ -262,9 +262,7 @@ DankOSD {
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() { function onVolumeChanged() {
if (!vertSlider.dragging) { vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
vertSlider.value = Math.min(100, Math.round(AudioService.sink.audio.volume * 100));
}
} }
} }
} }

View File

@@ -177,10 +177,11 @@ Item {
StyledText { StyledText {
text: { text: {
if (!SystemUpdateService.shellVersion) if (!SystemUpdateService.shellVersion && !DMSService.cliVersion)
return "dms"; return "dms";
let version = SystemUpdateService.shellVersion; let version = SystemUpdateService.shellVersion || "";
let cliVersion = DMSService.cliVersion || "";
// Debian/Ubuntu/OpenSUSE git format: 1.0.3+git2264.c5c5ce84 // Debian/Ubuntu/OpenSUSE git format: 1.0.3+git2264.c5c5ce84
let match = version.match(/^([\d.]+)\+git(\d+)\./); let match = version.match(/^([\d.]+)\+git(\d+)\./);
@@ -191,7 +192,25 @@ Item {
// Fedora COPR git format: 0.0.git.2267.d430cae9 // Fedora COPR git format: 0.0.git.2267.d430cae9
match = version.match(/^[\d.]+\.git\.(\d+)\./); match = version.match(/^[\d.]+\.git\.(\d+)\./);
if (match) { if (match) {
return `dms (git) v1.0.3-${match[1]}`; function extractBaseVersion(value) {
if (!value)
return "";
let baseMatch = value.match(/(\d+\.\d+\.\d+)/);
if (baseMatch)
return baseMatch[1];
baseMatch = value.match(/(\d+\.\d+)/);
if (baseMatch)
return baseMatch[1];
return "";
}
let baseVersion = extractBaseVersion(cliVersion);
if (!baseVersion)
baseVersion = extractBaseVersion(SystemUpdateService.semverVersion);
if (baseVersion) {
return `dms (git) v${baseVersion}-${match[1]}`;
}
return `dms (git) v${match[1]}`;
} }
// Stable release format: 1.0.3 // Stable release format: 1.0.3
@@ -200,6 +219,18 @@ Item {
return `dms v${match[1]}`; return `dms v${match[1]}`;
} }
if (!version && cliVersion) {
match = cliVersion.match(/^([\d.]+)\+git(\d+)\./);
if (match) {
return `dms (git) v${match[1]}-${match[2]}`;
}
match = cliVersion.match(/^([\d.]+)$/);
if (match) {
return `dms v${match[1]}`;
}
return `dms ${cliVersion}`;
}
return `dms ${version}`; return `dms ${version}`;
} }
font.pixelSize: Theme.fontSizeXLarge font.pixelSize: Theme.fontSizeXLarge

View File

@@ -15,6 +15,7 @@ Item {
property string expandedVpnUuid: "" property string expandedVpnUuid: ""
property string expandedWifiSsid: "" property string expandedWifiSsid: ""
property string expandedEthDevice: "" property string expandedEthDevice: ""
property int maxPinnedWifiNetworks: 3
Component.onCompleted: { Component.onCompleted: {
NetworkService.addRef(); NetworkService.addRef();
@@ -30,6 +31,40 @@ Item {
vpnFileBrowserLoader.item.open(); vpnFileBrowserLoader.item.open();
} }
function normalizePinList(value) {
if (Array.isArray(value))
return value.filter(v => v)
if (typeof value === "string" && value.length > 0)
return [value]
return []
}
function getPinnedWifiNetworks() {
const pins = SettingsData.wifiNetworkPins || {}
return normalizePinList(pins["preferredWifi"])
}
function toggleWifiPin(ssid) {
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
let pinnedList = normalizePinList(pins["preferredWifi"])
const pinIndex = pinnedList.indexOf(ssid)
if (pinIndex !== -1) {
pinnedList.splice(pinIndex, 1)
} else {
pinnedList.unshift(ssid)
if (pinnedList.length > maxPinnedWifiNetworks)
pinnedList = pinnedList.slice(0, maxPinnedWifiNetworks)
}
if (pinnedList.length > 0)
pins["preferredWifi"] = pinnedList
else
delete pins["preferredWifi"]
SettingsData.set("wifiNetworkPins", pins)
}
LazyLoader { LazyLoader {
id: vpnFileBrowserLoader id: vpnFileBrowserLoader
active: false active: false
@@ -1025,15 +1060,19 @@ Item {
model: { model: {
const ssid = NetworkService.currentWifiSSID; const ssid = NetworkService.currentWifiSSID;
const networks = NetworkService.wifiNetworks || []; const networks = NetworkService.wifiNetworks || [];
const pins = SettingsData.wifiNetworkPins || {}; const pinnedList = networkTab.getPinnedWifiNetworks();
const pinnedSSID = pins["preferredWifi"];
let sorted = [...networks]; let sorted = [...networks];
sorted.sort((a, b) => { sorted.sort((a, b) => {
if (a.ssid === pinnedSSID && b.ssid !== pinnedSSID) const aPinnedIndex = pinnedList.indexOf(a.ssid)
return -1; const bPinnedIndex = pinnedList.indexOf(b.ssid)
if (b.ssid === pinnedSSID && a.ssid !== pinnedSSID) if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
return 1; if (aPinnedIndex === -1)
return 1
if (bPinnedIndex === -1)
return -1
return aPinnedIndex - bPinnedIndex
}
if (a.ssid === ssid) if (a.ssid === ssid)
return -1; return -1;
if (b.ssid === ssid) if (b.ssid === ssid)
@@ -1049,7 +1088,7 @@ Item {
required property int index required property int index
readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID
readonly property bool isPinned: (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid readonly property bool isPinned: networkTab.getPinnedWifiNetworks().includes(modelData.ssid)
readonly property bool isExpanded: networkTab.expandedWifiSsid === modelData.ssid readonly property bool isExpanded: networkTab.expandedWifiSsid === modelData.ssid
width: parent.width width: parent.width
@@ -1224,13 +1263,7 @@ Item {
buttonSize: 28 buttonSize: 28
iconColor: isPinned ? Theme.primary : Theme.surfaceVariantText iconColor: isPinned ? Theme.primary : Theme.surfaceVariantText
onClicked: { onClicked: {
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {})); networkTab.toggleWifiPin(modelData.ssid)
if (isPinned) {
delete pins["preferredWifi"];
} else {
pins["preferredWifi"] = modelData.ssid;
}
SettingsData.set("wifiNetworkPins", pins);
} }
} }

View File

@@ -270,7 +270,9 @@ FloatingWindow {
root.updateFilteredPlugins(); root.updateFilteredPlugins();
return; return;
} }
thirdPartyConfirmModal.visible = true; thirdPartyConfirmLoader.active = true;
if (thirdPartyConfirmLoader.item)
thirdPartyConfirmLoader.item.show();
} }
} }
@@ -668,119 +670,132 @@ FloatingWindow {
} }
} }
FloatingWindow { LazyLoader {
id: thirdPartyConfirmModal id: thirdPartyConfirmLoader
active: false
objectName: "thirdPartyConfirm" FloatingWindow {
title: I18n.tr("Third-Party Plugin Warning") id: thirdPartyConfirmModal
implicitWidth: 500
implicitHeight: 350
color: Theme.surfaceContainer
visible: false
FocusScope { function show() {
anchors.fill: parent visible = true;
focus: true
Keys.onPressed: event => {
if (event.key === Qt.Key_Escape) {
thirdPartyConfirmModal.visible = false;
event.accepted = true;
}
} }
Column { function hide() {
visible = false;
}
objectName: "thirdPartyConfirm"
title: I18n.tr("Third-Party Plugin Warning")
implicitWidth: 500
implicitHeight: 350
color: Theme.surfaceContainer
visible: false
FocusScope {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingL focus: true
spacing: Theme.spacingL
Row { Keys.onPressed: event => {
width: parent.width if (event.key === Qt.Key_Escape) {
spacing: Theme.spacingM thirdPartyConfirmModal.hide();
event.accepted = true;
DankIcon {
name: "warning"
size: Theme.iconSize
color: Theme.warning
anchors.verticalCenter: parent.verticalCenter
} }
StyledText {
text: I18n.tr("Third-Party Plugin Warning")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - parent.spacing * 2 - Theme.iconSize - parent.children[1].implicitWidth - closeConfirmBtn.width
height: 1
}
DankActionButton {
id: closeConfirmBtn
iconName: "close"
iconSize: Theme.iconSize - 2
iconColor: Theme.outline
anchors.verticalCenter: parent.verticalCenter
onClicked: thirdPartyConfirmModal.visible = false
}
}
StyledText {
width: parent.width
text: I18n.tr("Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk.")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
wrapMode: Text.WordWrap
} }
Column { Column {
width: parent.width anchors.fill: parent
spacing: Theme.spacingS anchors.margins: Theme.spacingL
spacing: Theme.spacingL
StyledText { Row {
text: I18n.tr("• Plugins may contain bugs or security issues") width: parent.width
font.pixelSize: Theme.fontSizeSmall spacing: Theme.spacingM
color: Theme.surfaceVariantText
DankIcon {
name: "warning"
size: Theme.iconSize
color: Theme.warning
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Third-Party Plugin Warning")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - parent.spacing * 2 - Theme.iconSize - parent.children[1].implicitWidth - closeConfirmBtn.width
height: 1
}
DankActionButton {
id: closeConfirmBtn
iconName: "close"
iconSize: Theme.iconSize - 2
iconColor: Theme.outline
anchors.verticalCenter: parent.verticalCenter
onClicked: thirdPartyConfirmModal.hide()
}
} }
StyledText { StyledText {
text: I18n.tr("• Review code before installation when possible") width: parent.width
font.pixelSize: Theme.fontSizeSmall text: I18n.tr("Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk.")
color: Theme.surfaceVariantText font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
wrapMode: Text.WordWrap
} }
StyledText { Column {
text: I18n.tr("• Install only from trusted sources") width: parent.width
font.pixelSize: Theme.fontSizeSmall spacing: Theme.spacingS
color: Theme.surfaceVariantText
}
}
Item { StyledText {
width: parent.width text: I18n.tr("• Plugins may contain bugs or security issues")
height: parent.height - parent.spacing * 3 - y font.pixelSize: Theme.fontSizeSmall
} color: Theme.surfaceVariantText
}
Row { StyledText {
anchors.right: parent.right text: I18n.tr("• Review code before installation when possible")
spacing: Theme.spacingM font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
DankButton { StyledText {
text: I18n.tr("Cancel") text: I18n.tr("• Install only from trusted sources")
iconName: "close" font.pixelSize: Theme.fontSizeSmall
onClicked: thirdPartyConfirmModal.visible = false color: Theme.surfaceVariantText
}
} }
DankButton { Item {
text: I18n.tr("I Understand") width: parent.width
iconName: "check" height: parent.height - parent.spacing * 3 - y
onClicked: { }
SessionData.setShowThirdPartyPlugins(true);
root.updateFilteredPlugins(); Row {
thirdPartyConfirmModal.visible = false; anchors.right: parent.right
spacing: Theme.spacingM
DankButton {
text: I18n.tr("Cancel")
iconName: "close"
onClicked: thirdPartyConfirmModal.hide()
}
DankButton {
text: I18n.tr("I Understand")
iconName: "check"
onClicked: {
SessionData.setShowThirdPartyPlugins(true);
root.updateFilteredPlugins();
thirdPartyConfirmModal.hide();
}
} }
} }
} }

View File

@@ -383,7 +383,6 @@ Item {
widgetObj.showMicPercent = SettingsData.controlCenterShowMicPercent; widgetObj.showMicPercent = SettingsData.controlCenterShowMicPercent;
widgetObj.showBatteryIcon = SettingsData.controlCenterShowBatteryIcon; widgetObj.showBatteryIcon = SettingsData.controlCenterShowBatteryIcon;
widgetObj.showPrinterIcon = SettingsData.controlCenterShowPrinterIcon; widgetObj.showPrinterIcon = SettingsData.controlCenterShowPrinterIcon;
widgetObj.showScreenSharingIcon = SettingsData.controlCenterShowScreenSharingIcon;
} }
if (widgetId === "diskUsage") if (widgetId === "diskUsage")
widgetObj.mountPath = "/"; widgetObj.mountPath = "/";
@@ -444,7 +443,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[i] = newWidget; widgets[i] = newWidget;
break; break;
@@ -501,7 +499,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[widgetIndex] = newWidget; widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets); setWidgetsForSection(sectionId, widgets);
@@ -580,7 +577,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[widgetIndex] = newWidget; widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets); setWidgetsForSection(sectionId, widgets);
@@ -612,8 +608,7 @@ Item {
"showMicIcon": widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon, "showMicIcon": widget.showMicIcon ?? SettingsData.controlCenterShowMicIcon,
"showMicPercent": widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent, "showMicPercent": widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent,
"showBatteryIcon": widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon, "showBatteryIcon": widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon,
"showPrinterIcon": widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon, "showPrinterIcon": widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon
"showScreenSharingIcon": widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon
}; };
newWidget[settingName] = value; newWidget[settingName] = value;
@@ -680,7 +675,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[widgetIndex] = newWidget; widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets); setWidgetsForSection(sectionId, widgets);
@@ -741,7 +735,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[widgetIndex] = newWidget; widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets); setWidgetsForSection(sectionId, widgets);
@@ -802,7 +795,6 @@ Item {
newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent; newWidget.showMicPercent = widget.showMicPercent ?? SettingsData.controlCenterShowMicPercent;
newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; newWidget.showBatteryIcon = widget.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; newWidget.showPrinterIcon = widget.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
newWidget.showScreenSharingIcon = widget.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
} }
widgets[i] = newWidget; widgets[i] = newWidget;
widget = newWidget; widget = newWidget;
@@ -875,8 +867,6 @@ Item {
item.showBatteryIcon = widget.showBatteryIcon; item.showBatteryIcon = widget.showBatteryIcon;
if (widget.showPrinterIcon !== undefined) if (widget.showPrinterIcon !== undefined)
item.showPrinterIcon = widget.showPrinterIcon; item.showPrinterIcon = widget.showPrinterIcon;
if (widget.showScreenSharingIcon !== undefined)
item.showScreenSharingIcon = widget.showScreenSharingIcon;
if (widget.minimumWidth !== undefined) if (widget.minimumWidth !== undefined)
item.minimumWidth = widget.minimumWidth; item.minimumWidth = widget.minimumWidth;
if (widget.showSwap !== undefined) if (widget.showSwap !== undefined)

View File

@@ -875,11 +875,6 @@ Column {
icon: "print", icon: "print",
label: I18n.tr("Printer"), label: I18n.tr("Printer"),
setting: "showPrinterIcon" setting: "showPrinterIcon"
},
{
icon: "screen_record",
label: I18n.tr("Screen Sharing"),
setting: "showScreenSharingIcon"
} }
] ]
@@ -912,8 +907,6 @@ Column {
return wd?.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; return wd?.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon;
case "showPrinterIcon": case "showPrinterIcon":
return wd?.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; return wd?.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon;
case "showScreenSharingIcon":
return wd?.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon;
default: default:
return false; return false;
} }

View File

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

View File

@@ -27,10 +27,6 @@ Singleton {
property bool inOverview: false property bool inOverview: false
property var casts: []
property bool hasCasts: casts.length > 0
property bool hasActiveCast: casts.some(c => c.is_active)
property int currentKeyboardLayoutIndex: 0 property int currentKeyboardLayoutIndex: 0
property var keyboardLayoutNames: [] property var keyboardLayoutNames: []
@@ -360,15 +356,6 @@ Singleton {
case 'ScreenshotCaptured': case 'ScreenshotCaptured':
handleScreenshotCaptured(event.ScreenshotCaptured); handleScreenshotCaptured(event.ScreenshotCaptured);
break; break;
case 'CastsChanged':
handleCastsChanged(event.CastsChanged);
break;
case 'CastStartedOrChanged':
handleCastStartedOrChanged(event.CastStartedOrChanged);
break;
case 'CastStopped':
handleCastStopped(event.CastStopped);
break;
} }
} }
@@ -662,28 +649,6 @@ Singleton {
} }
} }
function handleCastsChanged(data) {
casts = data.casts || [];
}
function handleCastStartedOrChanged(data) {
if (!data.cast)
return;
const cast = data.cast;
const existingIndex = casts.findIndex(c => c.stream_id === cast.stream_id);
if (existingIndex >= 0) {
const updatedCasts = [...casts];
updatedCasts[existingIndex] = cast;
casts = updatedCasts;
} else {
casts = [...casts, cast];
}
}
function handleCastStopped(data) {
casts = casts.filter(c => c.stream_id !== data.stream_id);
}
function updateCurrentOutputWorkspaces() { function updateCurrentOutputWorkspaces() {
if (!currentOutput) { if (!currentOutput) {
currentOutputWorkspaces = allWorkspaces; currentOutputWorkspaces = allWorkspaces;

View File

@@ -1 +1 @@
v1.4-unstable v1.2.3