diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/App.xaml.cs b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/App.xaml.cs
index ad7bc1f5ee..2b0b75127f 100644
--- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/App.xaml.cs
+++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/App.xaml.cs
@@ -10,8 +10,6 @@ using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Controls;
-using Microsoft.UI.Xaml.Media;
using Microsoft.Windows.AppLifecycle;
using PowerDisplay.Helpers;
using PowerDisplay.Serialization;
@@ -75,11 +73,7 @@ namespace PowerDisplay
///
private void OnUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
{
- // Try to display error information
- ShowStartupError(e.Exception);
-
- // Mark exception as handled to prevent app crash
- e.Handled = true;
+ Logger.LogError("Unhandled exception", e.Exception);
}
///
@@ -196,7 +190,7 @@ namespace PowerDisplay
}
catch (Exception ex)
{
- ShowStartupError(ex);
+ Logger.LogError("PowerDisplay startup failed", ex);
}
}
@@ -260,66 +254,6 @@ namespace PowerDisplay
CancellationToken.None);
}
- ///
- /// Show startup error
- ///
- private void ShowStartupError(Exception ex)
- {
- try
- {
- Logger.LogError($"PowerDisplay startup failed: {ex.Message}");
-
- var errorWindow = new Window { Title = "PowerDisplay - Startup Error" };
- var panel = new StackPanel { Margin = new Thickness(20), Spacing = 16 };
-
- panel.Children.Add(new TextBlock
- {
- Text = "PowerDisplay Startup Failed",
- FontSize = 20,
- FontWeight = Microsoft.UI.Text.FontWeights.SemiBold,
- });
-
- panel.Children.Add(new TextBlock
- {
- Text = $"Error: {ex.Message}",
- FontSize = 14,
- TextWrapping = TextWrapping.Wrap,
- });
-
- panel.Children.Add(new TextBlock
- {
- Text = $"Details:\n{ex}",
- FontSize = 12,
- TextWrapping = TextWrapping.Wrap,
- Foreground = new SolidColorBrush(Microsoft.UI.Colors.Gray),
- Margin = new Thickness(0, 10, 0, 0),
- });
-
- var closeButton = new Button
- {
- Content = "Close",
- HorizontalAlignment = HorizontalAlignment.Right,
- Margin = new Thickness(0, 10, 0, 0),
- };
- closeButton.Click += (_, _) => errorWindow.Close();
- panel.Children.Add(closeButton);
-
- errorWindow.Content = new ScrollViewer
- {
- Content = panel,
- VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
- MaxHeight = 600,
- MaxWidth = 800,
- };
-
- errorWindow.Activate();
- }
- catch
- {
- Environment.Exit(1);
- }
- }
-
///
/// Gets the main window instance
///
diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml
index e4284b239d..8a5124361a 100644
--- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml
+++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/IdentifyWindow.xaml
@@ -1,11 +1,11 @@
-
-
+
/// Interaction logic for IdentifyWindow.xaml
///
- public sealed partial class IdentifyWindow : Window, IDisposable
+ public sealed partial class IdentifyWindow : Window
{
+ // Window size in device-independent units (DIU)
+ private const int WindowWidthDiu = 300;
+ private const int WindowHeightDiu = 280;
+
private AppWindow? _appWindow;
- private DesktopAcrylicController? _acrylicController;
- private SystemBackdropConfiguration? _configurationSource;
- private bool _disposed;
+ private double _dpiScale = 1.0;
+
+ [LibraryImport("user32.dll")]
+ private static partial uint GetDpiForWindow(IntPtr hwnd);
public IdentifyWindow(int number)
{
@@ -49,6 +54,9 @@ namespace PowerDisplay.PowerDisplayXAML
var windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
_appWindow = AppWindow.GetFromWindowId(windowId);
+ // Get DPI scale for this window
+ _dpiScale = GetDpiForWindow(hwnd) / 96.0;
+
if (_appWindow != null)
{
// Remove title bar using OverlappedPresenter
@@ -61,38 +69,17 @@ namespace PowerDisplay.PowerDisplayXAML
presenter.IsMaximizable = false;
}
- // Set window size to fit the large number (200pt font)
- _appWindow.Resize(new SizeInt32 { Width = 300, Height = 280 });
+ // Set window size scaled for DPI
+ // AppWindow.Resize expects physical pixels
+ int physicalWidth = (int)(WindowWidthDiu * _dpiScale);
+ int physicalHeight = (int)(WindowHeightDiu * _dpiScale);
+ _appWindow.Resize(new SizeInt32 { Width = physicalWidth, Height = physicalHeight });
}
// Set window topmost and hide from taskbar
WindowHelper.SetWindowTopmost(hwnd, true);
WindowHelper.HideFromTaskbar(hwnd);
WindowHelper.DisableWindowMovingAndResizing(hwnd);
-
- // Configure 90% transparent acrylic backdrop
- ConfigureAcrylicBackdrop();
- }
-
- private void ConfigureAcrylicBackdrop()
- {
- if (!DesktopAcrylicController.IsSupported())
- {
- return;
- }
-
- _configurationSource = new SystemBackdropConfiguration();
- _acrylicController = new DesktopAcrylicController();
-
- // Set 90% transparency (TintOpacity 0.1 = 10% tint = 90% transparent)
- _acrylicController.TintColor = Windows.UI.Color.FromArgb(255, 0, 0, 0);
- _acrylicController.TintOpacity = 0.1f;
- _acrylicController.LuminosityOpacity = 0f;
-
- // Add target using WinRT cast
- var target = WinRT.CastExtensions.As(this);
- _acrylicController.AddSystemBackdropTarget(target);
- _acrylicController.SetSystemBackdropConfiguration(_configurationSource);
}
///
@@ -106,26 +93,16 @@ namespace PowerDisplay.PowerDisplayXAML
}
var workArea = displayArea.WorkArea;
- int windowWidth = 300;
- int windowHeight = 280;
+
+ // Window size in physical pixels (already scaled for DPI)
+ int physicalWidth = (int)(WindowWidthDiu * _dpiScale);
+ int physicalHeight = (int)(WindowHeightDiu * _dpiScale);
// Calculate center position (WorkArea coordinates are in physical pixels)
- int x = workArea.X + ((workArea.Width - windowWidth) / 2);
- int y = workArea.Y + ((workArea.Height - windowHeight) / 2);
+ int x = workArea.X + ((workArea.Width - physicalWidth) / 2);
+ int y = workArea.Y + ((workArea.Height - physicalHeight) / 2);
_appWindow.Move(new PointInt32(x, y));
}
-
- public void Dispose()
- {
- if (_disposed)
- {
- return;
- }
-
- _disposed = true;
- _acrylicController?.Dispose();
- _acrylicController = null;
- }
}
}
diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml
index d747fd252c..80ec7fba87 100644
--- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml
+++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml
@@ -193,7 +193,6 @@
Minimum="{x:Bind MinBrightness, Mode=OneWay}"
PointerCaptureLost="Slider_PointerCaptureLost"
Tag="Brightness"
- ValueChanged="Slider_ValueChanged"
Value="{x:Bind Brightness, Mode=OneWay}" />
@@ -226,7 +225,6 @@
Minimum="0"
PointerCaptureLost="Slider_PointerCaptureLost"
Tag="Contrast"
- ValueChanged="Slider_ValueChanged"
Value="{x:Bind ContrastPercent, Mode=OneWay}" />
@@ -260,7 +258,6 @@
Minimum="{x:Bind MinVolume, Mode=OneWay}"
PointerCaptureLost="Slider_PointerCaptureLost"
Tag="Volume"
- ValueChanged="Slider_ValueChanged"
Value="{x:Bind Volume, Mode=OneWay}" />
diff --git a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs
index 08c28ad8f0..e20fa83a4a 100644
--- a/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs
+++ b/src/modules/powerdisplay/PowerDisplay/PowerDisplayXAML/MainWindow.xaml.cs
@@ -9,12 +9,9 @@ using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.UI;
-using Microsoft.UI.Composition;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
-using Microsoft.UI.Xaml.Media;
-using Microsoft.UI.Xaml.Media.Animation;
using PowerDisplay.Common.Models;
using PowerDisplay.Configuration;
using PowerDisplay.Helpers;
@@ -602,17 +599,6 @@ namespace PowerDisplay
}
}
- ///
- /// Slider ValueChanged event handler - does nothing during drag
- /// This allows the slider UI to update smoothly without triggering hardware operations
- ///
- private void Slider_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
- {
- // During drag, this event fires 60-120 times per second
- // We intentionally do nothing here to keep UI smooth
- // The actual ViewModel update happens in PointerCaptureLost after drag completes
- }
-
///
/// Slider PointerCaptureLost event handler - updates ViewModel when drag completes
/// This is the WinUI3 recommended way to detect drag completion
@@ -663,75 +649,6 @@ namespace PowerDisplay
Logger.LogDebug($"[UI] ViewModel property {propertyName} updated successfully");
}
- ///
- /// Input source item click handler - switches the monitor input source
- ///
- private async void InputSourceItem_Click(object sender, RoutedEventArgs e)
- {
- Logger.LogInfo("[UI] InputSourceItem_Click: Event triggered!");
-
- if (sender is not Button button)
- {
- Logger.LogWarning("[UI] InputSourceItem_Click: sender is not Button");
- return;
- }
-
- Logger.LogInfo($"[UI] InputSourceItem_Click: Button clicked, Tag type = {button.Tag?.GetType().Name ?? "null"}, DataContext type = {button.DataContext?.GetType().Name ?? "null"}");
-
- // Get the InputSourceItem from Tag (not DataContext - Flyout doesn't inherit DataContext properly)
- var inputSourceItem = button.Tag as InputSourceItem;
- if (inputSourceItem == null)
- {
- Logger.LogWarning("[UI] InputSourceItem_Click: Tag is not InputSourceItem");
- return;
- }
-
- Logger.LogInfo($"[UI] InputSourceItem_Click: InputSourceItem found - Value=0x{inputSourceItem.Value:X2}, Name={inputSourceItem.Name}, MonitorId={inputSourceItem.MonitorId}");
-
- int inputSourceValue = inputSourceItem.Value;
- string monitorId = inputSourceItem.MonitorId;
-
- // Use MonitorId for direct lookup (Flyout popup is not in visual tree)
- MonitorViewModel? monitorVm = null;
-
- if (!string.IsNullOrEmpty(monitorId) && _viewModel != null)
- {
- monitorVm = _viewModel.Monitors.FirstOrDefault(m => m.Id == monitorId);
- Logger.LogInfo($"[UI] InputSourceItem_Click: Found MonitorViewModel by ID: {monitorVm?.Name ?? "null"}");
- }
-
- // Fallback: search through all monitors (for backwards compatibility)
- if (monitorVm == null && _viewModel != null)
- {
- Logger.LogInfo("[UI] InputSourceItem_Click: MonitorId lookup failed, trying fallback search");
- foreach (var vm in _viewModel.Monitors)
- {
- if (vm.SupportsInputSource && vm.AvailableInputSources != null)
- {
- if (vm.AvailableInputSources.Any(s => s.Value == inputSourceValue))
- {
- monitorVm = vm;
- Logger.LogInfo($"[UI] InputSourceItem_Click: Found MonitorViewModel by fallback: {vm.Name}");
- break;
- }
- }
- }
- }
-
- if (monitorVm == null)
- {
- Logger.LogWarning("[UI] InputSourceItem_Click: Could not find MonitorViewModel");
- return;
- }
-
- Logger.LogInfo($"[UI] Switching input source for {monitorVm.Name} to 0x{inputSourceValue:X2} ({inputSourceItem.Name})");
-
- // Set the input source
- await monitorVm.SetInputSourceAsync(inputSourceValue);
-
- Logger.LogInfo("[UI] InputSourceItem_Click: SetInputSourceAsync completed");
- }
-
///
/// Input source ListView selection changed handler - switches the monitor input source
///
@@ -766,13 +683,6 @@ namespace PowerDisplay
// Set the input source
await monitorVm.SetInputSourceAsync(selectedItem.Value);
-
- // Close the flyout after selection
- if (listView.Parent is StackPanel stackPanel &&
- stackPanel.Parent is Flyout flyout)
- {
- flyout.Hide();
- }
}
///