Browse Source

activate message fix: a call to .Show now waits until both WM_SHOWWINDOW and
WM_ACTIVATE have been processed before returning, so it is guaranteed that
once it returns and the form is visible, it is actually on the screen on X11

* ContainerControl.cs: Only send focus to the control if the top container
is already focused. This is so that, when a form is first shown, all
the enter/leave events are done first before any focus stuff comes in.
If a control has no top container, there's an extra check on Control.Focus
to make sure it gets focused in this particular case.

* Control.cs: Force focus if the control is active but did not receive
focus after being set as active.

* MdiClient.cs: Dispose the form when closing

* XplatUIX11.cs: When mapping and unmapping windows, make sure the call
doesn't return until both WM_SHOWWINDOW and WM_ACTIVATE have come in
if the window is a top Form.
Reset all hwnd properties when the window has been destroyed so that
we don't land in any codepaths that might try to do something with it.
Added a bunch of debugging messages. If TRACE is defined, all X calls
are logged through DebugHelper. Set a few missing EntryPoint attributes.

* System.Windows.Forms.Internal/DebugHelper.cs: Added. Wrapper for Debug.*
methods, with some extras to ease debugging.

* System.Windows.Forms.Internal/Accessor.cs: Added. Provides access to
various internal properties, for testing purposes.

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

Andreia Gaita 17 years ago
parent
commit
30d3eeea79

+ 5 - 0
mcs/class/Managed.Windows.Forms/ChangeLog

@@ -1,3 +1,8 @@
+2008-10-31  Andreia Gaita  <[email protected]>
+
+	* System.Windows.Forms.dll.sources, SWF.csproj, SWF2k5.csproj:
+	  Added internal classes for debugging purposes
+
 2008-10-23  Andreia Gaita  <[email protected]>
 
 	* SWF.csproj, SWF2k5.csproj: Update project files

+ 10 - 0
mcs/class/Managed.Windows.Forms/SWF.csproj

@@ -228,6 +228,16 @@
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
+                <File
+                    RelPath = "System.Windows.Forms.Internal\Accessor.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "System.Windows.Forms.Internal\DebugHelper.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
                 <File
                     RelPath = "System.Windows.Forms.PropertyGridInternal\PropertiesTab.cs"
                     SubType = "Code"

+ 2 - 0
mcs/class/Managed.Windows.Forms/SWF2k5.csproj

@@ -173,6 +173,8 @@
     <Compile Include="System.Windows.Forms.Design\ToolStripItemDesignerAvailability.cs" />
     <Compile Include="System.Windows.Forms.Design\ToolStripItemDesignerAvailabilityAttribute.cs" />
     <Compile Include="System.Windows.Forms.Design\WindowsFormsComponentEditor.cs" />
+    <Compile Include="System.Windows.Forms.Internal\Accessor.cs" />
+    <Compile Include="System.Windows.Forms.Internal\DebugHelper.cs" />
     <Compile Include="System.Windows.Forms.PropertyGridInternal\PropertiesTab.cs" />
     <Compile Include="System.Windows.Forms.RTF\Charcode.cs" />
     <Compile Include="System.Windows.Forms.RTF\Charset.cs" />

+ 50 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms.Internal/Accessor.cs

@@ -0,0 +1,50 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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) 2008 Novell, Inc.
+//
+// Authors:
+//	Andreia Gaita ([email protected])
+//
+#if DEBUG_shana
+using System;
+
+namespace System.Windows.Forms.Internal
+{
+	public class Accessor
+	{
+		public static IntPtr Display {
+			get { return XplatUIX11.Display; }
+		}
+		
+		public static int Screen {
+			get { return XplatUIX11.Screen; }
+		}
+
+		public static IntPtr ClientWindow (Control c) {
+			return Hwnd.ObjectFromHandle(c.Handle).ClientWindow;
+		}
+
+		public static IntPtr Colormap {
+			get { return XplatUIX11.DefaultColorMap; }
+		}
+
+	}
+}
+#endif

+ 7 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms.Internal/ChangeLog

@@ -0,0 +1,7 @@
+2008-10-31  Andreia Gaita  <[email protected]>
+
+	* DebugHelper.cs: Wrapper for Debug.* methods,
+	  with some extras to ease debugging.
+
+	* Accessor.cs: Provides access to various internal properties, for
+	  testing purposes.

+ 281 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms.Internal/DebugHelper.cs

@@ -0,0 +1,281 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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) 2008 Novell, Inc.
+//
+// Authors:
+//	Andreia Gaita ([email protected])
+//
+
+//#define DEBUG
+//#define TRACE
+
+using System;
+#if NET_2_0
+using System.Collections.Generic;
+#else
+using System.Collections;
+#endif
+using System.Reflection;
+using System.Text;
+using System.IO;
+using System.Diagnostics;
+
+namespace System.Windows.Forms
+{
+	internal class DebugHelper
+	{
+		static DebugHelper () {
+			Debug.AutoFlush = true;
+		}
+		
+		struct Data {
+			public MethodBase method;
+			public object[] args;
+			public Data (MethodBase m, object[] a) {
+				this.method = m;
+				this.args = a;
+			}
+		}
+#if NET_2_0		
+		static Stack<Data> methods = new Stack<Data>();
+#else
+		class DataStack : System.Collections.Stack {
+			public new Data Peek () {
+				return (Data) base.Peek ();
+			}
+			public new Data Pop () {
+				return (Data) base.Pop ();
+			}
+			public DataStack (int initialCapacity) : base (initialCapacity) {}
+			public DataStack () : base () {}
+			public DataStack (ICollection icol) : base (icol) {}
+		}
+		static DataStack methods = new DataStack();
+#endif
+		
+		[Conditional("DEBUG")]
+		internal static void DumpCallers () {
+            StackTrace trace = new StackTrace(true);
+			int count = trace.FrameCount;
+			Debug.Indent ();
+			for (int i = 1; i < count; i++) {
+            	StackFrame parentFrame = trace.GetFrame(i);
+            	MethodBase parentMethod = parentFrame.GetMethod();
+				string file = parentFrame.GetFileName();
+				if (file != null && file.Length > 1)
+					file = file.Substring (file.LastIndexOf (Path.DirectorySeparatorChar) + 1);
+				Debug.WriteLine(parentMethod.DeclaringType.Name + "." + parentMethod.Name + 
+				              " at " + file + ":" + parentFrame.GetFileLineNumber()
+				              );				
+			}
+			
+			Debug.Unindent ();
+		}
+
+		[Conditional("DEBUG")]
+		internal static void DumpCallers (int count) {
+            StackTrace trace = new StackTrace(true);
+			int c = (count > trace.FrameCount ? trace.FrameCount : count);
+			Debug.Indent ();
+			for (int i = 1; i < c; i++) {
+            	StackFrame parentFrame = trace.GetFrame(i);
+            	MethodBase parentMethod = parentFrame.GetMethod();
+				string file = parentFrame.GetFileName();
+				if (file != null && file.Length > 1)
+					file = file.Substring (file.LastIndexOf (Path.DirectorySeparatorChar) + 1);
+				Debug.WriteLine(parentMethod.DeclaringType.Name + "." + parentMethod.Name + 
+				              " at " + file + ":" + parentFrame.GetFileLineNumber()
+				              );				
+			}
+			
+			Debug.Unindent ();
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Enter ()
+		{
+			StackTrace trace = new StackTrace();
+			methods.Push (new Data (trace.GetFrame(1).GetMethod(), null));
+			Print ();
+			Debug.Indent ();
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Enter (object[] args) 
+		{
+			StackTrace trace = new StackTrace();
+			methods.Push (new Data (trace.GetFrame(1).GetMethod(), args));
+			Print ();
+			Debug.Indent ();
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Leave ()
+		{
+			if (methods.Count > 0) {
+				methods.Pop ();
+				Debug.Unindent ();
+			}
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Print ()
+		{
+			if (methods.Count == 0)
+				return;
+
+			Data data = methods.Peek ();
+			Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Print (int index)
+		{
+			if (methods.Count == 0 || methods.Count <= index || index < 0)
+				return;
+
+#if NET_2_0
+			Stack<Data> temp = new Stack<Data>(index-1);
+#else
+			DataStack temp = new DataStack(index-1);
+#endif
+			for (int i = 0; i < index; i++)
+				temp.Push (methods.Pop ());
+
+			Data data = methods.Peek ();
+			for (int i = 0; i < temp.Count; i++)
+				methods.Push (temp.Pop());
+			temp = null;
+
+			Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Print (string methodName, string parameterName) 
+		{
+			if (methods.Count == 0)
+				return;
+			
+#if NET_2_0
+			Stack<Data> temp = new Stack<Data>();
+#else
+			DataStack temp = new DataStack();
+#endif
+			Data data = methods.Peek ();
+			bool foundit = false;
+			for (int i = 0; i < methods.Count; i++)
+			{
+				data = methods.Peek ();
+				if (data.method.Name.Equals (methodName)) {
+					foundit = true;
+					break;
+				}
+				temp.Push (methods.Pop ());
+			}
+
+			for (int i = 0; i < temp.Count; i++)
+				methods.Push (temp.Pop());
+			temp = null;
+
+			if (!foundit)
+				return;
+
+			Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
+			ParameterInfo[] pi = data.method.GetParameters ();
+
+			for (int i = 0; i < pi.Length; i++) {
+				if (pi[i].Name == parameterName) {
+					Debug.Indent ();
+					Debug.Write (parameterName + "=");
+					if (pi[i].ParameterType == typeof(IntPtr))
+						Debug.WriteLine (String.Format ("0x{0:x}", ((IntPtr)data.args[i]).ToInt32()));
+					else
+						Debug.WriteLine (data.args[i]);
+					Debug.Unindent ();
+				}
+			}			
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Print (string parameterName)
+		{
+			if (methods.Count == 0)
+				return;
+			Data data = methods.Peek ();
+			
+			ParameterInfo[] pi = data.method.GetParameters ();
+
+			for (int i = 0; i < pi.Length; i++) {
+				if (pi[i].Name == parameterName) {
+					Debug.Indent ();
+					Debug.Write (parameterName + "=");
+					if (pi[i].ParameterType == typeof(IntPtr))
+						Debug.WriteLine (String.Format ("0x{0:x}", data.args[i]));
+					else
+						Debug.WriteLine (data.args[i]);
+					Debug.Unindent ();
+				}
+			}			
+		}
+
+		[Conditional("DEBUG")]
+		internal static void WriteLine (object arg)
+		{
+			Debug.WriteLine (arg);
+		}
+
+		[Conditional("DEBUG")]
+		internal static void WriteLine (string format, params object[] arg)
+		{
+			Debug.WriteLine (String.Format (format, arg));
+		}
+
+		[Conditional("DEBUG")]
+		internal static void WriteLine (string message)
+		{
+			Debug.WriteLine (message);
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Indent ()
+		{
+			Debug.Indent ();
+		}
+
+		[Conditional("DEBUG")]
+		internal static void Unindent ()
+		{
+			Debug.Unindent ();
+		}
+		
+		[Conditional("TRACE")]
+		internal static void TraceWriteLine (string format, params object[] arg)
+		{
+			Debug.WriteLine (String.Format (format, arg));
+		}
+
+		[Conditional("TRACE")]
+		internal static void TraceWriteLine (string message)
+		{
+			Debug.WriteLine (message);
+		}
+		
+	}
+}

+ 2 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources

@@ -17,6 +17,8 @@ System.Windows.Forms.Design/PropertyTab.cs
 System.Windows.Forms.Design/ToolStripItemDesignerAvailability.cs
 System.Windows.Forms.Design/ToolStripItemDesignerAvailabilityAttribute.cs
 System.Windows.Forms.Design/WindowsFormsComponentEditor.cs
+System.Windows.Forms.Internal/Accessor.cs
+System.Windows.Forms.Internal/DebugHelper.cs
 System.Windows.Forms.PropertyGridInternal/PropertiesTab.cs
 System.Windows.Forms.RTF/Charcode.cs
 System.Windows.Forms.RTF/Charset.cs

+ 25 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog

@@ -1,3 +1,28 @@
+2008-10-31  Andreia Gaita  <[email protected]>
+
+	activate message fix: a call to .Show now waits until both WM_SHOWWINDOW and
+	WM_ACTIVATE have been processed before returning, so it is guaranteed that
+	once it returns and the form is visible, it is actually on the screen on X11
+
+	* ContainerControl.cs: Only send focus to the control if the top container
+	  is already focused. This is so that, when a form is first shown, all
+	  the enter/leave events are done first before any focus stuff comes in.
+	  If a control has no top container, there's an extra check on Control.Focus
+	  to make sure it gets focused in this particular case.
+
+	* Control.cs: Force focus if the control is active but did not receive
+	  focus after being set as active.
+
+	* MdiClient.cs: Dispose the form when closing
+
+	* XplatUIX11.cs: When mapping and unmapping windows, make sure the call
+	  doesn't return until both WM_SHOWWINDOW and WM_ACTIVATE have come in
+	  if the window is a top Form.
+	  Reset all hwnd properties when the window has been destroyed so that
+	  we don't land in any codepaths that might try to do something with it.
+	  Added a bunch of debugging messages. If TRACE is defined, all X calls
+	  are logged through DebugHelper. Set a few missing EntryPoint attributes.
+
 2008-10-29  Mario Carrion <[email protected]>
 
 	* ListViewItem.cs: Control enabled to support Accessibility:

+ 13 - 2
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs

@@ -179,9 +179,20 @@ namespace System.Windows.Forms {
 
 				// Scroll control into view
 				ScrollControlIntoView(active_control);
-
+				
+				
+				walk = this;
+				ctl = this;
+				while (walk != null) {
+					if (walk.Parent is ContainerControl) {
+						ctl = walk.Parent;
+					}
+					walk = walk.Parent;
+				}
+				
 				// Let the control know it's selected
-				SendControlFocus (active_control);
+				if (ctl.InternalContainsFocus)
+					SendControlFocus (active_control);
 			}
 		}
 

+ 2 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs

@@ -1451,6 +1451,8 @@ namespace System.Windows.Forms
 			container = GetContainerControl();
 			if (container != null && (Control)container != control) {
 				container.ActiveControl = control;
+				if (container.ActiveControl == control && !control.has_focus && control.IsHandleCreated)
+					XplatUI.SetFocus(control.window.Handle);
 			}
 			else if (control.IsHandleCreated) {
 				XplatUI.SetFocus(control.window.Handle);

+ 1 - 0
mcs/class/Managed.Windows.Forms/System.Windows.Forms/MdiClient.cs

@@ -657,6 +657,7 @@ namespace System.Windows.Forms {
 			}
 			SizeScrollBars ();
 			SetParentText (false);
+			form.Dispose();
 		}
 
 		internal void ActivateNextChild ()

File diff suppressed because it is too large
+ 888 - 16
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs


Some files were not shown because too many files changed in this diff