Ver Fonte

2005-02-19 Peter Bartok <[email protected]>

	* UserControl.cs: Added TextChanged event; added attributes
	* SizeGrip.cs: Implemented resizing and optional display of grip
	* Form.cs: Fixed attribute
	* XplatUI.cs, XplatUIDriver.cs, XplatUIOSX.cs, XplatUIWin32.cs:
	  Changed meaning of ScrollWindow bool argument; instead of the
	  clear attribute (which will be true usually anyway), it gives the
	  option of moving child controls as well.
	* XplatUIX11.cs:
	  - Changed to match new ScrollWindow argument
	  - Fixed GetWindowPos/SetWindowPos behaviour for toplevel controls,
	    now handles the implicit parent window a WM puts around us
	* ScrollableControl.cs: Implemented (not the prettiest, but it seems 
	  to work)
	* TextBoxBase.cs: Adjusted to new ScrollWindow arguments
	* TreeView.cs: Adjusted to new ScrollWindow arguments


svn path=/trunk/mcs/; revision=40918
Peter Dennis Bartok há 21 anos atrás
pai
commit
ea283a5786

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

@@ -1,3 +1,21 @@
+2005-02-19  Peter Bartok  <[email protected]>
+
+	* UserControl.cs: Added TextChanged event; added attributes
+	* SizeGrip.cs: Implemented resizing and optional display of grip
+	* Form.cs: Fixed attribute
+	* XplatUI.cs, XplatUIDriver.cs, XplatUIOSX.cs, XplatUIWin32.cs:
+	  Changed meaning of ScrollWindow bool argument; instead of the
+	  clear attribute (which will be true usually anyway), it gives the
+	  option of moving child controls as well.
+	* XplatUIX11.cs:
+	  - Changed to match new ScrollWindow argument
+	  - Fixed GetWindowPos/SetWindowPos behaviour for toplevel controls,
+	    now handles the implicit parent window a WM puts around us
+	* ScrollableControl.cs: Implemented (not the prettiest, but it seems 
+	  to work)
+	* TextBoxBase.cs: Adjusted to new ScrollWindow arguments
+	* TreeView.cs: Adjusted to new ScrollWindow arguments
+
 2005-02-19  Jordi Mas i Hernandez <[email protected]>
 
 	* Form.cs: Menu integration with non-client area

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

@@ -37,7 +37,7 @@ using System.Threading;
 namespace System.Windows.Forms {
 	[DesignerCategory("Form")]
 	[DesignTimeVisible(false)]
-	[Designer("System.Windows.Forms.Design.FormDesigner, " + Consts.AssemblySystem_Design, typeof(IRootDesigner))]
+	[Designer("System.Windows.Forms.Design.FormDocumentDesigner, " + Consts.AssemblySystem_Design, typeof(IRootDesigner))]
 	[DefaultEvent("Load")]
 	[ToolboxItem(false)]
 	public class Form : ContainerControl {

+ 237 - 14
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ScrollableControl.cs

@@ -39,11 +39,14 @@ namespace System.Windows.Forms {
 		private bool			auto_hscroll;
 		private bool			hscroll_visible;
 		private bool			vscroll_visible;
+		private bool			force_hscroll_visible;
+		private bool			force_vscroll_visible;
 		private bool			auto_scroll;
 		private Size			auto_scroll_margin;
 		private Size			auto_scroll_min_size;
-		private Point			auto_scroll_position;
+		private Point			scroll_position;
 		private DockPaddingEdges	dock_padding;
+		private SizeGrip		sizegrip;
 		private HScrollBar		hscrollbar;
 		private VScrollBar		vscrollbar;
 		#endregion	// Local Variables
@@ -183,11 +186,11 @@ namespace System.Windows.Forms {
 
 			// Public Instance Methods
 			public override PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, Attribute[] attributes) {
-				throw new NotImplementedException();
+				return TypeDescriptor.GetProperties(typeof(DockPaddingEdges), attributes);
 			}
 
 			public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) {
-				throw new NotImplementedException();
+				return true;
 			}
 		}
 		#endregion	// Subclass DockPaddingEdgesConverter
@@ -200,10 +203,14 @@ namespace System.Windows.Forms {
 			auto_vscroll = false;
 			hscroll_visible = false;
 			vscroll_visible = false;
+			force_hscroll_visible = false;
+			force_vscroll_visible = false;
 			auto_scroll_margin = new Size(0, 0);
 			auto_scroll_min_size = new Size(0, 0);
-			auto_scroll_position = new Point(0, 0);
+			scroll_position = new Point(0, 0);
 			dock_padding = new DockPaddingEdges();
+			SizeChanged +=new EventHandler(Recalculate);
+			VisibleChanged += new EventHandler(Recalculate);
 		}
 		#endregion	// Public Constructors
 
@@ -229,6 +236,35 @@ namespace System.Windows.Forms {
 				}
 
 				auto_scroll = value;
+				if (!auto_scroll) {
+					Controls.Remove(hscrollbar);
+					hscrollbar.Dispose();
+					hscrollbar = null;
+
+					Controls.Remove(vscrollbar);
+					vscrollbar.Dispose();
+					vscrollbar = null;
+
+					Controls.Remove(sizegrip);
+					sizegrip.Dispose();
+					sizegrip = null;
+				} else {
+					hscrollbar = new HScrollBar();
+					hscrollbar.Visible = false;
+					hscrollbar.ValueChanged += new EventHandler(HandleScrollBar);
+					hscrollbar.Height = SystemInformation.HorizontalScrollBarHeight;
+					this.Controls.Add(hscrollbar);
+
+					vscrollbar = new VScrollBar();
+					vscrollbar.Visible = false;
+					vscrollbar.ValueChanged += new EventHandler(HandleScrollBar);
+					vscrollbar.Width = SystemInformation.VerticalScrollBarWidth;
+					this.Controls.Add(vscrollbar);
+
+					sizegrip = new SizeGrip();
+					sizegrip.Visible = false;
+					this.Controls.Add(sizegrip);
+				}
 			}
 		}
 
@@ -266,11 +302,35 @@ namespace System.Windows.Forms {
 		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 		public Point AutoScrollPosition {
 			get {
-				return auto_scroll_position;
+				return new Point(-scroll_position.X, -scroll_position.Y);
 			}
 
 			set {
-				auto_scroll_position = value;
+				if ((value.X != scroll_position.X) || (value.Y != scroll_position.Y)) {
+					int	shift_x;
+					int	shift_y;
+
+					shift_x = 0;
+					shift_y = 0;
+					if (hscroll_visible) {
+						shift_x = value.X - scroll_position.X;
+					}
+
+					if (vscroll_visible) {
+						shift_y = value.Y - scroll_position.Y;
+					}
+
+					ScrollWindow(shift_x, shift_y);
+
+					if (hscroll_visible) {
+						hscrollbar.Value = scroll_position.X;
+					}
+
+					if (vscroll_visible) {
+						vscrollbar.Value = scroll_position.Y;
+					}
+
+				}
 			}
 		}
 
@@ -305,7 +365,7 @@ namespace System.Windows.Forms {
 			}
 
 			// DockPadding is documented as 'get' only ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWindowsFormsScrollableControlClassAutoScrollTopic.asp )
-			// but Microsoft's on that pageexamples show 'set' usage
+			// but Microsoft's examples on that page show 'set' usage
 //			set {
 //				dock_padding = value;
 //			}
@@ -332,9 +392,8 @@ namespace System.Windows.Forms {
 
 			set {
 				if (hscroll_visible != value) {
-					hscroll_visible = value;
-					if (hscroll_visible && hscrollbar == null)
-						hscrollbar = new HScrollBar ();
+					force_hscroll_visible = value;
+					Recalculate(this, EventArgs.Empty);
 				}
 			}
 		}
@@ -346,9 +405,8 @@ namespace System.Windows.Forms {
 
 			set {
 				if (vscroll_visible != value) {
-					vscroll_visible = value;
-					if (vscroll_visible && vscrollbar == null)
-						vscrollbar = new VScrollBar ();
+					force_vscroll_visible = value;
+					Recalculate(this, EventArgs.Empty);
 				}
 			}
 		}
@@ -359,17 +417,29 @@ namespace System.Windows.Forms {
 		}
 
 		public void SetAutoScrollMargin(int x, int y) {
+			if (x < 0) {
+				x = 0;
+			}
+
+			if (y < 0) {
+				y = 0;
+			}
+
+			auto_scroll_margin = new Size(x, y);
+			Recalculate(this, EventArgs.Empty);
 		}
 		#endregion	// Public Instance Methods
 
 		#region Protected Instance Methods
 		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected virtual void AdjustFormScrollbars(bool displayScrollbars) {
+			// Internal MS
 		}
 
 		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected bool GetScrollState(int bit) {
-			throw new NotImplementedException();
+			return false;
+			// Internal MS
 		}
 
 		[EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -379,6 +449,21 @@ namespace System.Windows.Forms {
 
 		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected override void OnMouseWheel(MouseEventArgs e) {
+			if (vscroll_visible) {
+				if (e.Delta > 0) {
+					if (vscrollbar.Minimum < (vscrollbar.Value - vscrollbar.LargeChange)) {
+						vscrollbar.Value -= vscrollbar.LargeChange;
+					} else {
+						vscrollbar.Value = vscrollbar.Minimum;
+					}
+				} else {
+					if (vscrollbar.Maximum > (vscrollbar.Value + vscrollbar.LargeChange)) {
+							vscrollbar.Value += vscrollbar.LargeChange;
+						} else {
+							vscrollbar.Value = vscrollbar.Maximum;
+						}
+					}
+			}
 			base.OnMouseWheel(e);
 		}
 
@@ -404,5 +489,143 @@ namespace System.Windows.Forms {
 			base.WndProc(ref m);
 		}
 		#endregion	// Protected Instance Methods
+
+		#region Internal & Private Methods
+		private Size Canvas {
+			get {
+				int	num_of_children;
+				int	width;
+				int	height;
+
+				num_of_children = child_controls.Count;
+				width = 0;
+				height = 0;
+
+				for (int i = 0; i < num_of_children; i++) {
+					if ((child_controls[i].Visible == false) || (child_controls[i] == hscrollbar) || (child_controls[i] == vscrollbar) || (child_controls[i] == sizegrip)) {
+						continue;
+					}
+					if (child_controls[i].Right > width) {
+						width = child_controls[i].Right;
+					}
+
+					if (child_controls[i].Bottom > height) {
+						height = child_controls[i].Bottom;
+					}
+				}
+
+				return new Size(width, height);
+			}
+		}
+
+		private void Recalculate(object sender, EventArgs e) {
+			Size	canvas;
+			Size	client;
+
+			// FIXME - this whole function begs for optimizations, all the math
+			// shouldn't have to be done over and over
+
+			// Check if we need scrollbars
+			if (!this.auto_scroll && !force_hscroll_visible && !force_vscroll_visible) {
+				return;
+			}
+
+			canvas = Canvas;
+			client = ClientRectangle.Size;
+
+			canvas.Width += auto_scroll_margin.Width + SystemInformation.VerticalScrollBarWidth;
+			canvas.Height += auto_scroll_margin.Height + SystemInformation.HorizontalScrollBarHeight;
+
+			//  || (scroll_position.X == 0 && scroll_position.Y == 0)
+
+			if ((canvas.Width >= client.Width) || (auto_scroll_min_size.Width > client.Width) || force_hscroll_visible) {
+				// Need horz
+
+				hscrollbar.Left = 0;
+				hscrollbar.Top = client.Height - SystemInformation.HorizontalScrollBarHeight;
+				hscrollbar.Maximum = Math.Max(0, canvas.Width - client.Width + SystemInformation.VerticalScrollBarWidth);
+
+				hscroll_visible = true;
+			} else {
+				hscroll_visible = false;
+				scroll_position.X = 0;
+			}
+
+			if ((canvas.Height >= client.Height) || (auto_scroll_min_size.Height > client.Height) || force_vscroll_visible) {
+				// Need vert
+				vscrollbar.Left = client.Width - SystemInformation.VerticalScrollBarWidth;
+				vscrollbar.Top = 0;
+
+				// FIXME - Working around some scrollbar bugs here; shouldn't have to add the height again (see canvas+= above)
+				vscrollbar.Maximum = Math.Max(0, canvas.Height - client.Height + SystemInformation.HorizontalScrollBarHeight);
+				vscroll_visible = true;
+			} else {
+				vscroll_visible = false;
+				scroll_position.Y = 0;
+			}
+
+			if (hscroll_visible && vscroll_visible) {
+				hscrollbar.Width = ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth;
+				vscrollbar.Height = ClientRectangle.Height - SystemInformation.HorizontalScrollBarHeight;
+
+				sizegrip.Left =  hscrollbar.Right;
+				sizegrip.Top =  vscrollbar.Bottom;
+				sizegrip.Width = SystemInformation.VerticalScrollBarWidth;
+				sizegrip.Height = SystemInformation.HorizontalScrollBarHeight;
+
+				hscrollbar.Visible = true;
+				vscrollbar.Visible = true;
+				sizegrip.Visible = true;
+			} else {
+				sizegrip.Visible = false;
+				if (hscroll_visible) {
+					hscrollbar.Width = ClientRectangle.Width;
+					hscrollbar.Visible = true;
+				} else {
+					hscrollbar.Visible = false;
+				}
+
+				if (vscroll_visible) {
+					vscrollbar.Height = ClientRectangle.Height;
+					vscrollbar.Visible = true;
+				} else {
+					vscrollbar.Visible = false;
+				}
+			}
+		}
+
+		private void HandleScrollBar(object sender, EventArgs e) {
+			if (sender == vscrollbar) {
+				ScrollWindow(0, vscrollbar.Value- scroll_position.Y);
+			} else {
+				ScrollWindow(hscrollbar.Value - scroll_position.X, 0);
+			}
+		}
+
+		private void ScrollWindow(int XOffset, int YOffset) {
+			int	num_of_children;
+
+			SuspendLayout();
+
+			num_of_children = child_controls.Count;
+
+			for (int i = 0; i < num_of_children; i++) {
+				if (child_controls[i] == hscrollbar || child_controls[i] == vscrollbar || child_controls[i] == sizegrip) {
+					continue;
+				}
+				child_controls[i].Left -= XOffset;
+				child_controls[i].Top -= YOffset;
+				// Is this faster? child_controls[i].Location -= new Size(XOffset, YOffset);
+			}
+
+			scroll_position.X += XOffset;
+			scroll_position.Y += YOffset;
+
+			// Should we call XplatUI.ScrollWindow???
+			Invalidate();
+			ResumeLayout();
+		}
+		#endregion	// Internal & Private Methods
+
 	}
 }

+ 86 - 17
mcs/class/Managed.Windows.Forms/System.Windows.Forms/SizeGrip.cs

@@ -30,42 +30,111 @@ using System.Drawing;
 namespace System.Windows.Forms {
 
 	internal class SizeGrip : Control {
+		#region Local Variables
+		private bool	redraw;
+		private Point	capture_point;
+		private int	window_w;
+		private int	window_h;
+		private bool	show_grip;
+		private bool	hide_pending;
+		#endregion	// Local Variables
 
-		private bool redraw = true;
-		
+		#region Constructors
 		public SizeGrip ()
 		{
+			this.Cursor = Cursors.SizeNWSE;
+			show_grip = true;
+			redraw = true;
+			hide_pending = false;
 		}
+		#endregion	// Constructors
 
-		protected override void OnPaint (PaintEventArgs pe)
-		{
+		#region Properties
+		public bool ShowGrip {
+			get {
+				return show_grip;
+			}
+
+			set {
+				show_grip = value;
+				redraw = true;
+			}
+		}
+		#endregion	// Properties
+
+		#region Methods
+		protected override void OnPaint (PaintEventArgs pe) {
 			base.OnPaint (pe);
 
-			if (redraw)
-				Draw ();
+			if (redraw) {
+				if (show_grip) {
+					ControlPaint.DrawSizeGrip(DeviceContext, BackColor, ClientRectangle);
+				}
+			}
 
-			pe.Graphics.DrawImage (ImageBuffer, pe.ClipRectangle, pe.ClipRectangle, GraphicsUnit.Pixel);
+			pe.Graphics.DrawImage(ImageBuffer, pe.ClipRectangle, pe.ClipRectangle, GraphicsUnit.Pixel);
 		}
 
-		protected override void OnSizeChanged (EventArgs e)
-		{
+		protected override void OnSizeChanged (EventArgs e) {
 			base.OnSizeChanged (e);
 			redraw = true;
 		}
 
-		protected override void OnVisibleChanged (EventArgs e)
-		{
+		protected override void OnVisibleChanged (EventArgs e) {
 			base.OnVisibleChanged (e);
 			redraw = true;
 		}
 
-		private void Draw ()
-		{
-			ControlPaint.DrawSizeGrip (DeviceContext, BackColor, ClientRectangle);
-			redraw = false;
-		}
-	}
+		protected override void OnMouseDown(MouseEventArgs e) {
+			Capture = true;
+			
+			capture_point = Control.MousePosition;
+
+			window_w = parent.Width;
+			window_h = parent.Height;
+		}
+
+		protected override void OnMouseMove(MouseEventArgs e) {
+			if (this.is_captured) {
+				int	delta_x;
+				int	delta_y;
+				Point	current_point;
+
+				current_point = Control.MousePosition;
+
+				delta_x = current_point.X - capture_point.X;
+				delta_y = current_point.Y - capture_point.Y;
+
+				this.parent.Size = new Size(window_w + delta_x, window_h + delta_y);
+				XplatUI.DoEvents();
+			}
+		}
 
+		protected override void OnMouseUp(MouseEventArgs e) {
+			if (Capture) {
+				Capture = false;
+				if (hide_pending) {
+					Hide();
+					hide_pending = false;
+				}
+			}
+		}
+
+
+		protected override void SetVisibleCore(bool value) {
+			if (Capture) {
+				if (value == false) {
+					hide_pending = true;
+				} else {
+					hide_pending = false;
+				}
+				return;
+			}
+			base.SetVisibleCore (value);
+		}
+
+		#endregion	// Methods
+	}
 }
 
 

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

@@ -1115,7 +1115,7 @@ static int current;
 		}
 
 		private void hscroll_ValueChanged(object sender, EventArgs e) {
-			XplatUI.ScrollWindow(this.Handle, document.ViewPortX-this.hscroll.Value, 0, true);
+			XplatUI.ScrollWindow(this.Handle, document.ViewPortX-this.hscroll.Value, 0, false);
 			document.ViewPortX = this.hscroll.Value;
 			document.UpdateCaret();
 			Console.WriteLine("Dude scrolled");

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

@@ -993,7 +993,7 @@ namespace System.Windows.Forms {
 			skipped_nodes = vbar.Value;
 
 			int y_move = (old_skip - skipped_nodes) * ItemHeight;
-			XplatUI.ScrollWindow (Handle, ViewportRectangle, 0, y_move, true);
+			XplatUI.ScrollWindow (Handle, ViewportRectangle, 0, y_move, false);
 		}
 
 		private void HScrollBarValueChanged(object sender, EventArgs e)
@@ -1001,7 +1001,7 @@ namespace System.Windows.Forms {
 			int old_offset = hbar_offset;
 			hbar_offset = hbar.Value;
 
-			XplatUI.ScrollWindow (Handle, ViewportRectangle, old_offset - hbar_offset, 0, true);
+			XplatUI.ScrollWindow (Handle, ViewportRectangle, old_offset - hbar_offset, 0, false);
 		}
 
 		private int GetOpenNodeCount ()

+ 19 - 1
mcs/class/Managed.Windows.Forms/System.Windows.Forms/UserControl.cs

@@ -17,7 +17,7 @@
 // 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]
@@ -28,9 +28,15 @@
 // COMPLETE
 
 using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
 using System.Drawing;
 
 namespace System.Windows.Forms {
+	[DefaultEvent("Load")]
+	[DesignerCategory("UserControl")]
+	[Designer("System.Windows.Forms.Design.UserControlDocumentDesigner, " + Consts.AssemblySystem_Design, typeof(IRootDesigner))]
+	[Designer("System.Windows.Forms.Design.ControlDesigner, " + Consts.AssemblySystem_Design)]
 	public class UserControl : ContainerControl {
 		#region Public Constructors
 		public UserControl() {
@@ -45,6 +51,10 @@ namespace System.Windows.Forms {
 		}
 
 
+		[Bindable(false)]
+		[Browsable(false)]
+		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+		[EditorBrowsable(EditorBrowsableState.Never)]
 		public override string Text {
 			get {
 				return base.Text;
@@ -57,6 +67,7 @@ namespace System.Windows.Forms {
 		#endregion	// Public Instance Properties
 
 		#region Protected Instance Methods
+		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected override void OnCreateControl() {
 			base.OnCreateControl();
 
@@ -65,14 +76,17 @@ namespace System.Windows.Forms {
 			OnLoad(EventArgs.Empty);
 		}
 
+		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected virtual void OnLoad(EventArgs e) {
 			if (Load != null) Load(this, e);
 		}
 
+		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected override void OnMouseDown(MouseEventArgs e) {
 			base.OnMouseDown(e);
 		}
 
+		[EditorBrowsable(EditorBrowsableState.Advanced)]
 		protected override void WndProc(ref Message m) {
 			base.WndProc(ref m);
 		}
@@ -80,6 +94,10 @@ namespace System.Windows.Forms {
 
 		#region Events
 		public event EventHandler	Load;
+
+		[Browsable(false)]
+		[EditorBrowsable(EditorBrowsableState.Never)]
+		public event EventHandler	TextChanged;
 		#endregion	// Events
 	}
 }

+ 4 - 4
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUI.cs

@@ -464,12 +464,12 @@ namespace System.Windows.Forms {
 			}
 		}
 
-		internal static void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool clear) {
-			driver.ScrollWindow(hwnd, rectangle, XAmount, YAmount, clear);
+		internal static void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool with_children) {
+			driver.ScrollWindow(hwnd, rectangle, XAmount, YAmount, with_children);
 		}
 
-		internal static void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear) {
-			driver.ScrollWindow(hwnd, XAmount, YAmount, clear);
+		internal static void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool with_children) {
+			driver.ScrollWindow(hwnd, XAmount, YAmount, with_children);
 		}
 
 		internal static bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {

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

@@ -179,8 +179,8 @@ namespace System.Windows.Forms {
 		internal abstract void SetFocus(IntPtr hwnd);
 		internal abstract IntPtr GetActive();
 
-		internal abstract void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool clear);
-		internal abstract void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear);
+		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);
 
 		internal abstract bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent);
 

+ 6 - 6
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIOSX.cs

@@ -1472,11 +1472,11 @@ DEBUG THIS:
 			return GetFontMetrics(g.GetHdc(), font.ToHfont(), out ascent, out descent);
 		}
 
-		internal override void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool clear) {
+		internal override void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool with_children) {
 			throw new NotImplementedException("Need to implement the overload that provides the rectangle for ScrollWindow");
 		}
 
-		internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear) {
+		internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool with_children) {
 			IntPtr rect = IntPtr.Zero;
 			HIRect vBounds = new HIRect ();
                         HIViewGetBounds (hwnd, ref vBounds);
@@ -1485,15 +1485,15 @@ DEBUG THIS:
 			ScrollRect (ref rect, (short)XAmount, (short)-YAmount, IntPtr.Zero);
 
 			if (YAmount > 0) {
-				Invalidate (hwnd, new Rectangle (0, YAmount, (int)vBounds.size.width, (int)(vBounds.size.height)), clear);
+				Invalidate (hwnd, new Rectangle (0, YAmount, (int)vBounds.size.width, (int)(vBounds.size.height)), true);
 			} else if (YAmount < 0) {
-				Invalidate (hwnd, new Rectangle (0, 0, (int)vBounds.size.width, -YAmount), clear);
+				Invalidate (hwnd, new Rectangle (0, 0, (int)vBounds.size.width, -YAmount), true);
 			}
 
 			if (XAmount > 0) {
-				Invalidate (hwnd, new Rectangle (0, 0, XAmount, (int)vBounds.size.height), clear);
+				Invalidate (hwnd, new Rectangle (0, 0, XAmount, (int)vBounds.size.height), true);
 			} else if (XAmount < 0) {
-				Invalidate (hwnd, new Rectangle ((int)(vBounds.size.width+XAmount), 0, (int)vBounds.size.width, (int)vBounds.size.height), clear);
+				Invalidate (hwnd, new Rectangle ((int)(vBounds.size.width+XAmount), 0, (int)vBounds.size.width, (int)vBounds.size.height), true);
 			}
 		}
 

+ 4 - 4
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs

@@ -1388,7 +1388,7 @@ namespace System.Windows.Forms {
 			return true;
 		}
 
-		internal override void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool clear) {
+		internal override void ScrollWindow(IntPtr hwnd, Rectangle rectangle, int XAmount, int YAmount, bool with_children) {
 			RECT	rect;
 
 			rect = new RECT();
@@ -1397,12 +1397,12 @@ namespace System.Windows.Forms {
 			rect.right = rectangle.Right;
 			rect.bottom = rectangle.Bottom;
 
-			Win32ScrollWindowEx(hwnd, XAmount, YAmount, ref rect, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, clear ? (ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE) : ScrollWindowExFlags.SW_NONE);
+			Win32ScrollWindowEx(hwnd, XAmount, YAmount, ref rect, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
 			Win32UpdateWindow(hwnd);
 		}
 
-		internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear) {
-			Win32ScrollWindowEx(hwnd, XAmount, YAmount, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, clear ? (ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE) : ScrollWindowExFlags.SW_NONE);
+		internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool with_children) {
+			Win32ScrollWindowEx(hwnd, XAmount, YAmount, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
 		}
 
 		internal override bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {

+ 40 - 5
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

@@ -726,6 +726,24 @@ namespace System.Windows.Forms {
 
 			return (IntPtr)result;
 		}
+		private IntPtr XGetParent(IntPtr handle) {
+			IntPtr	Root;
+			IntPtr	Parent;
+			IntPtr	Children;
+			int	ChildCount;
+
+			lock (XlibLock) {
+				XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
+			}
+
+			if (Children!=IntPtr.Zero) {
+				lock (XlibLock) {
+					XFree(Children);
+				}
+			}
+			return Parent;
+		}
+
 		#endregion	// Private Methods
 
 		#region	Callbacks
@@ -1877,8 +1895,14 @@ namespace System.Windows.Forms {
 							(hwnd.width != xevent.ConfigureEvent.width) || (hwnd.height != xevent.ConfigureEvent.height)) {
 							msg.message=Msg.WM_WINDOWPOSCHANGED;
 
-							hwnd.x = xevent.ConfigureEvent.x;
-							hwnd.y = xevent.ConfigureEvent.y;
+							if (hwnd.parent != null) {
+								hwnd.x = xevent.ConfigureEvent.x;
+								hwnd.y = xevent.ConfigureEvent.y;
+							} else {
+								IntPtr	child;
+								// We need to 'discount' the window the WM has put us in
+								XTranslateCoordinates(DisplayHandle, XGetParent(hwnd.whole_window), RootWindow, xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, out hwnd.x, out hwnd.y, out child);
+							}
 							hwnd.width = xevent.ConfigureEvent.width;
 							hwnd.height = xevent.ConfigureEvent.height;
 						} else {
@@ -2250,7 +2274,7 @@ namespace System.Windows.Forms {
 			y = dest_y_return;
 		}
 
-		internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool clear) {
+		internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
 			Hwnd		hwnd;
 			IntPtr		gc;
 			XGCValues	gc_values;
@@ -2278,6 +2302,10 @@ namespace System.Windows.Forms {
 
 			gc_values = new XGCValues();
 
+			if (with_children) {
+				gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
+			}
+
 			gc = XCreateGC(DisplayHandle, hwnd.client_window, 0, ref gc_values);
 
 			XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
@@ -2300,7 +2328,14 @@ namespace System.Windows.Forms {
 			UpdateWindow(handle);
 		}
 
-		internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear){ throw new NotImplementedException(); }
+		internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
+			Hwnd	hwnd;
+
+			hwnd = Hwnd.GetObjectFromWindow(handle);
+	
+			ScrollWindow(handle, hwnd.ClientRect, XAmount, YAmount, with_children);
+		}
+
 		internal override void SendAsyncMethod (AsyncMethodData method) {
 			XEvent xevent = new XEvent ();
 
@@ -2809,7 +2844,7 @@ namespace System.Windows.Forms {
 		internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
 
 		[DllImport ("libX11", EntryPoint="XQueryTree")]
-		internal extern static int XQueryTree(IntPtr display, IntPtr window, ref IntPtr root_return, ref IntPtr parent_return, ref IntPtr children_return, ref int nchildren_return);
+		internal extern static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
 
 		[DllImport ("libX11", EntryPoint="XFree")]
 		internal extern static int XFree(IntPtr data);