// Carbon Specific
internal static GrabStruct Grab;
- private static Carbon.Caret Caret;
+ internal static Carbon.Caret Caret;
private static Carbon.Dnd Dnd;
private static Hashtable WindowMapping;
private static Hashtable HandleMapping;
// Timers
private ArrayList TimerList;
+ private static bool in_doevents;
static readonly object instancelock = new object ();
static readonly object queuelock = new object ();
RefCount = 0;
TimerList = new ArrayList ();
+ in_doevents = false;
MessageQueue = new Queue ();
Initialize ();
for (int i = 0; i < TimerList.Count; i++) {
Timer timer = (Timer) TimerList [i];
if (timer.Enabled && timer.Expires <= now) {
- timer.FireTick ();
- timer.Update (now);
+ // Timer ticks:
+ // - Before MainForm.OnLoad if DoEvents () is called.
+ // - After MainForm.OnLoad if not.
+ //
+ if (in_doevents ||
+ (Application.MWFThread.Current.Context != null &&
+ Application.MWFThread.Current.Context.MainForm != null &&
+ Application.MWFThread.Current.Context.MainForm.IsLoaded)) {
+ timer.FireTick ();
+ timer.Update (now);
+ }
}
}
}
if (client) {
hwnd.AddInvalidArea(x, y, width, height);
- if (!hwnd.expose_pending) {
+ if (!hwnd.expose_pending && hwnd.visible) {
MSG msg = new MSG ();
msg.message = Msg.WM_PAINT;
msg.hwnd = hwnd.Handle;
}
} else {
hwnd.AddNcInvalidArea (x, y, width, height);
- if (!hwnd.nc_expose_pending) {
+ if (!hwnd.nc_expose_pending && hwnd.visible) {
MSG msg = new MSG ();
Region rgn = new Region (hwnd.Invalid);
IntPtr hrgn = rgn.GetHrgn (null); // Graphics object isn't needed
msg.hwnd = hwnd.Handle;
MessageQueue.Enqueue (msg);
hwnd.nc_expose_pending = true;
+
}
}
}
}
internal override void Activate(IntPtr handle) {
+ if (ActiveWindow != IntPtr.Zero) {
+ ActivateWindow (HIViewGetWindow (ActiveWindow), false);
+ }
ActivateWindow (HIViewGetWindow (handle), true);
+ ActiveWindow = handle;
}
internal override void AudibleAlert() {
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 (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
if (WindowHandle != IntPtr.Zero) {
if (Control.FromHandle(hwnd.Handle) is Form) {
Form f = Control.FromHandle(hwnd.Handle) as Form;
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);
}
}
+ if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
+ SetWindowState(hwnd.Handle, FormWindowState.Minimized);
+ } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
+ SetWindowState(hwnd.Handle, FormWindowState.Maximized);
+ }
+
return hwnd.Handle;
}
return CreateWindow(create_params);
}
- [MonoTODO]
- internal override Bitmap DefineStdCursorBitmap (StdCursor id)
- {
- throw new NotImplementedException ();
+ internal override Bitmap DefineStdCursorBitmap (StdCursor id) {
+ return Carbon.Cursor.DefineStdCursorBitmap (id);
}
- [MonoTODO]
- internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
- return IntPtr.Zero;
+
+ internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
+ return Carbon.Cursor.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
}
- internal override IntPtr DefineStdCursor(StdCursor id) {
- switch (id) {
- case StdCursor.AppStarting:
- return (IntPtr)Carbon.ThemeCursor.kThemeSpinningCursor;
- case StdCursor.Arrow:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.Cross:
- return (IntPtr)Carbon.ThemeCursor.kThemeCrossCursor;
- case StdCursor.Default:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.Hand:
- return (IntPtr)Carbon.ThemeCursor.kThemeOpenHandCursor;
- case StdCursor.Help:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.HSplit:
- return (IntPtr)Carbon.ThemeCursor.kThemeResizeLeftRightCursor;
- case StdCursor.IBeam:
- return (IntPtr)Carbon.ThemeCursor.kThemeIBeamCursor;
- case StdCursor.No:
- return (IntPtr)Carbon.ThemeCursor.kThemeNotAllowedCursor;
- case StdCursor.NoMove2D:
- return (IntPtr)Carbon.ThemeCursor.kThemeNotAllowedCursor;
- case StdCursor.NoMoveHoriz:
- return (IntPtr)Carbon.ThemeCursor.kThemeNotAllowedCursor;
- case StdCursor.NoMoveVert:
- return (IntPtr)Carbon.ThemeCursor.kThemeNotAllowedCursor;
- case StdCursor.PanEast:
- return (IntPtr)Carbon.ThemeCursor.kThemeResizeRightCursor;
- case StdCursor.PanNE:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanNorth:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanNW:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanSE:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanSouth:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanSW:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.PanWest:
- return (IntPtr)Carbon.ThemeCursor.kThemeResizeLeftCursor;
- case StdCursor.SizeAll:
- return (IntPtr)Carbon.ThemeCursor.kThemeResizeLeftRightCursor;
- case StdCursor.SizeNESW:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.SizeNS:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.SizeNWSE:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.SizeWE:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.UpArrow:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.VSplit:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- case StdCursor.WaitCursor:
- return (IntPtr)Carbon.ThemeCursor.kThemeSpinningCursor;
- default:
- return (IntPtr)Carbon.ThemeCursor.kThemeArrowCursor;
- }
+ internal override IntPtr DefineStdCursor (StdCursor id) {
+ return Carbon.Cursor.DefineStdCursor (id);
}
internal override IntPtr DefWndProc(ref Message msg) {
}
break;
}
+ case Msg.WM_SETCURSOR: {
+ // Pass to parent window first
+ while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
+ hwnd = hwnd.parent;
+ msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
+ }
+
+ if (msg.Result == IntPtr.Zero) {
+ IntPtr handle;
+
+ switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
+ case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
+ case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
+ case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
+ //FIXME: AudibleAlert();
+ }
+ handle = Cursors.Default.handle;
+ break;
+
+ case HitTest.HTHELP: handle = Cursors.Help.handle; break;
+ case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
+ case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
+ case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
+ case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
+ case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
+
+ #if SameAsDefault
+ case HitTest.HTGROWBOX:
+ case HitTest.HTSIZE:
+ case HitTest.HTZOOM:
+ case HitTest.HTVSCROLL:
+ case HitTest.HTSYSMENU:
+ case HitTest.HTREDUCE:
+ case HitTest.HTNOWHERE:
+ case HitTest.HTMAXBUTTON:
+ case HitTest.HTMINBUTTON:
+ case HitTest.HTMENU:
+ case HitTest.HSCROLL:
+ case HitTest.HTBOTTOM:
+ case HitTest.HTCAPTION:
+ case HitTest.HTCLIENT:
+ case HitTest.HTCLOSE:
+ #endif
+ default: handle = Cursors.Default.handle; break;
+ }
+ SetCursor(msg.HWnd, handle);
+ }
+ return (IntPtr)1;
+ }
}
return IntPtr.Zero;
}
CFRelease (hwnd.client_window);
*/
- if (WindowMapping [hwnd.Handle] != null)
+ if (WindowMapping [hwnd.Handle] != null) {
DisposeWindow ((IntPtr)(WindowMapping [hwnd.Handle]));
+ WindowMapping.Remove (hwnd.Handle);
+ }
}
internal override IntPtr DispatchMessage(ref MSG msg) {
}
internal override void DoEvents() {
+ MSG msg = new MSG ();
+
+ in_doevents = true;
+ while (PeekMessage (null, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
+ TranslateMessage (ref msg);
+ DispatchMessage (ref msg);
+ }
+ in_doevents = false;
+
}
internal override void EnableWindow(IntPtr handle, bool Enable) {
}
internal override IntPtr GetActive() {
- foreach (DictionaryEntry entry in WindowMapping)
- if (IsWindowActive ((IntPtr)(entry.Value)))
- return (IntPtr)(entry.Key);
-
- return IntPtr.Zero;
+ return ActiveWindow;
}
internal override Region GetClipRegion(IntPtr hwnd) {
if (Idle != null)
Idle (this, EventArgs.Empty);
else if (TimerList.Count == 0) {
- ReceiveNextEvent (0, IntPtr.Zero, Convert.ToDouble ("0." + Timer.Minimum), true, ref evtRef);
+ ReceiveNextEvent (0, IntPtr.Zero, 0.15, true, ref evtRef);
if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
SendEventToEventTarget (evtRef, target);
ReleaseEvent (evtRef);
}
internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
- return true;
+ IntPtr evtRef = IntPtr.Zero;
+ IntPtr target = GetEventDispatcherTarget();
+ CheckTimers (DateTime.UtcNow);
+ ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
+ if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
+ SendEventToEventTarget (evtRef, target);
+ ReleaseEvent (evtRef);
+ }
+
+ lock (queuelock) {
+ if (MessageQueue.Count <= 0) {
+ return false;
+ } else {
+ object queueobj;
+ if (flags == (uint)PeekMessageFlags.PM_REMOVE)
+ queueobj = MessageQueue.Dequeue ();
+ else
+ queueobj = MessageQueue.Peek ();
+
+ if (queueobj is GCHandle) {
+ XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
+ return false;
+ }
+ msg = (MSG)queueobj;
+ return true;
+ }
+ }
}
internal override bool PostMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
}
internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool clear) {
- Carbon.HIRect scroll_rect = new Carbon.HIRect ();
- scroll_rect.origin.x = area.X;
- scroll_rect.origin.y = area.Y;
- scroll_rect.size.width = area.Width;
- scroll_rect.size.height = area.Height;
- HIViewScrollRect (handle, ref scroll_rect, (float)XAmount, (float)YAmount);
+ /*
+ * This used to use a HIViewScrollRect but this causes issues with the fact that we dont coalesce
+ * updates properly with our short-circuiting of the window manager. For now we'll do a less
+ * efficient invalidation of the entire handle which appears to fix the problem
+ * see bug #381084
+ */
+ Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
+ Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
}
- internal override void ScrollWindow(IntPtr hwnd, int XAmount, int YAmount, bool clear) {
- Carbon.HIRect scroll_rect = new Carbon.HIRect ();
-
- HIViewGetBounds (hwnd, ref scroll_rect);
- HIViewScrollRect (hwnd, ref scroll_rect, (float)XAmount, (float)YAmount);
+ internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool clear) {
+ Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
+ Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
}
[MonoTODO]
internal override void SetCaretPos (IntPtr hwnd, int x, int y) {
- if (Caret.Hwnd == hwnd) {
+ if (hwnd != IntPtr.Zero && hwnd == Caret.Hwnd) {
+ Caret.X = x;
+ Caret.Y = y;
ClientToScreen (hwnd, ref x, ref y);
SizeWindow (new Rectangle (x, y, Caret.Width, Caret.Height), CaretWindow);
Caret.Timer.Stop ();
HideCaret ();
- Caret.X = x;
- Caret.Y = y;
if (Caret.Visible == 1) {
ShowCaret ();
Caret.Timer.Start ();
internal override void SetCursor(IntPtr window, IntPtr cursor) {
Hwnd hwnd = Hwnd.ObjectFromHandle (window);
- if (hwnd.Handle == window)
- hwnd.ClientCursor = cursor;
- else
- hwnd.WholeCursor = cursor;
+ hwnd.Cursor = cursor;
}
internal override void SetCursorPos(IntPtr handle, int x, int y) {
HIViewSetVisible (hwnd.client_window, visible);
hwnd.visible = visible;
+ hwnd.Mapped = true;
return true;
}
SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
Control ctrl = Control.FromHandle (handle);
- Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (ctrl.GetCreateParams (), new Size (width, height));
+ CreateParams cp = ctrl.GetCreateParams ();
+ Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (cp, new Size (width, height));
Carbon.Rect rect = new Carbon.Rect ();
if (WindowMapping [hwnd.Handle] != null) {
- SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
+ if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
+ SetRect (ref rect, (short)x, (short)y, (short)(x+TranslatedSize.Width), (short)(y+TranslatedSize.Height));
+ } else {
+ SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
+ }
SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
Carbon.HIRect frame_rect = new Carbon.HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
HIViewSetFrame (hwnd.whole_window, ref frame_rect);
+ SetCaretPos (Caret.Hwnd, Caret.X, Caret.Y);
} else {
Carbon.HIRect frame_rect = new Carbon.HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
HIViewSetFrame (hwnd.whole_window, ref frame_rect);
return true;
} else if (!Bottom) {
Hwnd after_hwnd = Hwnd.ObjectFromHandle (after_handle);
- HIViewSetZOrder (hwnd.whole_window, 2, after_hwnd.whole_window);
+ HIViewSetZOrder (hwnd.whole_window, 2, (after_handle == IntPtr.Zero ? IntPtr.Zero : after_hwnd.whole_window));
} else {
HIViewSetZOrder (hwnd.whole_window, 1, IntPtr.Zero);
return true;
return false;
}
}
- internal override Size MinimizedWindowSize { get{ throw new NotImplementedException(); } }
internal override Size MinimizedWindowSpacingSize { get{ throw new NotImplementedException(); } }
internal override Size MinimumWindowSize {
}
}
- internal override Size MinWindowTrackSize { get{ throw new NotImplementedException(); } }
-
internal override Keys ModifierKeys {
get {
return KeyboardHandler.ModifierKeys;
internal override bool MouseButtonsSwapped { get{ throw new NotImplementedException(); } }
internal override bool MouseWheelPresent { get{ throw new NotImplementedException(); } }
+ internal override MouseButtons MouseButtons {
+ get {
+ return MouseState;
+ }
+ }
+
internal override Rectangle VirtualScreen {
get {
return WorkingArea;