[Gtk-sharp-list] Fwd: Dragging Floating windows

Andy Selvig ajselvig at gmail.com
Sun Aug 3 11:28:17 EDT 2008


Hi-

I sent the e-mail below a couple weeks ago and haven't gotten any
response. I'm not sure if it just didn't go through or what the deal
is. Anyway, if anyone has any idea how to help it would be
appreciated, otherwise some direction as to where else to go for help
would be great.

Thanks.


---------- Forwarded message ----------
From: Andy Selvig <ajselvig at gmail.com>
Date: Wed, Jul 23, 2008 at 7:54 AM
Subject: Dragging Floating windows
To: gtk-sharp-list at lists.ximian.com


Hello All-

I'm having some trouble with dragging a floating, decoration-less
window around the screen. I have written a small (tried to keep it
under 100 lines but failed) app that demonstrates the problem.

The main window simply contains a button. When the user clicks on the
button, the button reparents itself to a floating window and the user
can then drag the window around the screen. The problem is that, after
the user clicks the button but BEFORE they let go of the mouse button,
the dragging doesn't seem to behave quite right. If the mouse is moved
slowly enough, it works fine, but at a certain speed the floating
window will stop tracking it. The strange thing is that if the user
lets go and clicks on the button again, the dragging will work
perfectly, no matter what the speed. It basically just doesn't seem to
be receiving the mouse events properly after the reparent.

I tried looking through the C source for HandleBox, but couldn't find
what makes it not behave this way. My source code is attached. Any
help would be greatly appreciated.

Thanks.

-Andy





using System;



namespace FloatDraggingTest

{

	/// <summary>

	/// Main window.

	/// </summary>

	class MainWindow : Gtk.Window

	{

		/// <summary>

		/// Application entry point.

		/// </summary>

		public static void Main(string[] args)

		{

			Gtk.Application.Init();

			MainWindow win = new MainWindow();

			win.ShowAll();

			Gtk.Application.Run();

		}





		/// <summary>

		/// Main window default constructor.

		/// </summary>

		public MainWindow()

			: base(Gtk.WindowType.Toplevel)

		{

			floatWidget = new FloatWidget("Click Me");

			Add(floatWidget);



			DeleteEvent += OnDeleteEvent;

		}



		/// <summary>

		/// Called when the window is deleted, stops the application.

		/// </summary>

		/// <param name="o"></param>

		/// <param name="args"></param>

		void OnDeleteEvent(object o, Gtk.DeleteEventArgs args)

		{

			Gtk.Application.Quit();

		}





		private FloatWidget floatWidget;



	}





	/// <summary>

	/// A widget that you can grab and drag around.

	/// </summary>

	class FloatWidget : Gtk.Button

	{



		/// <summary>

		/// Default constructor.

		/// </summary>

		/// <param name="text"> Text to display on the widget.</param>

		public FloatWidget(string text)

			: base(new Gtk.Label(text))

		{

			// create the float window

			floatWindow = new Gtk.Window(Gtk.WindowType.Toplevel);

			floatWindow.Decorated = false;



			AddEvents((int)Gdk.EventMask.AllEventsMask); // add all events

		}



		private Gtk.Window floatWindow;



		private bool grabbed = false;



		private Gdk.Point grabPoint;



		protected override bool OnButtonPressEvent(Gdk.EventButton evnt)

		{

			grabbed = true;

			int grabX, grabY;

			GetPointer(out grabX, out grabY);

			grabPoint = new Gdk.Point(grabX, grabY);

			return true;

		}



		protected override bool OnButtonReleaseEvent(Gdk.EventButton evnt)

		{

			grabbed = false;

			return true;

		}



		protected override bool OnMotionNotifyEvent(Gdk.EventMotion evnt)

		{

			if (grabbed) // the window has been grabbed

			{

				if (Parent != floatWindow) // it isn't floating yet, float it

				{

					Reparent(floatWindow);

					floatWindow.ShowAll();

				}

				MoveToCursor();

			}



			return true;

		}



		protected override bool OnLeaveNotifyEvent(Gdk.EventCrossing evnt)

		{

			if (grabbed)

				MoveToCursor();

			return true;

		}



		/// <summary>

		/// Moves the floating window to the cursor.

		/// </summary>

		protected void MoveToCursor()

		{

			int cursorX, cursorY, windowX, windowY;

			GetPointer(out cursorX, out cursorY);

			GdkWindow.GetPosition(out windowX, out windowY);

			floatWindow.GdkWindow.Move(windowX + cursorX - grabPoint.X, windowY
+ cursorY - grabPoint.Y);

			Display.Sync();

		}



	}





}


More information about the Gtk-sharp-list mailing list