mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-29 16:02:51 -05:00
Fix icon theme change
This commit is contained in:
205
Common/Prefs.qml
205
Common/Prefs.qml
@@ -37,6 +37,8 @@ Singleton {
|
|||||||
property string iconTheme: "System Default"
|
property string iconTheme: "System Default"
|
||||||
property var availableIconThemes: ["System Default"]
|
property var availableIconThemes: ["System Default"]
|
||||||
property string systemDefaultIconTheme: "Adwaita"
|
property string systemDefaultIconTheme: "Adwaita"
|
||||||
|
property bool qt5ctAvailable: false
|
||||||
|
property bool qt6ctAvailable: false
|
||||||
property bool useOSLogo: false
|
property bool useOSLogo: false
|
||||||
property string osLogoColorOverride: ""
|
property string osLogoColorOverride: ""
|
||||||
property real osLogoBrightness: 0.5
|
property real osLogoBrightness: 0.5
|
||||||
@@ -46,6 +48,7 @@ Singleton {
|
|||||||
property string wallpaperLastPath: ""
|
property string wallpaperLastPath: ""
|
||||||
property string profileLastPath: ""
|
property string profileLastPath: ""
|
||||||
property bool doNotDisturb: false
|
property bool doNotDisturb: false
|
||||||
|
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
parseSettings(settingsFile.text());
|
parseSettings(settingsFile.text());
|
||||||
@@ -91,6 +94,7 @@ Singleton {
|
|||||||
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false;
|
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false;
|
||||||
applyStoredTheme();
|
applyStoredTheme();
|
||||||
detectAvailableIconThemes();
|
detectAvailableIconThemes();
|
||||||
|
detectQtTools();
|
||||||
updateGtkIconTheme(iconTheme);
|
updateGtkIconTheme(iconTheme);
|
||||||
applyStoredIconTheme();
|
applyStoredIconTheme();
|
||||||
} else {
|
} else {
|
||||||
@@ -348,98 +352,110 @@ Singleton {
|
|||||||
systemDefaultDetectionProcess.running = true;
|
systemDefaultDetectionProcess.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function detectQtTools() {
|
||||||
|
qtToolsDetectionProcess.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
function setIconTheme(themeName) {
|
function setIconTheme(themeName) {
|
||||||
iconTheme = themeName;
|
iconTheme = themeName;
|
||||||
|
|
||||||
updateGtkIconTheme(themeName);
|
updateGtkIconTheme(themeName);
|
||||||
|
updateQtIconTheme(themeName);
|
||||||
updateQuickshellIconTheme(themeName);
|
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateGtkIconTheme(themeName) {
|
function updateGtkIconTheme(themeName) {
|
||||||
var gtkThemeName;
|
console.log("Updating GTK icon theme to:", themeName);
|
||||||
|
var gtkThemeName = (themeName === "System Default") ? systemDefaultIconTheme : themeName;
|
||||||
switch(themeName) {
|
|
||||||
case "System Default":
|
var preferDark = (!isLightMode) ? "true" : "false";
|
||||||
gtkThemeName = systemDefaultIconTheme;
|
var gtkSettings =
|
||||||
break;
|
"[Settings]\n" +
|
||||||
case "Papirus":
|
"gtk-icon-theme-name=" + gtkThemeName + "\n" +
|
||||||
gtkThemeName = "Papirus";
|
"gtk-theme-name=" + (isLightMode ? "Adwaita" : "Adwaita-dark") + "\n" +
|
||||||
break;
|
"gtk-application-prefer-dark-theme=" + preferDark + "\n";
|
||||||
case "Papirus-Dark":
|
|
||||||
gtkThemeName = "Papirus-Dark";
|
var home = _shq(root._homeUrl.replace("file://", ""));
|
||||||
break;
|
var script =
|
||||||
case "Papirus-Light":
|
"mkdir -p " + home + "/.config/gtk-3.0 " + home + "/.config/gtk-4.0 2>/dev/null || true\n" +
|
||||||
gtkThemeName = "Papirus-Light";
|
"printf %s " + _shq(gtkSettings) + " > " + home + "/.config/gtk-3.0/settings.ini\n" +
|
||||||
break;
|
"printf %s " + _shq(gtkSettings) + " > " + home + "/.config/gtk-4.0/settings.ini\n" +
|
||||||
case "Adwaita":
|
"rm -rf " + home + "/.cache/icon-cache " + home + "/.cache/thumbnails 2>/dev/null || true\n";
|
||||||
gtkThemeName = "Adwaita";
|
|
||||||
break;
|
Quickshell.execDetached(["sh", "-lc", script]);
|
||||||
default:
|
|
||||||
gtkThemeName = themeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
envCheckProcess.command = ["sh", "-c", "echo 'QT_QPA_PLATFORMTHEME=' $QT_QPA_PLATFORMTHEME"];
|
|
||||||
envCheckProcess.running = true;
|
|
||||||
|
|
||||||
var gtk3Settings = `[Settings]
|
|
||||||
gtk-icon-theme-name=${gtkThemeName}
|
|
||||||
gtk-theme-name=Adwaita-dark
|
|
||||||
gtk-application-prefer-dark-theme=true`;
|
|
||||||
|
|
||||||
gtk3Process.command = ["sh", "-c", `mkdir -p ~/.config/gtk-3.0 && echo '${gtk3Settings}' > ~/.config/gtk-3.0/settings.ini`];
|
|
||||||
gtk3Process.running = true;
|
|
||||||
|
|
||||||
gtk4Process.command = ["sh", "-c", `mkdir -p ~/.config/gtk-4.0 && echo '${gtk3Settings}' > ~/.config/gtk-4.0/settings.ini`];
|
|
||||||
gtk4Process.running = true;
|
|
||||||
|
|
||||||
reloadThemeProcess.command = ["sh", "-c", "gsettings set org.gnome.desktop.interface icon-theme '" + gtkThemeName + "' 2>/dev/null || true"];
|
|
||||||
reloadThemeProcess.running = true;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateQuickshellIconTheme(themeName) {
|
function updateQtIconTheme(themeName) {
|
||||||
var quickshellThemeName;
|
console.log("Updating Qt icon theme to:", themeName);
|
||||||
|
var qtThemeName = (themeName === "System Default") ? "" : themeName;
|
||||||
switch(themeName) {
|
|
||||||
case "System Default":
|
var home = _shq(root._homeUrl.replace("file://", ""));
|
||||||
quickshellThemeName = "";
|
if (!qtThemeName) {
|
||||||
break;
|
var revertScript =
|
||||||
case "Papirus":
|
"remove_icon_theme() {\n" +
|
||||||
quickshellThemeName = "Papirus";
|
" local config_file=\"$1\"\n" +
|
||||||
break;
|
" if [ -f \"$config_file\" ]; then\n" +
|
||||||
case "Papirus-Dark":
|
" awk '\n" +
|
||||||
quickshellThemeName = "Papirus-Dark";
|
" BEGIN { in_appearance = 0 }\n" +
|
||||||
break;
|
" /^\\[Appearance\\]/ { in_appearance = 1; print; next }\n" +
|
||||||
case "Papirus-Light":
|
" /^\\[/ && in_appearance { in_appearance = 0 }\n" +
|
||||||
quickshellThemeName = "Papirus-Light";
|
" in_appearance && /^icon_theme=/ { next }\n" +
|
||||||
break;
|
" { print }\n" +
|
||||||
case "Adwaita":
|
" ' \"$config_file\" > \"$config_file.tmp\" && mv \"$config_file.tmp\" \"$config_file\"\n" +
|
||||||
quickshellThemeName = "Adwaita";
|
" fi\n" +
|
||||||
break;
|
"}\n" +
|
||||||
default:
|
"remove_icon_theme " + home + "/.config/qt5ct/qt5ct.conf\n" +
|
||||||
quickshellThemeName = themeName;
|
"remove_icon_theme " + home + "/.config/qt6ct/qt6ct.conf\n" +
|
||||||
|
"rm -f " + home + "/.config/environment.d/95-qtct.conf 2>/dev/null || true\n" +
|
||||||
|
"systemctl --user import-environment --unset=QT_QPA_PLATFORMTHEME 2>/dev/null || true\n" +
|
||||||
|
"dbus-update-activation-environment --systemd QT_QPA_PLATFORMTHEME= 2>/dev/null || true\n" +
|
||||||
|
"rm -rf " + home + "/.cache/icon-cache " + home + "/.cache/thumbnails 2>/dev/null || true\n";
|
||||||
|
|
||||||
|
Quickshell.execDetached(["sh", "-lc", revertScript]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var script =
|
||||||
|
"mkdir -p " + home + "/.config/qt5ct " + home + "/.config/qt6ct " + home + "/.config/environment.d 2>/dev/null || true\n" +
|
||||||
if (quickshellThemeName) {
|
"update_qt_config() {\n" +
|
||||||
envSetProcess.command = ["sh", "-c", `export QS_ICON_THEME="${quickshellThemeName}" && rm -rf ~/.cache/icon-cache ~/.cache/thumbnails 2>/dev/null || true`];
|
" local config_file=\"$1\"\n" +
|
||||||
} else {
|
" local theme_name=\"$2\"\n" +
|
||||||
envSetProcess.command = ["sh", "-c", `unset QS_ICON_THEME && rm -rf ~/.cache/icon-cache ~/.cache/thumbnails 2>/dev/null || true`];
|
" if [ -f \"$config_file\" ]; then\n" +
|
||||||
}
|
" if grep -q '^\\[Appearance\\]' \"$config_file\"; then\n" +
|
||||||
envSetProcess.running = true;
|
" awk -v theme=\"$theme_name\" '\n" +
|
||||||
|
" BEGIN { in_appearance = 0 }\n" +
|
||||||
|
" /^\\[Appearance\\]/ { in_appearance = 1; print; next }\n" +
|
||||||
|
" /^\\[/ && in_appearance { in_appearance = 0 }\n" +
|
||||||
|
" in_appearance && /^icon_theme=/ { print \"icon_theme=\" theme; next }\n" +
|
||||||
|
" in_appearance && /^\\[/ { print \"icon_theme=\" theme; print; in_appearance = 0; next }\n" +
|
||||||
|
" { print }\n" +
|
||||||
|
" END { if (in_appearance) print \"icon_theme=\" theme }\n" +
|
||||||
|
" ' \"$config_file\" > \"$config_file.tmp\" && mv \"$config_file.tmp\" \"$config_file\"\n" +
|
||||||
|
" else\n" +
|
||||||
|
" printf '\\n[Appearance]\\nicon_theme=%s\\n' \"$theme_name\" >> \"$config_file\"\n" +
|
||||||
|
" fi\n" +
|
||||||
|
" else\n" +
|
||||||
|
" printf '[Appearance]\\nicon_theme=%s\\n' \"$theme_name\" > \"$config_file\"\n" +
|
||||||
|
" fi\n" +
|
||||||
|
"}\n" +
|
||||||
|
"update_qt_config " + home + "/.config/qt5ct/qt5ct.conf " + _shq(qtThemeName) + "\n" +
|
||||||
|
"update_qt_config " + home + "/.config/qt6ct/qt6ct.conf " + _shq(qtThemeName) + "\n" +
|
||||||
|
"if command -v qt6ct >/dev/null 2>&1; then\n" +
|
||||||
|
" printf 'QT_QPA_PLATFORMTHEME=qt6ct\\n' > " + home + "/.config/environment.d/95-qtct.conf\n" +
|
||||||
|
"elif command -v qt5ct >/dev/null 2>&1; then\n" +
|
||||||
|
" printf 'QT_QPA_PLATFORMTHEME=qt5ct\\n' > " + home + "/.config/environment.d/95-qtct.conf\n" +
|
||||||
|
"else\n" +
|
||||||
|
" rm -f " + home + "/.config/environment.d/95-qtct.conf 2>/dev/null || true\n" +
|
||||||
|
"fi\n" +
|
||||||
|
"systemctl --user import-environment QT_QPA_PLATFORMTHEME 2>/dev/null || true\n" +
|
||||||
|
"dbus-update-activation-environment --systemd QT_QPA_PLATFORMTHEME 2>/dev/null || true\n" +
|
||||||
|
"rm -rf " + home + "/.cache/icon-cache " + home + "/.cache/thumbnails 2>/dev/null || true\n";
|
||||||
|
|
||||||
|
Quickshell.execDetached(["sh", "-lc", script]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyStoredIconTheme() {
|
function applyStoredIconTheme() {
|
||||||
if (iconTheme && iconTheme !== "System Default") {
|
updateGtkIconTheme(iconTheme);
|
||||||
updateGtkIconTheme(iconTheme);
|
updateQtIconTheme(iconTheme);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUseOSLogo(enabled) {
|
function setUseOSLogo(enabled) {
|
||||||
@@ -497,6 +513,11 @@ gtk-application-prefer-dark-theme=true`;
|
|||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to safely single-quote shell strings
|
||||||
|
function _shq(s) {
|
||||||
|
return "'" + String(s).replace(/'/g, "'\\''") + "'";
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: loadSettings()
|
Component.onCompleted: loadSettings()
|
||||||
|
|
||||||
|
|
||||||
@@ -610,6 +631,28 @@ gtk-application-prefer-dark-theme=true`;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: qtToolsDetectionProcess
|
||||||
|
command: ["sh", "-c", "echo -n 'qt5ct:'; command -v qt5ct >/dev/null && echo 'true' || echo 'false'; echo -n 'qt6ct:'; command -v qt6ct >/dev/null && echo 'true' || echo 'false'"]
|
||||||
|
running: false
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
if (text && text.trim()) {
|
||||||
|
var lines = text.trim().split('\n');
|
||||||
|
for (var i = 0; i < lines.length; i++) {
|
||||||
|
var line = lines[i];
|
||||||
|
if (line.startsWith('qt5ct:')) {
|
||||||
|
qt5ctAvailable = line.split(':')[1] === 'true';
|
||||||
|
} else if (line.startsWith('qt6ct:')) {
|
||||||
|
qt6ctAvailable = line.split(':')[1] === 'true';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
target: "wallpaper"
|
target: "wallpaper"
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ DankModal {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 4
|
active: settingsTabBar.currentIndex === 4
|
||||||
visible: active
|
visible: active
|
||||||
asynchronous: true
|
asynchronous: false
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
AppearanceTab {}
|
AppearanceTab {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,16 +85,17 @@ ScrollView {
|
|||||||
DankDropdown {
|
DankDropdown {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Icon Theme"
|
text: "Icon Theme"
|
||||||
description: "Select icon theme (requires restart)"
|
description: "Select icon theme (may require logout to apply)"
|
||||||
currentValue: Prefs.iconTheme
|
currentValue: Prefs.iconTheme
|
||||||
options: Prefs.availableIconThemes
|
options: Prefs.availableIconThemes
|
||||||
onValueChanged: (value) => {
|
onValueChanged: (value) => {
|
||||||
Prefs.setIconTheme(value);
|
Prefs.setIconTheme(value);
|
||||||
|
if (value !== "System Default" && !Prefs.qt5ctAvailable && !Prefs.qt6ctAvailable) {
|
||||||
|
ToastService.showWarning("qt5ct or qt6ct not found - Qt app themes may not update without these tools");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transparency Settings Section
|
// Transparency Settings Section
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ paru -S quickshell-git
|
|||||||
| matugen | Allows dynamic themes based on wallpaper | Just can choose from preconfigured themes instead of dynamic colors |
|
| matugen | Allows dynamic themes based on wallpaper | Just can choose from preconfigured themes instead of dynamic colors |
|
||||||
| ddcutil (or brightnessctl) | Allows controlling brightness of monitors | No Brightness |
|
| ddcutil (or brightnessctl) | Allows controlling brightness of monitors | No Brightness |
|
||||||
| wl-clipboard | Unlocks copy functionality of certain elements, such as process PIDs | No copy |
|
| wl-clipboard | Unlocks copy functionality of certain elements, such as process PIDs | No copy |
|
||||||
|
| qt5ct + qt6ct | Icon theme | Setting icon theme in settings won't work for QT5 or QT6 applications |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Arch
|
# Arch
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Rectangle {
|
|||||||
property string currentValue: ""
|
property string currentValue: ""
|
||||||
property var options: []
|
property var options: []
|
||||||
property var optionIcons: [] // Array of icon names corresponding to options
|
property var optionIcons: [] // Array of icon names corresponding to options
|
||||||
|
property bool forceRecreate: false
|
||||||
|
|
||||||
signal valueChanged(string value)
|
signal valueChanged(string value)
|
||||||
|
|
||||||
@@ -18,10 +19,36 @@ Rectangle {
|
|||||||
height: 60
|
height: 60
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceHover
|
color: Theme.surfaceHover
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
// Force a small delay to ensure proper initialization
|
||||||
|
forceRecreateTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: forceRecreateTimer
|
||||||
|
interval: 50
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
root.forceRecreate = !root.forceRecreate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
var popup = popupLoader.item;
|
||||||
|
if (popup && popup.visible) {
|
||||||
|
popup.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible && dropdownMenu.visible)
|
var popup = popupLoader.item;
|
||||||
dropdownMenu.close();
|
if (!visible && popup && popup.visible)
|
||||||
|
popup.close();
|
||||||
|
else if (visible) {
|
||||||
|
// Force recreate popup when component becomes visible
|
||||||
|
forceRecreateTimer.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -70,13 +97,14 @@ Rectangle {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (dropdownMenu.visible) {
|
var popup = popupLoader.item;
|
||||||
dropdownMenu.close();
|
if (popup && popup.visible) {
|
||||||
} else {
|
popup.close();
|
||||||
|
} else if (popup) {
|
||||||
var pos = dropdown.mapToItem(Overlay.overlay, 0, dropdown.height + 4);
|
var pos = dropdown.mapToItem(Overlay.overlay, 0, dropdown.height + 4);
|
||||||
dropdownMenu.x = pos.x;
|
popup.x = pos.x;
|
||||||
dropdownMenu.y = pos.y;
|
popup.y = pos.y;
|
||||||
dropdownMenu.open();
|
popup.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,15 +153,26 @@ Rectangle {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup {
|
Loader {
|
||||||
id: dropdownMenu
|
id: popupLoader
|
||||||
|
active: true
|
||||||
|
property bool recreateFlag: root.forceRecreate
|
||||||
|
onRecreateFlagChanged: {
|
||||||
|
// Force recreation by toggling active
|
||||||
|
active = false;
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: Component {
|
||||||
|
Popup {
|
||||||
|
id: dropdownMenu
|
||||||
|
|
||||||
parent: Overlay.overlay
|
parent: Overlay.overlay
|
||||||
width: 180
|
width: 180
|
||||||
height: Math.min(200, root.options.length * 36 + 16)
|
height: Math.min(200, root.options.length * 36 + 16)
|
||||||
padding: 0
|
padding: 0
|
||||||
modal: true
|
modal: true
|
||||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
@@ -212,7 +251,8 @@ Rectangle {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentValue = modelData;
|
root.currentValue = modelData;
|
||||||
root.valueChanged(modelData);
|
root.valueChanged(modelData);
|
||||||
dropdownMenu.close();
|
var popup = popupLoader.item;
|
||||||
|
if (popup) popup.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +261,9 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user