diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs index 1162cf9d70..a09918a3a6 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs @@ -63,7 +63,7 @@ namespace Avalonia.Win32.WinRT.Composition { if (!_syncContext.IsCurrent) throw new InvalidOperationException(); - + var iid = IID_ID3D11Texture2D; void* pTexture; var off = _surfaceInterop.BeginDraw(null, &iid, &pTexture); @@ -92,7 +92,7 @@ namespace Avalonia.Win32.WinRT.Composition Monitor.Enter(_pumpLock); return Disposable.Create(() => Monitor.Exit(_pumpLock)); } - + public void Dispose() { if (_syncContext == null) diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs index ebdbae06d7..f5706b6fb5 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs @@ -44,7 +44,7 @@ namespace Avalonia.Win32.WinRT.Composition _compositorInterop = _compositor.QueryInterface(); _compositorDesktopInterop = _compositor.QueryInterface(); using var device = MicroComRuntime.CreateProxyFor(_angle.GetDirect3DDevice(), true); - + _device = _compositorInterop.CreateGraphicsDevice(device); _blurBrush = CreateAcrylicBlurBackdropBrush(); _micaBrush = CreateMicaBackdropBrush(); @@ -71,15 +71,18 @@ namespace Avalonia.Win32.WinRT.Composition AvaloniaLocator.CurrentMutable.BindToSelf(connect); AvaloniaLocator.CurrentMutable.Bind().ToConstant(connect); tcs.SetResult(true); + } catch (Exception e) { tcs.SetException(e); return; } - connect.RunLoop(); - }) { IsBackground = true }; + }) + { + IsBackground = true + }; th.SetApartmentState(ApartmentState.STA); th.Start(); return tcs.Task.Result; @@ -94,9 +97,9 @@ namespace Avalonia.Win32.WinRT.Composition { _parent = parent; } - public void Dispose() { + } public void Invoke(IAsyncAction asyncInfo, AsyncStatus asyncStatus) @@ -107,7 +110,6 @@ namespace Avalonia.Win32.WinRT.Composition } public MicroComShadow Shadow { get; set; } - public void OnReferencedFromNative() { } @@ -116,12 +118,12 @@ namespace Avalonia.Win32.WinRT.Composition { } } - + private void RunLoop() { { var st = Stopwatch.StartNew(); - using (var act = _compositor5.RequestCommitAsync()) + using (var act = _compositor5.RequestCommitAsync()) act.SetCompleted(new RunLoopHandler(this)); while (true) { @@ -152,6 +154,7 @@ namespace Avalonia.Win32.WinRT.Composition { Logger.TryGet(LogEventLevel.Error, "WinUIComposition") ?.Log(null, "Unable to initialize WinUI compositor: {0}", e); + } } @@ -168,19 +171,17 @@ namespace Avalonia.Win32.WinRT.Composition using var sc = _syncContext.EnsureLocked(); using var desktopTarget = _compositorDesktopInterop.CreateDesktopWindowTarget(hWnd, 0); using var target = desktopTarget.QueryInterface(); - - using var drawingSurface = _device.CreateDrawingSurface(new UnmanagedMethods.SIZE(), - DirectXPixelFormat.B8G8R8A8UIntNormalized, + + using var drawingSurface = _device.CreateDrawingSurface(new UnmanagedMethods.SIZE(), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); using var surface = drawingSurface.QueryInterface(); using var surfaceInterop = drawingSurface.QueryInterface(); - + using var surfaceBrush = _compositor.CreateSurfaceBrushWithSurface(surface); using var brush = surfaceBrush.QueryInterface(); using var spriteVisual = _compositor.CreateSpriteVisual(); spriteVisual.SetBrush(brush); - using var visual = spriteVisual.QueryInterface(); using var visual2 = spriteVisual.QueryInterface(); using var container = _compositor.CreateContainerVisual(); @@ -188,7 +189,7 @@ namespace Avalonia.Win32.WinRT.Composition using var containerVisual2 = container.QueryInterface(); containerVisual2.SetRelativeSizeAdjustment(new Vector2(1, 1)); using var containerChildren = container.Children; - + target.SetRoot(containerVisual); using var blur = CreateBlurVisual(_blurBrush); @@ -200,10 +201,10 @@ namespace Avalonia.Win32.WinRT.Composition } var compositionRoundedRectangleGeometry = ClipVisual(blur, mica); - + containerChildren.InsertAtTop(blur); containerChildren.InsertAtTop(visual); - + return new WinUICompositedWindow(_syncContext, _compositor, _pumpLock, target, surfaceInterop, visual, blur, mica, compositionRoundedRectangleGeometry); } @@ -223,9 +224,8 @@ namespace Avalonia.Win32.WinRT.Composition private unsafe ICompositionBrush CreateAcrylicBlurBackdropBrush() { - using var backDropParameterFactory = - NativeWinRTMethods.CreateActivationFactory( - "Windows.UI.Composition.CompositionEffectSourceParameter"); + using var backDropParameterFactory = NativeWinRTMethods.CreateActivationFactory( + "Windows.UI.Composition.CompositionEffectSourceParameter"); using var backdropString = new HStringInterop("backdrop"); using var backDropParameter = backDropParameterFactory.Create(backdropString.Handle); @@ -235,7 +235,8 @@ namespace Avalonia.Win32.WinRT.Composition using var compositionEffectBrush = blurEffectFactory.CreateBrush(); using var backdrop = _compositor2.CreateBackdropBrush(); using var backdropBrush = backdrop.QueryInterface(); - + + var saturateEffect = new SaturationEffect(blurEffect); using var satEffectFactory = _compositor.CreateEffectFactory(saturateEffect); using var sat = satEffectFactory.CreateBrush(); @@ -259,8 +260,8 @@ namespace Avalonia.Win32.WinRT.Composition foreach (var visual in containerVisuals) { visual?.SetClip(geometricClipWithGeometry.QueryInterface()); - } - + } + return roundedRectangleGeometry.CloneReference(); } @@ -269,8 +270,8 @@ namespace Avalonia.Win32.WinRT.Composition using var spriteVisual = _compositor.CreateSpriteVisual(); using var visual = spriteVisual.QueryInterface(); using var visual2 = spriteVisual.QueryInterface(); - - + + spriteVisual.SetBrush(compositionBrush); visual.SetIsVisible(0); visual2.SetRelativeSizeAdjustment(new Vector2(1.0f, 1.0f)); diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 0a0f600520..651d3adb11 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -82,7 +82,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; @@ -105,7 +105,9 @@ namespace Avalonia.Win32 _windowProperties = new WindowProperties { - ShowInTaskbar = false, IsResizable = true, Decorations = SystemDecorations.Full + ShowInTaskbar = false, + IsResizable = true, + Decorations = SystemDecorations.Full }; _rendererLock = new ManagedDeferredRendererLock(); @@ -114,13 +116,13 @@ namespace Avalonia.Win32 var compositionConnector = AvaloniaLocator.Current.GetService(); _isUsingComposition = compositionConnector is { } && - glPlatform is EglPlatformOpenGlInterface egl && - egl.Display is AngleWin32EglDisplay angleDisplay && - angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; + glPlatform is EglPlatformOpenGlInterface egl && + egl.Display is AngleWin32EglDisplay angleDisplay && + angleDisplay.PlatformApi == AngleOptions.PlatformApi.DirectX11; CreateWindow(); _framebuffer = new FramebufferManager(_hwnd); - + if (glPlatform != null) { if (_isUsingComposition) @@ -166,7 +168,7 @@ namespace Avalonia.Win32 public Action PositionChanged { get; set; } public Action WindowStateChanged { get; set; } - + public Action LostFocus { get; set; } public Action TransparencyLevelChanged { get; set; } @@ -222,8 +224,7 @@ namespace Avalonia.Win32 return new Size(rcWindow.Width, rcWindow.Height) / RenderScaling; } - DwmGetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, out var rect, - Marshal.SizeOf(typeof(RECT))); + DwmGetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, out var rect, Marshal.SizeOf(typeof(RECT))); return new Size(rect.Width, rect.Height) / RenderScaling; } } @@ -232,8 +233,7 @@ namespace Avalonia.Win32 public IPlatformHandle Handle { get; private set; } - public virtual Size MaxAutoSizeHint => - new Size(_maxTrackSize.X / RenderScaling, _maxTrackSize.Y / RenderScaling); + public virtual Size MaxAutoSizeHint => new Size(_maxTrackSize.X / RenderScaling, _maxTrackSize.Y / RenderScaling); public IMouseDevice MouseDevice => _mouseDevice; @@ -241,7 +241,7 @@ namespace Avalonia.Win32 { get { - if (_isFullScreenActive) + if(_isFullScreenActive) { return WindowState.FullScreen; } @@ -264,7 +264,7 @@ namespace Avalonia.Win32 ShowWindow(value, true); } - _showWindowState = value; + _showWindowState = value; } } @@ -272,7 +272,7 @@ namespace Avalonia.Win32 protected IntPtr Hwnd => _hwnd; - public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) + public void SetTransparencyLevelHint (WindowTransparencyLevel transparencyLevel) { TransparencyLevel = EnableBlur(transparencyLevel); } @@ -312,12 +312,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) @@ -385,8 +385,7 @@ namespace Avalonia.Win32 } else { - bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || - Win32Platform.WindowsVersion.Build >= 19628; + bool canUseAcrylic = Win32Platform.WindowsVersion.Major > 10 || Win32Platform.WindowsVersion.Build >= 19628; var accent = new AccentPolicy(); var accentStructSize = Marshal.SizeOf(accent); @@ -537,7 +536,7 @@ namespace Avalonia.Win32 { BeforeCloseCleanup(true); } - + DestroyWindow(_hwnd); _hwnd = IntPtr.Zero; } @@ -603,7 +602,7 @@ namespace Avalonia.Win32 public void SetParent(IWindowImpl parent) { _parent = (WindowImpl)parent; - + var parentHwnd = _parent?._hwnd ?? IntPtr.Zero; if (parentHwnd == IntPtr.Zero && !_windowProperties.ShowInTaskbar) @@ -714,7 +713,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, @@ -770,7 +769,7 @@ namespace Avalonia.Win32 } if (ShCoreAvailable && Win32Platform.WindowsVersion > PlatformConstants.Windows8) - { + { var monitor = MonitorFromWindow( _hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); @@ -816,9 +815,7 @@ namespace Avalonia.Win32 // Set new window style and size. SetStyle(current & ~(WindowStyles.WS_CAPTION | WindowStyles.WS_THICKFRAME), false); - SetExtendedStyle( - currentEx & ~(WindowStyles.WS_EX_DLGMODALFRAME | WindowStyles.WS_EX_WINDOWEDGE | - WindowStyles.WS_EX_CLIENTEDGE | WindowStyles.WS_EX_STATICEDGE), false); + SetExtendedStyle(currentEx & ~(WindowStyles.WS_EX_DLGMODALFRAME | WindowStyles.WS_EX_WINDOWEDGE | WindowStyles.WS_EX_CLIENTEDGE | WindowStyles.WS_EX_STATICEDGE), false); // On expand, if we're given a window_rect, grow to it, otherwise do // not resize. @@ -828,9 +825,8 @@ namespace Avalonia.Win32 var window_rect = monitor_info.rcMonitor.ToPixelRect(); SetWindowPos(_hwnd, IntPtr.Zero, window_rect.X, window_rect.Y, - window_rect.Width, window_rect.Height, - SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | - SetWindowPosFlags.SWP_FRAMECHANGED); + window_rect.Width, window_rect.Height, + SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED); _isFullScreenActive = true; } @@ -849,22 +845,21 @@ namespace Avalonia.Win32 var new_rect = _savedWindowInfo.WindowRect.ToPixelRect(); SetWindowPos(_hwnd, IntPtr.Zero, new_rect.X, new_rect.Y, new_rect.Width, - new_rect.Height, - SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | - SetWindowPosFlags.SWP_FRAMECHANGED); + new_rect.Height, + SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED); UpdateWindowProperties(_windowProperties, true); } 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); @@ -873,8 +868,7 @@ namespace Avalonia.Win32 borderCaptionThickness.left *= -1; borderCaptionThickness.top *= -1; - bool wantsTitleBar = _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) || - _extendTitleBarHint == -1; + bool wantsTitleBar = _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) || _extendTitleBarHint == -1; if (!wantsTitleBar) { @@ -888,22 +882,15 @@ 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; + margins.cyTopHeight = _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && !_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome) ? borderCaptionThickness.top : 1; if (WindowState == WindowState.Maximized) { - _extendedMargins = new Thickness(0, (borderCaptionThickness.top - borderThickness.top) / RenderScaling, - 0, 0); - _offScreenMargin = new Thickness(borderThickness.left / RenderScaling, - borderThickness.top / RenderScaling, borderThickness.right / RenderScaling, - borderThickness.bottom / RenderScaling); + _extendedMargins = new Thickness(0, (borderCaptionThickness.top - borderThickness.top) / RenderScaling, 0, 0); + _offScreenMargin = new Thickness(borderThickness.left / RenderScaling, borderThickness.top / RenderScaling, borderThickness.right / RenderScaling, borderThickness.bottom / RenderScaling); } else { @@ -920,13 +907,12 @@ namespace Avalonia.Win32 { return; } - + if (DwmIsCompositionEnabled(out bool compositionEnabled) < 0 || !compositionEnabled) { _isClientAreaExtended = false; return; } - GetClientRect(_hwnd, out var rcClient); GetWindowRect(_hwnd, out var rcWindow); @@ -949,14 +935,12 @@ 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) && - !_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints - .PreferSystemChrome))) + if(!_isClientAreaExtended || (_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && + !_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome))) { EnableCloseButton(_hwnd); } @@ -971,12 +955,12 @@ namespace Avalonia.Win32 private void ShowWindow(WindowState state, bool activate) { _shown = true; - + if (_isClientAreaExtended) { ExtendClientArea(); } - + ShowWindowCommand? command; var newWindowProperties = _windowProperties; @@ -994,7 +978,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; @@ -1024,7 +1008,7 @@ namespace Avalonia.Win32 SetFocus(_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 @@ -1042,7 +1026,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) { @@ -1069,7 +1053,7 @@ namespace Avalonia.Win32 SetWindowPos(_hwnd, WindowPosZOrder.HWND_NOTOPMOST, x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); } } - } + } private WindowStyles GetWindowStateStyles() { @@ -1222,7 +1206,10 @@ namespace Avalonia.Win32 var margins = new MARGINS { - cyBottomHeight = margin, cxRightWidth = margin, cxLeftWidth = margin, cyTopHeight = margin + cyBottomHeight = margin, + cxRightWidth = margin, + cxLeftWidth = margin, + cyTopHeight = margin }; DwmExtendFrameIntoClientArea(_hwnd, ref margins); @@ -1243,7 +1230,7 @@ namespace Avalonia.Win32 SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_FRAMECHANGED); } - } + } } private const int MF_BYCOMMAND = 0x0; @@ -1257,13 +1244,12 @@ namespace Avalonia.Win32 void DisableCloseButton(IntPtr hwnd) { EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE, - MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } - void EnableCloseButton(IntPtr hwnd) { EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE, - MF_BYCOMMAND | MF_ENABLED); + MF_BYCOMMAND | MF_ENABLED); } #if USE_MANAGED_DRAG @@ -1294,9 +1280,9 @@ namespace Avalonia.Win32 public void SetExtendClientAreaToDecorationsHint(bool hint) { _isClientAreaExtended = hint; - - ExtendClientArea(); - } + + ExtendClientArea(); + } public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints) { @@ -1304,7 +1290,7 @@ namespace Avalonia.Win32 ExtendClientArea(); } - + /// public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight) { @@ -1318,11 +1304,9 @@ namespace Avalonia.Win32 /// public Action ExtendClientAreaToDecorationsChanged { get; set; } - + /// - public bool NeedsManagedDecorations => _isClientAreaExtended && - _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints - .PreferSystemChrome); + public bool NeedsManagedDecorations => _isClientAreaExtended && _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome); /// public Thickness ExtendedMargins => _extendedMargins; @@ -1331,8 +1315,7 @@ namespace Avalonia.Win32 public Thickness OffScreenMargin => _offScreenMargin; /// - public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = - new AcrylicPlatformCompensationLevels(1, 0.8, 0); + public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 0.8, 0); private ResizeReasonScope SetResizeReason(PlatformResizeReason reason) { @@ -1360,7 +1343,7 @@ namespace Avalonia.Win32 { private readonly WindowImpl _owner; private readonly PlatformResizeReason _restore; - + public ResizeReasonScope(WindowImpl owner, PlatformResizeReason restore) { _owner = owner;