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

Reply via email to