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:
Olle Håkansson 2014-04-20 23:30:37 +02:00 committed by thefiddler
parent 7c3872531e
commit d1fb2597bb

View file

@ -64,8 +64,8 @@ namespace OpenTK.Platform.MacOS
static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber"); static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber");
static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:"); static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:");
static readonly IntPtr selStyleMask = Selector.Get("styleMask"); static readonly IntPtr selStyleMask = Selector.Get("styleMask");
static readonly IntPtr selIsMiniaturized = Selector.Get("isMiniaturized"); // static readonly IntPtr selIsMiniaturized = Selector.Get("isMiniaturized");
static readonly IntPtr selIsZoomed = Selector.Get("isZoomed"); // static readonly IntPtr selIsZoomed = Selector.Get("isZoomed");
static readonly IntPtr selMiniaturize = Selector.Get("miniaturize:"); static readonly IntPtr selMiniaturize = Selector.Get("miniaturize:");
static readonly IntPtr selDeminiaturize = Selector.Get("deminiaturize:"); static readonly IntPtr selDeminiaturize = Selector.Get("deminiaturize:");
static readonly IntPtr selZoom = Selector.Get("zoom:"); static readonly IntPtr selZoom = Selector.Get("zoom:");
@ -96,15 +96,15 @@ namespace OpenTK.Platform.MacOS
private System.Drawing.Icon icon; private System.Drawing.Icon icon;
private LegacyInputDriver inputDriver = new LegacyInputDriver(); private LegacyInputDriver inputDriver = new LegacyInputDriver();
private WindowBorder windowBorder = WindowBorder.Resizable; private WindowBorder windowBorder = WindowBorder.Resizable;
private WindowState windowState = WindowState.Normal;
private MacOSKeyMap keyMap = new MacOSKeyMap(); private MacOSKeyMap keyMap = new MacOSKeyMap();
private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs(); private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0); private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
string title; string title;
RectangleF normalBounds;
int normalLevel;
bool exclusiveFullscreen = true; const bool exclusiveFullscreen = true;
bool fullscreenMode;
RectangleF preFullscreenBounds;
int preFullscreenLevel;
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device) public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{ {
@ -114,6 +114,7 @@ namespace OpenTK.Platform.MacOS
Class.RegisterMethod(windowClass, new WindowDidMoveDelegate(WindowDidMove), "windowDidMove:", "v@:@"); Class.RegisterMethod(windowClass, new WindowDidMoveDelegate(WindowDidMove), "windowDidMove:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidBecomeKeyDelegate(WindowDidBecomeKey), "windowDidBecomeKey:", "v@:@"); Class.RegisterMethod(windowClass, new WindowDidBecomeKeyDelegate(WindowDidBecomeKey), "windowDidBecomeKey:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidResignKeyDelegate(WindowDidResignKey), "windowDidResignKey:", "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 WindowDidMiniaturizeDelegate(WindowDidMiniaturize), "windowDidMiniaturize:", "v@:@");
Class.RegisterMethod(windowClass, new WindowDidDeminiaturizeDelegate(WindowDidDeminiaturize), "windowDidDeminiaturize:", "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 WindowShouldZoomToFrameDelegate(WindowShouldZoomToFrame), "windowShouldZoom:toFrame:", "b@:@{NSRect={NSPoint=ff}{NSSize=ff}}");
@ -148,6 +149,7 @@ namespace OpenTK.Platform.MacOS
delegate void WindowDidMoveDelegate(IntPtr self, IntPtr cmd, IntPtr notification); delegate void WindowDidMoveDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
delegate void WindowDidBecomeKeyDelegate(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 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 WindowDidMiniaturizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
delegate void WindowDidDeminiaturizeDelegate(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); delegate bool WindowShouldZoomToFrameDelegate(IntPtr self, IntPtr cmd, IntPtr nsWindow, RectangleF toFrame);
@ -157,8 +159,16 @@ namespace OpenTK.Platform.MacOS
delegate bool CanBecomeMainWindowDelegate(IntPtr self, IntPtr cmd); delegate bool CanBecomeMainWindowDelegate(IntPtr self, IntPtr cmd);
private void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification) private void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
{
OnResize(true);
}
private void OnResize(bool resetTracking)
{
if (resetTracking)
{ {
ResetTrackingArea(); ResetTrackingArea();
}
GraphicsContext.CurrentContext.Update(windowInfo); GraphicsContext.CurrentContext.Update(windowInfo);
Resize(this, EventArgs.Empty); Resize(this, EventArgs.Empty);
} }
@ -180,21 +190,45 @@ namespace OpenTK.Platform.MacOS
FocusedChanged(this, EventArgs.Empty); 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) private void WindowDidMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
{ {
windowState = WindowState.Minimized;
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
OnResize(false); // Don't set tracking area when we minimize
} }
private void WindowDidDeminiaturize(IntPtr self, IntPtr cmd, IntPtr notification) private void WindowDidDeminiaturize(IntPtr self, IntPtr cmd, IntPtr notification)
{ {
windowState = WindowState.Normal;
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
OnResize(true);
} }
private bool WindowShouldZoomToFrame(IntPtr self, IntPtr cmd, IntPtr nsWindow, RectangleF toFrame) 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. 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); WindowStateChanged(this, EventArgs.Empty);
return true; }
return false;
} }
private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender) private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender)
@ -497,8 +531,7 @@ namespace OpenTK.Platform.MacOS
private void RestoreWindowState() private void RestoreWindowState()
{ {
var ws = WindowState; if (windowState == WindowState.Fullscreen)
if (ws == WindowState.Fullscreen)
{ {
//Cocoa.SendVoid(windowInfo.ViewHandle, selExitFullScreenModeWithOptions, IntPtr.Zero); //Cocoa.SendVoid(windowInfo.ViewHandle, selExitFullScreenModeWithOptions, IntPtr.Zero);
@ -506,46 +539,38 @@ namespace OpenTK.Platform.MacOS
if (exclusiveFullscreen) if (exclusiveFullscreen)
{ {
OpenTK.Platform.MacOS.Carbon.CG.DisplayReleaseAll(); OpenTK.Platform.MacOS.Carbon.CG.DisplayReleaseAll();
Cocoa.SendVoid(windowInfo.Handle, selSetLevel, preFullscreenLevel); Cocoa.SendVoid(windowInfo.Handle, selSetLevel, normalLevel);
} }
UpdateWindowBorder(); UpdateWindowBorder();
InternalBounds = preFullscreenBounds; InternalBounds = normalBounds;
fullscreenMode = false;
} }
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); Cocoa.SendVoid(windowInfo.Handle, selDeminiaturize, windowInfo.Handle);
} }
windowState = WindowState.Normal;
} }
public WindowState WindowState public WindowState WindowState
{ {
get get
{ {
if (fullscreenMode) return windowState;
return WindowState.Fullscreen;
if (Cocoa.SendBool(windowInfo.Handle, selIsMiniaturized))
return WindowState.Minimized;
if (Cocoa.SendBool(windowInfo.Handle, selIsZoomed))
return WindowState.Maximized;
return WindowState.Normal;
} }
set set
{ {
var oldState = WindowState; var oldState = windowState;
if (oldState == value) if (oldState == value)
return; return;
RestoreWindowState(); RestoreWindowState();
bool sendEvent = true;
if (value == WindowState.Fullscreen) if (value == WindowState.Fullscreen)
{ {
@ -566,14 +591,11 @@ namespace OpenTK.Platform.MacOS
// //
// Cocoa.SendVoid(windowInfo.ViewHandle, selEnterFullScreenModeWithOptions, GetCurrentScreen(), nsDictionary); // Cocoa.SendVoid(windowInfo.ViewHandle, selEnterFullScreenModeWithOptions, GetCurrentScreen(), nsDictionary);
fullscreenMode = true; normalBounds = InternalBounds;
preFullscreenBounds = InternalBounds;
var screenFrame = GetCurrentScreenFrame();
if (exclusiveFullscreen) if (exclusiveFullscreen)
{ {
preFullscreenLevel = Cocoa.SendInt(windowInfo.Handle, selLevel); normalLevel = Cocoa.SendInt(windowInfo.Handle, selLevel);
var windowLevel = OpenTK.Platform.MacOS.Carbon.CG.ShieldingWindowLevel(); var windowLevel = OpenTK.Platform.MacOS.Carbon.CG.ShieldingWindowLevel();
OpenTK.Platform.MacOS.Carbon.CG.CaptureAllDisplays(); OpenTK.Platform.MacOS.Carbon.CG.CaptureAllDisplays();
@ -581,8 +603,11 @@ namespace OpenTK.Platform.MacOS
} }
Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)NSWindowStyle.Borderless); Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)NSWindowStyle.Borderless);
InternalBounds = screenFrame; InternalBounds = GetCurrentScreenFrame();
SetMenuVisible(false); SetMenuVisible(false);
windowState = value;
WindowStateChanged(this, EventArgs.Empty);
} }
else if (value == WindowState.Maximized) else if (value == WindowState.Maximized)
{ {
@ -591,15 +616,12 @@ namespace OpenTK.Platform.MacOS
else if (value == WindowState.Minimized) else if (value == WindowState.Minimized)
{ {
Cocoa.SendVoid(windowInfo.Handle, selMiniaturize, windowInfo.Handle); Cocoa.SendVoid(windowInfo.Handle, selMiniaturize, windowInfo.Handle);
sendEvent = false; // Event sent by listener
} }
else if (value == WindowState.Normal)
if (sendEvent)
{ {
windowState = value;
WindowStateChanged(this, EventArgs.Empty); WindowStateChanged(this, EventArgs.Empty);
} }
WindowDidResize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
} }
} }