Better handling of maximized window.
Used the “zoom” command before, but it has some limitations (e.g. no event when zoom is done).
This commit is contained in:
parent
7c3872531e
commit
d1fb2597bb
1 changed files with 81 additions and 59 deletions
|
@ -64,8 +64,8 @@ namespace OpenTK.Platform.MacOS
|
|||
static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber");
|
||||
static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:");
|
||||
static readonly IntPtr selStyleMask = Selector.Get("styleMask");
|
||||
static readonly IntPtr selIsMiniaturized = Selector.Get("isMiniaturized");
|
||||
static readonly IntPtr selIsZoomed = Selector.Get("isZoomed");
|
||||
// static readonly IntPtr selIsMiniaturized = Selector.Get("isMiniaturized");
|
||||
// static readonly IntPtr selIsZoomed = Selector.Get("isZoomed");
|
||||
static readonly IntPtr selMiniaturize = Selector.Get("miniaturize:");
|
||||
static readonly IntPtr selDeminiaturize = Selector.Get("deminiaturize:");
|
||||
static readonly IntPtr selZoom = Selector.Get("zoom:");
|
||||
|
@ -96,15 +96,15 @@ namespace OpenTK.Platform.MacOS
|
|||
private System.Drawing.Icon icon;
|
||||
private LegacyInputDriver inputDriver = new LegacyInputDriver();
|
||||
private WindowBorder windowBorder = WindowBorder.Resizable;
|
||||
private WindowState windowState = WindowState.Normal;
|
||||
private MacOSKeyMap keyMap = new MacOSKeyMap();
|
||||
private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
|
||||
private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
|
||||
string title;
|
||||
RectangleF normalBounds;
|
||||
int normalLevel;
|
||||
|
||||
bool exclusiveFullscreen = true;
|
||||
bool fullscreenMode;
|
||||
RectangleF preFullscreenBounds;
|
||||
int preFullscreenLevel;
|
||||
const bool exclusiveFullscreen = true;
|
||||
|
||||
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||
{
|
||||
|
@ -114,10 +114,11 @@ namespace OpenTK.Platform.MacOS
|
|||
Class.RegisterMethod(windowClass, new WindowDidMoveDelegate(WindowDidMove), "windowDidMove:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowDidBecomeKeyDelegate(WindowDidBecomeKey), "windowDidBecomeKey:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowDidResignKeyDelegate(WindowDidResignKey), "windowDidResignKey:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowWillMiniaturizeDelegate(WindowWillMiniaturize), "windowWillMiniaturize:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowDidMiniaturizeDelegate(WindowDidMiniaturize), "windowDidMiniaturize:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowDidDeminiaturizeDelegate(WindowDidDeminiaturize), "windowDidDeminiaturize:", "v@:@");
|
||||
Class.RegisterMethod(windowClass, new WindowShouldZoomToFrameDelegate(WindowShouldZoomToFrame), "windowShouldZoom:toFrame:", "b@:@{NSRect={NSPoint=ff}{NSSize=ff}}");
|
||||
|
||||
|
||||
Class.RegisterMethod(windowClass, new WindowShouldCloseDelegate(WindowShouldClose), "windowShouldClose:", "b@:@");
|
||||
Class.RegisterMethod(windowClass, new AcceptsFirstResponderDelegate(AcceptsFirstResponder), "acceptsFirstResponder", "b@:");
|
||||
Class.RegisterMethod(windowClass, new CanBecomeKeyWindowDelegate(CanBecomeKeyWindow), "canBecomeKeyWindow", "b@:");
|
||||
|
@ -148,6 +149,7 @@ namespace OpenTK.Platform.MacOS
|
|||
delegate void WindowDidMoveDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate void WindowDidBecomeKeyDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate void WindowDidResignKeyDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate void WindowWillMiniaturizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate void WindowDidMiniaturizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate void WindowDidDeminiaturizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
|
||||
delegate bool WindowShouldZoomToFrameDelegate(IntPtr self, IntPtr cmd, IntPtr nsWindow, RectangleF toFrame);
|
||||
|
@ -158,7 +160,15 @@ namespace OpenTK.Platform.MacOS
|
|||
|
||||
private void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||
{
|
||||
ResetTrackingArea();
|
||||
OnResize(true);
|
||||
}
|
||||
|
||||
private void OnResize(bool resetTracking)
|
||||
{
|
||||
if (resetTracking)
|
||||
{
|
||||
ResetTrackingArea();
|
||||
}
|
||||
GraphicsContext.CurrentContext.Update(windowInfo);
|
||||
Resize(this, EventArgs.Empty);
|
||||
}
|
||||
|
@ -180,21 +190,45 @@ namespace OpenTK.Platform.MacOS
|
|||
FocusedChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void WindowWillMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||
{
|
||||
// Can get stuck in weird states if we maximize, then minimize;
|
||||
// restoring to the old state would override the normalBounds.
|
||||
// To avoid this without adding complexity, just restore state here.
|
||||
RestoreWindowState(); // Avoid getting in weird states
|
||||
}
|
||||
|
||||
private void WindowDidMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||
{
|
||||
windowState = WindowState.Minimized;
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
OnResize(false); // Don't set tracking area when we minimize
|
||||
}
|
||||
|
||||
private void WindowDidDeminiaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||
{
|
||||
windowState = WindowState.Normal;
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
OnResize(true);
|
||||
}
|
||||
|
||||
private bool WindowShouldZoomToFrame(IntPtr self, IntPtr cmd, IntPtr nsWindow, RectangleF toFrame)
|
||||
{
|
||||
// Problem: This is called before the zoom/unzoom event animation begins rather than afterwards.
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
return true;
|
||||
if (windowState == WindowState.Maximized)
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
normalBounds = InternalBounds;
|
||||
Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)GetStyleMask(WindowBorder.Fixed));
|
||||
|
||||
InternalBounds = toFrame;
|
||||
windowState = WindowState.Maximized;
|
||||
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender)
|
||||
|
@ -497,8 +531,7 @@ namespace OpenTK.Platform.MacOS
|
|||
|
||||
private void RestoreWindowState()
|
||||
{
|
||||
var ws = WindowState;
|
||||
if (ws == WindowState.Fullscreen)
|
||||
if (windowState == WindowState.Fullscreen)
|
||||
{
|
||||
//Cocoa.SendVoid(windowInfo.ViewHandle, selExitFullScreenModeWithOptions, IntPtr.Zero);
|
||||
|
||||
|
@ -506,74 +539,63 @@ namespace OpenTK.Platform.MacOS
|
|||
if (exclusiveFullscreen)
|
||||
{
|
||||
OpenTK.Platform.MacOS.Carbon.CG.DisplayReleaseAll();
|
||||
Cocoa.SendVoid(windowInfo.Handle, selSetLevel, preFullscreenLevel);
|
||||
Cocoa.SendVoid(windowInfo.Handle, selSetLevel, normalLevel);
|
||||
}
|
||||
|
||||
UpdateWindowBorder();
|
||||
InternalBounds = preFullscreenBounds;
|
||||
fullscreenMode = false;
|
||||
InternalBounds = normalBounds;
|
||||
}
|
||||
else if (ws == WindowState.Maximized)
|
||||
else if (windowState == WindowState.Maximized)
|
||||
{
|
||||
Cocoa.SendVoid(windowInfo.Handle, selZoom, windowInfo.Handle);
|
||||
UpdateWindowBorder();
|
||||
InternalBounds = normalBounds;
|
||||
}
|
||||
else if (ws == WindowState.Minimized)
|
||||
else if (windowState == WindowState.Minimized)
|
||||
{
|
||||
Cocoa.SendVoid(windowInfo.Handle, selDeminiaturize, windowInfo.Handle);
|
||||
}
|
||||
|
||||
windowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
public WindowState WindowState
|
||||
{
|
||||
get
|
||||
{
|
||||
if (fullscreenMode)
|
||||
return WindowState.Fullscreen;
|
||||
|
||||
if (Cocoa.SendBool(windowInfo.Handle, selIsMiniaturized))
|
||||
return WindowState.Minimized;
|
||||
|
||||
if (Cocoa.SendBool(windowInfo.Handle, selIsZoomed))
|
||||
return WindowState.Maximized;
|
||||
|
||||
return WindowState.Normal;
|
||||
return windowState;
|
||||
}
|
||||
set
|
||||
{
|
||||
var oldState = WindowState;
|
||||
var oldState = windowState;
|
||||
if (oldState == value)
|
||||
return;
|
||||
|
||||
RestoreWindowState();
|
||||
bool sendEvent = true;
|
||||
|
||||
if (value == WindowState.Fullscreen)
|
||||
{
|
||||
// NSApplicationPresentationOptions options =
|
||||
// NSApplicationPresentationOptions.DisableAppleMenu |
|
||||
// NSApplicationPresentationOptions.HideMenuBar |
|
||||
// NSApplicationPresentationOptions.HideDock;
|
||||
//
|
||||
// // "Exclusive fullscreen"?
|
||||
// //NSApplicationPresentationOptions.DisableProcessSwitching;
|
||||
//
|
||||
// var obj = Cocoa.SendIntPtr(Class.Get("NSNumber"), Selector.Get("numberWithUnsignedLong:"), (ulong)options);
|
||||
// var key = Cocoa.ToNSString("NSFullScreenModeApplicationPresentationOptions");
|
||||
//
|
||||
// var nsDictionary = Cocoa.SendIntPtr(Class.Get("NSDictionary"), Selector.Alloc);
|
||||
// nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Get("initWithObjectsAndKeys:"), obj, key, IntPtr.Zero);
|
||||
// nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Autorelease);
|
||||
//
|
||||
// Cocoa.SendVoid(windowInfo.ViewHandle, selEnterFullScreenModeWithOptions, GetCurrentScreen(), nsDictionary);
|
||||
// NSApplicationPresentationOptions options =
|
||||
// NSApplicationPresentationOptions.DisableAppleMenu |
|
||||
// NSApplicationPresentationOptions.HideMenuBar |
|
||||
// NSApplicationPresentationOptions.HideDock;
|
||||
//
|
||||
// // "Exclusive fullscreen"?
|
||||
// //NSApplicationPresentationOptions.DisableProcessSwitching;
|
||||
//
|
||||
// var obj = Cocoa.SendIntPtr(Class.Get("NSNumber"), Selector.Get("numberWithUnsignedLong:"), (ulong)options);
|
||||
// var key = Cocoa.ToNSString("NSFullScreenModeApplicationPresentationOptions");
|
||||
//
|
||||
// var nsDictionary = Cocoa.SendIntPtr(Class.Get("NSDictionary"), Selector.Alloc);
|
||||
// nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Get("initWithObjectsAndKeys:"), obj, key, IntPtr.Zero);
|
||||
// nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Autorelease);
|
||||
//
|
||||
// Cocoa.SendVoid(windowInfo.ViewHandle, selEnterFullScreenModeWithOptions, GetCurrentScreen(), nsDictionary);
|
||||
|
||||
fullscreenMode = true;
|
||||
|
||||
preFullscreenBounds = InternalBounds;
|
||||
var screenFrame = GetCurrentScreenFrame();
|
||||
normalBounds = InternalBounds;
|
||||
|
||||
if (exclusiveFullscreen)
|
||||
{
|
||||
preFullscreenLevel = Cocoa.SendInt(windowInfo.Handle, selLevel);
|
||||
normalLevel = Cocoa.SendInt(windowInfo.Handle, selLevel);
|
||||
var windowLevel = OpenTK.Platform.MacOS.Carbon.CG.ShieldingWindowLevel();
|
||||
|
||||
OpenTK.Platform.MacOS.Carbon.CG.CaptureAllDisplays();
|
||||
|
@ -581,8 +603,11 @@ namespace OpenTK.Platform.MacOS
|
|||
}
|
||||
|
||||
Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)NSWindowStyle.Borderless);
|
||||
InternalBounds = screenFrame;
|
||||
InternalBounds = GetCurrentScreenFrame();
|
||||
SetMenuVisible(false);
|
||||
|
||||
windowState = value;
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
}
|
||||
else if (value == WindowState.Maximized)
|
||||
{
|
||||
|
@ -591,15 +616,12 @@ namespace OpenTK.Platform.MacOS
|
|||
else if (value == WindowState.Minimized)
|
||||
{
|
||||
Cocoa.SendVoid(windowInfo.Handle, selMiniaturize, windowInfo.Handle);
|
||||
sendEvent = false; // Event sent by listener
|
||||
}
|
||||
|
||||
if (sendEvent)
|
||||
else if (value == WindowState.Normal)
|
||||
{
|
||||
windowState = value;
|
||||
WindowStateChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
WindowDidResize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -833,7 +855,7 @@ namespace OpenTK.Platform.MacOS
|
|||
{
|
||||
return Cocoa.SendRect(windowInfo.ViewHandle, selFrame);
|
||||
}
|
||||
|
||||
|
||||
private IntPtr GetCurrentScreen()
|
||||
{
|
||||
return Cocoa.SendIntPtr(windowInfo.Handle, selScreen);
|
||||
|
|
Loading…
Reference in a new issue