Bug 24127 - Gdk.Event becomes corrupt if you store it.
Summary: Gdk.Event becomes corrupt if you store it.
Status: NEW
Alias: None
Product: Gtk#
Classification: Mono
Component: other ()
Version: 2.x
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-10-29 07:09 UTC by fdpierson93
Modified: 2014-10-29 07:15 UTC (History)
1 user (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 24127 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEW

Description fdpierson93 2014-10-29 07:09:37 UTC
I believe it has to this code here. Whenever you access an Event's property, it access the Native property, which returns a marshaled structure from the raw pointer. I don't know exactly what code gives the Event its raw pointer, but the pointer is problematic because it becomes corrupt over time. The code below shows how event properties are implemented.

NativeStruct Native {
	get { return (NativeStruct) Marshal.PtrToStructure (raw, typeof(NativeStruct)); }}


public uint Button {
	get { return Native.button; }}

The pointer only really works when the Event is fresh. But if you want to store the event to consume later, it becomes corrupt. Run this program below with Windows' version of Monodevelop to see what I mean. Also notice that some members do not corrupt, such as X and Y, but Type does corrupt.

using Gdk;
using Gtk;
using System;

public class Program {
	public static void Main() {
		Application.Init ();
		new MyWindow ("Event Bug").Show ();
		Application.Run ();
	}
}
	
public class MyWindow : Gtk.Window {
	private EventButton StoredEvent = null;

	public MyWindow (string Title) : base(Title) {
		AddEvents ((int)EventMask.AllEventsMask);
	}

	protected override bool OnButtonPressEvent (EventButton e) {
		if (StoredEvent == null) StoredEvent = e;
		else Console.WriteLine ("{0} {1} {2}",
			StoredEvent.X, StoredEvent.Y, StoredEvent.Type);
		return true;
	}
}

In order to have a non-corrupt pointer, I had to take code from EventButton and do my own marshalling. Instead of using Event's existing pointer, I allocated my own. Here's my fix.

using Gdk;
using Gtk;
using System;
using System.Runtime.InteropServices;

public class Program {
	public static void Main() {
		Application.Init ();
		new MyWindow ("Event Bug").Show ();
		Application.Run ();
	}
}

public class MyWindow : Gtk.Window {
	private EventButton Stored = null;
	private IntPtr Pointer = IntPtr.Zero;

	[StructLayout (LayoutKind.Sequential)]
	struct EventStruct {
		EventType type;
		IntPtr window;
		sbyte send_event;
		public uint time;
		public double x;
		public double y;
		public IntPtr axes;
		public uint state;
		public uint button;
		public IntPtr device;
		public double x_root;
		public double y_root;
	}

	public MyWindow (string Title) : base(Title) {
		Pointer = Marshal.AllocHGlobal (Marshal.SizeOf (new EventStruct ()));
		AddEvents ((int)EventMask.AllEventsMask);
	}

	~MyWindow()
		{ Marshal.FreeHGlobal (Pointer); }

	protected override bool OnButtonPressEvent (EventButton e) {
		if (Stored == null) {
			EventStruct Struct = (EventStruct)Marshal.PtrToStructure (e.Handle, typeof(EventStruct));
			Marshal.StructureToPtr (Struct, Pointer, true);
			Stored = new EventButton (Pointer);
		}
		Console.WriteLine ("{0} {1} {2}", Stored.X, Stored.Y ,Stored.Type);
		return true;
	}
}
Comment 1 fdpierson93 2014-10-29 07:15:15 UTC
Apologies if anything on here looks wrong, this is my first bug report!