2007-11-01 Geoff Norton <gnorton@novell.com>
authorGeoff Norton <grompf@sublimeintervention.com>
Fri, 2 Nov 2007 00:08:14 +0000 (00:08 -0000)
committerGeoff Norton <grompf@sublimeintervention.com>
Fri, 2 Nov 2007 00:08:14 +0000 (00:08 -0000)
    * XplatUI*.cs: Add GetPreviousWindow utility method to return windows in
    order of Z-Order.
    * Hwnd.cs: Add initial implementation of GetClippingRectangles to clip sibling
    children out of the drawing view on mac.
    * XplatUIOSX.cs: Code cleanup.  Handle more window grab cases.  Fix SetParent
    to handle the orphan and invisible case (1/2 fixes TabStrip drawing in FormsTest)

svn path=/trunk/mcs/; revision=88702

mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/XplatUIX11-new.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

index 74e31a32e305f87638ce9c4b381a72c357e1968e..f0f7867ad4b571af8a4031a2b8f95ef9afe153a2 100644 (file)
@@ -525,6 +525,11 @@ namespace System.Windows.Forms.X11Internal {
                        return IntPtr.Zero;
                }
 
+               // This is a nop on win32 and x11
+               internal override IntPtr GetPreviousWindow(IntPtr handle) {
+                       return handle;
+               }
+
                internal override void GetCursorPos (IntPtr handle, out int x, out int y)
                {
                        display.GetCursorPos ((X11Hwnd)Hwnd.ObjectFromHandle(handle),
index 110b8dd2afe4b25bb86651e34b74d60321b4669e..0cac0785dd0a8cb6b1163f60ceb8f4a786bfe1ff 100644 (file)
@@ -1,3 +1,12 @@
+2007-11-01  Geoff Norton  <gnorton@novell.com>
+
+       * XplatUI*.cs: Add GetPreviousWindow utility method to return windows in
+       order of Z-Order.
+       * Hwnd.cs: Add initial implementation of GetClippingRectangles to clip sibling 
+       children out of the drawing view on mac.
+       * XplatUIOSX.cs: Code cleanup.  Handle more window grab cases.  Fix SetParent
+       to handle the orphan and invisible case (1/2 fixes TabStrip drawing in FormsTest)
+       
 2007-11-01  Jonathan Pobst  <monkey@jpobst.com>
 
        * ToolStrip.cs: Don't process MouseUp for a ToolStripControlHost, clicking
index 6640a7adc0b8e1dede5d6900210e7c05d9c62bf0..7dacdd464a69787c96196c2ca0a09efff61e4787 100644 (file)
@@ -86,6 +86,7 @@ namespace System.Windows.Forms {
                internal Point          previous_child_startup_location = new Point (int.MinValue, int.MinValue);
                static internal Point   previous_main_startup_location = new Point (int.MinValue, int.MinValue);
                internal ArrayList children;
+               internal ArrayList masks;
                #endregion      // Local Variables
 
                // locks for some operations (used in XplatUIX11.cs)
@@ -116,6 +117,7 @@ namespace System.Windows.Forms {
                        fixed_size = false;
                        drawing_stack = new Stack ();
                        children = new ArrayList ();
+                       masks = new ArrayList ();
                }
 
                public void Dispose() {
@@ -276,6 +278,46 @@ namespace System.Windows.Forms {
                        return GetClientRectangle (cp, menu, width, height);
                }
 
+               // This could be greatly optimized by caching the outputs and only updating when something is moved
+               // in the parent planar space.  To do that we need to track z-order in the parent space as well
+               public ArrayList GetClippingRectangles ()
+               {
+                       if (parent == null)
+                               return masks;
+
+                       masks = new ArrayList ();
+                       ArrayList siblings = parent.children;
+
+                       foreach (Hwnd sibling in siblings) {
+                               bool clip = false;
+                               IntPtr sibling_handle = whole_window;
+
+                               if (sibling == this)
+                                       continue;
+                               
+                               // This entire method should be cached to find all higher views at the time of query
+                               do {
+                                       sibling_handle = XplatUI.GetPreviousWindow (sibling_handle);
+
+                                       if (sibling_handle == sibling.WholeWindow) {
+
+                                               Rectangle intersect = Rectangle.Intersect (new Rectangle (X, Y, Width, Height), new Rectangle (sibling.X, sibling.Y, sibling.Width, sibling.Height));
+                               
+                                               if (intersect == Rectangle.Empty)
+                                                       continue;
+                                       
+                                               intersect.X -= X;
+                                               intersect.Y -= Y;
+                                               intersect.Y = parent.Height - intersect.Y - intersect.Height;
+                                       
+                                               masks.Add (intersect);
+                                       }
+                               } while (sibling_handle != IntPtr.Zero);
+                       }
+
+                       return masks;
+               }
+
                public static Borders GetBorders (CreateParams cp, Menu menu)
                {
 
index b7a5918db13ad23b80285ce2043b24b3111d1e33..1525e3682149a6ee5de969a8a53a492406f08cca 100644 (file)
@@ -678,6 +678,10 @@ namespace System.Windows.Forms {
                        return driver.GetParent(handle);
                }
 
+               internal static IntPtr GetPreviousWindow(IntPtr handle) {
+                       return driver.GetPreviousWindow(handle);
+               }
+
                internal static bool GetText(IntPtr handle, out string text) {
                        #if DriverDebug
                                Console.WriteLine("GetText({0}): Called", Window(handle));
index a766d76bbdbd1b6c6d38f3db5022125397d0a7f1..f7851a44dfa0eae927b41b2ea7c9e586ad043927 100644 (file)
@@ -344,6 +344,7 @@ namespace System.Windows.Forms {
                internal abstract IntPtr GetFocus();
                internal abstract void SetFocus(IntPtr hwnd);
                internal abstract IntPtr GetActive();
+               internal abstract IntPtr GetPreviousWindow(IntPtr hwnd);
 
                internal abstract void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool with_children);
                internal abstract void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool with_children);
index a6ada7c750ceb3857a01b65058f7b25ffbb7e941..c2199fc61bbecfc4649600eb1bf9aa7dd085e360 100644 (file)
@@ -72,7 +72,6 @@ namespace System.Windows.Forms {
                private static Hashtable WindowBackgrounds;
                private static Hwnd GrabWindowHwnd;
                private static IntPtr FosterParent;
-               private static int TitleBarHeight;
                private static int MenuBarHeight;
                private static EventTypeSpec [] view_events = new EventTypeSpec [] {
                                                                        new EventTypeSpec (OSXConstants.kEventClassControl, OSXConstants.kEventControlSetFocusPart), 
@@ -198,7 +197,6 @@ namespace System.Windows.Forms {
                        CheckError (GetWindowBounds (FosterParent, 32, ref structRect), "GetWindowBounds ()");
                        CheckError (GetWindowBounds (FosterParent, 33, ref contentRect), "GetWindowBounds ()");
                        
-                       TitleBarHeight = Math.Abs(structRect.top - contentRect.top);
                        MenuBarHeight = GetMBarHeight ();
                        
                        // Focus
@@ -401,14 +399,17 @@ namespace System.Windows.Forms {
                                        
                                        Hwnd hwnd = Hwnd.ObjectFromHandle (view_handle);
                                        
-                                       if (GrabWindowHwnd != null)
-                                               hwnd = GrabWindowHwnd;
-                                       
                                        if (hwnd == null)
                                                return -9874;
-                                               
-                                       // Generate the message
+                                       
                                        bool client = (hwnd.ClientWindow == view_handle ? true : false);
+
+                                       if (GrabWindowHwnd != null) {
+                                               hwnd = GrabWindowHwnd;
+                                               client = true;
+                                       }
+                                       
+                                       // Generate the message
                                        msg.hwnd = hwnd.Handle;
                                        msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE);
                                        msg.lParam = (IntPtr) ((ushort)window_pt.y << 16 | (ushort)window_pt.x);
@@ -600,10 +601,13 @@ namespace System.Windows.Forms {
                                        int x = point.x;
                                        int y = point.y;
 
-                                       if (GrabWindowHwnd != null)
+                                       bool client = (hwnd.ClientWindow == handle ? true : false);
+
+                                       if (GrabWindowHwnd != null) {
                                                hwnd = GrabWindowHwnd;
+                                               client = false;
+                                       }
 
-                                       bool client = (hwnd.ClientWindow == handle ? true : false);
                                        if (client)
                                                ScreenToClient (hwnd.Handle, ref x, ref y);
 
@@ -1261,7 +1265,7 @@ namespace System.Windows.Forms {
                        hwnd.y = Y;
                        hwnd.width = Width;
                        hwnd.height = Height;
-                       hwnd.parent = Hwnd.ObjectFromHandle (cp.Parent);
+                       hwnd.Parent = Hwnd.ObjectFromHandle (cp.Parent);
                        hwnd.initial_style = cp.WindowStyle;
                        hwnd.initial_ex_style = cp.WindowExStyle;
 
@@ -1597,6 +1601,10 @@ namespace System.Windows.Forms {
                        }
                        return IntPtr.Zero;
                }
+
+               internal override IntPtr GetPreviousWindow(IntPtr handle) {
+                       return HIViewGetPreviousView(handle);
+               }
                
                internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
                        QDPoint pt = new QDPoint ();
@@ -1701,7 +1709,6 @@ namespace System.Windows.Forms {
                
                internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
                        GrabWindowHwnd = Hwnd.ObjectFromHandle (handle);
-                       Console.WriteLine ("GrabWindowHwnd: {0}", GrabWindowHwnd);
                }
                
                internal override void UngrabWindow(IntPtr hwnd) {
@@ -2021,13 +2028,16 @@ namespace System.Windows.Forms {
                }
 
                internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
+                       IntPtr ParentHandle = IntPtr.Zero;
                        Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
                        
                        hwnd.Parent = Hwnd.ObjectFromHandle (parent);
                        if (HIViewGetSuperview (hwnd.whole_window) != IntPtr.Zero) {
                                CheckError (HIViewRemoveFromSuperview (hwnd.whole_window), "HIViewRemoveFromSuperview ()");
                        }
-                       CheckError (HIViewAddSubview (hwnd.Parent.client_window, hwnd.whole_window));
+                       if (hwnd.parent == null)
+                               HIViewFindByID (HIViewGetRoot (FosterParent), new HIViewID (OSXConstants.kEventClassWindow, 1), ref ParentHandle);
+                       CheckError (HIViewAddSubview (hwnd.parent == null ? ParentHandle : hwnd.Parent.client_window, hwnd.whole_window));
                        HIViewPlaceInSuperviewAt (hwnd.whole_window, hwnd.X, hwnd.Y);
                        CheckError (HIViewAddSubview (hwnd.whole_window, hwnd.client_window));
                        HIViewPlaceInSuperviewAt (hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y);
@@ -2095,34 +2105,52 @@ namespace System.Windows.Forms {
                                return;
                        }
 
-                       if (width < 0) width = 0;
-                       if (height < 0) height = 0;
+                       // Win32 automatically changes negative width/height to 0.
+                       if (width < 0)
+                               width = 0;
+                       if (height < 0)
+                               height = 0;
+                               
+                       // X requires a sanity check for width & height; otherwise it dies
+                       if (hwnd.zero_sized && width > 0 && height > 0) {
+                               if (hwnd.visible) {
+                                       HIViewSetVisible(hwnd.WholeWindow, true);
+                               }
+                               hwnd.zero_sized = false;
+                       }
+
+                       if ((width < 1) || (height < 1)) {
+                               hwnd.zero_sized = true;
+                               HIViewSetVisible(hwnd.WholeWindow, false);
+                       }
 
                        // Save a server roundtrip (and prevent a feedback loop)
                        if ((hwnd.x == x) && (hwnd.y == y) && (hwnd.width == width) && (hwnd.height == height)) {
                                return;
                        }
 
-                       hwnd.x = x;
-                       hwnd.y = y;
-                       hwnd.width = width;
-                       hwnd.height = height;
-                       SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
+                       if (!hwnd.zero_sized) {
+                               hwnd.x = x;
+                               hwnd.y = y;
+                               hwnd.width = width;
+                               hwnd.height = height;
+                               SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
 
-                       Control ctrl = Control.FromHandle (handle);
-                       Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (ctrl.GetCreateParams (), new Size (width, height));
-                       Rect rect = new Rect ();
+                               Control ctrl = Control.FromHandle (handle);
+                               Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (ctrl.GetCreateParams (), new Size (width, height));
+                               Rect rect = new Rect ();
 
-                       if (WindowMapping [hwnd.Handle] != null) {
-                               SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
-                               SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
-                               HIRect frame_rect = new HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
-                               HIViewSetFrame (hwnd.whole_window, ref frame_rect);
-                       } else {
-                               HIRect frame_rect = new HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
-                               HIViewSetFrame (hwnd.whole_window, ref frame_rect);
+                               if (WindowMapping [hwnd.Handle] != null) {
+                                       SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
+                                       SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
+                                       HIRect frame_rect = new HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
+                                       HIViewSetFrame (hwnd.whole_window, ref frame_rect);
+                               } else {
+                                       HIRect frame_rect = new HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
+                                       HIViewSetFrame (hwnd.whole_window, ref frame_rect);
+                               }
+                               PerformNCCalc(hwnd);
                        }
-                       PerformNCCalc(hwnd);
 
                        hwnd.x = x;
                        hwnd.y = y;
index b835d4ba99587ef8894ffb4e2df8fbc3cc4c5bb1..a6bf73c87fc210abf006181e3c550cbfbbf11d38 100644 (file)
@@ -2215,6 +2215,11 @@ namespace System.Windows.Forms {
                        return Win32GetParent(handle);
                }
 
+               // This is a nop on win32 and x11
+               internal override IntPtr GetPreviousWindow(IntPtr handle) {
+                       return handle;
+               }
+
                internal override void GrabWindow(IntPtr hWnd, IntPtr ConfineToHwnd) {
                        grab_hwnd = hWnd;
                        Win32SetCapture(hWnd);
index 7535bcfc2ce3b97fee0b7284ed79bc2fcfd83639..dcc23f69fb44a0233948ca691417967c0ea35abd 100644 (file)
@@ -3525,6 +3525,11 @@ namespace System.Windows.Forms {
                        }
                        return IntPtr.Zero;
                }
+               
+               // This is a nop on win32 and x11
+               internal override IntPtr GetPreviousWindow(IntPtr handle) {
+                       return handle;
+               }
 
                internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
                        IntPtr  use_handle;