From 22b4dda3aab46956c67daa2ac266383384fc7c05 Mon Sep 17 00:00:00 2001
From: Jaylyn Barbee <51131738+Jaylyn-Barbee@users.noreply.github.com>
Date: Mon, 2 Mar 2026 15:26:31 -0500
Subject: [PATCH] [Light Switch] Add 10s timeout and pre-check for location
detection (#45887)
- Add 10-second timeout to GetGeopositionAsync to prevent infinite
spinner
- Pre-check location services availability when dialog opens; disable
Detect Location button with message if unavailable
- Show user-friendly error messages for timeout and unavailable
scenarios
- Add LocationErrorText UI element and localized string resources
## PR Checklist
- [x] Closes: #45860
- [x] Closes: #42852
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../SettingsXAML/Views/LightSwitchPage.xaml | 6 +++
.../Views/LightSwitchPage.xaml.cs | 49 +++++++++++++++----
.../Settings.UI/Strings/en-us/Resources.resw | 6 +++
3 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml
index 6941258e06..a532cf18dd 100644
--- a/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml
+++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/LightSwitchPage.xaml
@@ -376,6 +376,12 @@
VerticalAlignment="Center"
IsActive="False"
Visibility="Collapsed" />
+
sendConfigMsg = ShellPage.SendDefaultIPCMessage;
@@ -101,6 +104,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
this.SyncLoader.IsActive = true;
this.SyncLoader.Visibility = Visibility.Visible;
this.LocationResultPanel.Visibility = Visibility.Collapsed;
+ this.LocationErrorText.Visibility = Visibility.Collapsed;
try
{
@@ -108,13 +112,15 @@ namespace Microsoft.PowerToys.Settings.UI.Views
var accessStatus = await Geolocator.RequestAccessAsync();
if (accessStatus != GeolocationAccessStatus.Allowed)
{
- // User denied location or it's not available
+ ShowLocationError(ResourceLoaderInstance.ResourceLoader.GetString("LightSwitch_LocationError_Unavailable"));
return;
}
var geolocator = new Geolocator { DesiredAccuracy = PositionAccuracy.Default };
- Geoposition pos = await geolocator.GetGeopositionAsync();
+ using var cts = new CancellationTokenSource(GeoLocationTimeout);
+ var positionTask = geolocator.GetGeopositionAsync().AsTask(cts.Token);
+ Geoposition pos = await positionTask;
double latitude = Math.Round(pos.Coordinate.Point.Position.Latitude);
double longitude = Math.Round(pos.Coordinate.Point.Position.Longitude);
@@ -130,7 +136,6 @@ namespace Microsoft.PowerToys.Settings.UI.Views
// Since we use this mode, we can remove the selected city data.
this.ViewModel.SelectedCity = null;
- // ViewModel.CityTimesText = $"Sunrise: {result.SunriseHour}:{result.SunriseMinute:D2}\n" + $"Sunset: {result.SunsetHour}:{result.SunsetMinute:D2}";
this.SyncButton.IsEnabled = true;
this.SyncLoader.IsActive = false;
this.SyncLoader.Visibility = Visibility.Collapsed;
@@ -139,18 +144,29 @@ namespace Microsoft.PowerToys.Settings.UI.Views
this.LongitudeBox.IsEnabled = true;
this.LocationResultPanel.Visibility = Visibility.Visible;
}
+ catch (OperationCanceledException)
+ {
+ ShowLocationError(ResourceLoaderInstance.ResourceLoader.GetString("LightSwitch_LocationError_Timeout"));
+ }
catch (Exception ex)
{
- this.SyncButton.IsEnabled = true;
- this.SyncLoader.IsActive = false;
- this.SyncLoader.Visibility = Visibility.Collapsed;
- this.LocationResultPanel.Visibility = Visibility.Collapsed;
- this.LatitudeBox.IsEnabled = true;
- this.LongitudeBox.IsEnabled = true;
+ ShowLocationError(ResourceLoaderInstance.ResourceLoader.GetString("LightSwitch_LocationError_Timeout"));
Logger.LogInfo($"Location error: " + ex.Message);
}
}
+ private void ShowLocationError(string message)
+ {
+ this.SyncButton.IsEnabled = true;
+ this.SyncLoader.IsActive = false;
+ this.SyncLoader.Visibility = Visibility.Collapsed;
+ this.LocationResultPanel.Visibility = Visibility.Collapsed;
+ this.LatitudeBox.IsEnabled = true;
+ this.LongitudeBox.IsEnabled = true;
+ this.LocationErrorText.Text = message;
+ this.LocationErrorText.Visibility = Visibility.Visible;
+ }
+
private void LatLonBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
{
double latitude = this.LatitudeBox.Value;
@@ -301,6 +317,21 @@ namespace Microsoft.PowerToys.Settings.UI.Views
{
this.LocationDialog.IsPrimaryButtonEnabled = false;
this.LocationResultPanel.Visibility = Visibility.Collapsed;
+ this.LocationErrorText.Visibility = Visibility.Collapsed;
+
+ // Pre-check location services availability
+ var accessStatus = await Geolocator.RequestAccessAsync();
+ if (accessStatus != GeolocationAccessStatus.Allowed)
+ {
+ this.SyncButton.IsEnabled = false;
+ this.LocationErrorText.Text = ResourceLoaderInstance.ResourceLoader.GetString("LightSwitch_LocationError_Unavailable");
+ this.LocationErrorText.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ this.SyncButton.IsEnabled = true;
+ }
+
await this.LocationDialog.ShowAsync();
}
diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
index 8c9bed2782..c90423c39d 100644
--- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
+++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw
@@ -5150,6 +5150,12 @@ The break timer font matches the text font.
Sunset
+
+ Unable to connect to location services. Please try again or enter your coordinates manually.
+
+
+ Location services unavailable. Please enter your coordinates manually.
+
Close PowerToys
Don't loc "PowerToys"