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(); } } }
_______________________________________________ Gtk-sharp-list maillist - Gtk-sharp-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/gtk-sharp-list