[Mono-winforms-list] X11Dnd + XEMBED = NRE

Ivan N. Zlatev contact at i-nz.net
Thu Aug 2 19:02:22 EDT 2007


I have finally managed to get the gtk parenting of a mwf control to
work (for the winforms designer addin for MonoDevelop), but with 2
major problems one of which I have tracked down below.

In the MonoDevelop scenario I have a GtkSocket in MD to parent a GTK+
container on a remote designer process. The remote designer process
has the gtk container (where I parent the mwf control) and the mwf
design surface threads and it adds a GtkPlug containing gtk container
(which contains a MWF panel, which contains the design surface) to the
MD socket.

I currently have a major issue with Drag and Drop support in this case
scenarion, which is caused by the Socket/Plug (XEMBED). I get a NRE
when a DnD operation is performed [1]. After investigation I was able
to find that it comes from the MwfWindow (IntPtr source) call [2]
which returns null, because the DnD source (exposed as a private
IntPtr field) is not a MWF Control (even though the DnD operation has
been started from the MWF control parented in a MWF panel). I suppose
this has to do with this quote from

"XDND drag-and-drop does not work with reparented external windows,
since messages are exchanged with the toplevel window only. This is
done for performance reasons. While it is cheap to get the window
under the mouse pointer, it is very expensive to get a window under
another window. Unfortunately, this is required quite often when
dragging objects around, since the pointer may overlap the drag icon.

Solving the drag-and-drop problem, however, is quite easy, since the
XDND protocol was carefully designed in a way that makes it possible
to support embedded windows. Basically, the embedder has to operate as
drag-and-drop proxy for the client. Any XDND messages like XdndEnter,
Xdnd,Leave, etc. simply have to be passed through. A toolkit's XDND
implementation has to take this situation in consideration. "

What would be the best way to approach this in order to enable MWF's
X11Dnd code to handle such a scenario where the drag source is not a
MWF Control?

		private Control MwfWindow (IntPtr window)
			Hwnd hwnd = Hwnd.ObjectFromHandle (window);
			if (hwnd == null)
				return null;

An example use of MwfWindow here:

		private bool QueryContinue (bool escape, DragAction action)
			QueryContinueDragEventArgs qce = new QueryContinueDragEventArgs
((int) XplatUI.State.ModifierKeys,
					escape, action);

			Control c = MwfWindow (source);
			c.DndContinueDrag (qce);

			switch (qce.Action) {
			case DragAction.Continue:
				return true;
			case DragAction.Drop:
				SendDrop (drag_data.LastTopLevel, source, IntPtr.Zero);
				return true;
			case DragAction.Cancel:
				drag_data.Reset ();
				c.InternalCapture = false;

			tracking = false;
			return false;

[1] NRE Backtrace

Unhandled Exception: System.NullReferenceException: Object reference
not set to an instance of an object
  at System.Windows.Forms.X11Dnd.QueryContinue (Boolean escape,
DragAction action) [0x00000]
  at System.Windows.Forms.X11Dnd.HandleStatusEvent
(System.Windows.Forms.XEvent& xevent) [0x00000]
  at System.Windows.Forms.X11Dnd.HandleClientMessage
(System.Windows.Forms.XEvent& xevent) [0x00000]
  at System.Windows.Forms.XplatUIX11.GetMessage (System.Object
queue_id, System.Windows.Forms.MSG& msg, IntPtr handle, Int32
wFilterMin, Int32 wFilterMax) [0x00000]
  at System.Windows.Forms.XplatUI.GetMessage (System.Object queue_id,
System.Windows.Forms.MSG& msg, IntPtr hWnd, Int32 wFilterMin, Int32
wFilterMax) [0x00000]
  at System.Windows.Forms.X11Dnd.StartDrag (IntPtr handle,
System.Object data, DragDropEffects allowed_effects) [0x00000]
  at System.Windows.Forms.XplatUIX11.StartDrag (IntPtr handle,
System.Object data, DragDropEffects allowed_effects) [0x00000]
  at System.Windows.Forms.XplatUI.StartDrag (IntPtr handle,
System.Object data, DragDropEffects allowedEffects) [0x00000]
  at System.Windows.Forms.Control.DoDragDrop (System.Object data,
DragDropEffects allowedEffects) [0x00000]
  at (wrapper remoting-invoke-with-check)
  at Mono.Design.UISelectionService.DragBegin () [0x00000]
  at Mono.Design.ControlDesigner.OnMouseDragBegin (Int32 x, Int32 y) [0x00000]
  at Mono.Design.ControlDesigner.OnMouseMove (Int32 x, Int32 y) [0x00000]
  at Mono.Design.ControlDesigner.WndProc
(System.Windows.Forms.Message& m) [0x00000]
  at Mono.Design.ControlDesigner.Mono.Design.IMessageReceiver.WndProc
(System.Windows.Forms.Message& m) [0x00000]
  at Mono.Design.WndProcRouter.System.Windows.Forms.IWindowTarget.OnMessage
(System.Windows.Forms.Message& m) [0x00000]
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc
(System.Windows.Forms.Message& m) [0x00000]
  at System.Windows.Forms.NativeWindow.WndProc (IntPtr hWnd, Msg msg,
IntPtr wParam, IntPtr lParam) [0x00000]
  at System.Windows.Forms.XplatUIX11.DispatchMessage
(System.Windows.Forms.MSG& msg) [0x00000]
  at System.Windows.Forms.XplatUI.DispatchMessage
(System.Windows.Forms.MSG& msg) [0x00000]
  at System.Windows.Forms.Application.RunLoop (Boolean Modal,
System.Windows.Forms.ApplicationContext context) [0x00000]
  at System.Windows.Forms.Application.Run () [0x00000]
  at WinFormsAddin.EditorProcess.InitializeMWF () [0x00000]
Ivan N. Zlatev

Web: http://www.i-nZ.net
"It's all some kind of whacked out conspiracy."

More information about the Mono-winforms-list mailing list