diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h index 8c51e1cf50..2424e48c64 100644 --- a/native/Avalonia.Native/inc/avalonia-native.h +++ b/native/Avalonia.Native/inc/avalonia-native.h @@ -204,6 +204,15 @@ enum AvnMenuItemToggleType Radio }; +enum AvnExtendClientAreaChromeHints +{ + AvnChromeHintsNoChrome, + AvnChromeHintsSystemTitleBar = 0x01, + AvnChromeHintsManagedChromeButtons = 0x02, + AvnChromeHintsPreferSystemChromeButtons = 0x04, + AvnChromeHintsOSXThickTitleBar = 0x08, +}; + AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown { public: @@ -277,6 +286,8 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase virtual HRESULT SetWindowState(AvnWindowState state) = 0; virtual HRESULT GetWindowState(AvnWindowState*ret) = 0; virtual HRESULT SetExtendClientArea (bool enable) = 0; + virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) = 0; + virtual HRESULT GetExtendTitleBarHeight (double*ret) = 0; }; AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 19b0524a26..50cb9940b8 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -475,6 +475,7 @@ private: NSRect _preZoomSize; bool _transitioningWindowState; bool _isClientAreaExtended; + AvnExtendClientAreaChromeHints _extendClientHints; FORWARD_IUNKNOWN() BEGIN_INTERFACE_MAP() @@ -489,6 +490,7 @@ private: WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl) { _isClientAreaExtended = false; + _extendClientHints = AvnChromeHintsNoChrome; _fullScreenActive = false; _canResize = true; _decorations = SystemDecorationsFull; @@ -509,6 +511,9 @@ private: for (id button in titlebarView.subviews) { if ([button isKindOfClass:[NSButton class]]) { [button setHidden: (_decorations != SystemDecorationsFull)]; + [[button layer] setZPosition:5]; + [button setWantsLayer:true]; + } } } @@ -771,25 +776,75 @@ private: virtual HRESULT SetExtendClientArea (bool enable) override { _isClientAreaExtended = enable; - [Window setTitleVisibility:NSWindowTitleHidden]; - [Window setTitlebarAppearsTransparent:enable]; - Window.movableByWindowBackground = true; - - NSRect x; - x.size.height = 50; - x.size.width = Window.frame.size.width; - [Window contentLayoutRect] = x; + if(enable) + { + Window.titleVisibility = NSWindowTitleHidden; + + if(_extendClientHints & AvnChromeHintsSystemTitleBar) + { + [Window setTitlebarAppearsTransparent:false]; + View.layer.zPosition = 1; + } + else + { + [Window setTitlebarAppearsTransparent:true]; + View.layer.zPosition = 0; + } + + if(_extendClientHints & AvnChromeHintsOSXThickTitleBar) + { + Window.toolbar = [NSToolbar new]; + Window.toolbar.showsBaselineSeparator = false; + } + else + { + Window.toolbar = nullptr; + } + } + else + { + Window.titleVisibility = NSWindowTitleVisible; + Window.toolbar = nullptr; + [Window setTitlebarAppearsTransparent:false]; + View.layer.zPosition = 0; + } - auto customToolbar = [NSToolbar new]; + UpdateStyle(); - customToolbar.showsBaselineSeparator = true; - Window.toolbar = customToolbar; + return S_OK; + } + + virtual HRESULT SetExtendClientAreaHints (AvnExtendClientAreaChromeHints hints) + { + _extendClientHints = hints; - UpdateStyle(); + SetExtendClientArea(_isClientAreaExtended); return S_OK; } + virtual HRESULT GetExtendTitleBarHeight (double*ret) + { + if(ret == nullptr) + { + return E_POINTER; + } + + for (id subview in Window.contentView.superview.subviews) + { + if ([subview isKindOfClass:NSClassFromString(@"NSTitlebarContainerView")]) + { + NSView *titlebarView = [subview subviews][0]; + + *ret = (double)titlebarView.frame.size.height; + + return S_OK; + } + } + + return E_FAIL; + } + void EnterFullScreenMode () { _fullScreenActive = true; diff --git a/src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs b/src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs index 075e4ba436..b59d0ffe2e 100644 --- a/src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs +++ b/src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs @@ -10,6 +10,9 @@ namespace Avalonia.Platform SystemTitleBar = 0x01, ManagedChromeButtons = 0x02, PreferSystemChromeButtons = 0x04, + + OSXThickTitleBar = 0x08, + AdaptiveChromeWithTitleBar = SystemTitleBar | PreferSystemChromeButtons, AdaptiveChromeWithoutTitleBar = PreferSystemChromeButtons, } diff --git a/src/Avalonia.Native/WindowImpl.cs b/src/Avalonia.Native/WindowImpl.cs index 0adc009911..3afe8c670b 100644 --- a/src/Avalonia.Native/WindowImpl.cs +++ b/src/Avalonia.Native/WindowImpl.cs @@ -102,7 +102,7 @@ namespace Avalonia.Native public Action ExtendClientAreaToDecorationsChanged { get; set; } - public Thickness ExtendedMargins { get; } = new Thickness(0, 20, 0, 0); + public Thickness ExtendedMargins { get; private set; } public Thickness OffScreenMargin { get; } = new Thickness(); @@ -137,12 +137,17 @@ namespace Avalonia.Native public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint) { _isExtended = extendIntoClientAreaHint; + _native.SetExtendClientArea(extendIntoClientAreaHint); + + ExtendedMargins = _isExtended ? new Thickness(0, _native.GetExtendTitleBarHeight(), 0, 0) : new Thickness(); + ExtendClientAreaToDecorationsChanged?.Invoke(true); } public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints) { + _native.SetExtendClientAreaHints ((AvnExtendClientAreaChromeHints)hints); } public void SetExtendClientAreaTitleBarHeightHint(double titleBarHeight)