From b9e9da579f38ff952e6388d825f1b4524abfc8ef Mon Sep 17 00:00:00 2001 From: bbedward Date: Fri, 27 Feb 2026 22:37:10 -0500 Subject: [PATCH] weather: fix fallback temporarily --- core/internal/geolocation/client.go | 19 +++++-- core/internal/geolocation/client_geoclue.go | 7 +++ core/internal/geolocation/client_ip.go | 4 +- core/internal/server/location/manager.go | 5 +- quickshell/Services/LocationService.qml | 62 ++++++++++++++++++--- quickshell/Services/WeatherService.qml | 10 +++- 6 files changed, 86 insertions(+), 21 deletions(-) diff --git a/core/internal/geolocation/client.go b/core/internal/geolocation/client.go index a37ebd44..b5d03077 100644 --- a/core/internal/geolocation/client.go +++ b/core/internal/geolocation/client.go @@ -3,12 +3,23 @@ package geolocation import "github.com/AvengeMedia/DankMaterialShell/core/internal/log" func NewClient() Client { - if geoclueClient, err := newGeoClueClient(); err != nil { + geoclueClient, err := newGeoClueClient() + if err != nil { log.Warnf("Failed to initialize GeoClue2 client: %v", err) - } else { + log.Info("Falling back to IP location") + return newIpClient() + } + + loc, _ := geoclueClient.GetLocation() + if loc.Latitude != 0 || loc.Longitude != 0 { return geoclueClient } - log.Info("Falling back to IP location") - return newIpClient() + log.Info("GeoClue2 has no fix yet, seeding with IP location") + ipClient := newIpClient() + if ipLoc, err := ipClient.GetLocation(); err == nil { + geoclueClient.SeedLocation(ipLoc) + } + + return geoclueClient } diff --git a/core/internal/geolocation/client_geoclue.go b/core/internal/geolocation/client_geoclue.go index 3d3bb64e..a06aadf4 100644 --- a/core/internal/geolocation/client_geoclue.go +++ b/core/internal/geolocation/client_geoclue.go @@ -222,6 +222,13 @@ func (c *GeoClueClient) notifySubscribers() { }) } +func (c *GeoClueClient) SeedLocation(loc Location) { + c.locationMutex.Lock() + defer c.locationMutex.Unlock() + c.currLocation.Latitude = loc.Latitude + c.currLocation.Longitude = loc.Longitude +} + func (c *GeoClueClient) GetLocation() (Location, error) { c.locationMutex.RLock() defer c.locationMutex.RUnlock() diff --git a/core/internal/geolocation/client_ip.go b/core/internal/geolocation/client_ip.go index 2736a2db..cc62bcd5 100644 --- a/core/internal/geolocation/client_ip.go +++ b/core/internal/geolocation/client_ip.go @@ -31,10 +31,8 @@ func newIpClient() *IpClient { func (c *IpClient) Subscribe(id string) chan Location { ch := make(chan Location, 1) - if location, err := c.GetLocation(); err != nil { + if location, err := c.GetLocation(); err == nil { ch <- location - } else { - close(ch) } return ch diff --git a/core/internal/server/location/manager.go b/core/internal/server/location/manager.go index 8866c1d0..24bcd957 100644 --- a/core/internal/server/location/manager.go +++ b/core/internal/server/location/manager.go @@ -14,8 +14,9 @@ func NewManager(client geolocation.Client) (*Manager, error) { } m := &Manager{ - client: client, - dirty: make(chan struct{}), + client: client, + dirty: make(chan struct{}), + stopChan: make(chan struct{}), state: &State{ Latitude: currLocation.Latitude, diff --git a/quickshell/Services/LocationService.qml b/quickshell/Services/LocationService.qml index 41345f40..281b9d0e 100644 --- a/quickshell/Services/LocationService.qml +++ b/quickshell/Services/LocationService.qml @@ -10,14 +10,17 @@ Singleton { id: root readonly property bool locationAvailable: DMSService.isConnected && (DMSService.capabilities.length === 0 || DMSService.capabilities.includes("location")) + readonly property bool valid: latitude !== 0 || longitude !== 0 property var latitude: 0.0 property var longitude: 0.0 signal locationChanged(var data) + readonly property var lowPriorityCmd: ["nice", "-n", "19", "ionice", "-c3"] + readonly property var curlBaseCmd: ["curl", "-sS", "--fail", "--connect-timeout", "3", "--max-time", "6", "--limit-rate", "100k", "--compressed"] + Component.onCompleted: { - console.info("LocationService: Initializing..."); getState(); } @@ -25,27 +28,68 @@ Singleton { target: DMSService function onLocationStateUpdate(data) { - if (locationAvailable) { - handleStateUpdate(data); - } + if (!locationAvailable) + return; + handleStateUpdate(data); } } function handleStateUpdate(data) { - root.latitude = data.latitude; - root.longitude = data.longitude; + const lat = data.latitude; + const lon = data.longitude; + if (lat === 0 && lon === 0) + return; - root.locationChanged(data) + root.latitude = lat; + root.longitude = lon; + root.locationChanged(data); } function getState() { - if (!locationAvailable) + if (!locationAvailable) { + fetchIPLocation(); return; + } DMSService.sendRequest("location.getState", null, response => { - if (response.result) { + if (response.result && (response.result.latitude !== 0 || response.result.longitude !== 0)) { handleStateUpdate(response.result); + return; } + fetchIPLocation(); }); } + + function fetchIPLocation() { + if (root.valid) + return; + ipLocationFetcher.running = true; + } + + Process { + id: ipLocationFetcher + command: root.lowPriorityCmd.concat(root.curlBaseCmd).concat(["http://ip-api.com/json/"]) + running: false + + stdout: StdioCollector { + onStreamFinished: { + const raw = text.trim(); + if (!raw || raw[0] !== "{") + return; + + try { + const data = JSON.parse(raw); + if (data.status === "fail") + return; + + const lat = parseFloat(data.lat); + const lon = parseFloat(data.lon); + if (isNaN(lat) || isNaN(lon) || (lat === 0 && lon === 0)) + return; + + root.handleStateUpdate({ latitude: lat, longitude: lon }); + } catch (e) {} + } + } + } } diff --git a/quickshell/Services/WeatherService.qml b/quickshell/Services/WeatherService.qml index c76ffd3f..134789ea 100644 --- a/quickshell/Services/WeatherService.qml +++ b/quickshell/Services/WeatherService.qml @@ -512,6 +512,8 @@ Singleton { } function getLocationFromService() { + if (!LocationService.valid) + return; getLocationFromCoords(LocationService.latitude, LocationService.longitude); } @@ -829,9 +831,11 @@ Singleton { target: LocationService function onLocationChanged(data) { - if (SettingsData.useAutoLocation) { - root.getLocationFromCoords(data.latitude, data.longitude) - } + if (!SettingsData.useAutoLocation) + return; + if (data.latitude === 0 && data.longitude === 0) + return; + root.getLocationFromCoords(data.latitude, data.longitude); } }