mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
integrate light/dark mode and profile image with desktop portal
This commit is contained in:
@@ -22,7 +22,6 @@ Singleton {
|
||||
property bool use24HourClock: true
|
||||
property bool useFahrenheit: false
|
||||
property bool nightModeEnabled: false
|
||||
property string profileImage: ""
|
||||
property string weatherLocation: "New York, NY"
|
||||
property string weatherCoordinates: "40.7128,-74.0060"
|
||||
property bool useAutoLocation: false
|
||||
@@ -147,7 +146,6 @@ Singleton {
|
||||
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true;
|
||||
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false;
|
||||
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false;
|
||||
profileImage = settings.profileImage !== undefined ? settings.profileImage : "";
|
||||
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY";
|
||||
weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060";
|
||||
useAutoLocation = settings.useAutoLocation !== undefined ? settings.useAutoLocation : false;
|
||||
@@ -229,7 +227,6 @@ Singleton {
|
||||
"use24HourClock": use24HourClock,
|
||||
"useFahrenheit": useFahrenheit,
|
||||
"nightModeEnabled": nightModeEnabled,
|
||||
"profileImage": profileImage,
|
||||
"weatherLocation": weatherLocation,
|
||||
"weatherCoordinates": weatherCoordinates,
|
||||
"useAutoLocation": useAutoLocation,
|
||||
@@ -421,10 +418,6 @@ Singleton {
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
function setProfileImage(imageUrl) {
|
||||
profileImage = imageUrl;
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
// Widget visibility setters
|
||||
function setShowLauncherButton(enabled) {
|
||||
|
||||
@@ -151,13 +151,13 @@ PanelWindow {
|
||||
id: profileImageLoader
|
||||
|
||||
source: {
|
||||
if (Prefs.profileImage === "")
|
||||
if (PortalService.profileImage === "")
|
||||
return "";
|
||||
|
||||
if (Prefs.profileImage.startsWith("/"))
|
||||
return "file://" + Prefs.profileImage;
|
||||
if (PortalService.profileImage.startsWith("/"))
|
||||
return "file://" + PortalService.profileImage;
|
||||
|
||||
return Prefs.profileImage;
|
||||
return PortalService.profileImage;
|
||||
}
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
@@ -215,7 +215,7 @@ PanelWindow {
|
||||
name: "warning"
|
||||
size: Theme.iconSize + 8
|
||||
color: Theme.primaryText
|
||||
visible: Prefs.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||
visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||
}
|
||||
|
||||
}
|
||||
@@ -743,8 +743,7 @@ PanelWindow {
|
||||
description: "Use light theme instead of dark theme"
|
||||
checked: Prefs.isLightMode
|
||||
onToggled: (checked) => {
|
||||
Prefs.setLightMode(checked);
|
||||
Theme.isLightMode = checked;
|
||||
PortalService.setLightMode(checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,11 +167,11 @@ Item {
|
||||
Image {
|
||||
id: profileImageLoader
|
||||
source: {
|
||||
if (Prefs.profileImage === "")
|
||||
if (PortalService.profileImage === "")
|
||||
return ""
|
||||
if (Prefs.profileImage.startsWith("/"))
|
||||
return "file://" + Prefs.profileImage
|
||||
return Prefs.profileImage
|
||||
if (PortalService.profileImage.startsWith("/"))
|
||||
return "file://" + PortalService.profileImage
|
||||
return PortalService.profileImage
|
||||
}
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
@@ -226,7 +226,7 @@ Item {
|
||||
name: "warning"
|
||||
size: Theme.iconSize + 4
|
||||
color: Theme.primaryText
|
||||
visible: Prefs.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||
visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,7 @@ ScrollView {
|
||||
description: "Use light theme instead of dark theme"
|
||||
checked: Prefs.isLightMode
|
||||
onToggled: (checked) => {
|
||||
Prefs.setLightMode(checked);
|
||||
Theme.isLightMode = checked;
|
||||
PortalService.setLightMode(checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,13 +83,13 @@ ScrollView {
|
||||
id: avatarImageSource
|
||||
|
||||
source: {
|
||||
if (Prefs.profileImage === "")
|
||||
if (PortalService.profileImage === "")
|
||||
return "";
|
||||
|
||||
if (Prefs.profileImage.startsWith("/"))
|
||||
return "file://" + Prefs.profileImage;
|
||||
if (PortalService.profileImage.startsWith("/"))
|
||||
return "file://" + PortalService.profileImage;
|
||||
|
||||
return Prefs.profileImage;
|
||||
return PortalService.profileImage;
|
||||
}
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
@@ -147,7 +147,7 @@ ScrollView {
|
||||
name: "warning"
|
||||
size: Theme.iconSizeLarge
|
||||
color: Theme.error
|
||||
visible: Prefs.profileImage !== "" && avatarImageSource.status === Image.Error
|
||||
visible: PortalService.profileImage !== "" && avatarImageSource.status === Image.Error
|
||||
}
|
||||
|
||||
}
|
||||
@@ -158,7 +158,7 @@ ScrollView {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
text: Prefs.profileImage ? Prefs.profileImage.split('/').pop() : "No profile image selected"
|
||||
text: PortalService.profileImage ? PortalService.profileImage.split('/').pop() : "No profile image selected"
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.surfaceText
|
||||
elide: Text.ElideMiddle
|
||||
@@ -166,12 +166,32 @@ ScrollView {
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: Prefs.profileImage ? Prefs.profileImage : ""
|
||||
text: PortalService.profileImage ? PortalService.profileImage : ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
elide: Text.ElideMiddle
|
||||
width: parent.width
|
||||
visible: Prefs.profileImage !== ""
|
||||
visible: PortalService.profileImage !== ""
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingXS
|
||||
visible: !PortalService.accountsServiceAvailable
|
||||
|
||||
DankIcon {
|
||||
name: "error"
|
||||
size: Theme.iconSizeSmall
|
||||
color: Theme.error
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "xdg-desktop-portal-gtk missing"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.error
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Row {
|
||||
@@ -214,12 +234,13 @@ ScrollView {
|
||||
|
||||
}
|
||||
|
||||
|
||||
StyledRect {
|
||||
width: 80
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceVariant
|
||||
opacity: Prefs.profileImage !== "" ? 1 : 0.5
|
||||
opacity: PortalService.profileImage !== "" ? 1 : 0.5
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
@@ -243,10 +264,10 @@ ScrollView {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: Prefs.profileImage !== ""
|
||||
enabled: PortalService.profileImage !== ""
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
Prefs.setProfileImage("");
|
||||
PortalService.setProfileImage("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +572,7 @@ ScrollView {
|
||||
browserType: "profile"
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: (path) => {
|
||||
Prefs.setProfileImage(path);
|
||||
PortalService.setProfileImage(path);
|
||||
visible = false;
|
||||
}
|
||||
onDialogClosed: {}
|
||||
|
||||
186
Services/PortalService.qml
Normal file
186
Services/PortalService.qml
Normal file
@@ -0,0 +1,186 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool accountsServiceAvailable: false
|
||||
property string systemProfileImage: ""
|
||||
property string profileImage: ""
|
||||
property bool settingsPortalAvailable: false
|
||||
property int systemColorScheme: 0 // 0=default, 1=prefer-dark, 2=prefer-light
|
||||
|
||||
function getSystemProfileImage() {
|
||||
systemProfileCheckProcess.running = true
|
||||
}
|
||||
|
||||
function setProfileImage(imagePath) {
|
||||
profileImage = imagePath
|
||||
if (accountsServiceAvailable && imagePath) {
|
||||
setSystemProfileImage(imagePath)
|
||||
}
|
||||
}
|
||||
|
||||
function getSystemColorScheme() {
|
||||
systemColorSchemeCheckProcess.running = true
|
||||
}
|
||||
|
||||
function setLightMode(isLightMode) {
|
||||
if (typeof Theme !== "undefined") {
|
||||
Theme.isLightMode = isLightMode
|
||||
}
|
||||
if (typeof Prefs !== "undefined") {
|
||||
Prefs.setLightMode(isLightMode)
|
||||
}
|
||||
if (settingsPortalAvailable) {
|
||||
setSystemColorScheme(isLightMode)
|
||||
}
|
||||
}
|
||||
|
||||
function setSystemColorScheme(isLightMode) {
|
||||
if (!settingsPortalAvailable) return
|
||||
|
||||
var colorScheme = isLightMode ? "prefer-light" : "prefer-dark"
|
||||
var script = "gsettings set org.gnome.desktop.interface color-scheme '" + colorScheme + "'"
|
||||
|
||||
systemColorSchemeSetProcess.command = ["bash", "-c", script]
|
||||
systemColorSchemeSetProcess.running = true
|
||||
}
|
||||
|
||||
function setSystemProfileImage(imagePath) {
|
||||
if (!accountsServiceAvailable || !imagePath) return
|
||||
|
||||
var script = [
|
||||
"dbus-send --system --print-reply --dest=org.freedesktop.Accounts",
|
||||
"/org/freedesktop/Accounts/User$(id -u)",
|
||||
"org.freedesktop.Accounts.User.SetIconFile",
|
||||
"string:'" + imagePath + "'"
|
||||
].join(" ")
|
||||
|
||||
systemProfileSetProcess.command = ["bash", "-c", script]
|
||||
systemProfileSetProcess.running = true
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
checkAccountsService()
|
||||
checkSettingsPortal()
|
||||
}
|
||||
|
||||
function checkAccountsService() {
|
||||
accountsServiceCheckProcess.running = true
|
||||
}
|
||||
|
||||
function checkSettingsPortal() {
|
||||
settingsPortalCheckProcess.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: accountsServiceCheckProcess
|
||||
command: ["bash", "-c", "dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts.FindUserByName string:\"$USER\""]
|
||||
running: false
|
||||
|
||||
onExited: (exitCode) => {
|
||||
root.accountsServiceAvailable = (exitCode === 0)
|
||||
if (root.accountsServiceAvailable) {
|
||||
root.getSystemProfileImage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: systemProfileCheckProcess
|
||||
command: ["bash", "-c", "dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts/User$(id -u) org.freedesktop.DBus.Properties.Get string:org.freedesktop.Accounts.User string:IconFile"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var match = text.match(/string\s+"([^"]+)"/)
|
||||
if (match && match[1] && match[1] !== "" && match[1] !== "/var/lib/AccountsService/icons/") {
|
||||
root.systemProfileImage = match[1]
|
||||
|
||||
if (!root.profileImage || root.profileImage === "") {
|
||||
root.profileImage = root.systemProfileImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: (exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
root.systemProfileImage = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: systemProfileSetProcess
|
||||
running: false
|
||||
|
||||
onExited: (exitCode) => {
|
||||
if (exitCode === 0) {
|
||||
root.getSystemProfileImage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: settingsPortalCheckProcess
|
||||
command: ["gdbus", "call", "--session", "--dest", "org.freedesktop.portal.Desktop", "--object-path", "/org/freedesktop/portal/desktop", "--method", "org.freedesktop.portal.Settings.ReadOne", "org.freedesktop.appearance", "color-scheme"]
|
||||
running: false
|
||||
|
||||
onExited: (exitCode) => {
|
||||
root.settingsPortalAvailable = (exitCode === 0)
|
||||
if (root.settingsPortalAvailable) {
|
||||
root.getSystemColorScheme()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: systemColorSchemeCheckProcess
|
||||
command: ["gdbus", "call", "--session", "--dest", "org.freedesktop.portal.Desktop", "--object-path", "/org/freedesktop/portal/desktop", "--method", "org.freedesktop.portal.Settings.ReadOne", "org.freedesktop.appearance", "color-scheme"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var match = text.match(/uint32 (\d+)/)
|
||||
if (match && match[1]) {
|
||||
root.systemColorScheme = parseInt(match[1])
|
||||
|
||||
if (typeof Theme !== "undefined") {
|
||||
var shouldBeLightMode = (root.systemColorScheme === 2)
|
||||
if (Theme.isLightMode !== shouldBeLightMode) {
|
||||
Theme.isLightMode = shouldBeLightMode
|
||||
if (typeof Prefs !== "undefined") {
|
||||
Prefs.setLightMode(shouldBeLightMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: (exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
root.systemColorScheme = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: systemColorSchemeSetProcess
|
||||
running: false
|
||||
|
||||
onExited: (exitCode) => {
|
||||
if (exitCode === 0) {
|
||||
Qt.callLater(() => {
|
||||
root.getSystemColorScheme()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user