Author: pbartok
Date: 2005-12-08 20:17:53 -0500 (Thu, 08 Dec 2005)
New Revision: 54138

Modified:
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
Log:
2005-12-08  Peter Dennis Bartok  <[EMAIL PROTECTED]>

        * Control.cs:
          - Added internal version of Invoke, with additional argument 
            indicating if we're calling it from a Dispose() handler. That
            way we can avoid BeginInvoke throwing an exception if we're
            calling for an already destroyed window.
          - Added a dispose argument to BeginInvokeInternal, and made the
            check if a valid window handle chain exists conditional on
            it not being a dispose call
          - Removed code in DestroyHandle to destroy our children. Since we
            now handle the WM_DESTROY message we will catch all our children
            being destroyed.
          - Now calling OnHandleDestroyed from our new WM_DESTROY handler
        * Form.cs:
          - Added a field to track the application context of the form.
          - No need to set closing variable as response to WM_CLOSE, instead
            we destroy the window. We also call PostQuitMessage if the form
            has an application context (which makes it the main app form,
            which, when closed terminates the app)
        * XplatUI.cs:
          - Dropped Exit() method, it's naming was confusing
          - Added PostQuitMessage() which causes GetMessage to return false
            once the message queue is empty
        * XplatUIDriver.cs, XplatUIWin32.cs: Dropped Exit(), added 
          PostQuitMessage()
        * XplatUIOSX.cs: Switched signature for Exit method since Exit() is
          no longer a valid XplatUI method, but left it in since it's used
          internally. Added empty PostQuitMessage() method.
        * MenuAPI.cs: Replaced call to Exit() with call to
          PostQuitMessage, even though this is probably no longer needed.
        * Hwnd.cs: Added 'pretty' ToString() to support debugging.
        * X11Structs.cs: Added pretty XEvent.ToString() to support debugging.
        * Application.cs:
          - Replaced call to XplatUI.Exit() with PostQuitMessage()
          - Removed old debug code that would call XplatUI for exception
            display, enabled standard exception handling (Still not enabled
            though, until NativeWindow's ExternalExceptionHandler define
            is removed
        * NativeWindow.cs:
          - Added internal method to allow control to update NativeWindow
            after a window has been destroyed
          - Added handling of already destroyed windows when calling i
            DestroyWindow
          - Added removal of handle from list on ReleaseHandle
        * XplatUIX11.cs:
          - Dropped GetMessageResult var and related code
          - Added PostQuitState to field to track if PostQuitMessage has been
            called
          - Dropped Exit() method
          - Added PostQuitMessage() method
          - GetMessage now will return false if PostQuitState is set and no
            more messages are in the queue.
          - Expose handler will no longer generate WM_PAINT messages if we are
            in PostQuitState since it's very likely any windows have already
            been destroyed, and since Hwnd won't get updated until we have
            processed the DestroyNotify we'd be causing X errors.
        


Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs   
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs   
2005-12-09 01:17:53 UTC (rev 54138)
@@ -17,13 +17,12 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-// Copyright (c) 2004 Novell, Inc.
+// Copyright (c) 2004 - 2005 Novell, Inc.
 //
 // Authors:
 //     Peter Bartok    [EMAIL PROTECTED]
 //
 
-
 // COMPLETE
 
 using Microsoft.Win32;
@@ -266,7 +265,7 @@
 #endif
 
                public static void Exit() {
-                       XplatUI.Exit();
+                       XplatUI.PostQuitMessage(0);
                }
 
                public static void ExitThread() {
@@ -287,20 +286,13 @@
                                Application.ThreadException(null, new 
ThreadExceptionEventArgs(t));
                                return;
                        }
-#if !later
-                        else {
-                               XplatUI.HandleException(t);
-                       }
-#else
-                       // TODO: Missing implementation
-                       //if (SystemInformation.UserInteractive)
-                       {
+
+                       if (SystemInformation.UserInteractive) {
                                Form form = new ThreadExceptionDialog (t);
                                form.ShowDialog ();
-                       }
-                       //else
+                       } else {
                                Console.WriteLine (t.ToString ());
-#endif
+                       }
                }
 
                public static void RemoveMessageFilter(IMessageFilter filter) {
@@ -313,6 +305,7 @@
 
                        if (app_context != null) {
                                form = app_context.MainForm;
+                               form.context = app_context;
                        }
 
                        if (form != null) {
@@ -357,6 +350,10 @@
 
                        messageloop_started = false;
 
+                       if (form != null) {
+                               form.context = null;
+                       }
+
                        if (ThreadExit != null) {
                                ThreadExit(null, EventArgs.Empty);
                        }

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2005-12-09 01:17:53 UTC (rev 54138)
@@ -1,3 +1,61 @@
+2005-12-08  Peter Dennis Bartok  <[EMAIL PROTECTED]>
+
+       * Control.cs:
+         - Added internal version of Invoke, with additional argument 
+           indicating if we're calling it from a Dispose() handler. That
+           way we can avoid BeginInvoke throwing an exception if we're
+           calling for an already destroyed window.
+         - Added a dispose argument to BeginInvokeInternal, and made the
+           check if a valid window handle chain exists conditional on
+           it not being a dispose call
+         - Removed code in DestroyHandle to destroy our children. Since we
+           now handle the WM_DESTROY message we will catch all our children
+           being destroyed.
+         - Now calling OnHandleDestroyed from our new WM_DESTROY handler
+       * Form.cs:
+         - Added a field to track the application context of the form.
+         - No need to set closing variable as response to WM_CLOSE, instead
+           we destroy the window. We also call PostQuitMessage if the form
+           has an application context (which makes it the main app form,
+           which, when closed terminates the app)
+       * XplatUI.cs:
+         - Dropped Exit() method, it's naming was confusing
+         - Added PostQuitMessage() which causes GetMessage to return false
+           once the message queue is empty
+       * XplatUIDriver.cs, XplatUIWin32.cs: Dropped Exit(), added 
+         PostQuitMessage()
+       * XplatUIOSX.cs: Switched signature for Exit method since Exit() is
+         no longer a valid XplatUI method, but left it in since it's used
+         internally. Added empty PostQuitMessage() method.
+       * MenuAPI.cs: Replaced call to Exit() with call to
+         PostQuitMessage, even though this is probably no longer needed.
+       * Hwnd.cs: Added 'pretty' ToString() to support debugging.
+       * X11Structs.cs: Added pretty XEvent.ToString() to support debugging.
+       * Application.cs:
+         - Replaced call to XplatUI.Exit() with PostQuitMessage()
+         - Removed old debug code that would call XplatUI for exception
+           display, enabled standard exception handling (Still not enabled
+           though, until NativeWindow's ExternalExceptionHandler define
+           is removed
+       * NativeWindow.cs:
+         - Added internal method to allow control to update NativeWindow
+           after a window has been destroyed
+         - Added handling of already destroyed windows when calling i
+           DestroyWindow
+         - Added removal of handle from list on ReleaseHandle
+       * XplatUIX11.cs:
+         - Dropped GetMessageResult var and related code
+         - Added PostQuitState to field to track if PostQuitMessage has been
+           called
+         - Dropped Exit() method
+         - Added PostQuitMessage() method
+         - GetMessage now will return false if PostQuitState is set and no
+           more messages are in the queue.
+         - Expose handler will no longer generate WM_PAINT messages if we are
+           in PostQuitState since it's very likely any windows have already
+           been destroyed, and since Hwnd won't get updated until we have
+           processed the DestroyNotify we'd be causing X errors.
+       
 2005-12-07  Peter Dennis Bartok  <[EMAIL PROTECTED]>
 
        * Control.cs(WndProc): Apparently I'm suffering from brain cloud.

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs       
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs       
2005-12-09 01:17:53 UTC (rev 54138)
@@ -725,8 +725,8 @@
                        }
 
                        if (this.InvokeRequired) {
-                               this.Invoke(new MethodInvoker(DestroyHandle));
-                               this.Invoke(new 
RemoveDelegate(controls.Remove), new object[] {this});
+                               this.InvokeInternal(new 
MethodInvoker(DestroyHandle), true);
+                               this.InvokeInternal(new 
RemoveDelegate(controls.Remove), new object[] {this}, true);
                        } else {
                                DestroyHandle();
                                controls.Remove(this);
@@ -757,19 +757,22 @@
                #endregion      // Internal Properties
 
                #region Private & Internal Methods
-               internal IAsyncResult BeginInvokeInternal (Delegate method, 
object [] args) {
+               internal IAsyncResult BeginInvokeInternal (Delegate method, 
object [] args, bool disposing) {
                        AsyncMethodResult       result;
                        AsyncMethodData         data;
-                       Control                 p;
 
-                       p = this;
-                       do {
-                               if (!p.IsHandleCreated) {
-                                       throw new 
InvalidOperationException("Cannot call Invoke or InvokeAsync on a control until 
the window handle is created");
-                               }
-                               p = p.parent;
-                       } while (p != null);
+                       if (!disposing) {
+                               Control                 p;
 
+                               p = this;
+                               do {
+                                       if (!p.IsHandleCreated) {
+                                               throw new 
InvalidOperationException("Cannot call Invoke or InvokeAsync on a control until 
the window handle is created");
+                                       }
+                                       p = p.parent;
+                               } while (p != null);
+                       }
+
                        result = new AsyncMethodResult ();
                        data = new AsyncMethodData ();
 
@@ -2313,12 +2316,12 @@
                #region Public Instance Methods
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                public IAsyncResult BeginInvoke(Delegate method) {
-                       return BeginInvokeInternal(method, null);
+                       return BeginInvokeInternal(method, null, false);
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                public IAsyncResult BeginInvoke (Delegate method, object[] 
args) {
-                       return BeginInvokeInternal (method, args);
+                       return BeginInvokeInternal (method, args, false);
                }
 
                public void BringToFront() {
@@ -2504,6 +2507,19 @@
                        return EndInvoke(result);
                }
 
+               internal object InvokeInternal (Delegate method, bool 
disposing) {
+                       return InvokeInternal(method, null, disposing);
+               }
+
+               internal object InvokeInternal (Delegate method, object[] args, 
bool disposing) {
+                       if (!this.InvokeRequired) {
+                               return method.DynamicInvoke(args);
+                       }
+
+                       IAsyncResult result = BeginInvokeInternal (method, 
args, disposing);
+                       return EndInvoke(result);
+               }
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                public void PerformLayout() {
                        PerformLayout(null, null);
@@ -2905,18 +2921,9 @@
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void DestroyHandle() {
                        if (IsHandleCreated) {
-                               // Destroy our children before we destroy 
ourselves, to prevent them from
-                               // being implictly (without us knowing) 
destroyed
-                               Control [] controls = 
child_controls.GetAllControls ();
-                               for (int i=0; i < controls.Length; i++) {
-                                       controls[i].DestroyHandle();
-                               }
-
-
                                if (window != null) {
                                        window.DestroyHandle();
                                }
-                               OnHandleDestroyed(EventArgs.Empty);
                        }
                }
 
@@ -3496,6 +3503,12 @@
                        }
 
                        switch((Msg)m.Msg) {
+                               case Msg.WM_DESTROY: {
+                                       OnHandleDestroyed(EventArgs.Empty);
+                                       window.InvalidateHandle();
+                                       break;
+                               }
+
                                case Msg.WM_WINDOWPOSCHANGED: {
                                        if (Visible) {
                                                UpdateBounds();

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs  
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs  
2005-12-09 01:17:53 UTC (rev 54138)
@@ -74,6 +74,7 @@
                private Rectangle               maximized_bounds;
                private Rectangle               default_maximized_bounds;
                private double                  opacity;
+               internal ApplicationContext     context;
                Color                           transparency_key;
 
                #endregion      // Local Variables
@@ -964,7 +965,10 @@
                        OnClosing (args);
                        if (!args.Cancel) {
                                OnClosed (EventArgs.Empty);
-                               closing = true;
+                               DestroyHandle();
+                               if (context != null) {
+                                       XplatUI.PostQuitMessage(0);
+                               }
                                return;
                        }
                }
@@ -1441,16 +1445,23 @@
 
                        switch((Msg)m.Msg) {
                                case Msg.WM_CLOSE: {
+                                       Close();
+#if not
                                        CancelEventArgs args = new 
CancelEventArgs();
 
                                        OnClosing(args);
 
                                        if (!args.Cancel) {
                                                OnClosed(EventArgs.Empty);
-                                               closing = true;
+                                               DestroyHandle();
+                                               if (context != null) {
+                                                       
XplatUI.PostQuitMessage(0);
+                                               }
                                                base.WndProc(ref m);
                                                break;
                                        }
+#endif
+                                       base.WndProc(ref m);
                                        break;
                                }
 

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs  
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs  
2005-12-09 01:17:53 UTC (rev 54138)
@@ -481,6 +481,11 @@
                        invalid = Rectangle.Empty;
                        expose_pending = false;
                }
+
+               public override string ToString() {
+                       return String.Format("Hwnd, ClientWindow:{0:X}, 
WholeWindow:{1:X}, Handle:{2:X}", client_window, whole_window, handle);
+               }
+
                #endregion      // Methods
        }
 }

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs       
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs       
2005-12-09 01:17:53 UTC (rev 54138)
@@ -216,7 +216,7 @@
                        }
 
                        if (!no_quit)
-                               XplatUI.Exit();
+                               XplatUI.PostQuitMessage(0);
 
                        tracker.Dispose ();
 

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs  
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NativeWindow.cs  
2005-12-09 01:17:53 UTC (rev 54138)
@@ -63,11 +63,15 @@
                }
                #endregion      // Public Static Methods
 
-               #region Private and Internal Static Methods
+               #region Private and Internal Methods
                internal static NativeWindow FindWindow(IntPtr handle) {
                        return (NativeWindow)window_collection[handle];
-                       
                }
+
+               internal void InvalidateHandle() {
+                       window_collection.Remove(window_handle);
+                       window_handle = IntPtr.Zero;
+               }
                #endregion
 
                #region Public Instance Methods
@@ -95,12 +99,15 @@
                }
 
                public virtual void DestroyHandle() {
-                       window_collection.Remove(window_handle);
-                       XplatUI.DestroyWindow(window_handle);
-                       window_handle=IntPtr.Zero;
+                       if (window_handle != IntPtr.Zero) {
+                               window_collection.Remove(window_handle);
+                               XplatUI.DestroyWindow(window_handle);
+                               window_handle=IntPtr.Zero;
+                       }
                }
 
                public virtual void ReleaseHandle() {
+                       window_collection.Remove(window_handle);
                        window_handle=IntPtr.Zero;
                        OnHandleChange();
                }

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs    
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Structs.cs    
2005-12-09 01:17:53 UTC (rev 54138)
@@ -550,6 +550,9 @@
                
//[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, 
SizeConst=24)]
                //[ FieldOffset(0) ] internal int[] pad;
                [ FieldOffset(0) ] internal XEventPad Pad;
+               public override string ToString() {
+                       return type.ToString();
+               }
        }
 
        [StructLayout(LayoutKind.Sequential)]

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs       
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs       
2005-12-09 01:17:53 UTC (rev 54138)
@@ -390,10 +390,6 @@
                        driver.EnableWindow(handle, Enable);
                }
 
-               internal static void Exit() {
-                       driver.Exit();
-               }
-
                internal static IntPtr GetActive() {
                        #if DriverDebug
                                Console.WriteLine("GetActive(): Called");
@@ -554,6 +550,10 @@
                        return driver.PeekMessage(ref msg, hWnd, wFilterMin, 
wFilterMax, flags);
                }
 
+               internal static void PostQuitMessage(int exitCode) {
+                       driver.PostQuitMessage(exitCode);
+               }
+
                internal static void ReleaseMenuDC(IntPtr handle, Graphics dc) {
                        #if DriverDebug
                                Console.WriteLine("ReleaseMenuDC({0:X}): 
Called", handle.ToInt32());

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs 
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIDriver.cs 
2005-12-09 01:17:53 UTC (rev 54138)
@@ -106,7 +106,6 @@
 
                #region XplatUI Driver Methods
                internal abstract void AudibleAlert();
-               internal abstract void Exit();
 
                internal abstract void EnableThemes();
 
@@ -157,6 +156,7 @@
                internal abstract void HandleException(Exception e);
                internal abstract void DoEvents();
                internal abstract bool PeekMessage(ref MSG msg, IntPtr hWnd, 
int wFilterMin, int wFilterMax, uint flags);
+               internal abstract void PostQuitMessage(int exitCode);
                internal abstract bool GetMessage(ref MSG msg, IntPtr hWnd, int 
wFilterMin, int wFilterMax);
                internal abstract bool TranslateMessage(ref MSG msg);
                internal abstract IntPtr DispatchMessage(ref MSG msg);

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs    
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs    
2005-12-09 01:17:53 UTC (rev 54138)
@@ -1088,7 +1088,7 @@
                                case Msg.WM_DESTROY: {
                                        if (WindowMapping [hwnd.Handle] != null)
 
-                                               XplatUI.Exit ();
+                                               Exit ();
                                        break;
                                }
                        }
@@ -1138,7 +1138,7 @@
                        //Like X11 we need not do anything here
                }
 
-               internal override void Exit() {
+               internal void Exit() {
                        GetMessageResult = false;
                        ExitToShell ();
                }
@@ -1376,6 +1376,11 @@
                        msg.lParam = lParam;
                        MessageQueue.Enqueue (msg);
                }
+
+               [MonoTODO]
+               internal override void PostQuitMessage(int exitCode) {
+                       throw new NotImplementedException();
+               }
                
                [MonoTODO]
                internal override void ReleaseMenuDC(IntPtr hwnd, Graphics dc) {

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs  
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs  
2005-12-09 01:17:53 UTC (rev 54138)
@@ -994,10 +994,6 @@
                        Console.WriteLine("Xplat version $revision: $");
                }
 
-               internal override void Exit() {
-                       Win32PostQuitMessage(0);
-               }
-
                internal override void AudibleAlert() {
                        Win32PlaySound("Default", IntPtr.Zero, 
SndFlags.SND_ALIAS | SndFlags.SND_ASYNC | SndFlags.SND_NOSTOP | 
SndFlags.SND_NOWAIT);
                }
@@ -1237,6 +1233,10 @@
                        return Win32PeekMessage(ref msg, hWnd, wFilterMin, 
wFilterMax, flags);
                }
 
+               internal override void PostQuitMessage(int exitCode) {
+                       Win32PostQuitMessage(exitCode);
+               }
+
                internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int 
wFilterMin, int wFilterMax) {
                        bool            result;
 

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs    
2005-12-08 23:20:52 UTC (rev 54137)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs    
2005-12-09 01:17:53 UTC (rev 54138)
@@ -83,6 +83,7 @@
                private static IntPtr           FosterParent;           // 
Container to hold child windows until their parent exists
                private static XErrorHandler    ErrorHandler;           // 
Error handler delegate
                private static bool             ErrorExceptions;        // 
Throw exceptions on X errors
+               private static bool             PostQuitState;          // True 
if we've got an pending exit
 
                // Clipboard
                private static IntPtr           ClipMagic = new 
IntPtr(27051977);
@@ -93,7 +94,6 @@
                private static int              AsyncAtom;              // 
Support for async messages
 
                // Message Loop
-               private static bool             GetMessageResult;       // 
Value returned by GetMessage()
                private static XEventQueue      MessageQueue;           // 
Holds our queued up events
                #if __MonoCS__                                          //
                private static Pollfd[]         pollfds;                // For 
watching the X11 socket
@@ -367,7 +367,7 @@
                                Keyboard = new X11Keyboard(DisplayHandle);
                                Dnd = new X11Dnd (DisplayHandle);
 
-                               GetMessageResult = true;
+                               PostQuitState = false;
 
                                DoubleClickInterval = 500;
 
@@ -997,7 +997,7 @@
                                lock (XlibLock) {
                                        XNextEvent (DisplayHandle, ref xevent);
                                }
-
+//Console.WriteLine("Got x event {0}", xevent);
                                switch (xevent.type) {
                                        case XEventName.Expose:
                                                AddExpose (xevent);
@@ -2191,8 +2191,6 @@
                                        XDestroyWindow(DisplayHandle, 
hwnd.whole_window);
                                }
                        }
-
-                       hwnd.Dispose();
                }
 
                internal override IntPtr DispatchMessage(ref MSG msg) {
@@ -2279,11 +2277,6 @@
                        // We do nothing; On X11 SetModal is used to create 
modal dialogs, on Win32 this function is used (see comment there)
                }
 
-               internal override void Exit() {
-                       GetMessageResult = false;
-                       Graphics.FromHdcInternal (IntPtr.Zero);
-               }
-
                internal override IntPtr GetActive() {
                        Atom    actual_atom;
                        int     actual_format;
@@ -2415,9 +2408,13 @@
                                if (MessageQueue.Count > 0) {
                                        xevent = (XEvent) MessageQueue.Dequeue 
();
                                } else {
-                                       msg.hwnd= IntPtr.Zero;
-                                       msg.message = Msg.WM_ENTERIDLE;
-                                       return true;
+                                       if (!PostQuitState) {
+                                               msg.hwnd= IntPtr.Zero;
+                                               msg.message = Msg.WM_ENTERIDLE;
+                                               return true;
+                                       }
+
+                                       return false;
                                }
                        }
 
@@ -2738,6 +2735,10 @@
                                }
 
                                case XEventName.Expose: {
+                                       if (PostQuitState) {
+                                               goto ProcessNextMessage;
+                                       }
+
                                        if (!client) {
                                                switch (hwnd.border_style) {
                                                        case 
FormBorderStyle.Fixed3D: {
@@ -2792,7 +2793,7 @@
                                        hwnd = 
Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
 
                                        // We may get multiple for the same 
window, act only one the first (when Hwnd still knows about it)
-                                       if (hwnd != null) {
+                                       if ((hwnd != null) && 
(hwnd.client_window == xevent.DestroyWindowEvent.window)) {
                                                msg.hwnd = hwnd.client_window;
                                                msg.message=Msg.WM_DESTROY;
                                                hwnd.Dispose();
@@ -2864,7 +2865,7 @@
                                }
                        }
 
-                       return GetMessageResult;
+                       return true;
                }
 
                internal override bool GetText(IntPtr handle, out string text) {
@@ -3163,6 +3164,14 @@
                        MessageQueue.Enqueue (xevent);
                }
 
+               internal override void PostQuitMessage(int exitCode) {
+                       XFlush(DisplayHandle);
+                       PostQuitState = true;
+
+                       // Remove our display handle from S.D
+                       Graphics.FromHdcInternal (IntPtr.Zero);
+               }
+
                internal override void ReleaseMenuDC(IntPtr handle, Graphics 
dc) {
                        dc.Dispose();
                }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to