Browse Source

[OSX] implement FullScreen and fix sync of window states.

pull/3849/head
Dan Walmsley 6 years ago
parent
commit
c38c7e2d65
  1. 1
      native/Avalonia.Native/inc/avalonia-native.h
  2. 2
      native/Avalonia.Native/src/OSX/window.h
  3. 126
      native/Avalonia.Native/src/OSX/window.mm

1
native/Avalonia.Native/inc/avalonia-native.h

@ -135,6 +135,7 @@ enum AvnWindowState
Normal, Normal,
Minimized, Minimized,
Maximized, Maximized,
FullScreen,
}; };
enum AvnStandardCursorType enum AvnStandardCursorType

2
native/Avalonia.Native/src/OSX/window.h

@ -33,6 +33,8 @@ struct INSWindowHolder
struct IWindowStateChanged struct IWindowStateChanged
{ {
virtual void WindowStateChanged () = 0; virtual void WindowStateChanged () = 0;
virtual void StartStateTransition () = 0;
virtual void EndStateTransition () = 0;
}; };
#endif /* window_h */ #endif /* window_h */

126
native/Avalonia.Native/src/OSX/window.mm

@ -408,6 +408,8 @@ private:
SystemDecorations _hasDecorations = SystemDecorationsFull; SystemDecorations _hasDecorations = SystemDecorationsFull;
CGRect _lastUndecoratedFrame; CGRect _lastUndecoratedFrame;
AvnWindowState _lastWindowState; AvnWindowState _lastWindowState;
bool _inSetWindowState;
bool _transitioningWindowState;
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
BEGIN_INTERFACE_MAP() BEGIN_INTERFACE_MAP()
@ -421,6 +423,8 @@ private:
ComPtr<IAvnWindowEvents> WindowEvents; ComPtr<IAvnWindowEvents> WindowEvents;
WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl) WindowImpl(IAvnWindowEvents* events, IAvnGlContext* gl) : WindowBaseImpl(events, gl)
{ {
_transitioningWindowState = false;
_inSetWindowState = false;
_lastWindowState = Normal; _lastWindowState = Normal;
WindowEvents = events; WindowEvents = events;
[Window setCanBecomeKeyAndMain]; [Window setCanBecomeKeyAndMain];
@ -457,11 +461,29 @@ private:
} }
} }
void StartStateTransition () override
{
_transitioningWindowState = true;
}
void EndStateTransition () override
{
_transitioningWindowState = false;
}
void WindowStateChanged () override void WindowStateChanged () override
{ {
AvnWindowState state; if(!_inSetWindowState && !_transitioningWindowState)
GetWindowState(&state); {
WindowEvents->WindowStateChanged(state); AvnWindowState state;
GetWindowState(&state);
if(_lastWindowState != state)
{
_lastWindowState = state;
WindowEvents->WindowStateChanged(state);
}
}
} }
bool UndecoratedIsMaximized () bool UndecoratedIsMaximized ()
@ -586,6 +608,12 @@ private:
return E_POINTER; return E_POINTER;
} }
if(([Window styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask)
{
*ret = FullScreen;
return S_OK;
}
if([Window isMiniaturized]) if([Window isMiniaturized])
{ {
*ret = Minimized; *ret = Minimized;
@ -608,12 +636,25 @@ private:
{ {
@autoreleasepool @autoreleasepool
{ {
if(_lastWindowState == state)
{
return S_OK;
}
_inSetWindowState = true;
auto currentState = _lastWindowState;
_lastWindowState = state; _lastWindowState = state;
if(_shown) if(_shown)
{ {
switch (state) { switch (state) {
case Maximized: case Maximized:
if(currentState == FullScreen)
{
[Window toggleFullScreen:nullptr];
}
lastPositionSet.X = 0; lastPositionSet.X = 0;
lastPositionSet.Y = 0; lastPositionSet.Y = 0;
@ -629,15 +670,29 @@ private:
break; break;
case Minimized: case Minimized:
if(currentState == FullScreen)
{
[Window toggleFullScreen:nullptr];
}
[Window miniaturize:Window]; [Window miniaturize:Window];
break; break;
default: case FullScreen:
[Window toggleFullScreen:nullptr];
break;
case Normal:
if([Window isMiniaturized]) if([Window isMiniaturized])
{ {
[Window deminiaturize:Window]; [Window deminiaturize:Window];
} }
if(currentState == FullScreen)
{
[Window toggleFullScreen:nullptr];
}
if(IsZoomed()) if(IsZoomed())
{ {
DoZoom(); DoZoom();
@ -646,23 +701,17 @@ private:
} }
} }
_inSetWindowState = false;
return S_OK; return S_OK;
} }
} }
virtual void OnResized () override virtual void OnResized () override
{ {
if(_shown) if(_shown && !_inSetWindowState && !_transitioningWindowState)
{ {
auto windowState = [Window isMiniaturized] ? Minimized WindowStateChanged();
: (IsZoomed() ? Maximized : Normal);
if (windowState != _lastWindowState)
{
_lastWindowState = windowState;
WindowEvents->WindowStateChanged(windowState);
}
} }
} }
@ -1378,7 +1427,54 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)windowDidResize:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification
{ {
_parent->OnResized(); auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->WindowStateChanged();
}
}
- (void)windowWillExitFullScreen:(NSNotification *)notification
{
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->StartStateTransition();
}
}
- (void)windowDidExitFullScreen:(NSNotification *)notification
{
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->EndStateTransition();
parent->WindowStateChanged();
}
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification
{
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->StartStateTransition();
}
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification
{
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->EndStateTransition();
parent->WindowStateChanged();
}
} }
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame

Loading…
Cancel
Save