Merge branch 'main' of https://github.com/noctalia-dev/noctalia-shell
This commit is contained in:
commit
4520ed3cbf
12 changed files with 60 additions and 53 deletions
|
|
@ -26,7 +26,7 @@ Singleton {
|
||||||
property string defaultAvatar: Quickshell.env("HOME") + "/.face"
|
property string defaultAvatar: Quickshell.env("HOME") + "/.face"
|
||||||
|
|
||||||
// Used to access via Settings.data.xxx.yyy
|
// Used to access via Settings.data.xxx.yyy
|
||||||
property alias data: adapter
|
readonly property alias data: adapter
|
||||||
|
|
||||||
property bool isLoaded: false
|
property bool isLoaded: false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,10 @@ Loader {
|
||||||
margins {
|
margins {
|
||||||
top: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|
top: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|
||||||
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top"
|
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top"
|
||||||
&& Settings.data.bar.backgroundOpacity > 0 ? Math.floor(Style.barHeight * scaling) : 0
|
&& Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||||
bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|
bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|
||||||
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom"
|
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom"
|
||||||
&& Settings.data.bar.backgroundOpacity > 0 ? Math.floor(Style.barHeight * scaling) : 0
|
&& Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source we want to show only as a ring
|
// Source we want to show only as a ring
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ Rectangle {
|
||||||
|
|
||||||
// Anchor the menu to the tray icon item (parent) and position it below the icon
|
// Anchor the menu to the tray icon item (parent) and position it below the icon
|
||||||
const menuX = (width / 2) - (trayMenu.item.width / 2)
|
const menuX = (width / 2) - (trayMenu.item.width / 2)
|
||||||
const menuY = (Style.barHeight * scaling)
|
const menuY = Math.round(Style.barHeight * scaling)
|
||||||
trayMenu.item.menu = modelData.menu
|
trayMenu.item.menu = modelData.menu
|
||||||
trayMenu.item.showAt(parent, menuX, menuY)
|
trayMenu.item.showAt(parent, menuX, menuY)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ NPanel {
|
||||||
// Search bar
|
// Search bar
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Style.barHeight * scaling
|
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
|
||||||
Layout.bottomMargin: Style.marginM * scaling
|
Layout.bottomMargin: Style.marginM * scaling
|
||||||
radius: Style.radiusM * scaling
|
radius: Style.radiusM * scaling
|
||||||
color: Color.mSurface
|
color: Color.mSurface
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ ColumnLayout {
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.topMargin: Style.marginS * scaling
|
Layout.topMargin: Style.marginS * scaling
|
||||||
Layout.preferredWidth: updateText.implicitWidth + 46 * scaling
|
Layout.preferredWidth: updateText.implicitWidth + 46 * scaling
|
||||||
Layout.preferredHeight: Style.barHeight * scaling
|
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
|
||||||
radius: Style.radiusL * scaling
|
radius: Style.radiusL * scaling
|
||||||
color: updateArea.containsMouse ? Color.mPrimary : Color.transparent
|
color: updateArea.containsMouse ? Color.mPrimary : Color.transparent
|
||||||
border.color: Color.mPrimary
|
border.color: Color.mPrimary
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ ColumnLayout {
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "Automatic Scheduling"
|
label: "Automatic Scheduling"
|
||||||
description: `Based on the sunset and sunrise time in <i>${LocationService.data.stableName}</i> - recommended.`
|
description: `Based on the sunset and sunrise time in <i>${LocationService.stableName}</i> - recommended.`
|
||||||
checked: Settings.data.nightLight.autoSchedule
|
checked: Settings.data.nightLight.autoSchedule
|
||||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||||
visible: Settings.data.nightLight.enabled
|
visible: Settings.data.nightLight.enabled
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
visible: LocationService.data.coordinatesReady
|
visible: LocationService.coordinatesReady
|
||||||
text: `${LocationService.data.stableName} (${LocationService.displayCoordinates})`
|
text: `${LocationService.stableName} (${LocationService.displayCoordinates})`
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
color: Color.mOnSurfaceVariant
|
color: Color.mOnSurfaceVariant
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ NPanel {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Style.barHeight * scaling
|
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -313,7 +313,7 @@ NPanel {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.preferredWidth: Style.baseWidgetSize * 2.5 * scaling
|
Layout.preferredWidth: Style.baseWidgetSize * 2.5 * scaling
|
||||||
Layout.preferredHeight: Style.barHeight * scaling
|
Layout.preferredHeight: Math.round(Style.barHeight * scaling)
|
||||||
radius: Style.radiusM * scaling
|
radius: Style.radiusM * scaling
|
||||||
color: Color.mPrimary
|
color: Color.mPrimary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ Singleton {
|
||||||
property string githubDataFile: Quickshell.env("NOCTALIA_GITHUB_FILE") || (Settings.cacheDir + "github.json")
|
property string githubDataFile: Quickshell.env("NOCTALIA_GITHUB_FILE") || (Settings.cacheDir + "github.json")
|
||||||
property int githubUpdateFrequency: 60 * 60 // 1 hour expressed in seconds
|
property int githubUpdateFrequency: 60 * 60 // 1 hour expressed in seconds
|
||||||
property bool isFetchingData: false
|
property bool isFetchingData: false
|
||||||
property alias data: adapter // Used to access via GitHubService.data.xxx.yyy
|
readonly property alias data: adapter // Used to access via GitHubService.data.xxx.yyy
|
||||||
|
|
||||||
// Public properties for easy access
|
// Public properties for easy access
|
||||||
property string latestVersion: "Unknown"
|
property string latestVersion: "Unknown"
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,28 @@ Singleton {
|
||||||
property string locationFile: Quickshell.env("NOCTALIA_WEATHER_FILE") || (Settings.cacheDir + "location.json")
|
property string locationFile: Quickshell.env("NOCTALIA_WEATHER_FILE") || (Settings.cacheDir + "location.json")
|
||||||
property int weatherUpdateFrequency: 30 * 60 // 30 minutes expressed in seconds
|
property int weatherUpdateFrequency: 30 * 60 // 30 minutes expressed in seconds
|
||||||
property bool isFetchingWeather: false
|
property bool isFetchingWeather: false
|
||||||
property alias data: adapter // Used to access via LocationService.data.xxx
|
|
||||||
|
readonly property alias data: adapter // Used to access via LocationService.data.xxx from outside, best to use "adapter" inside the service.
|
||||||
|
|
||||||
|
// Stable UI properties - only updated when location is fully resolved
|
||||||
|
property bool coordinatesReady: false
|
||||||
|
property string stableLatitude: ""
|
||||||
|
property string stableLongitude: ""
|
||||||
|
property string stableName: ""
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
id: locationFileView
|
id: locationFileView
|
||||||
path: locationFile
|
path: locationFile
|
||||||
onAdapterUpdated: saveTimer.start()
|
onAdapterUpdated: saveTimer.start()
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
|
Logger.log("Location", "Loaded cached data")
|
||||||
// Initialize stable properties on load
|
// Initialize stable properties on load
|
||||||
if (adapter.latitude !== "" && adapter.longitude !== "" && adapter.weatherLastFetch > 0) {
|
if (adapter.latitude !== "" && adapter.longitude !== "" && adapter.weatherLastFetch > 0) {
|
||||||
adapter.stableLatitude = adapter.latitude
|
root.stableLatitude = adapter.latitude
|
||||||
adapter.stableLongitude = adapter.longitude
|
root.stableLongitude = adapter.longitude
|
||||||
adapter.coordinatesReady = true
|
root.stableName = adapter.name
|
||||||
|
root.coordinatesReady = true
|
||||||
|
Logger.log("Location", "Coordinates ready")
|
||||||
}
|
}
|
||||||
updateWeather()
|
updateWeather()
|
||||||
}
|
}
|
||||||
|
|
@ -42,21 +52,17 @@ Singleton {
|
||||||
property int weatherLastFetch: 0
|
property int weatherLastFetch: 0
|
||||||
property var weather: null
|
property var weather: null
|
||||||
|
|
||||||
// Stable UI properties - only updated when location is fully resolved
|
|
||||||
property bool coordinatesReady: false
|
|
||||||
property string stableLatitude: ""
|
|
||||||
property string stableLongitude: ""
|
|
||||||
property string stableName: ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper property for UI components (outside JsonAdapter to avoid binding loops)
|
// Helper property for UI components (outside JsonAdapter to avoid binding loops)
|
||||||
readonly property string displayCoordinates: {
|
readonly property string displayCoordinates: {
|
||||||
if (!data.coordinatesReady || data.stableLatitude === "" || data.stableLongitude === "") {
|
if (!root.coordinatesReady || root.stableLatitude === "" || root.stableLongitude === "") {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
const lat = parseFloat(data.stableLatitude).toFixed(4)
|
const lat = parseFloat(root.stableLatitude).toFixed(4)
|
||||||
const lon = parseFloat(data.stableLongitude).toFixed(4)
|
const lon = parseFloat(root.stableLongitude).toFixed(4)
|
||||||
return `${lat}, ${lon}`
|
return `${lat}, ${lon}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,19 +96,18 @@ Singleton {
|
||||||
Logger.log("Location", "Resetting weather data")
|
Logger.log("Location", "Resetting weather data")
|
||||||
|
|
||||||
// Mark as changing to prevent UI updates
|
// Mark as changing to prevent UI updates
|
||||||
data.coordinatesReady = false
|
root.coordinatesReady = false
|
||||||
|
// Reset stable properties
|
||||||
|
root.stableLatitude = ""
|
||||||
|
root.stableLongitude = ""
|
||||||
|
root.stableName = ""
|
||||||
|
|
||||||
// Reset core data
|
// Reset core data
|
||||||
data.latitude = ""
|
adapter.latitude = ""
|
||||||
data.longitude = ""
|
adapter.longitude = ""
|
||||||
data.name = ""
|
adapter.name = ""
|
||||||
data.weatherLastFetch = 0
|
adapter.weatherLastFetch = 0
|
||||||
data.weather = null
|
adapter.weather = null
|
||||||
|
|
||||||
// Reset stable properties
|
|
||||||
data.stableLatitude = ""
|
|
||||||
data.stableLongitude = ""
|
|
||||||
data.stableName = ""
|
|
||||||
|
|
||||||
// Try to fetch immediately
|
// Try to fetch immediately
|
||||||
updateWeather()
|
updateWeather()
|
||||||
|
|
@ -115,9 +120,9 @@ Singleton {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data.weatherLastFetch === "") || (data.weather === null) || (data.latitude === "") || (data.longitude === "")
|
if ((adapter.weatherLastFetch === "") || (adapter.weather === null) || (adapter.latitude === "") || (adapter.longitude === "")
|
||||||
|| (data.name !== Settings.data.location.name)
|
|| (adapter.name !== Settings.data.location.name)
|
||||||
|| (Time.timestamp >= data.weatherLastFetch + weatherUpdateFrequency)) {
|
|| (Time.timestamp >= adapter.weatherLastFetch + weatherUpdateFrequency)) {
|
||||||
getFreshWeather()
|
getFreshWeather()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,28 +134,28 @@ Singleton {
|
||||||
// Check if location name has changed
|
// Check if location name has changed
|
||||||
const locationChanged = data.name !== Settings.data.location.name
|
const locationChanged = data.name !== Settings.data.location.name
|
||||||
if (locationChanged) {
|
if (locationChanged) {
|
||||||
data.coordinatesReady = false
|
root.coordinatesReady = false
|
||||||
Logger.log("Location", "Location changed from", data.name, "to", Settings.data.location.name)
|
Logger.log("Location", "Location changed from", adapter.name, "to", Settings.data.location.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data.latitude === "") || (data.longitude === "") || locationChanged) {
|
if ((adapter.latitude === "") || (adapter.longitude === "") || locationChanged) {
|
||||||
|
|
||||||
_geocodeLocation(Settings.data.location.name, function (latitude, longitude, name, country) {
|
_geocodeLocation(Settings.data.location.name, function (latitude, longitude, name, country) {
|
||||||
Logger.log("Location", "Geocoded", Settings.data.location.name, "to:", latitude, "/", longitude)
|
Logger.log("Location", "Geocoded", Settings.data.location.name, "to:", latitude, "/", longitude)
|
||||||
|
|
||||||
// Save location name
|
// Save location name
|
||||||
data.name = Settings.data.location.name
|
adapter.name = Settings.data.location.name
|
||||||
|
|
||||||
// Save GPS coordinates
|
// Save GPS coordinates
|
||||||
data.latitude = latitude.toString()
|
adapter.latitude = latitude.toString()
|
||||||
data.longitude = longitude.toString()
|
adapter.longitude = longitude.toString()
|
||||||
|
|
||||||
data.stableName = `${name}, ${country}`
|
root.stableName = `${name}, ${country}`
|
||||||
|
|
||||||
_fetchWeather(latitude, longitude, errorCallback)
|
_fetchWeather(latitude, longitude, errorCallback)
|
||||||
}, errorCallback)
|
}, errorCallback)
|
||||||
} else {
|
} else {
|
||||||
_fetchWeather(data.latitude, data.longitude, errorCallback)
|
_fetchWeather(adapter.latitude, adapter.longitude, errorCallback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,9 +205,9 @@ Singleton {
|
||||||
data.weatherLastFetch = Time.timestamp
|
data.weatherLastFetch = Time.timestamp
|
||||||
|
|
||||||
// Update stable display values only when complete and successful
|
// Update stable display values only when complete and successful
|
||||||
data.stableLatitude = data.latitude = weatherData.latitude.toString()
|
root.stableLatitude = data.latitude = weatherData.latitude.toString()
|
||||||
data.stableLongitude = data.longitude = weatherData.longitude.toString()
|
root.stableLongitude = data.longitude = weatherData.longitude.toString()
|
||||||
data.coordinatesReady = true
|
root.coordinatesReady = true
|
||||||
|
|
||||||
isFetchingWeather = false
|
isFetchingWeather = false
|
||||||
Logger.log("Location", "Cached weather to disk - stable coordinates updated")
|
Logger.log("Location", "Cached weather to disk - stable coordinates updated")
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ Singleton {
|
||||||
var cmd = ["wlsunset"]
|
var cmd = ["wlsunset"]
|
||||||
cmd.push("-t", `${params.nightTemp}`, "-T", `${params.dayTemp}`)
|
cmd.push("-t", `${params.nightTemp}`, "-T", `${params.dayTemp}`)
|
||||||
if (params.autoSchedule) {
|
if (params.autoSchedule) {
|
||||||
cmd.push("-l", `${LocationService.data.stableLatitude}`, "-L", `${LocationService.data.stableLongitude}`)
|
cmd.push("-l", `${LocationService.stableLatitude}`, "-L", `${LocationService.stableLongitude}`)
|
||||||
} else {
|
} else {
|
||||||
cmd.push("-S", params.manualSunrise)
|
cmd.push("-S", params.manualSunrise)
|
||||||
cmd.push("-s", params.manualSunset)
|
cmd.push("-s", params.manualSunset)
|
||||||
|
|
@ -55,11 +55,13 @@ Singleton {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: LocationService.data
|
target: LocationService
|
||||||
function onCoordinatesReadyChanged() {
|
function onCoordinatesReadyChanged() {
|
||||||
|
if (LocationService.coordinatesReady) {
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Foreground process runner
|
// Foreground process runner
|
||||||
Process {
|
Process {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ Loader {
|
||||||
property real opacityValue: originalOpacity
|
property real opacityValue: originalOpacity
|
||||||
|
|
||||||
property alias isClosing: hideTimer.running
|
property alias isClosing: hideTimer.running
|
||||||
readonly property real barHeight: Style.barHeight * scaling
|
readonly property real barHeight: Math.round(Style.barHeight * scaling)
|
||||||
readonly property bool barAtBottom: Settings.data.bar.position === "bottom"
|
readonly property bool barAtBottom: Settings.data.bar.position === "bottom"
|
||||||
|
|
||||||
signal opened
|
signal opened
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue