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

Compare commits

...

5 Commits

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

* fix: typo in change unit button
2025-11-21 21:41:12 -05:00
bbedward
f8dc6ad2bc update CONTRIBUTING 2025-11-21 17:30:54 -05:00
bbedward
e22482988f weather: fix display when 0 temp
fixes #782
2025-11-21 17:06:57 -05:00
8 changed files with 129 additions and 120 deletions

View File

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

View File

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

View File

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

View File

@@ -37,10 +37,10 @@ BasePill {
StyledText {
text: {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
if (temp === undefined || temp === null || temp === 0) {
if (!WeatherService.weather.available) {
return "--";
}
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
@@ -64,11 +64,10 @@ BasePill {
StyledText {
text: {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
if (temp === undefined || temp === null || temp === 0) {
if (!WeatherService.weather.available) {
return "--°" + (SettingsData.useFahrenheit ? "F" : "C");
}
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
}
font.pixelSize: Theme.barTextSize(root.barThickness)

View File

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

View File

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

View File

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

View File

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