Permalink
Browse files

Much improved handling of window/border states.

  • Loading branch information...
1 parent df6caa3 commit 4573db2ceb4f3c808648e0cb5d0e967ca6087ea9 @Ollhax Ollhax committed with thefiddler Apr 22, 2014
Showing with 72 additions and 38 deletions.
  1. +72 −38 Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
@@ -28,7 +28,7 @@ class CocoaNativeWindow : INativeWindow
static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
- static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
+ //static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
static readonly IntPtr selContentView = Selector.Get("contentView");
static readonly IntPtr selConvertRectFromScreen = Selector.Get("convertRectFromScreen:");
static readonly IntPtr selConvertRectToScreen = Selector.Get("convertRectToScreen:");
@@ -41,6 +41,7 @@ class CocoaNativeWindow : INativeWindow
static readonly IntPtr selIsVisible = Selector.Get("isVisible");
static readonly IntPtr selSetIsVisible = Selector.Get("setIsVisible:");
static readonly IntPtr selFrame = Selector.Get("frame");
+ static readonly IntPtr selVisibleFrame = Selector.Get("visibleFrame");
static readonly IntPtr selBounds = Selector.Get("bounds");
static readonly IntPtr selScreen = Selector.Get("screen");
static readonly IntPtr selSetFrame = Selector.Get("setFrame:display:");
@@ -64,10 +65,12 @@ class CocoaNativeWindow : INativeWindow
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 selPerformMiniaturize = Selector.Get("performMiniaturize:");
static readonly IntPtr selMiniaturize = Selector.Get("miniaturize:");
static readonly IntPtr selDeminiaturize = Selector.Get("deminiaturize:");
+ //static readonly IntPtr selPerformZoom = Selector.Get("performZoom:");
static readonly IntPtr selZoom = Selector.Get("zoom:");
static readonly IntPtr selLevel = Selector.Get("level");
static readonly IntPtr selSetLevel = Selector.Get("setLevel:");
@@ -96,14 +99,17 @@ static CocoaNativeWindow()
private System.Drawing.Icon icon;
private LegacyInputDriver inputDriver = new LegacyInputDriver();
private WindowBorder windowBorder = WindowBorder.Resizable;
+ private Nullable<WindowBorder> deferredWindowBorder;
+ private Nullable<WindowBorder> previousWindowBorder;
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);
private string title;
- private RectangleF normalBounds;
+ private RectangleF previousBounds;
private int normalLevel;
private bool shouldClose;
+ private int suppressResize;
private const bool exclusiveFullscreen = false;
@@ -119,7 +125,6 @@ public CocoaNativeWindow(int x, int y, int width, int height, string title, Grap
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@:");
@@ -171,7 +176,9 @@ private void OnResize(bool resetTracking)
ResetTrackingArea();
}
GraphicsContext.CurrentContext.Update(windowInfo);
- Resize(this, EventArgs.Empty);
+
+ if (suppressResize == 0)
+ Resize(this, EventArgs.Empty);
}
private void WindowDidMove(IntPtr self, IntPtr cmd, IntPtr notification)
@@ -221,8 +228,8 @@ private bool WindowShouldZoomToFrame(IntPtr self, IntPtr cmd, IntPtr nsWindow, R
}
else
{
- normalBounds = InternalBounds;
- Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)GetStyleMask(WindowBorder.Fixed));
+ previousBounds = InternalBounds;
+ previousWindowBorder = WindowBorder;
InternalBounds = toFrame;
windowState = WindowState.Maximized;
@@ -550,31 +557,53 @@ public IWindowInfo WindowInfo
private void RestoreWindowState()
{
+ suppressResize++;
if (windowState == WindowState.Fullscreen)
{
- //Cocoa.SendVoid(windowInfo.ViewHandle, selExitFullScreenModeWithOptions, IntPtr.Zero);
-
SetMenuVisible(true);
if (exclusiveFullscreen)
{
OpenTK.Platform.MacOS.Carbon.CG.DisplayReleaseAll();
Cocoa.SendVoid(windowInfo.Handle, selSetLevel, normalLevel);
}
- UpdateWindowBorder();
- InternalBounds = normalBounds;
+ RestoreBorder();
+ InternalBounds = previousBounds;
}
else if (windowState == WindowState.Maximized)
{
- UpdateWindowBorder();
- InternalBounds = normalBounds;
+ RestoreBorder();
+ InternalBounds = previousBounds;
}
else if (windowState == WindowState.Minimized)
{
Cocoa.SendVoid(windowInfo.Handle, selDeminiaturize, windowInfo.Handle);
}
windowState = WindowState.Normal;
+ suppressResize--;
+ }
+
+ private void HideBorder()
+ {
+ suppressResize++;
+ SetWindowBorder(WindowBorder.Hidden);
+ ProcessEvents();
+ suppressResize--;
+ }
+
+ private void RestoreBorder()
+ {
+ suppressResize++;
+ SetWindowBorder(
+ deferredWindowBorder.HasValue ? deferredWindowBorder.Value :
+ previousWindowBorder.HasValue ? previousWindowBorder.Value :
+ windowBorder);
+
+ ProcessEvents();
+ suppressResize--;
+ deferredWindowBorder = null;
+ previousWindowBorder = null;
}
public WindowState WindowState
@@ -593,25 +622,6 @@ public WindowState WindowState
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);
-
- normalBounds = InternalBounds;
-
if (exclusiveFullscreen)
{
normalLevel = Cocoa.SendInt(windowInfo.Handle, selLevel);
@@ -621,16 +631,19 @@ public WindowState WindowState
Cocoa.SendVoid(windowInfo.Handle, selSetLevel, windowLevel);
}
- Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)NSWindowStyle.Borderless);
- InternalBounds = GetCurrentScreenFrame();
+ previousBounds = InternalBounds;
+ previousWindowBorder = WindowBorder;
+
SetMenuVisible(false);
+ HideBorder();
+ InternalBounds = GetCurrentScreenFrame();
windowState = value;
WindowStateChanged(this, EventArgs.Empty);
}
else if (value == WindowState.Maximized)
{
- Cocoa.SendVoid(windowInfo.Handle, selZoom, windowInfo.Handle);
+ WindowShouldZoomToFrame(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, GetCurrentScreenVisibleFrame());
}
else if (value == WindowState.Minimized)
{
@@ -640,6 +653,7 @@ public WindowState WindowState
{
windowState = value;
WindowStateChanged(this, EventArgs.Empty);
+ Resize(this, EventArgs.Empty);
}
}
}
@@ -652,12 +666,27 @@ public WindowBorder WindowBorder
}
set
{
- windowBorder = value;
- UpdateWindowBorder();
+ // Do not allow border changes during fullscreen mode.
+ if (windowState == WindowState.Fullscreen || windowState == WindowState.Maximized)
+ {
+ deferredWindowBorder = value;
+ return;
+ }
+
+ if (windowBorder == value)
+ return;
+
+ SetWindowBorder(value);
WindowBorderChanged(this, EventArgs.Empty);
}
}
+ private void SetWindowBorder(WindowBorder windowBorder)
+ {
+ this.windowBorder = windowBorder;
+ UpdateWindowBorder();
+ }
+
private static NSWindowStyle GetStyleMask(WindowBorder windowBorder)
{
switch (windowBorder)
@@ -885,6 +914,11 @@ private RectangleF GetCurrentScreenFrame()
return Cocoa.SendRect(GetCurrentScreen(), selFrame);
}
+ private RectangleF GetCurrentScreenVisibleFrame()
+ {
+ return Cocoa.SendRect(GetCurrentScreen(), selVisibleFrame);
+ }
+
private void SetCursorVisible(bool visible)
{
// Problem: Unlike the PC version, you can move the mouse out of the window.

0 comments on commit 4573db2

Please sign in to comment.