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,
Minimized,
Maximized,
FullScreen,
};
enum AvnStandardCursorType

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

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

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

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

Loading…
Cancel
Save