|
|
|
@ -84,7 +84,7 @@ namespace Avalonia.Win32 |
|
|
|
private Size _minSize; |
|
|
|
private Size _maxSize; |
|
|
|
private POINT _maxTrackSize; |
|
|
|
private WindowImpl _parent; |
|
|
|
private WindowImpl _parent; |
|
|
|
private ExtendClientAreaChromeHints _extendChromeHints = ExtendClientAreaChromeHints.Default; |
|
|
|
private bool _isCloseRequested; |
|
|
|
private bool _shown; |
|
|
|
@ -172,7 +172,7 @@ namespace Avalonia.Win32 |
|
|
|
public Action<PixelPoint> PositionChanged { get; set; } |
|
|
|
|
|
|
|
public Action<WindowState> WindowStateChanged { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
public Action LostFocus { get; set; } |
|
|
|
|
|
|
|
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; } |
|
|
|
@ -245,7 +245,7 @@ namespace Avalonia.Win32 |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
if(_isFullScreenActive) |
|
|
|
if (_isFullScreenActive) |
|
|
|
{ |
|
|
|
return WindowState.FullScreen; |
|
|
|
} |
|
|
|
@ -268,7 +268,7 @@ namespace Avalonia.Win32 |
|
|
|
ShowWindow(value, value != WindowState.Minimized); // If the window is minimized, it shouldn't be activated
|
|
|
|
} |
|
|
|
|
|
|
|
_showWindowState = value; |
|
|
|
_showWindowState = value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -276,7 +276,7 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
protected IntPtr Hwnd => _hwnd; |
|
|
|
|
|
|
|
public void SetTransparencyLevelHint (WindowTransparencyLevel transparencyLevel) |
|
|
|
public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) |
|
|
|
{ |
|
|
|
TransparencyLevel = EnableBlur(transparencyLevel); |
|
|
|
} |
|
|
|
@ -316,12 +316,12 @@ namespace Avalonia.Win32 |
|
|
|
} |
|
|
|
|
|
|
|
var blurInfo = new DWM_BLURBEHIND(false); |
|
|
|
|
|
|
|
|
|
|
|
if (transparencyLevel == WindowTransparencyLevel.Blur) |
|
|
|
{ |
|
|
|
blurInfo = new DWM_BLURBEHIND(true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DwmEnableBlurBehindWindow(_hwnd, ref blurInfo); |
|
|
|
|
|
|
|
if (transparencyLevel == WindowTransparencyLevel.Transparent) |
|
|
|
@ -377,13 +377,24 @@ namespace Avalonia.Win32 |
|
|
|
{ |
|
|
|
if (_isUsingComposition) |
|
|
|
{ |
|
|
|
_blurHost?.SetBlur(transparencyLevel switch |
|
|
|
var effect = transparencyLevel switch |
|
|
|
{ |
|
|
|
WindowTransparencyLevel.Mica => BlurEffect.Mica, |
|
|
|
WindowTransparencyLevel.AcrylicBlur => BlurEffect.Acrylic, |
|
|
|
WindowTransparencyLevel.Blur => BlurEffect.Acrylic, |
|
|
|
_ => BlurEffect.None |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
if (Win32Platform.WindowsVersion >= WinUICompositorConnection.MinHostBackdropVersion) |
|
|
|
{ |
|
|
|
unsafe |
|
|
|
{ |
|
|
|
int pvUseBackdropBrush = effect == BlurEffect.Acrylic ? 1 : 0; |
|
|
|
DwmSetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_USE_HOSTBACKDROPBRUSH, &pvUseBackdropBrush, sizeof(int)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
_blurHost?.SetBlur(effect); |
|
|
|
|
|
|
|
return transparencyLevel; |
|
|
|
} |
|
|
|
@ -481,12 +492,12 @@ namespace Avalonia.Win32 |
|
|
|
if (customRendererFactory != null) |
|
|
|
return customRendererFactory.Create(root, loop); |
|
|
|
|
|
|
|
return Win32Platform.UseDeferredRendering |
|
|
|
? _isUsingComposition |
|
|
|
return Win32Platform.UseDeferredRendering |
|
|
|
? _isUsingComposition |
|
|
|
? new DeferredRenderer(root, loop) |
|
|
|
{ |
|
|
|
RenderOnlyOnRenderThread = true |
|
|
|
} |
|
|
|
} |
|
|
|
: (IRenderer)new DeferredRenderer(root, loop, rendererLock: _rendererLock) |
|
|
|
: new ImmediateRenderer(root); |
|
|
|
} |
|
|
|
@ -540,7 +551,7 @@ namespace Avalonia.Win32 |
|
|
|
{ |
|
|
|
BeforeCloseCleanup(true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DestroyWindow(_hwnd); |
|
|
|
_hwnd = IntPtr.Zero; |
|
|
|
} |
|
|
|
@ -606,7 +617,7 @@ namespace Avalonia.Win32 |
|
|
|
public void SetParent(IWindowImpl parent) |
|
|
|
{ |
|
|
|
_parent = (WindowImpl)parent; |
|
|
|
|
|
|
|
|
|
|
|
var parentHwnd = _parent?._hwnd ?? IntPtr.Zero; |
|
|
|
|
|
|
|
if (parentHwnd == IntPtr.Zero && !_windowProperties.ShowInTaskbar) |
|
|
|
@ -717,7 +728,7 @@ namespace Avalonia.Win32 |
|
|
|
_isUsingComposition ? (int)WindowStyles.WS_EX_NOREDIRECTIONBITMAP : 0, |
|
|
|
atom, |
|
|
|
null, |
|
|
|
(int)WindowStyles.WS_OVERLAPPEDWINDOW | (int) WindowStyles.WS_CLIPCHILDREN, |
|
|
|
(int)WindowStyles.WS_OVERLAPPEDWINDOW | (int)WindowStyles.WS_CLIPCHILDREN, |
|
|
|
CW_USEDEFAULT, |
|
|
|
CW_USEDEFAULT, |
|
|
|
CW_USEDEFAULT, |
|
|
|
@ -773,7 +784,7 @@ namespace Avalonia.Win32 |
|
|
|
} |
|
|
|
|
|
|
|
if (ShCoreAvailable && Win32Platform.WindowsVersion > PlatformConstants.Windows8) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var monitor = MonitorFromWindow( |
|
|
|
_hwnd, |
|
|
|
MONITOR.MONITOR_DEFAULTTONEAREST); |
|
|
|
@ -856,14 +867,14 @@ namespace Avalonia.Win32 |
|
|
|
} |
|
|
|
|
|
|
|
TaskBarList.MarkFullscreen(_hwnd, fullscreen); |
|
|
|
|
|
|
|
|
|
|
|
ExtendClientArea(); |
|
|
|
} |
|
|
|
|
|
|
|
private MARGINS UpdateExtendMargins() |
|
|
|
{ |
|
|
|
RECT borderThickness = new RECT(); |
|
|
|
RECT borderCaptionThickness = new RECT(); |
|
|
|
RECT borderCaptionThickness = new RECT(); |
|
|
|
|
|
|
|
AdjustWindowRectEx(ref borderCaptionThickness, (uint)(GetStyle()), false, 0); |
|
|
|
AdjustWindowRectEx(ref borderThickness, (uint)(GetStyle() & ~WindowStyles.WS_CAPTION), false, 0); |
|
|
|
@ -886,7 +897,7 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
if (_extendTitleBarHint != -1) |
|
|
|
{ |
|
|
|
borderCaptionThickness.top = (int)(_extendTitleBarHint * RenderScaling); |
|
|
|
borderCaptionThickness.top = (int)(_extendTitleBarHint * RenderScaling); |
|
|
|
} |
|
|
|
|
|
|
|
margins.cyTopHeight = _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && !_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome) ? borderCaptionThickness.top : 1; |
|
|
|
@ -911,7 +922,7 @@ namespace Avalonia.Win32 |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (DwmIsCompositionEnabled(out bool compositionEnabled) < 0 || !compositionEnabled) |
|
|
|
{ |
|
|
|
_isClientAreaExtended = false; |
|
|
|
@ -939,11 +950,11 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
_offScreenMargin = new Thickness(); |
|
|
|
_extendedMargins = new Thickness(); |
|
|
|
|
|
|
|
Resize(new Size(rcWindow.Width/ RenderScaling, rcWindow.Height / RenderScaling), PlatformResizeReason.Layout); |
|
|
|
|
|
|
|
Resize(new Size(rcWindow.Width / RenderScaling, rcWindow.Height / RenderScaling), PlatformResizeReason.Layout); |
|
|
|
} |
|
|
|
|
|
|
|
if(!_isClientAreaExtended || (_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && |
|
|
|
if (!_isClientAreaExtended || (_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && |
|
|
|
!_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome))) |
|
|
|
{ |
|
|
|
EnableCloseButton(_hwnd); |
|
|
|
@ -959,12 +970,12 @@ namespace Avalonia.Win32 |
|
|
|
private void ShowWindow(WindowState state, bool activate) |
|
|
|
{ |
|
|
|
_shown = true; |
|
|
|
|
|
|
|
|
|
|
|
if (_isClientAreaExtended) |
|
|
|
{ |
|
|
|
ExtendClientArea(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ShowWindowCommand? command; |
|
|
|
|
|
|
|
var newWindowProperties = _windowProperties; |
|
|
|
@ -982,7 +993,7 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
case WindowState.Normal: |
|
|
|
newWindowProperties.IsFullScreen = false; |
|
|
|
command = IsWindowVisible(_hwnd) ? ShowWindowCommand.Restore : |
|
|
|
command = IsWindowVisible(_hwnd) ? ShowWindowCommand.Restore : |
|
|
|
activate ? ShowWindowCommand.Normal : ShowWindowCommand.ShowNoActivate; |
|
|
|
break; |
|
|
|
|
|
|
|
@ -1013,7 +1024,7 @@ namespace Avalonia.Win32 |
|
|
|
SetForegroundWindow(_hwnd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void BeforeCloseCleanup(bool isDisposing) |
|
|
|
{ |
|
|
|
// Based on https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs#L4270-L4337
|
|
|
|
@ -1031,7 +1042,7 @@ namespace Avalonia.Win32 |
|
|
|
// Our window closed callback will set enabled state to a correct value after child window gets destroyed.
|
|
|
|
_parent.SetEnabled(true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// We also need to activate our parent window since again OS might try to activate a window behind if it is not set.
|
|
|
|
if (wasActive) |
|
|
|
{ |
|
|
|
@ -1058,7 +1069,7 @@ namespace Avalonia.Win32 |
|
|
|
SetWindowPos(_hwnd, WindowPosZOrder.HWND_NOTOPMOST, x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private WindowStyles GetWindowStateStyles() |
|
|
|
{ |
|
|
|
@ -1235,7 +1246,7 @@ namespace Avalonia.Win32 |
|
|
|
SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | |
|
|
|
SetWindowPosFlags.SWP_FRAMECHANGED); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private const int MF_BYCOMMAND = 0x0; |
|
|
|
@ -1285,9 +1296,9 @@ namespace Avalonia.Win32 |
|
|
|
public void SetExtendClientAreaToDecorationsHint(bool hint) |
|
|
|
{ |
|
|
|
_isClientAreaExtended = hint; |
|
|
|
|
|
|
|
ExtendClientArea(); |
|
|
|
} |
|
|
|
|
|
|
|
ExtendClientArea(); |
|
|
|
} |
|
|
|
|
|
|
|
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints) |
|
|
|
{ |
|
|
|
@ -1295,7 +1306,7 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
ExtendClientArea(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight) |
|
|
|
{ |
|
|
|
@ -1309,7 +1320,7 @@ namespace Avalonia.Win32 |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public bool NeedsManagedDecorations => _isClientAreaExtended && _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome); |
|
|
|
|
|
|
|
@ -1348,7 +1359,7 @@ namespace Avalonia.Win32 |
|
|
|
{ |
|
|
|
private readonly WindowImpl _owner; |
|
|
|
private readonly PlatformResizeReason _restore; |
|
|
|
|
|
|
|
|
|
|
|
public ResizeReasonScope(WindowImpl owner, PlatformResizeReason restore) |
|
|
|
{ |
|
|
|
_owner = owner; |
|
|
|
|