Osu: Raw input issue on GNU/Linux since the 2018.915.0 version

Created on 24 Sep 2018  路  14Comments  路  Source: ppy/osu

I was playing osu!lazer without any problem until the 2018.915.0 version breaks the raw input option.

Here is a video of the issue: https://youtu.be/lsfJ96dCIL0
And logs : https://framadrop.org/r/l_-sS5jBau#LFMP2eIJVlwr/6bxD4nZlskAZ2dMEFSuF1QdgWcILTM=

As you can see, when cursor sensitivity is set to less than 1, the cursor tends to return to its starting location. When its set to greater than 1, the cursor tends to move (with more and more speed) towards the edge of the window.

The 2018.910.0 version is working fine.

framework-fix-required linux input

Most helpful comment

UPDATE: I jumped the gun on this one. There's more to the problem than just SDL only.

@bdach pointed out to me that INeedsMousePositionFeedback could also be the culprit for input 'amplification'.

True enough, removing just that from https://github.com/ppy/osu-framework/blob/4d58344fb52493cc7022c47ddbdec9fea5c04c98/osu.Framework/Input/Handlers/Mouse/OsuTKRawMouseHandler.cs#L17 somewhat solves the issue.

Looking further, INeedsMousePositionFeedback is getting called twice. once in the abstract InputManager, and the second time would be when raw input is used.

The end results of this change is that the desktop cursor will not be at the same coordinates as when in game (noticeable when you alt-tab out of the game).

Though this does raise more questions than answers - how does x11 survive having its input handled twice?

All 14 comments

Same with the 2018.928.0 version.

Raw Input active also seems to break scrolling with your mouse on linux.

@Alexmitter On the latest version? What distro?

Raw Input active also seems to break scrolling with your mouse on linux.

Mmmh... No problem with me, I think that's another issue.

@morguldir freshly compiled from the master branch. Xubuntu 18.04.1 64bit.

@Leeo97one as the Linux support is more like accidentally, I guess there are quite a few issues like that. But I can confirm it, scrolling is only not possible if raw input is active.

Anyway, another issue is already open for this: https://github.com/ppy/osu/issues/3338

Simillar issue on 2018.915.0 version. Mouse wheel only works when raw input is disabled. On Ubuntu 18.04.1 distro

I was pretty dumb, one year ago. Yes, the issue is not about mousewheel. Sorry about that

But this issue is not about the mouse wheel. x)

Touchscreen seems to be affected by this as well. When using raw input with a custom sensitivity taps are mapped to seemingly random locations, and dragging experiences the same glitches as the mouse cursor.
Using .NET Core on Gentoo Linux (Glibc, OpenRC), if that information turns out to be of any relevance.
Game log: runtime.log

This seems to have been introduced on osuTK between the 1.0.7 and 1.0.8 updates. This can be show by switching the framework (tested on 2018.913.0 because it builds with both) the issue disappear and reappear accordingly. Narrowing down what change on osuTK was responsible for such seems to not be a trivial task however, because the Git history on the osuTK repository seems to be incomplete? (it jumps from commit f64058c9 to 2f2f05c5, version 1.0.4 straight to 1.0.8, and none of them seems to even build. Am I missing something?)

There have been very few changes to osuTK. you can check build numbers to commit hashes on appveyor
https://ci.appveyor.com/project/peppy/opentk

After a few weeks of continuous digging, and also taking lots of time to setup the tooling, here are my findings.

First of all, I would have to make a distinction between two issues that I face on linux.

  • Raw input cursor on linux that breaks when you change sensitivity to something other than 1
  • Raw input cursor on linux that slides slowly to the edge when returning from alt-tab && sensitivity is at 1

The video by @Leeo97one shows both at the same time, but for me its only either one of the above at any one time.

I cannot say for sure that they are unrelated. My findings only address the first issue, though I have come across the second issue when the sens is at well...1

The linux raw input problem lies in SDL more than just SDL (check my next comment for an update). In getUpdatedPosition, the difference between state and lastState is getting "amplified" in a feedback loop. The two paramenters come from osuTK.Input.Mouse.GetStates(newRawStates);.

Tracing back, Lnux platform's implementation of GetStates is SDL2. I have stdout all the way until SDL2InputDriver.cs's FilterInputEvents, which is the furthest I can go. And the X and Y is still wrong.

According to https://wiki.libsdl.org/SDL_MouseMotionEvent?highlight=%28%5CbCategoryStruct%5Cb%29%7C%28CategoryEvents%29#Remarks, this mouseevent occurs whenever a user moves the mouse within the application window is too vague for me and I cant explore further. Unless I know how SDL_MouseEvents are generated, my findings will end here.

If you like to try out my method, here it is:

Clone a framework
Place this piece of code below this line (Forgive me as I have not learnt to use Logger.Print)
https://github.com/ppy/osu-framework/blob/4d58344fb52493cc7022c47ddbdec9fea5c04c98/osu.Framework/Input/Handlers/Mouse/OsuTKRawMouseHandler.cs#L161

Console.Write("statePos: " + state.X + ", " + state.Y + "\t");
Console.Write("lastPos: " + lastState.RawState.X + ", " + lastState.RawState.Y + "\t");
Console.Write("diff: " + (state.X - lastState.RawState.X) + ", " + (state.Y - lastState.RawState.Y) + "\t");
Console.Write("diff*sens: " + (state.X - lastState.RawState.X) * (float)Sensitivity.Value + ", "
                            + (state.Y - lastState.RawState.Y) * (float)Sensitivity.Value + "  \t");
Console.Write("currentPos: " + currentPosition.X + ", " + currentPosition.Y + "\n");

Then run osu.Framework.Tests -> Input -> InputManager -> ToggleRawInput and observe your cmd

Here is the amplification on display. nth statePos = n-1th lastPos + diff*sens

Sensitivity = 5

statePos: -12, -349     lastPos: -13, -349      diff: 1, 0      diff*sens: 5, 0         currentPos: 401, 165
statePos: -8, -349      lastPos: -12, -349      diff: 4, 0      diff*sens: 20, 0        currentPos: 421, 165
statePos: 12, -349      lastPos: -8, -349       diff: 20, 0     diff*sens: 100, 0       currentPos: 521, 165
statePos: 112, -349     lastPos: 12, -349       diff: 100, 0    diff*sens: 500, 0       currentPos: 1021, 165
statePos: 612, -349     lastPos: 112, -349      diff: 500, 0    diff*sens: 2500, 0      currentPos: 3521, 165
statePos: 1510, -349    lastPos: 612, -349      diff: 898, 0    diff*sens: 4490, 0      currentPos: 8011, 165
statePos: 1510, -348    lastPos: 1510, -349     diff: 0, 1      diff*sens: 0, 5         currentPos: 8011, 170
statePos: 1510, -344    lastPos: 1510, -348     diff: 0, 4      diff*sens: 0, 20        currentPos: 8011, 190
statePos: 1510, -324    lastPos: 1510, -344     diff: 0, 20     diff*sens: 0, 100       currentPos: 8011, 290
statePos: 1510, -224    lastPos: 1510, -324     diff: 0, 100    diff*sens: 0, 500       currentPos: 8011, 790
statePos: 1510, 276     lastPos: 1510, -224     diff: 0, 500    diff*sens: 0, 2500      currentPos: 8011, 3290

Sensitivity = 0.5

statePos: 142, -300     lastPos: 142, -297      diff: 0, -3     diff*sens: 0, -1.5      currentPos: 338, 179.5
statePos: 142, -299     lastPos: 142, -300      diff: 0, 1      diff*sens: 0, 0.5       currentPos: 338, 180
statePos: 142, -300     lastPos: 142, -299      diff: 0, -1     diff*sens: 0, -0.5      currentPos: 338, 179.5
statePos: 143, -299     lastPos: 142, -300      diff: 1, 1      diff*sens: 0.5, 0.5     currentPos: 338.5, 180
statePos: 142, -299     lastPos: 143, -299      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 338, 180
statePos: 142, -300     lastPos: 142, -299      diff: 0, -1     diff*sens: 0, -0.5      currentPos: 338, 179.5
statePos: 142, -298     lastPos: 142, -300      diff: 0, 2      diff*sens: 0, 1         currentPos: 338, 180.5
statePos: 142, -300     lastPos: 142, -298      diff: 0, -2     diff*sens: 0, -1        currentPos: 338, 179.5
statePos: 142, -301     lastPos: 142, -300      diff: 0, -1     diff*sens: 0, -0.5      currentPos: 338, 179
statePos: 142, -300     lastPos: 142, -301      diff: 0, 1      diff*sens: 0, 0.5       currentPos: 338, 179.5
statePos: 142, -301     lastPos: 142, -300      diff: 0, -1     diff*sens: 0, -0.5      currentPos: 338, 179

Compare this against a somewhat working x11 platform backend framework

Sensitivity = 5

statePos: 439, -105     lastPos: 439, -106      diff: 0, 1      diff*sens: 0, 5         currentPos: 556, -342
statePos: 439, -104     lastPos: 439, -105      diff: 0, 1      diff*sens: 0, 5         currentPos: 556, -337
statePos: 440, -104     lastPos: 439, -104      diff: 1, 0      diff*sens: 5, 0         currentPos: 561, -337
statePos: 440, -103     lastPos: 440, -104      diff: 0, 1      diff*sens: 0, 5         currentPos: 561, -332
statePos: 441, -103     lastPos: 440, -103      diff: 1, 0      diff*sens: 5, 0         currentPos: 566, -332
statePos: 441, -102     lastPos: 441, -103      diff: 0, 1      diff*sens: 0, 5         currentPos: 566, -327
statePos: 442, -102     lastPos: 441, -102      diff: 1, 0      diff*sens: 5, 0         currentPos: 571, -327
statePos: 443, -102     lastPos: 442, -102      diff: 1, 0      diff*sens: 5, 0         currentPos: 576, -327
statePos: 443, -101     lastPos: 443, -102      diff: 0, 1      diff*sens: 0, 5         currentPos: 576, -322
statePos: 444, -101     lastPos: 443, -101      diff: 1, 0      diff*sens: 5, 0         currentPos: 581, -322
statePos: 445, -101     lastPos: 444, -101      diff: 1, 0      diff*sens: 5, 0         currentPos: 586, -322

Sensitivity = 0.5

statePos: 550, -202     lastPos: 552, -202      diff: -2, 0     diff*sens: -1, 0        currentPos: 586.5, 363.5
statePos: 547, -202     lastPos: 550, -202      diff: -3, 0     diff*sens: -1.5, 0      currentPos: 585, 363.5
statePos: 546, -203     lastPos: 547, -202      diff: -1, -1    diff*sens: -0.5, -0.5   currentPos: 584.5, 363
statePos: 543, -203     lastPos: 546, -203      diff: -3, 0     diff*sens: -1.5, 0      currentPos: 583, 363
statePos: 542, -203     lastPos: 543, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 582.5, 363
statePos: 541, -203     lastPos: 542, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 582, 363
statePos: 538, -203     lastPos: 541, -203      diff: -3, 0     diff*sens: -1.5, 0      currentPos: 580.5, 363
statePos: 537, -203     lastPos: 538, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 580, 363
statePos: 536, -203     lastPos: 537, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 579.5, 363
statePos: 535, -203     lastPos: 536, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 579, 363
statePos: 534, -203     lastPos: 535, -203      diff: -1, 0     diff*sens: -0.5, 0      currentPos: 578.5, 363

Flip this ternary operator to force it to use x11
https://github.com/ppy/osu-framework/blob/4d58344fb52493cc7022c47ddbdec9fea5c04c98/osu.Framework/Host.cs#L20

NOTE: "switching" to x11 is not a permanent (if any one will use it at all) solution as the SDL wil be used in the future. Plus there will be an input lag that slowly creeps in, up to 500ms of delay when using x11 backend.

OS: Manjaro 18.1.1 Juhraya
libinput: 1.14.2-1
xf86-input 0.29.0-1
Kernel: 5.3.7-2-MANJARO
Mouse: Logitech G103 Prodigy @ 1000Hz
Customisation: I have set my libinput via https://wiki.archlinux.org/index.php/Libinput#Via_xinput and https://wiki.archlinux.org/index.php/Mouse_acceleration#Mouse_acceleration_with_libinput
Also have a custome udev entry per https://www.freedesktop.org/software/systemd/man/hwdb.html

UPDATE: I jumped the gun on this one. There's more to the problem than just SDL only.

@bdach pointed out to me that INeedsMousePositionFeedback could also be the culprit for input 'amplification'.

True enough, removing just that from https://github.com/ppy/osu-framework/blob/4d58344fb52493cc7022c47ddbdec9fea5c04c98/osu.Framework/Input/Handlers/Mouse/OsuTKRawMouseHandler.cs#L17 somewhat solves the issue.

Looking further, INeedsMousePositionFeedback is getting called twice. once in the abstract InputManager, and the second time would be when raw input is used.

The end results of this change is that the desktop cursor will not be at the same coordinates as when in game (noticeable when you alt-tab out of the game).

Though this does raise more questions than answers - how does x11 survive having its input handled twice?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

smileyhead picture smileyhead  路  3Comments

lenzfilipski picture lenzfilipski  路  3Comments

LevKatenin picture LevKatenin  路  3Comments

Axeanz picture Axeanz  路  3Comments

smileyhead picture smileyhead  路  3Comments