diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm index 2dee90bfa3..0bd4b0f462 100644 --- a/native/Avalonia.Native/src/OSX/AvnWindow.mm +++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm @@ -435,9 +435,23 @@ return; } - if(window->WindowState() == Maximized) + // If the window has been moved into a position where it's "zoomed" + // Then it should be set as Maximized. + if (window->WindowState() != Maximized && window->IsZoomed()) { - window->SetWindowState(Normal); + window->SetWindowState(Maximized, false); + } + // We should only return the window state to normal if + // the internal window state is maximized, and macOS says + // the window is no longer zoomed (I.E, the user has moved it) + // Stage Manager will "move" the window when repositioning it + // So if the window was "maximized" before, it should stay maximized + else if(window->WindowState() == Maximized && !window->IsZoomed()) + { + // If we're moving the window while maximized, + // we need to let macOS handle if it should be resized + // And not handle it ourselves. + window->SetWindowState(Normal, false); } } diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.h b/native/Avalonia.Native/src/OSX/WindowImpl.h index fce7273f30..37699082ed 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.h +++ b/native/Avalonia.Native/src/OSX/WindowImpl.h @@ -71,6 +71,8 @@ BEGIN_INTERFACE_MAP() void ExitFullScreenMode (); virtual HRESULT SetWindowState (AvnWindowState state) override; + + virtual HRESULT SetWindowState (AvnWindowState state, bool shouldResize); virtual bool IsModal() override; diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index 03f3319bcd..341085ec08 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -451,6 +451,10 @@ void WindowImpl::ExitFullScreenMode() { } HRESULT WindowImpl::SetWindowState(AvnWindowState state) { + return SetWindowState(state, true); +} + +HRESULT WindowImpl::SetWindowState(AvnWindowState state, bool shouldResize) { START_COM_CALL; @autoreleasepool { @@ -474,61 +478,63 @@ HRESULT WindowImpl::SetWindowState(AvnWindowState state) { if (_shown) { _actualWindowState = _lastWindowState; - switch (state) { - case Maximized: - if (currentState == FullScreen) { - ExitFullScreenMode(); - } + if (shouldResize) { + switch (state) { + case Maximized: + if (currentState == FullScreen) { + ExitFullScreenMode(); + } - lastPositionSet.X = 0; - lastPositionSet.Y = 0; + lastPositionSet.X = 0; + lastPositionSet.Y = 0; - if ([Window isMiniaturized]) { - [Window deminiaturize:Window]; - } + if ([Window isMiniaturized]) { + [Window deminiaturize:Window]; + } - if (!IsZoomed()) { - DoZoom(); - } - break; + if (!IsZoomed()) { + DoZoom(); + } + break; - case Minimized: - if (currentState == FullScreen) { - ExitFullScreenMode(); - } else { - [Window miniaturize:Window]; - } - break; + case Minimized: + if (currentState == FullScreen) { + ExitFullScreenMode(); + } else { + [Window miniaturize:Window]; + } + break; - case FullScreen: - if ([Window isMiniaturized]) { - [Window deminiaturize:Window]; - } + case FullScreen: + if ([Window isMiniaturized]) { + [Window deminiaturize:Window]; + } - EnterFullScreenMode(); - break; + EnterFullScreenMode(); + break; - case Normal: - if ([Window isMiniaturized]) { - [Window deminiaturize:Window]; - } + case Normal: + if ([Window isMiniaturized]) { + [Window deminiaturize:Window]; + } - if (currentState == FullScreen) { - ExitFullScreenMode(); - } + if (currentState == FullScreen) { + ExitFullScreenMode(); + } - if (IsZoomed()) { - if (_decorations == SystemDecorationsFull) { - DoZoom(); - } else { - [Window setFrame:_preZoomSize display:true]; - auto newFrame = [Window contentRectForFrameRect:[Window frame]].size; + if (IsZoomed()) { + if (_decorations == SystemDecorationsFull) { + DoZoom(); + } else { + [Window setFrame:_preZoomSize display:true]; + auto newFrame = [Window contentRectForFrameRect:[Window frame]].size; - [View setFrameSize:newFrame]; - } + [View setFrameSize:newFrame]; + } - } - break; + } + break; + } } WindowEvents->WindowStateChanged(_actualWindowState);