Xeethrax's picture

Hiding mouse cursor in Ubuntu 11.04, any suggestions?

I realise there are several threads already regarding the lack of or dysfunction of this functionality in OpenTK -- this is more of a request of alternative methods of hiding the mouse cursor. The solution offered in the issue thread http://www.opentk.com/node/1560?page=1 (using Cursor.Current with blank cursor) seems to only work in windows for me.

I can only imagine that this is an issue that many people have encountered, and thus I ask;

Does anyone have a (working) solution for hiding the mouse in Ubuntu 11.04?

Thanks!


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Please try with the latest version from svn (instructions here http://www.opentk.com/project/svn) which has official support for cursor hiding.

Xeethrax's picture

Hey, thanks for your reply (and all your effort on OpenTK) :)

After updating from svn and creating the libXi symlink as suggested here: http://www.opentk.com/node/2280, the cursor is indeed hidden, and with a normal mouse everything works just fine.

However.. My game uses a touchscreen, and this presents a new problem. If I show the cursor, the touchscreen input behaves properly, but with CursorVisible=false it starts behaving very erratic. When i press down on the touchscreen the cursor starts jumping to seemingly random positions with every click (or move). I can spam clicks on a single position and the cursor ends up at a random position everytime. When I click and drag, the cursor seems to alternate between a random position and (0, Y) or (X, 0), depending on where my finger is currently pressing. Extremely odd behavior. I have interactivity which requires click-and-drag actions so I'm quite dependant on the mousecoords being correct all the time.

Some of the touchscreens uses the Gentouch driver (which I'm testing on), others use ELO touch drivers (not yet tested). I should mention I had this problem with Tao+SDL as well. I previously used Glut because it gave me the least amount of headaches, ie. fullscreen on dual monitors and hiding the mouse worked without issues.

I realise that this probably isn't OpenTK's fault (as I had the problem with SDL as well), but I can't help but to ask if anyone has any suggestions?

the Fiddler's picture

Oh, the joy of input drivers on X. Can you please compile a debug version of OpenTK.dll and run your application with that? This will print a number of diagnostic messages to System.Diagnostics.Debug - please post these here to help understand what is going on.

A little background: OpenTK uses two input drivers for X. The first uses old-school "core X" input events which are supported pretty much everywhere, but are limited in flexibility (only one mouse device, no support for relative movements).. The second one uses the newer XInput2 API which is significantly more flexible - but requires a recent xorg installation (built within the last one-and-a-half year or so).

Now, OpenTK has three hard requirements for mouse input:

  1. report absolute X, Y coordinates
  2. hide and limit the pointer inside a specified window
  3. when #2 is active, also report relative (unlimited) X, Y coordinates

Now, core X does not report relative movements so #3 requires a hack where the pointer is reset to the center of the window after every motion. Of course, this then breaks #1, so OpenTK uses a second hack to decouple the real mouse location from what it reports when the pointer is hidden. I assume that SDL follows a similar approach to this issue.

The XInput2 driver does not suffer from this issue, as the underlying API can report both absolute and relative motions at the same time. (Of course, OpenTK could still suffer from a bug that manifests under specific conditions like touch input - however such bugs should be fixable).

In short, the first step to fixing this issue is finding out which input driver is in use. The debug version of OpenTK will report that. (Additionally, which distro are you using? XInput2 was introduced in Ubuntu 10.04 if I remember correctly).

If core X is in use, then there's a good chance that the issue isn't fixable (I've spent the better part of last Fall trying to find a solution, before confirming with the Wine source code that this issue is indeed unfixable...) If XInput2 is in use, then we need to trace what motion values are reaching OpenTK and find out what is going wrong.

If you are curious, the input drivers for X are in Soucre/OpenTK/Platform/X11/X11Mouse.cs and Xi2Mouse.cs. The code is deceptively simple when compared to the pain involved in writing, testing and debugging!

Xeethrax's picture

Hello again!

So I went ahead and did as you asked and the debug-version is telling me I'm using XI2Mouse -- and as the title suggests, I'm using Ubuntu 11.04.

I had a glance through Xi2Mouse.cs, which by itself wasn't too informative regarding my issue. I had a peek down the rabbit-hole though and concluded this will have to wait until the morning, as my brain has already started rebooting. I certainly can appreciate the painstaking process required to make it all work, though!

I do have one question from what I've seen so far though, why do you see the need to limit the pointer inside the window while the cursor is hidden? It seems to move the cursor to the middle of the screen as well, which one tend to do for first/third person cameras so you don't stop getting relative movement when the cursor hits the edge of the screen? Shouldn't that be a separate feature, rather than intertwined with the cursors visibility? I can't see any reason why hiding the cursor would cause a need to control its location?

In any case, I'd be happy to provide you with any information you'd require :) Once again, I appreciate your efforts.

Regards,
Xee

(Seems the spamfilter stopped this message last night but I'm posting it now anyway..)

Xeethrax's picture

So I had a hunch that the programmatic movement of the mousecursor in X11GLNative.cs when CursorVisible=false might be causing problems, so I went ahead and commented out line 826-851 and just used

SetMouseClamped(mouse, x, y, 0, 0, Width, Height);
mouse_rel_x = x;
mouse_rel_y = y;

and it pretty much fixed my problem. As far as I can see it didn't introduce any new problems either, but then again I only run my game fullscreen.

tksuoran's picture
Xeethrax wrote:

Hello again!
I do have one question from what I've seen so far though, why do you see the need to limit the pointer inside the window while the cursor is hidden? It seems to move the cursor to the middle of the screen as well, which one tend to do for first/third person cameras so you don't stop getting relative movement when the cursor hits the edge of the screen? Shouldn't that be a separate feature, rather than intertwined with the cursors visibility? I can't see any reason why hiding the cursor would cause a need to control its location?

I agree, hiding mouse and "autowarping" should be two distinct features. For touch screen you do want only to hide.

tksuoran's picture

Setting window.CursorVisible = false; does not seem to enable autowarping on Windows. Can it be enabled somehow?

Edit: This does it - I wonder if this works with all mouse drivers including Ubuntus etc..

        private bool lockMouse = false;
        public bool LockMouse
        {
            get
            {
                return lockMouse;
            }
            set
            {
                lockMouse = value;
                if(value)
                {
                    CenterMouse();
                }
                else
                {
                    ignore = false;
                }
            }
        }
        bool ignore = false;
        private void CenterMouse()
        {
            System.Drawing.Point centerInWindow = new System.Drawing.Point(window.Width / 2, window.Height / 2);
            System.Drawing.Point centerInScreen = window.PointToScreen(centerInWindow);
            ignore = true;
            OpenTK.Input.Mouse.SetPosition(centerInScreen.X, centerInScreen.Y);
        }
        void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs e)
        {
            if(ignore == false)
            {
                if(lockMouse)
                {
                    mouseXDelta += e.XDelta;
                    mouseYDelta += e.YDelta;
                    CenterMouse();
                }
            }
            else
            {
                ignore = false;
            }
        }
exe's picture

Problem: Mouse stops moving when mouse button is pressed.