Author: jackson
Date: 2007-05-25 17:24:02 -0400 (Fri, 25 May 2007)
New Revision: 77978
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/ChangeLog
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
Log:
* X11Dnd.cs: Rework to make StartDrag a blocking call that runs
it's own message loop.
* XplatUIX11.cs: Remove some of the dnd hooks
* X11Display.cs: Remove some of the dnd hooks.
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-05-25 21:20:07 UTC (rev 77977)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-05-25 21:24:02 UTC (rev 77978)
@@ -1,3 +1,9 @@
+2007-05-25 Jackson Harper <[EMAIL PROTECTED]>
+
+ * X11Dnd.cs: Rework to make StartDrag a blocking call that runs
+ it's own message loop.
+ * XplatUIX11.cs: Remove some of the dnd hooks
+
2007-05-25 Gert Driesen <[EMAIL PROTECTED]>
* XplatUIX11.cs: Change MinimumWindowSize to {Width=0,Height=0}
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs
2007-05-25 21:20:07 UTC (rev 77977)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs
2007-05-25 21:24:02 UTC (rev 77978)
@@ -29,6 +29,7 @@
using System.IO;
using System.Text;
using System.Drawing;
+using System.Threading;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
@@ -280,6 +281,8 @@
public IntPtr Action;
public IntPtr [] SupportedTypes;
public MouseButtons MouseState;
+ public DragDropEffects AllowedEffects;
+ public Point CurMousePos;
public IntPtr LastWindow;
public IntPtr LastTopLevel;
@@ -340,6 +343,7 @@
// check out the TODO below
//private IntPtr CurrentCursorHandle;
+ private bool tracking = false;
private X11Keyboard keyboard;
public X11Dnd (IntPtr display, X11Keyboard keyboard)
@@ -384,7 +388,7 @@
drag_data.MouseState = XplatUIX11.MouseState;
drag_data.Data = data;
drag_data.SupportedTypes = DetermineSupportedTypes
(data);
-
+ drag_data.AllowedEffects = allowed_effects;
drag_data.Action = ActionFromEffect (allowed_effects);
if (CursorNo == null) {
@@ -396,19 +400,74 @@
}
drag_data.LastTopLevel = IntPtr.Zero;
- return DragDropEffects.Copy;
+
+ System.Windows.Forms.MSG msg = new MSG();
+ object queue_id = XplatUI.StartLoop
(Thread.CurrentThread);
+
+ Timer timer = new Timer ();
+ timer.Tick += new EventHandler (DndTickHandler);
+ timer.Interval = 50;
+ timer.Start ();
+
+ int suc;
+ drag_data.State = DragState.Dragging;
+
+ suc = XplatUIX11.XSetSelectionOwner (display,
XdndSelection,
+ drag_data.Window, IntPtr.Zero);
+
+ if (suc == 0) {
+ Console.Error.WriteLine ("Could not take
ownership of XdndSelection aborting drag.");
+ drag_data.Reset ();
+ return DragDropEffects.None;
+ }
+
+ drag_data.State = DragState.Dragging;
+ drag_data.CurMousePos = new Point ();
+ tracking = true;
+
+ while (tracking && XplatUI.GetMessage (queue_id, ref
msg, IntPtr.Zero, 0, 0)) {
+
+ if (msg.message >= Msg.WM_KEYFIRST &&
msg.message <= Msg.WM_KEYLAST) {
+ HandleKeyMessage (msg);
+ } else {
+ switch (msg.message) {
+ case Msg.WM_LBUTTONUP:
+ case Msg.WM_RBUTTONUP:
+ if (msg.message ==
Msg.WM_LBUTTONDOWN && drag_data.MouseState != MouseButtons.Left)
+ break;;
+ if (msg.message ==
Msg.WM_RBUTTONDOWN && drag_data.MouseState != MouseButtons.Right)
+ break;
+
+ HandleButtonUpMsg ();
+ break;
+ case Msg.WM_MOUSEMOVE:
+ drag_data.CurMousePos.X =
Control.LowOrder ((int) msg.lParam.ToInt32 ());
+ drag_data.CurMousePos.Y =
Control.HighOrder ((int) msg.lParam.ToInt32 ());
+
+ HandleMouseOver ();
+ // We don't want to dispatch
mouse move
+ continue;
+ }
+
+ XplatUI.DispatchMessage (ref msg);
+ }
+ }
+
+ timer.Stop ();
+ if (drag_event != null)
+ return drag_event.Effect;
+
+ return DragDropEffects.None;
}
- public bool HandleButtonRelease (ref XEvent xevent)
+ private void DndTickHandler (object sender, EventArgs e)
{
- if (drag_data == null)
- return false;
+ HandleMouseOver ();
+ }
- if (!((drag_data.MouseState == MouseButtons.Left &&
- xevent.ButtonEvent.button == 1) ||
- (drag_data.MouseState ==
MouseButtons.Right &&
-
xevent.ButtonEvent.button == 3)))
- return false;
+ public void HandleButtonUpMsg ()
+ {
+
if (drag_data.State == DragState.Beginning) {
//state = State.Accepting;
@@ -416,8 +475,8 @@
if (drag_data.WillAccept) {
- if (QueryContinue (xevent, false,
DragAction.Drop))
- return true;
+ if (QueryContinue (false,
DragAction.Drop))
+ return;
}
@@ -427,101 +486,73 @@
// handlers
}
- return false;
+ return;
}
- public bool HandleMotionNotify (ref XEvent xevent)
+ public bool HandleMouseOver ()
{
- if (drag_data == null)
- return false;
+ bool dnd_aware = false;
+ IntPtr toplevel = IntPtr.Zero;
+ IntPtr window = XplatUIX11.RootWindowHandle;
- if (drag_data.State == DragState.Beginning) {
- int suc;
+ IntPtr root, child;
+ int x_temp, y_temp;
+ int x_root, y_root;
+ int mask_return;
+ int x = x_root = drag_data.CurMousePos.X;
+ int y = y_root = drag_data.CurMousePos.Y;
- drag_data.State = DragState.Dragging;
-
- suc = XplatUIX11.XSetSelectionOwner (display,
XdndSelection,
- drag_data.Window,
- xevent.ButtonEvent.time);
-
- if (suc == 0) {
- Console.Error.WriteLine ("Could not
take ownership of XdndSelection aborting drag.");
- drag_data.Reset ();
- return false;
- }
-
- drag_data.State = DragState.Dragging;
- } else if (drag_data.State != DragState.None) {
- bool dnd_aware = false;
- IntPtr toplevel = IntPtr.Zero;
- IntPtr window = XplatUIX11.RootWindowHandle;
-
- IntPtr root, child;
- int x_temp, y_temp;
- int mask_return;
-
- while (XplatUIX11.XQueryPointer (display,
- window,
- out root, out child,
- out x_temp, out y_temp,
- out xevent.MotionEvent.x,
- out xevent.MotionEvent.y,
- out mask_return)) {
+ while (XplatUIX11.XQueryPointer (display, window, out
root, out child,
+ out x_temp, out y_temp, out x,
out y, out mask_return)) {
- if (!dnd_aware) {
- dnd_aware = IsWindowDndAware
(window);
- if (dnd_aware) {
- toplevel = window;
-
xevent.MotionEvent.x_root = x_temp;
-
xevent.MotionEvent.y_root = y_temp;
- }
+ if (!dnd_aware) {
+ dnd_aware = IsWindowDndAware (window);
+ if (dnd_aware) {
+ toplevel = window;
+ x_root = x_temp;
+ y_root = y_temp;
}
+ }
- if (child == IntPtr.Zero)
- break;
+ if (child == IntPtr.Zero)
+ break;
- window = child;
- }
+ window = child;
+ }
- if (window != drag_data.LastWindow &&
drag_data.State == DragState.Entered) {
- drag_data.State = DragState.Dragging;
+ if (window != drag_data.LastWindow && drag_data.State
== DragState.Entered) {
+ drag_data.State = DragState.Dragging;
- // TODO: Send a Leave if this is an MWF
window
+ // TODO: Send a Leave if this is an MWF window
- if (toplevel != drag_data.LastTopLevel)
- SendLeave
(drag_data.LastTopLevel, xevent.MotionEvent.window);
- }
+ if (toplevel != drag_data.LastTopLevel)
+ SendLeave (drag_data.LastTopLevel,
toplevel);
+ }
- drag_data.State = DragState.Entered;
- if (toplevel != drag_data.LastTopLevel) {
- // Entering a new toplevel window
- SendEnter (toplevel, drag_data.Window,
drag_data.SupportedTypes);
- } else {
- // Already in a toplevel window, so
send a position
- SendPosition (toplevel,
drag_data.Window,
- drag_data.Action,
-
xevent.MotionEvent.x_root,
-
xevent.MotionEvent.y_root,
-
xevent.MotionEvent.time);
- }
+ drag_data.State = DragState.Entered;
+ if (toplevel != drag_data.LastTopLevel) {
+ // Entering a new toplevel window
+ SendEnter (toplevel, drag_data.Window,
drag_data.SupportedTypes);
+ } else {
+ // Already in a toplevel window, so send a
position
+ SendPosition (toplevel, drag_data.Window,
+ drag_data.Action,
+ x_root, y_root,
+ IntPtr.Zero);
+ }
- drag_data.LastTopLevel = toplevel;
- drag_data.LastWindow = window;
- return true;
- }
- return false;
+ drag_data.LastTopLevel = toplevel;
+ drag_data.LastWindow = window;
+ return true;
}
- public bool HandleKeyPress (ref XEvent xevent)
+ public void HandleKeyMessage (MSG msg)
{
- if (VirtualKeys.VK_ESCAPE == (VirtualKeys)
keyboard.EventToVkey (xevent)) {
- if (!QueryContinue (xevent, true,
DragAction.Cancel))
- return true;
+ if (VirtualKeys.VK_ESCAPE == (VirtualKeys) msg.wParam) {
+ QueryContinue (true, DragAction.Cancel);
}
-
- return false;
}
-
+
// return true if the event is handled here
public bool HandleClientMessage (ref XEvent xevent)
{
@@ -578,7 +609,7 @@
return true;
}
- private bool QueryContinue (XEvent xevent, bool escape,
DragAction action)
+ private bool QueryContinue (bool escape, DragAction action)
{
QueryContinueDragEventArgs qce = new
QueryContinueDragEventArgs ((int) XplatUI.State.ModifierKeys,
escape, action);
@@ -590,14 +621,15 @@
case DragAction.Continue:
return true;
case DragAction.Drop:
- SendDrop (drag_data.LastTopLevel, source,
xevent.ButtonEvent.time);
- break;
+ SendDrop (drag_data.LastTopLevel, source,
IntPtr.Zero);
+ return true;
case DragAction.Cancel:
drag_data.Reset ();
c.InternalCapture = false;
break;
}
+ tracking = false;
return false;
}
@@ -692,7 +724,11 @@
pos_y = (int) xevent.ClientMessageEvent.ptr3 & 0xFFFF;
// Copy is implicitly allowed
- allowed = EffectFromAction
(xevent.ClientMessageEvent.ptr5) | DragDropEffects.Copy;
+ Control source_control = MwfWindow (source);
+ if (source_control == null)
+ allowed = EffectFromAction
(xevent.ClientMessageEvent.ptr5) | DragDropEffects.Copy;
+ else
+ allowed = drag_data.AllowedEffects;
IntPtr parent, child, new_child, last_drop_child;
parent = XplatUIX11.XRootWindow (display, 0);
@@ -741,16 +777,19 @@
if (converts_pending > 0)
return true;
+
if (!status_sent) {
drag_event = new DragEventArgs (data, 0, pos_x,
pos_y,
allowed, DragDropEffects.None);
control.DndEnter (drag_event);
+
SendStatus (source, drag_event.Effect);
status_sent = true;
} else {
drag_event.x = pos_x;
drag_event.y = pos_y;
control.DndOver (drag_event);
+
SendStatus (source, drag_event.Effect);
}
@@ -777,7 +816,7 @@
if (control != null && drag_event != null) {
drag_event = new DragEventArgs (data,
0, pos_x, pos_y,
- allowed, DragDropEffects.None);
+ allowed, drag_event.Effect);
control.DndDrop (drag_event);
}
SendFinished ();
@@ -794,9 +833,10 @@
private bool HandleStatusEvent (ref XEvent xevent)
{
+
if (drag_data != null && drag_data.State ==
DragState.Entered) {
- if (!QueryContinue (xevent, false,
DragAction.Continue))
+ if (!QueryContinue (false, DragAction.Continue))
return true;
drag_data.WillAccept = ((int)
xevent.ClientMessageEvent.ptr2 & 0x1) != 0;
@@ -816,6 +856,7 @@
allowed |= DragDropEffects.Move;
if (action == XdndActionLink)
allowed |= DragDropEffects.Link;
+
return allowed;
}
@@ -1002,6 +1043,8 @@
xevent.ClientMessageEvent.ptr1 = toplevel;
XplatUIX11.XSendEvent (display, source, false,
IntPtr.Zero, ref xevent);
+
+ tracking = false;
}
// There is a somewhat decent amount of overhead
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
2007-05-25 21:20:07 UTC (rev 77977)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
2007-05-25 21:24:02 UTC (rev 77978)
@@ -3624,8 +3624,6 @@
//
switch(xevent.type) {
case XEventName.KeyPress: {
- if (Dnd.InDrag ())
- Dnd.HandleKeyPress (ref xevent);
Keyboard.KeyEvent (FocusWindow, xevent,
ref msg);
break;
}
@@ -3753,12 +3751,6 @@
}
case XEventName.ButtonRelease: {
- if (Dnd.InDrag()) {
- if (Dnd.HandleButtonRelease
(ref xevent)) {
- break;
- }
- // Allow the LBUTTONUP message
to get through
- }
switch(xevent.ButtonEvent.button) {
case 1: {
@@ -3843,8 +3835,6 @@
Console.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client
? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
xevent.MotionEvent.x, xevent.MotionEvent.y);
#endif
- if (Dnd.HandleMotionNotify (ref
xevent))
- goto ProcessNextMessage;
if (Grab.Hwnd != IntPtr.Zero) {
msg.hwnd = Grab.Hwnd;
} else {
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/ChangeLog
===================================================================
---
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/ChangeLog
2007-05-25 21:20:07 UTC (rev 77977)
+++
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/ChangeLog
2007-05-25 21:24:02 UTC (rev 77978)
@@ -1,3 +1,7 @@
+2007-05-25 Jackson Harper <[EMAIL PROTECTED]>
+
+ * X11Display.cs: Remove some of the dnd hooks.
+
2007-05-03 Jonathan Pobst <[EMAIL PROTECTED]>
* XplatUIX11-new.cs: Implement RaiseIdle.
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs
===================================================================
---
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs
2007-05-25 21:20:07 UTC (rev 77977)
+++
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs
2007-05-25 21:24:02 UTC (rev 77978)
@@ -1963,8 +1963,6 @@
switch (xevent.type) {
case XEventName.KeyPress:
- if (Dnd.InDrag ())
- Dnd.HandleKeyPress (ref xevent);
Keyboard.KeyEvent (FocusWindow.Handle,
xevent, ref msg);
return true;
@@ -2084,12 +2082,6 @@
}
case XEventName.ButtonRelease:
- if (Dnd.InDrag()) {
- if (Dnd.HandleButtonRelease
(ref xevent))
- return true;
- // Don't return here, so that
the BUTTONUP message can get through
- }
-
switch(xevent.ButtonEvent.button) {
case 1:
if (client) {
@@ -2167,9 +2159,6 @@
xevent.MotionEvent.x, xevent.MotionEvent.y);
#endif
- if (Dnd.HandleMotionNotify (ref
xevent))
- goto ProcessNextMessage;
-
if (Grab.Hwnd != IntPtr.Zero)
msg.hwnd = Grab.Hwnd;
else
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches