Skip to content

Commit fdff728

Browse files
fix: Window resize now works on Linux
and the system has been uniformed on Windows/Linux to remove the ShowWindowDecoration settings
1 parent 1f531b4 commit fdff728

11 files changed

Lines changed: 108 additions & 77 deletions

File tree

src/WindowSwitcher.Lib/Data/Platform/Policies/LinuxSettingsPlatformPolicy.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/WindowSwitcher.Lib/Data/Platform/Policies/WindowsSettingsPlatformPolicy.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/WindowSwitcher.Lib/Data/Platform/SystemInfo/Abstractions/ISettingsPlatformPolicy.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/WindowSwitcher.Lib/Models/ConfigFile.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public class ConfigFile
1111
public bool EnableSentry { get; set; } = true;
1212
public string SentryDsn { get; set; } = "https://d4530a120abfe1da5f25305d84502c0a@o4511093969584128.ingest.de.sentry.io/4511093982036048";
1313
public string TelemetryUserId { get; set; } = Guid.NewGuid().ToString("D");
14-
public bool ShowWindowDecorations { get; set; } = false;
1514
public bool UseFixedWindowSize { get; set; } = false;
1615
public bool FocusOnHover { get; set; } = false;
1716
public int WindowWidth { get; set; } = 300;

src/WindowSwitcher.Tests/Platform/PlatformPoliciesTests.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ namespace WindowSwitcher.Tests.Platform;
55

66
public sealed class PlatformPoliciesTests
77
{
8-
[Fact]
9-
public void LinuxAndWindowsSettingsPolicies_ExposeExpectedDecorationFlags()
10-
{
11-
Assert.True(new LinuxSettingsPlatformPolicy().ShowWindowDecorationSetting);
12-
Assert.False(new WindowsSettingsPlatformPolicy().ShowWindowDecorationSetting);
13-
}
14-
158
[Fact]
169
public void LinuxAndWindowsPreviewPolicies_ExposeExpectedPreviewFlags()
1710
{

src/WindowSwitcher/Hosting/PlatformServiceCollectionExtensions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ public static IServiceCollection AddPlatformServices(this IServiceCollection ser
3737
IFloatingWindowHandleConfigurator,
3838
WindowsFloatingWindowHandleConfigurator
3939
>();
40-
services.AddSingleton<ISettingsPlatformPolicy, WindowsSettingsPlatformPolicy>();
4140
services.AddSingleton<IPlatformAppInfoProvider, WindowsPlatformAppInfoProvider>();
4241
}
4342
else if (OperatingSystem.IsLinux())
@@ -50,7 +49,6 @@ public static IServiceCollection AddPlatformServices(this IServiceCollection ser
5049
IFloatingWindowHandleConfigurator,
5150
NoOpFloatingWindowHandleConfigurator
5251
>();
53-
services.AddSingleton<ISettingsPlatformPolicy, LinuxSettingsPlatformPolicy>();
5452
services.AddSingleton<IPlatformAppInfoProvider, LinuxPlatformAppInfoProvider>();
5553
}
5654
else

src/WindowSwitcher/ViewModels/SettingsViewModel.cs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using CommunityToolkit.Mvvm.ComponentModel;
55
using CommunityToolkit.Mvvm.Input;
66
using WindowSwitcher.Lib.Data;
7-
using WindowSwitcher.Lib.Data.Platform.SystemInfo.Abstractions;
87
using WindowSwitcher.Lib.Models;
98
using WindowSwitcher.Theming;
109

@@ -13,24 +12,19 @@ namespace WindowSwitcher.ViewModels;
1312
public class SettingsViewModel : ObservableObject
1413
{
1514
private readonly ConfigFileAccessor _configAccessor = ConfigFileAccessor.GetInstance();
16-
private readonly ISettingsPlatformPolicy _settingsPlatformPolicy;
1715
private readonly Action _applyAction;
1816
private bool _pendingEnablePreviews;
1917
public IRelayCommand ApplyCommand { get; }
2018

21-
public SettingsViewModel(Action applyAction, ISettingsPlatformPolicy settingsPlatformPolicy)
19+
public SettingsViewModel(Action applyAction)
2220
{
2321
ArgumentNullException.ThrowIfNull(applyAction);
24-
ArgumentNullException.ThrowIfNull(settingsPlatformPolicy);
2522

2623
_applyAction = applyAction;
27-
_settingsPlatformPolicy = settingsPlatformPolicy;
2824
_pendingEnablePreviews = _configAccessor.ReadConfig(config => config.EnablePreviews);
2925
ApplyCommand = new RelayCommand(Apply);
3026
}
3127

32-
public bool ShowWindowDecorationSetting => _settingsPlatformPolicy.ShowWindowDecorationSetting;
33-
3428
public bool EnablePreviews
3529
{
3630
get => _pendingEnablePreviews;
@@ -103,18 +97,6 @@ public bool FocusOnHover
10397
);
10498
}
10599

106-
public bool ShowWindowDecorations
107-
{
108-
get => ReadSetting(config => config.ShowWindowDecorations);
109-
set =>
110-
UpdateSetting(
111-
nameof(ShowWindowDecorations),
112-
value,
113-
config => config.ShowWindowDecorations,
114-
(config, currentValue) => config.ShowWindowDecorations = currentValue
115-
);
116-
}
117-
118100
public bool UseFixedWindowSize
119101
{
120102
get => ReadSetting(config => config.UseFixedWindowSize);

src/WindowSwitcher/Windows/FloatingWindow.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
ExtendClientAreaChromeHints="NoChrome"
2020
ExtendClientAreaTitleBarHeightHint="-1"
2121
x:DataType="windows:MainWindow">
22-
<Canvas Name="WindowCanvas" Background="{StaticResource FloatingWindowBackgroundBrush}" PointerPressed="CanvasPointerPressed" PointerReleased="CanvasPointerReleased" PointerEntered="CanvasPointerEntered" PointerExited="CanvasPointerExited">
22+
<Canvas Name="WindowCanvas" Background="{StaticResource FloatingWindowBackgroundBrush}" PointerPressed="CanvasPointerPressed" PointerReleased="CanvasPointerReleased" PointerEntered="CanvasPointerEntered" PointerMoved="CanvasPointerMoved" PointerExited="CanvasPointerExited">
2323
<Canvas.ContextMenu>
2424
<ContextMenu Name="FloatingWindowContextMenu"></ContextMenu>
2525
</Canvas.ContextMenu>

src/WindowSwitcher/Windows/FloatingWindow.axaml.cs

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ namespace WindowSwitcher.Windows;
1818

1919
public partial class FloatingWindow : Window, IFloatingPreviewWindow
2020
{
21+
private const double ResizeGripThickness = 8d;
22+
private static readonly Cursor DefaultCursor = new(StandardCursorType.Arrow);
23+
private static readonly Cursor TopSideCursor = new(StandardCursorType.TopSide);
24+
private static readonly Cursor BottomSideCursor = new(StandardCursorType.BottomSide);
25+
private static readonly Cursor LeftSideCursor = new(StandardCursorType.LeftSide);
26+
private static readonly Cursor RightSideCursor = new(StandardCursorType.RightSide);
27+
private static readonly Cursor TopLeftCornerCursor = new(StandardCursorType.TopLeftCorner);
28+
private static readonly Cursor TopRightCornerCursor = new(StandardCursorType.TopRightCorner);
29+
private static readonly Cursor BottomLeftCornerCursor = new(StandardCursorType.BottomLeftCorner);
30+
private static readonly Cursor BottomRightCornerCursor = new(StandardCursorType.BottomRightCorner);
2131
private volatile bool _isPointerInside;
2232
private bool _closeRequestedByHost;
2333
private readonly IFloatingWindowHost _floatingWindowHost;
@@ -119,10 +129,92 @@ private void SetInitialWindowSettings()
119129
private void CanvasPointerPressed(object? sender, PointerPressedEventArgs e)
120130
{
121131
_floatingWindowHost.SetActivePreview(this);
122-
if (ConfigFileAccessor.GetInstance().ReadConfig(config => config.MoveWindows))
132+
133+
bool moveWindows = ConfigFileAccessor.GetInstance().ReadConfig(config => config.MoveWindows);
134+
135+
if (TryBeginResizeDrag(e))
136+
return;
137+
138+
if (moveWindows)
123139
BeginMoveDrag(e);
124140
}
125141

142+
private bool TryBeginResizeDrag(PointerPressedEventArgs e)
143+
{
144+
if (!CanResize)
145+
return false;
146+
147+
PointerPoint pointerPoint = e.GetCurrentPoint(this);
148+
if (!pointerPoint.Properties.IsLeftButtonPressed)
149+
return false;
150+
151+
WindowEdge? resizeEdge = ResolveResizeEdge(pointerPoint.Position);
152+
if (!resizeEdge.HasValue)
153+
return false;
154+
155+
BeginResizeDrag(resizeEdge.Value, e);
156+
return true;
157+
}
158+
159+
private WindowEdge? ResolveResizeEdge(Point pointerPosition)
160+
{
161+
if (Width <= 0 || Height <= 0)
162+
return null;
163+
164+
bool isNearLeft = pointerPosition.X <= ResizeGripThickness;
165+
bool isNearRight = pointerPosition.X >= Width - ResizeGripThickness;
166+
bool isNearTop = pointerPosition.Y <= ResizeGripThickness;
167+
bool isNearBottom = pointerPosition.Y >= Height - ResizeGripThickness;
168+
169+
if (isNearTop && isNearLeft)
170+
return WindowEdge.NorthWest;
171+
if (isNearTop && isNearRight)
172+
return WindowEdge.NorthEast;
173+
if (isNearBottom && isNearLeft)
174+
return WindowEdge.SouthWest;
175+
if (isNearBottom && isNearRight)
176+
return WindowEdge.SouthEast;
177+
if (isNearTop)
178+
return WindowEdge.North;
179+
if (isNearBottom)
180+
return WindowEdge.South;
181+
if (isNearLeft)
182+
return WindowEdge.West;
183+
if (isNearRight)
184+
return WindowEdge.East;
185+
186+
return null;
187+
}
188+
189+
private void UpdateResizeCursor(PointerEventArgs e)
190+
{
191+
if (!CanResize)
192+
{
193+
WindowCanvas.Cursor = DefaultCursor;
194+
return;
195+
}
196+
197+
PointerPoint pointerPoint = e.GetCurrentPoint(this);
198+
WindowEdge? edge = ResolveResizeEdge(pointerPoint.Position);
199+
WindowCanvas.Cursor = ResolveCursor(edge);
200+
}
201+
202+
private static Cursor ResolveCursor(WindowEdge? edge)
203+
{
204+
return edge switch
205+
{
206+
WindowEdge.North => TopSideCursor,
207+
WindowEdge.South => BottomSideCursor,
208+
WindowEdge.West => LeftSideCursor,
209+
WindowEdge.East => RightSideCursor,
210+
WindowEdge.NorthWest => TopLeftCornerCursor,
211+
WindowEdge.NorthEast => TopRightCornerCursor,
212+
WindowEdge.SouthWest => BottomLeftCornerCursor,
213+
WindowEdge.SouthEast => BottomRightCornerCursor,
214+
_ => DefaultCursor,
215+
};
216+
}
217+
126218
private void CanvasPointerReleased(object? sender, PointerReleasedEventArgs e)
127219
{
128220
_winAccessorBase.RaiseWindow(WindowConfig.WindowId);
@@ -131,6 +223,8 @@ private void CanvasPointerReleased(object? sender, PointerReleasedEventArgs e)
131223

132224
private void CanvasPointerEntered(object? sender, PointerEventArgs e)
133225
{
226+
UpdateResizeCursor(e);
227+
134228
if (_isPointerInside)
135229
return;
136230
_isPointerInside = true;
@@ -154,6 +248,12 @@ private void CanvasPointerEntered(object? sender, PointerEventArgs e)
154248
private void CanvasPointerExited(object? sender, PointerEventArgs e)
155249
{
156250
_isPointerInside = false;
251+
WindowCanvas.Cursor = DefaultCursor;
252+
}
253+
254+
private void CanvasPointerMoved(object? sender, PointerEventArgs e)
255+
{
256+
UpdateResizeCursor(e);
157257
}
158258

159259
private void FloatingWindowResized(object? sender, WindowResizedEventArgs e)
@@ -224,7 +324,6 @@ private void ApplySettingsCore(bool refreshPreviewPipeline)
224324
config.UseFixedWindowSize,
225325
config.WindowWidth,
226326
config.WindowHeight,
227-
config.ShowWindowDecorations,
228327
config.PreviewHighlightColor,
229328
});
230329

@@ -241,9 +340,10 @@ private void ApplySettingsCore(bool refreshPreviewPipeline)
241340
Height = WindowConfig.WindowHeight;
242341
}
243342

244-
SystemDecorations = configSnapshot.ShowWindowDecorations
245-
? SystemDecorations.Full
246-
: SystemDecorations.BorderOnly;
343+
if (!CanResize)
344+
WindowCanvas.Cursor = DefaultCursor;
345+
346+
SystemDecorations = SystemDecorations.BorderOnly;
247347

248348
if (Color.TryParse(configSnapshot.PreviewHighlightColor, out Color highlightColor))
249349
{

src/WindowSwitcher/Windows/SettingsWindow.axaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
IsChecked="{Binding MoveWindows, Mode=TwoWay}" />
2323
<CheckBox Content="Focus on hover"
2424
IsChecked="{Binding FocusOnHover, Mode=TwoWay}" />
25-
<CheckBox Content="Window decorations"
26-
IsVisible="{Binding ShowWindowDecorationSetting}"
27-
IsChecked="{Binding ShowWindowDecorations, Mode=TwoWay}" />
2825
<CheckBox Content="Enable previews"
2926
IsChecked="{Binding EnablePreviews, Mode=TwoWay}" />
3027
<CheckBox Content="Start minimized"

0 commit comments

Comments
 (0)