Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions config/Config.qml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ Singleton {
property string monoFont: "Iosevka Nerd Font Mono"
property int monoFontSize: 14
property bool tintIcons: false
property bool matchSysTrayIconColor: false
property bool enableCorners: true
property int animDuration: 300
property real shadowOpacity: 0.5
Expand Down Expand Up @@ -1099,7 +1100,7 @@ Singleton {
if (current.ambxst.dashboard && typeof current.ambxst.dashboard === "object" && !current.ambxst.dashboard.modifiers) {
console.log("Migrating nested ambxst binds to flat structure...");
const nested = current.ambxst.dashboard;

// Map old names to new names and update arguments
if (nested.widgets) {
current.ambxst.launcher = nested.widgets;
Expand Down Expand Up @@ -2992,6 +2993,7 @@ Singleton {
property string defaultFont: theme.font
property int animDuration: Services.GameModeService.toggled ? 0 : theme.animDuration
property bool tintIcons: theme.tintIcons
property bool matchSysTrayIconColor: theme.matchSysTrayIconColor

// Handle lightMode changes
onLightModeChanged: {
Expand Down Expand Up @@ -3037,7 +3039,7 @@ Singleton {
// Trigger save
GlobalStates.markShellChanged();
}
}
}
// If notch moves top
else if (notchPosition === "top") {
// Restore Dock if displaced
Expand Down Expand Up @@ -3139,20 +3141,20 @@ Singleton {

function resolveColor(colorValue) {
if (!colorValue) return "transparent"; // Fallback

if (isHexColor(colorValue)) {
return colorValue;
}

// Check Colors singleton
if (typeof Colors === 'undefined' || !Colors) return "transparent";
return Colors[colorValue] || "transparent";

return Colors[colorValue] || "transparent";
}

function resolveColorWithOpacity(colorValue, opacity) {
if (!colorValue) return Qt.rgba(0,0,0,0);

const color = isHexColor(colorValue) ? Qt.color(colorValue) : (Colors[colorValue] || Qt.color("transparent"));
return Qt.rgba(color.r, color.g, color.b, opacity);
}
Expand Down
1 change: 1 addition & 0 deletions config/defaults/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var data = {
"monoFont": "Iosevka Nerd Font Mono",
"monoFontSize": 14,
"tintIcons": false,
"matchSysTrayIconColor": false,
"enableCorners": true,
"animDuration": 300,
"shadowOpacity": 0.5,
Expand Down
12 changes: 12 additions & 0 deletions modules/bar/systray/SysTrayItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,23 @@ MouseArea {
width: parent.width
height: parent.height
smooth: true
// Keep the raw icon hidden when the tinted layer is active.
opacity: systrayIconTint.active ? 0 : 1
}

Tinted {
id: systrayIconTint
sourceItem: trayIcon
anchors.fill: trayIcon
active: Config.matchSysTrayIconColor
fullTint: true
tintColor: Config.tintIcons ? Styling.srItem("overprimary") : Colors.overBackground
}

Tinted {
sourceItem: trayIcon
anchors.fill: trayIcon
active: Config.tintIcons && !Config.matchSysTrayIconColor
}

StyledToolTip {
Expand Down
13 changes: 7 additions & 6 deletions modules/components/Tinted.qml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Item {
id: root
property var sourceItem: null // The icon item to tint
property bool fullTint: false // If true, apply solid primary color instead of shader
property color tintColor: Styling.srItem("overprimary")

// Subset of colors for optimization (consistent with TintedWallpaper.qml)
readonly property var optimizedPalette: [
Expand All @@ -26,11 +27,11 @@ Item {
// Palette generation for the shader
Item {
id: paletteSourceItem
visible: true
visible: true
width: root.optimizedPalette.length
height: 1
opacity: 0

Row {
anchors.fill: parent
Repeater {
Expand Down Expand Up @@ -69,14 +70,14 @@ Item {
hideSource: true
live: false // Static content - use scheduleUpdate() when source changes
}

// Update texture when sourceItem changes
Connections {
target: root.sourceItem
function onSourceChanged() { internalSource.scheduleUpdate(); }
function onStatusChanged() { internalSource.scheduleUpdate(); }
}

// Also update when this component becomes visible or sourceItem changes
Connections {
target: root
Expand All @@ -91,14 +92,14 @@ Item {
source: internalSource
brightness: 1.0
colorization: 1.0
colorizationColor: Styling.srItem("overprimary")
colorizationColor: root.tintColor
}

// Shader-based tint
ShaderEffect {
visible: !root.fullTint
anchors.fill: parent

property var source: internalSource
property var paletteTexture: paletteTextureSource
property real paletteSize: root.optimizedPalette.length
Expand Down
69 changes: 69 additions & 0 deletions modules/widgets/dashboard/controls/ThemePanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,75 @@ Item {
}
}

// Match Systray Icon Color toggle
RowLayout {
Layout.fillWidth: true
spacing: 8

Text {
text: "Theme System Tray Icons"
font.family: Config.theme.font
font.pixelSize: Styling.fontSize(0)
color: Colors.overBackground
Layout.fillWidth: true
}

Switch {
id: matchSysTrayIconColorSwitch
checked: Config.theme.matchSysTrayIconColor

readonly property bool configValue: Config.theme.matchSysTrayIconColor

onConfigValueChanged: {
if (checked !== configValue) {
checked = configValue;
}
}

onCheckedChanged: {
if (checked !== Config.theme.matchSysTrayIconColor) {
GlobalStates.markThemeChanged();
Config.theme.matchSysTrayIconColor = checked;
}
}

indicator: Rectangle {
implicitWidth: 40
implicitHeight: 20
x: matchSysTrayIconColorSwitch.leftPadding
y: parent.height / 2 - height / 2
radius: height / 2
color: matchSysTrayIconColorSwitch.checked ? Styling.srItem("overprimary") : Colors.surfaceBright
border.color: matchSysTrayIconColorSwitch.checked ? Styling.srItem("overprimary") : Colors.outline

Behavior on color {
enabled: Config.animDuration > 0
ColorAnimation {
duration: Config.animDuration / 2
}
}

Rectangle {
x: matchSysTrayIconColorSwitch.checked ? parent.width - width - 2 : 2
y: 2
width: parent.height - 4
height: width
radius: width / 2
color: matchSysTrayIconColorSwitch.checked ? Colors.background : Colors.overSurfaceVariant

Behavior on x {
enabled: Config.animDuration > 0
NumberAnimation {
duration: Config.animDuration / 2
easing.type: Easing.OutCubic
}
}
}
}
background: null
}
}

// Enable Corners toggle
RowLayout {
Layout.fillWidth: true
Expand Down