diff --git a/Source/GLControl/CarbonGLControl.cs b/Source/GLControl/CarbonGLControl.cs index 22dfef8e..40cebef5 100644 --- a/Source/GLControl/CarbonGLControl.cs +++ b/Source/GLControl/CarbonGLControl.cs @@ -46,7 +46,24 @@ namespace OpenTK this.mode = mode; this.control = owner; - window_info = Utilities.CreateMacOSCarbonWindowInfo(control.Handle, false, true); + window_info = Utilities.CreateMacOSCarbonWindowInfo(control.Handle, false, true, GetXOffset, GetYOffset); + } + + private int GetXOffset() + { + return control.Location.X; + } + + private int GetYOffset() + { + if (control.TopLevelControl != null) + { + System.Drawing.Point offset = control.PointToScreen (control.Location); + System.Drawing.Point windowOffset = control.TopLevelControl.PointToScreen (System.Drawing.Point.Empty); + int relativeY = offset.Y - windowOffset.Y; //control.TopLevelControl.Location.Y is not the same as windowOffset.Y for some reason. + return control.TopLevelControl.ClientSize.Height - control.Bottom - relativeY; + } + return control.Location.Y; } #region IGLControl Members diff --git a/Source/GLControl/GLControl.cs b/Source/GLControl/GLControl.cs index c2f616f6..faba119d 100644 --- a/Source/GLControl/GLControl.cs +++ b/Source/GLControl/GLControl.cs @@ -270,12 +270,30 @@ namespace OpenTK return; } - if (context != null) - context.Update(Implementation.WindowInfo); + if (Configuration.RunningOnMacOS) + { + DelayUpdate delay = PerformContextUpdate; + BeginInvoke(delay); //Need the native window to resize first otherwise our control will be in the wrong place. + } + else if (context != null) + context.Update (Implementation.WindowInfo); base.OnResize(e); } + /// + /// Needed to delay the invoke on OS X. Also needed because OpenTK is .NET 2, otherwise I'd use an inline Action. + /// + public delegate void DelayUpdate(); + /// + /// Execute the delayed context update + /// + public void PerformContextUpdate() + { + if (context != null) + context.Update (Implementation.WindowInfo); + } + /// /// Raises the ParentChanged event. /// diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index f8e0fe0c..eab21a05 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -172,32 +172,20 @@ namespace OpenTK.Platform.MacOS if (carbonWindow.IsControl == false) return; - // Todo: See if there is a way around using WinForms. - throw new NotImplementedException(); -#if false - System.Windows.Forms.Control ctrl = Control.FromHandle(carbonWindow.WindowRef); - - if (ctrl.TopLevelControl == null) - return; - - Rect rect = API.GetControlBounds(carbonWindow.WindowRef); - System.Windows.Forms.Form frm = (System.Windows.Forms.Form)ctrl.TopLevelControl; - - System.Drawing.Point loc = frm.PointToClient(ctrl.PointToScreen(System.Drawing.Point.Empty)); - - rect.X = (short)loc.X; - rect.Y = (short)loc.Y; + Rect rect = API.GetControlBounds(carbonWindow.WindowHandle); Debug.Print("Setting buffer_rect for control."); Debug.Print("MacOS Coordinate Rect: {0}", rect); - - rect.Y = (short)(ctrl.TopLevelControl.ClientSize.Height - rect.Y - rect.Height); - Debug.Print(" AGL Coordinate Rect: {0}", rect); - int[] glrect = new int[4]; - - glrect[0] = rect.X; - glrect[1] = rect.Y; + + if (carbonWindow.XOffset != null) + glrect[0] = rect.X + carbonWindow.XOffset(); + else + glrect[0] = rect.X; + if (carbonWindow.YOffset != null) + glrect[1] = rect.Y + carbonWindow.YOffset(); + else + glrect[1] = rect.Y; glrect[2] = rect.Width; glrect[3] = rect.Height; @@ -206,7 +194,6 @@ namespace OpenTK.Platform.MacOS Agl.aglEnable(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT); MyAGLReportError("aglEnable"); -#endif } void SetDrawable(CarbonWindowInfo carbonWindow) { diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs index 717a6c58..687857b2 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -32,6 +32,13 @@ using System.Text; namespace OpenTK.Platform.MacOS { + /// + /// This delegate represents any method that takes no arguments and returns an int. + /// I would have used Func but that requires .NET 4 + /// + /// The int value that your method returns + public delegate int GetInt(); + /// \internal /// /// Describes a Carbon window. @@ -45,6 +52,9 @@ namespace OpenTK.Platform.MacOS bool goFullScreenHack = false; bool goWindowedHack = false; + GetInt xOffset; + GetInt yOffset; + #region Constructors /// @@ -60,6 +70,12 @@ namespace OpenTK.Platform.MacOS this.isControl = isControl; } + public CarbonWindowInfo(IntPtr windowRef, bool ownHandle, bool isControl, GetInt getX, GetInt getY) : this(windowRef, ownHandle, isControl) + { + this.xOffset = getX; + this.yOffset = getY; + } + #endregion #region Public Members @@ -104,6 +120,16 @@ namespace OpenTK.Platform.MacOS // (e.g. MonoGame) public IntPtr WindowHandle { get { return Handle; } set { Handle = value; } } + public GetInt XOffset + { + get { return xOffset; } + set { xOffset = value; } + } + public GetInt YOffset + { + get { return yOffset; } + set { yOffset = value; } + } #endregion #region IDisposable Members diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index 82fa91ab..2de2dcea 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -273,7 +273,22 @@ namespace OpenTK.Platform /// A new IWindowInfo instance. public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool ownHandle, bool isControl) { - return new OpenTK.Platform.MacOS.CarbonWindowInfo(windowHandle, false, isControl); + return CreateMacOSCarbonWindowInfo(windowHandle, ownHandle, isControl, null, null); + } + + /// + /// Creates an IWindowInfo instance for the Mac OS X platform with an X and Y offset for the GL viewport location. + /// + /// The handle of the window. + /// Ignored. This is reserved for future use. + /// Set to true if windowHandle corresponds to a System.Windows.Forms control. + /// The X offset for the GL viewport + /// The Y offset for the GL viewport + /// A new IWindowInfo instance. + public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool ownHandle, bool isControl, + OpenTK.Platform.MacOS.GetInt xOffset, OpenTK.Platform.MacOS.GetInt yOffset) + { + return new OpenTK.Platform.MacOS.CarbonWindowInfo(windowHandle, false, isControl, xOffset, yOffset); } #endregion