Author: gnorton
Date: 2007-12-07 10:05:24 -0500 (Fri, 07 Dec 2007)
New Revision: 90936
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
Log:
2007-12-07 Geoff Norton <[EMAIL PROTECTED]>
* Hwnd.cs: Refactor GetClippingRectangles to suppose returning the
masks for our children as well as siblings to avoid having to query
Quartz for this information.
* XplatUICarbon.cs: Implement a delegate based system to pass
information to System.Drawing. Implement Async methods. Remove
the hack for the resize thumb and imlpement a transparent Grow Box.
Rework the messaging system to proplery create window's and messages,
fixes TabControl.
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-12-07 15:02:02 UTC (rev 90935)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-12-07 15:05:24 UTC (rev 90936)
@@ -1,3 +1,13 @@
+2007-12-07 Geoff Norton <[EMAIL PROTECTED]>
+
+ * Hwnd.cs: Refactor GetClippingRectangles to suppose returning the
+ masks for our children as well as siblings to avoid having to query
+ Quartz for this information.
+ * XplatUICarbon.cs: Implement a delegate based system to pass
+ information to System.Drawing. Implement Async methods. Remove
+ the hack for the resize thumb and imlpement a transparent Grow Box.
+ Rework the messaging system to proplery create window's and messages,
+ fixes TabControl.
2007-12-06 Andreia Gaita <[EMAIL PROTECTED]>
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
2007-12-07 15:02:02 UTC (rev 90935)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
2007-12-07 15:05:24 UTC (rev 90936)
@@ -86,7 +86,6 @@
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)
@@ -117,7 +116,6 @@
fixed_size = false;
drawing_stack = new Stack ();
children = new ArrayList ();
- masks = new ArrayList ();
}
public void Dispose() {
@@ -282,10 +280,17 @@
// 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)
+ ArrayList masks = new ArrayList ();
+
+ foreach (Hwnd child in children) {
+ if (child.visible)
+ masks.Add (new Rectangle (child.X,
child.Y, child.Width, child.Height));
+ }
+
+ if (parent == null) {
return masks;
+ }
- masks = new ArrayList ();
ArrayList siblings = parent.children;
foreach (Hwnd sibling in siblings) {
@@ -299,7 +304,7 @@
do {
sibling_handle =
XplatUI.GetPreviousWindow (sibling_handle);
- if (sibling_handle ==
sibling.WholeWindow) {
+ if (sibling_handle ==
sibling.WholeWindow && sibling.visible) {
Rectangle intersect =
Rectangle.Intersect (new Rectangle (X, Y, Width, Height), new Rectangle
(sibling.X, sibling.Y, sibling.Width, sibling.Height));
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
2007-12-07 15:02:02 UTC (rev 90935)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
2007-12-07 15:05:24 UTC (rev 90936)
@@ -36,6 +36,8 @@
/// Carbon Version
namespace System.Windows.Forms {
+ internal delegate Rectangle [] HwndDelegate (IntPtr handle);
+
internal class XplatUICarbon : XplatUIDriver {
#region Local Variables
// General driver variables
@@ -55,6 +57,7 @@
internal static MouseButtons MouseState;
internal static Carbon.Hover Hover;
+ internal static HwndDelegate HwndDelegate = new HwndDelegate
(GetClippingRectangles);
// Instance members
internal Point mouse_position;
@@ -82,8 +85,8 @@
// Timers
private ArrayList TimerList;
- static readonly object lockobj = new object ();
- static readonly object queueobj = new object ();
+ static readonly object instancelock = new object ();
+ static readonly object queuelock = new object ();
// Event Handlers
internal override event EventHandler Idle;
@@ -106,7 +109,7 @@
#region Singleton specific code
public static XplatUICarbon GetInstance() {
- lock (lockobj) {
+ lock (instancelock) {
if (Instance == null) {
Instance = new XplatUICarbon ();
}
@@ -126,15 +129,35 @@
internal void AddExpose (Hwnd hwnd, bool client, Carbon.HIRect
rect) {
AddExpose (hwnd, client, (int) rect.origin.x, (int)
rect.origin.y, (int) rect.size.width, (int) rect.size.height);
}
+
+ internal void AddExpose (Hwnd hwnd, bool client, Rectangle
rect) {
+ AddExpose (hwnd, client, (int) rect.X, (int) rect.Y,
(int) rect.Width, (int) rect.Height);
+ }
internal void FlushQueue () {
CheckTimers (DateTime.UtcNow);
while (MessageQueue.Count > 0) {
- MSG msg = (MSG)MessageQueue.Dequeue ();
- NativeWindow.WndProc (msg.hwnd, msg.message,
msg.wParam, msg.lParam);
+ object queueobj = MessageQueue.Dequeue ();
+ if (queueobj is GCHandle) {
+
XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
+ } else {
+ MSG msg = (MSG)queueobj;
+ NativeWindow.WndProc (msg.hwnd,
msg.message, msg.wParam, msg.lParam);
+ }
}
}
+ internal static Rectangle [] GetClippingRectangles (IntPtr
handle) {
+ Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
+
+ if (hwnd == null)
+ return null;
+ if (hwnd.Handle != handle)
+ return new Rectangle [] {hwnd.ClientRect};
+
+ return (Rectangle []) hwnd.GetClippingRectangles
().ToArray (typeof (Rectangle));
+ }
+
internal IntPtr GetMousewParam(int Delta) {
int result = 0;
@@ -321,7 +344,7 @@
Size qsize = size;
qsize.Width -= borders.left + borders.right;
- qsize.Height -= borders.top + borders.bottom -
15;
+ qsize.Height -= borders.top + borders.bottom;
size = qsize;
}
@@ -346,7 +369,7 @@
Size qsize = size;
qsize.Width += borders.left + borders.right;
- qsize.Height += borders.top + borders.bottom -
15;
+ qsize.Height += borders.top + borders.bottom;
size = qsize;
}
@@ -449,7 +472,32 @@
}
}
}
+
+ private void WaitForHwndMessage (Hwnd hwnd, Msg message) {
+ MSG msg = new MSG ();
+ bool done = false;
+ do {
+ if (GetMessage(null, ref msg, IntPtr.Zero, 0,
0)) {
+ if ((Msg)msg.message == Msg.WM_QUIT) {
+ PostQuitMessage (0);
+ done = true;
+ }
+ else {
+ if (msg.hwnd == hwnd.Handle) {
+ if ((Msg)msg.message ==
message)
+ break;
+ else if
((Msg)msg.message == Msg.WM_DESTROY)
+ done = true;
+ }
+
+ TranslateMessage (ref msg);
+ DispatchMessage (ref msg);
+ }
+ }
+ } while (!done);
+ }
+
//TODO: The old implementation does QD drawing where we cannot
do that anymore
private void InvertCaret () {
}
@@ -654,48 +702,27 @@
if (client) {
hwnd.AddInvalidArea(x, y, width, height);
-#if OptimizeDrawing
if (!hwnd.expose_pending) {
if (!hwnd.nc_expose_pending) {
-#endif
- MSG msg = new MSG ();
- msg.message = Msg.WM_PAINT;
- msg.hwnd = hwnd.Handle;
- msg.lParam = IntPtr.Zero;
- msg.wParam = IntPtr.Zero;
- MessageQueue.Enqueue (msg);
-#if OptimizeDrawing
+ HIViewSetNeedsDisplay
(hwnd.ClientWindow, true);
}
hwnd.expose_pending = true;
}
-#endif
} else {
hwnd.AddNcInvalidArea (x, y, width, height);
-#if OptimizeDrawing
if (!hwnd.nc_expose_pending) {
if (!hwnd.expose_pending) {
-#endif
- MSG msg = new MSG ();
- Rectangle rect = new Rectangle
(x, y, width, height);
- Region region = new Region
(rect);
- IntPtr hrgn = region.GetHrgn
(null);
- msg.message = Msg.WM_NCPAINT;
- msg.hwnd = hwnd.Handle;
- msg.wParam = hrgn ==
IntPtr.Zero ? (IntPtr)1 : hrgn;
- msg.refobject = region;
- MessageQueue.Enqueue (msg);
-#if OptimizeDrawing
+ HIViewSetNeedsDisplay
(hwnd.WholeWindow, true);
}
hwnd.nc_expose_pending = true;
}
-#endif
}
}
#endregion
#region Public Methods
internal void EnqueueMessage (MSG msg) {
- lock (queueobj) {
+ lock (queuelock) {
MessageQueue.Enqueue (msg);
}
}
@@ -856,6 +883,7 @@
hwnd.Parent = Hwnd.ObjectFromHandle (cp.Parent);
hwnd.initial_style = cp.WindowStyle;
hwnd.initial_ex_style = cp.WindowExStyle;
+ hwnd.visible = false;
if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
hwnd.enabled = false;
@@ -868,7 +896,8 @@
/* FIXME */
if (ParentHandle == IntPtr.Zero) {
- IntPtr window_view = IntPtr.Zero;
+ IntPtr WindowView = IntPtr.Zero;
+ IntPtr GrowBox = IntPtr.Zero;
Carbon.WindowClass windowklass =
Carbon.WindowClass.kOverlayWindowClass;
Carbon.WindowAttributes attributes =
Carbon.WindowAttributes.kWindowCompositingAttribute |
Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
if (StyleSet (cp.Style,
WindowStyles.WS_MINIMIZEBOX)) {
@@ -896,9 +925,14 @@
}
CreateNewWindow (windowklass, attributes, ref
rect, ref WindowHandle);
+#if DEBUG_DIRTY
+ HIViewFlashDirtyArea (WindowHandle);
+#endif
Carbon.EventHandler.InstallWindowHandler
(WindowHandle);
- HIViewFindByID (HIViewGetRoot (WindowHandle),
new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref
window_view);
- ParentHandle = window_view;
+ HIViewFindByID (HIViewGetRoot (WindowHandle),
new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref WindowView);
+ HIViewFindByID (HIViewGetRoot (WindowHandle),
new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 7), ref GrowBox);
+ HIGrowBoxViewSetTransparent (GrowBox, true);
+ ParentHandle = WindowView;
}
HIObjectCreate (__CFStringMakeConstantString
("com.apple.hiview"), 0, ref WholeWindow);
@@ -927,29 +961,36 @@
hwnd.WholeWindow = WholeWindow;
hwnd.ClientWindow = ClientWindow;
+ Text (hwnd.Handle, cp.Caption);
+
+ SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1,
IntPtr.Zero /* XXX unused */);
+ SendParentNotify (hwnd.Handle, Msg.WM_CREATE,
int.MaxValue, int.MaxValue);
+
if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE) ||
StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
if (WindowHandle != IntPtr.Zero) {
WindowMapping [hwnd.Handle] =
WindowHandle;
HandleMapping [WindowHandle] =
hwnd.Handle;
+
+ if (Control.FromHandle(hwnd.Handle) is
Form) {
+ Form f =
Control.FromHandle(hwnd.Handle) as Form;
+ if (f.WindowState ==
FormWindowState.Normal) {
+
SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+ }
+ }
IntPtr active = GetActive ();
ShowWindow (WindowHandle);
+ WaitForHwndMessage (hwnd,
Msg.WM_SHOWWINDOW);
if (active != IntPtr.Zero)
Activate (active);
}
HIViewSetVisible (WholeWindow, true);
HIViewSetVisible (ClientWindow, true);
hwnd.visible = true;
- } else {
- HIViewSetVisible (WholeWindow, false);
- HIViewSetVisible (ClientWindow, false);
- hwnd.visible = false;
+ if (!(Control.FromHandle(hwnd.Handle) is Form))
{
+ SendMessage(hwnd.Handle,
Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+ }
}
- Text (hwnd.Handle, cp.Caption);
-
- SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1,
IntPtr.Zero /* XXX unused */);
- SendMessage (hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1,
IntPtr.Zero);
-
return hwnd.Handle;
}
@@ -1054,15 +1095,11 @@
break;
}
case Msg.WM_PAINT: {
-#if OptimizeDrawing
hwnd.expose_pending = false;
-#endif
break;
}
case Msg.WM_NCPAINT: {
-#if OptimizeDrawing
hwnd.nc_expose_pending = false;
-#endif
break;
}
case Msg.WM_NCCALCSIZE: {
@@ -1236,7 +1273,9 @@
ReleaseEvent (evtRef);
}
- lock (queueobj) {
+ lock (queuelock) {
+ loop:
+
if (MessageQueue.Count <= 0) {
if (Idle != null)
Idle (this, EventArgs.Empty);
@@ -1257,7 +1296,13 @@
msg.message = Msg.WM_ENTERIDLE;
return GetMessageResult;
}
- msg = (MSG) MessageQueue.Dequeue ();
+ object queueobj = MessageQueue.Dequeue ();
+ if (queueobj is GCHandle) {
+
XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
+ goto loop;
+ } else {
+ msg = (MSG)queueobj;
+ }
}
return GetMessageResult;
}
@@ -1268,16 +1313,33 @@
}
internal override void GetWindowPos(IntPtr handle, bool
is_toplevel, out int x, out int y, out int width, out int height, out int
client_width, out int client_height) {
- Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
- Rectangle rect = hwnd.ClientRect;
-
- x = hwnd.x;
- y = hwnd.y;
- width = hwnd.width;
- height = hwnd.height;
+ Hwnd hwnd;
- client_width = rect.Width;
- client_height = rect.Height;
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
+ if (hwnd != null) {
+ x = hwnd.x;
+ y = hwnd.y;
+ width = hwnd.width;
+ height = hwnd.height;
+
+ PerformNCCalc(hwnd);
+
+ client_width = hwnd.ClientRect.Width;
+ client_height = hwnd.ClientRect.Height;
+
+ return;
+ }
+
+ // Should we throw an exception or fail silently?
+ // throw new ArgumentException("Called with an invalid
window handle", "handle");
+
+ x = 0;
+ y = 0;
+ width = 0;
+ height = 0;
+ client_width = 0;
+ client_height = 0;
}
internal override FormWindowState GetWindowState(IntPtr hwnd) {
@@ -1385,11 +1447,10 @@
clip_region.Intersect(hwnd.UserClip);
}
+ // FIXME: Clip region is hosed
// dc.Clip = clip_region;
paint_event = new PaintEventArgs(dc,
hwnd.Invalid);
-#if OptimizeDrawing
hwnd.expose_pending = false;
-#endif
hwnd.ClearInvalidArea();
hwnd.drawing_stack.Push (paint_event);
@@ -1398,14 +1459,13 @@
dc = Graphics.FromHwnd
(paint_hwnd.whole_window);
if (!hwnd.nc_invalid.IsEmpty) {
- dc.SetClip (hwnd.nc_invalid);
+ // FIXME: Clip region is hosed
+// dc.SetClip (hwnd.nc_invalid);
paint_event = new PaintEventArgs(dc,
hwnd.nc_invalid);
} else {
paint_event = new PaintEventArgs(dc,
new Rectangle(0, 0, hwnd.width, hwnd.height));
}
-#if OptimizeDrawing
hwnd.nc_expose_pending = false;
-#endif
hwnd.ClearNcInvalidArea ();
hwnd.drawing_stack.Push (paint_event);
@@ -1420,13 +1480,16 @@
hwnd = Hwnd.ObjectFromHandle(handle);
- Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
- dc.Flush ();
- dc.Dispose ();
+ // FIXME: Pop is causing invalid stack ops sometimes;
race condition?
+ try {
+ Graphics dc =
(Graphics)hwnd.drawing_stack.Pop();
+ dc.Flush ();
+ dc.Dispose ();
- PaintEventArgs pe =
(PaintEventArgs)hwnd.drawing_stack.Pop();
- pe.SetGraphics (null);
- pe.Dispose ();
+ PaintEventArgs pe =
(PaintEventArgs)hwnd.drawing_stack.Pop();
+ pe.SetGraphics (null);
+ pe.Dispose ();
+ } catch {}
if (Caret.Visible == 1) {
ShowCaret();
@@ -1511,7 +1574,8 @@
[MonoTODO]
internal override void SendAsyncMethod (AsyncMethodData method)
{
- throw new NotImplementedException ();
+ // Fake async
+ MessageQueue.Enqueue (GCHandle.Alloc (method));
}
[MonoTODO]
@@ -1661,9 +1725,13 @@
ShowWindow ((IntPtr)window);
else
HideWindow ((IntPtr)window);
+
+ if (visible)
+ SendMessage(handle, Msg.WM_WINDOWPOSCHANGED,
IntPtr.Zero, IntPtr.Zero);
HIViewSetVisible (hwnd.whole_window, visible);
HIViewSetVisible (hwnd.client_window, visible);
+
hwnd.visible = visible;
return true;
}
@@ -1867,20 +1935,15 @@
}
internal override void UpdateWindow(IntPtr handle) {
- Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
-
-#if OptimizeDrawing
- if (hwnd.visible && HIViewIsVisible (handle) &&
!hwnd.expose_pending) {
-#else
- if (hwnd.visible && HIViewIsVisible (handle)) {
-#endif
- MSG msg = new MSG ();
- msg.message = Msg.WM_PAINT;
- msg.hwnd = hwnd.Handle;
- msg.lParam = IntPtr.Zero;
- msg.wParam = IntPtr.Zero;
- MessageQueue.Enqueue (msg);
+ Hwnd hwnd;
+
+ hwnd = Hwnd.ObjectFromHandle(handle);
+
+ if (!hwnd.visible || !HIViewIsVisible (handle)) {
+ return;
}
+
+ SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero,
IntPtr.Zero);
}
internal override bool TranslateMessage(ref MSG msg) {
@@ -2037,6 +2100,10 @@
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
extern static int HIViewFindByID (IntPtr rootWnd,
Carbon.HIViewID id, ref IntPtr outPtr);
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
+ extern static int HIViewFlashDirtyArea (IntPtr view);
+
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
+ extern static int HIGrowBoxViewSetTransparent (IntPtr GrowBox,
bool transparency);
+
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
extern static IntPtr HIViewGetRoot (IntPtr hWnd);
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
extern static int HIObjectCreate (IntPtr cfStr, uint what, ref
IntPtr hwnd);
@@ -2066,6 +2133,8 @@
extern static IntPtr HIViewGetWindow (IntPtr aView);
[DllImport
("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
extern static int HIViewSetFrame (IntPtr view_handle, ref
Carbon.HIRect bounds);
+ [DllImport
("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
+ extern static int HIViewSetNeedsDisplay (IntPtr view_handle,
bool needs_display);
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
extern static void SetRect (ref Carbon.Rect r, short left,
short top, short right, short bottom);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches