[HN Gopher] Things you should know about Windows Input, but woul...
       ___________________________________________________________________
        
       Things you should know about Windows Input, but would rather not
        
       Author : w4rh4wk5
       Score  : 141 points
       Date   : 2024-09-17 15:08 UTC (7 hours ago)
        
 (HTM) web link (ph3at.github.io)
 (TXT) w3m dump (ph3at.github.io)
        
       | LordDragonfang wrote:
       | >If you are already an expert on game input on Windows, please
       | skip directly to our current solution and tell us how to do it
       | better, because I hope fervently that it's not the best!
       | 
       | This is a neat thing to see at the top of an article, very in
       | line with the hacker spirit.
        
         | plorkyeran wrote:
         | I don't write it explicitly, but this has been the goal pretty
         | much every time I've put a bunch of work into writing up how
         | I've done some complicated thing. It's half Cunningham's Law
         | and half trying to convince the experts out there that putting
         | in the effort of telling me the better way to do things won't
         | be wasted.
        
       | blibble wrote:
       | meanwhile under wayland if you move your 8k mouse too much then
       | the socket event buffer fills up and the compositor terminates
       | the connection, killing the app
        
         | mdaniel wrote:
         | <s>"1024x768 ought to be enough for anyone"</s>
         | 
         |  _Sorry, I thought you meant 8k like the resolution, not 8kHz
         | mouse sampling rate. I thought about deleting my comment, but
         | it made me laugh so maybe it will others, too_
        
         | Asooka wrote:
         | It's ok, it's only been in development for 16 years. Rome
         | wasn't built in a day!
        
       | rkharsan64 wrote:
       | > A few days later after the build is pushed to beta testers, you
       | get a bug report that the game window can no longer be moved
       | around. And then you realize that you just disabled the system's
       | ability to move the window around, because that is done using
       | legacy input.
       | 
       | I don't think I've seen any AAA games that allow me to run them
       | in windowed mode with decent performance.
       | 
       | Valorant, for example, switches to windowed mode when I press
       | Alt-Enter by mistake, but doesn't allow me to interact with the
       | window much. It also locks up completely when Alt-Tabbing, so I
       | don't know what's going on there.
       | 
       | Plus, I think the general expectation is to always run AAA games
       | in full-screen mode. In such cases, disabling legacy messages is
       | a viable approach.
        
         | xnorswap wrote:
         | That's odd, because in my experience almost all games run best
         | in "Borderless windowed" mode.
         | 
         | You get full-screen performance with the ability to easily alt-
         | tab without mode changes.
        
           | marzullo wrote:
           | I think it's only been with new DX12 presentation modes [1]
           | that games can use "Borderless windowed" without input lag.
           | Before that or without updated support, you would always get
           | a noticeable amount of input lag when not using exclusive
           | fullscreen. I played CSGO competitively for a while, and it
           | was definitely enough to be annoying.
           | 
           | [1] https://learn.microsoft.com/en-
           | us/windows/win32/direct3ddxgi...
        
             | xnorswap wrote:
             | This isn't my area of expertise, but isn't DX12 a decade
             | old at this point?
        
               | plorkyeran wrote:
               | Not needing to care about win7/8 is relatively recent (a
               | few years now, but a lot less than ten), and fully
               | supporting both dx11 and dx12 with no caveats was
               | sufficiently difficult that most games didn't really take
               | full advantage of dx12 until they could drop dx11.
        
               | debugnik wrote:
               | Flip model swap chains were already available since DXGI
               | 1.2 (Windows 8) and could be used with D3D11.
               | 
               | Strangely enough, Windows 7 also supported the flip
               | model, but only as an extension to D3D9, not 10/11.
        
             | debugnik wrote:
             | Flip model swap chains were already available for D3D11
             | since DXGI 1.2 (Windows 8) and also as an extension to D3D9
             | (but not 10/11) since Win 7.
        
           | Suppafly wrote:
           | >That's odd, because in my experience almost all games run
           | best in "Borderless windowed" mode.
           | 
           | I think the difference is between when you tell the game to
           | run that way in it's settings, versus abruptly forcing it by
           | doing alt-tab. Games where their default 'full screen' is
           | really 'borderless windowed' don't have problems when you
           | alt-tab, but a lot of them act weird when their 'full screen'
           | actually is a true full screen mode and you force them out of
           | it by alt-tabbing.
        
         | DrillShopper wrote:
         | I still don't get how people play Valorant with the kernel-
         | level anti-cheat
        
           | bigstrat2003 wrote:
           | The sad reality is that people simply do not give a damn/are
           | so weak willed that they will buy the game regardless. I wish
           | it weren't the case, but unfortunately it is.
        
       | phendrenad2 wrote:
       | Can you disable and re-enable NOLEGACY on-the-fly? Maybe you can
       | disable it when you calculate that the user has moved the mouse
       | outside of the game window region.
        
         | meepmorp wrote:
         | apparently not:
         | 
         | > This would at least solve the problem for the vast majority
         | of users, but it's not possible, as far as I can tell. You
         | seemingly cannot switch between legacy and raw input once
         | you've enabled it. You might think RIDEV_REMOVE would help, but
         | that completely removes all input that the device generates,
         | including both legacy and raw input.
        
         | LetsGetTechnicl wrote:
         | Unfortunately it seems that is not possible.
        
       | jchw wrote:
       | I just had a thought: I really wonder how mouse-in-pointer[1]
       | mode interacts with raw input. I had looked into mouse-in-pointer
       | somewhat extensively to try to understand how it behaves[2], in
       | part because I'd really like WM_POINTER in wine some day (but I
       | fear I will never actually be able to contribute to that effort,
       | since I'm just not in-the-weeds enough with Wine input, and I
       | don't think anyone is interested in holding my hand to figure it
       | out.) However, one thing I definitely never thought about is raw
       | input. It's pretty clear that both are implemented somewhere in
       | kernel mode, in front of the event processing queue, so I bet
       | they have an interaction. WM_POINTER events also implement
       | batching, so I wonder if enabling both and ensuring the
       | windowproc doesn't let it fallback can solve some problems.
       | Probably not, but worth a shot.
       | 
       | [1]: https://learn.microsoft.com/en-
       | us/windows/win32/api/winuser/...
       | 
       | [2]: https://github.com/jchv/WmPointerDemo
       | 
       | > Disable legacy input, create your own legacy input events at
       | low frequency. Another one in the category of "silly ideas that
       | probably could work", but there are a lot of legacy messages and
       | this would be another support nightmare.
       | 
       | This was my first thought when reading the article. Frankly it
       | would be a pain, but this seems like the sort of thing that
       | someone only has to do one time.
        
         | wvenable wrote:
         | I would think you only have to generate enough legacy mouse
         | messages that your application works. I'm sure I'm probably
         | missing some catch here but I know plenty of applications that
         | simulate input.
         | 
         | (Calling them "legacy" messages seems weird -- this is the
         | normal current way that input messages work for regular
         | applications).
        
           | jchw wrote:
           | Even if you do generate legacy input events, it is worth
           | noting that the kernel still knows that they're not real
           | input events. It seems to keep track of the current event on
           | a per-thread basis (maybe it's stuffed into the TIB or
           | something, but it could also just not be visible, I didn't
           | search too deeply.) The knock-on effect of this is that
           | sometimes DefWindowProc won't do the expected thing if you
           | feed it a synthetic event, which could lead to strange
           | behavior. You can of course use
           | CreateSyntheticPointerDevice[1], and try to emulate it like
           | that, but obviously then it knows that the events are coming
           | from a synthetic pointer device (which is also system-wide
           | and not just per-application!) So it feels like any way you
           | go, behavior will be slightly different than expected.
           | 
           | Will this matter? I'm not quite sure.
           | 
           | I think Microsoft's WebView2 component enables Mouse-in-
           | Pointer mode using the undocumented syscall for doing it per-
           | HWND, but apparently Raw Input is per-entire-process, so if
           | you aren't generating "legacy" events, will a WebView2
           | component in your process function as expected? Maybe if you
           | go the synthetic pointer route, but again, that's a pretty
           | big can of worms in and of itself.
           | 
           | Windows input is indeed very tricky. Seems like there's only
           | one way to figure out some of these answers. Perhaps I should
           | add RawInput to my test application and find out what the
           | interaction is.
           | 
           | [1]: https://learn.microsoft.com/en-
           | us/windows/win32/api/winuser/...
        
       | pentamassiv wrote:
       | I maintain a library to simulate input on Windows, macOS and
       | Linux. There are a ton of quirks on all of these platforms. On
       | Windows you can simulate text input. The text cannot start with a
       | new line character though. It is perfectly fine if it's not the
       | first one though. macOS also allows you to simulate text input,
       | but the text has to be shorter than 21 characters. Linux is
       | especially difficult with X11, multiple Wayland protocols and
       | libei.
        
         | Scramblejams wrote:
         | If it's available, I'd love a link.
        
         | indrora wrote:
         | Look into contributing to LibTAS.
         | 
         | It's very Linux specific but can frame by frame manipulate the
         | input that an application is getting, meant for speed runs of
         | games.
        
       | msp26 wrote:
       | Shoutout to Elden Ring where the entire game freezes when your
       | (wireless) mouse goes to sleep.
        
       | mdaniel wrote:
       | I have to be very disciplined about switching my layout back to
       | US English before launching games because they seem insistent on
       | using the _mapping_ for WASD versus the _keys_ for WASD. But,
       | worse (IMHO): _some_ games use the keys and thus I can 't predict
       | whether the game was coded correctly or not and thus I just gave
       | up and made it part of my launch process
       | 
       | I have secret desires to convert one of my old MacBook Pro
       | devices into a Steam-via-Proton setup to get out from under the
       | tyranny of Windows but since gaming is designed to be a break
       | from "work" ... that's why it's not already done
        
         | sickofparadox wrote:
         | This is the kind of slippery problem I would never think about
         | but would make me want to break my keyboard if I encountered in
         | real life.
        
           | mdaniel wrote:
           | I am very lucky that Win+spacebar switches, so it's low drama
           | to execute, just some drama to remember. Insult to injury,
           | and likely very related to the article's points: if I
           | remember _after_ launching the game, Win+spacebar is 50 /50
           | on whether the game notices and thus I usually just pay the
           | startup cost again if I forget rather than having things be
           | in limbo
        
             | thaumasiotes wrote:
             | > I am very lucky that Win+spacebar switches, so it's low
             | drama to execute, just some drama to remember.
             | 
             | Unless they've fixed this in the last few years, switching
             | your input mode like that while World of Warcraft is
             | running will cause some kind of crash that prevents you
             | from using the in-game chat. This felt especially egregious
             | because switching input modes is the kind of thing you want
             | to do all the time _if you 're using the in-game chat_.
        
             | dwattttt wrote:
             | There's a lot to be said for a consistent process that
             | always fixes a problem, vs one that fixes the problem
             | relatively permanently, inconsistently, and requires more
             | memory.
        
         | giancarlostoro wrote:
         | Not sure about Macbook Pro, but I converted my Windows 11
         | gaming desktop to Linux and Steam with Proton works just fine
         | for all the games I care about. The only game that didn't play
         | was Starfield and that was fixed shortly after a few weeks.
        
         | justin66 wrote:
         | That's easier than just changing the key bindings in game?
        
           | mdaniel wrote:
           | Option 1: remember to press Win+spacebar before launching
           | game
           | 
           | Option 2: launch game, navigate to settings, write down on a
           | sheet of paper what the current keybindings are (since one I
           | press "." for "e" it's going to either whine or blank out
           | whatever "." was mapped to when I started), repeat that
           | exercise about 25 times per game, times the 15 games I have
           | in rotation right now, feel that was a great use of my
           | "downtime"
           | 
           | Option 2 has the added bonus of making it 50/50 whether the
           | game help text _knows_ I remapped, and thus says  "press . to
           | open door" or whether it continues to say "press e to open
           | door" and I have to _guess_ whether it means  "their e" or
           | "my e"
        
             | card_zero wrote:
             | The way games ought to do keymapping is to just allow
             | conflicts. If you map two functions to the same key, that
             | key should do both things, until the player sorts it out.
             | The keymapper can put a warning sign up, "conflicts with
             | foobar", but it shouldn't remove the key from foobar, and
             | it shouldn't say "I can't allow you to do that", either.
        
         | Denvercoder9 wrote:
         | Your computer doesn't actually know what the keys for WASD are.
         | It just receives a number (commonly called scan code) for the
         | pressed key from the keyboard, and has to use the mapping to
         | determine which key that actually was.
         | 
         | There's some convention for which scan code to use for which
         | physical position on a keyboard, but that's not correlated with
         | what's actually printed on the key caps. E.g. on common QWERTY
         | keyboards the "A" key will have scan code 4, but on AZERTY
         | keyboards it will have scan code 20.
         | 
         | Games can probably get away by listening for the scan codes of
         | the keys in the position commonly used by WASD, but it's a bit
         | fragile, and they can't actually tell you what's printed on the
         | keys they're listening to. The lack of consistenency is
         | certainly annoying, though...
        
           | zamadatix wrote:
           | Scancode vs character code is what they are describing:
           | 
           | Games SHOULD use scancodes for positional mappings (like
           | WASD) and rely on the system keymap to decide what letter to
           | display them as. There is no "probably" here, the scancode is
           | the scancode and the keymap is the keymap.
           | 
           | Games OFTEN use the character codes directly regardless if
           | it's for a positional mapping or not. This requires explicit
           | support in the game for each possible system keymap,
           | otherwise you end up with nonsense mappings.
        
           | snuxoll wrote:
           | > Games can probably get away by listening for the scan codes
           | of the keys in the position commonly used by WASD, but it's a
           | bit fragile, and they can't actually tell you what's printed
           | on the keys they're listening to. The lack of consistenency
           | is certainly annoying, though...
           | 
           | The operating system knows how to map scan codes to
           | characters based on the keyboard mapping the user has
           | selected.                   Win32: MapVirtualKeyExA /
           | MapVirtualKeyW         MacOS: CGEventKeyboardGetUnicodeString
           | / UCKeyTranslate         Linux: xkb_state_key_get_utf8
           | 
           | Hell, glfw nicely wraps all of these up with glfwGetKeyName.
           | 
           | Stop reading character codes directly, use the scan code and
           | when displaying them map it using the system API so people
           | see the right freaking binding. It's not rocket science,
        
         | w4rh4wk5 wrote:
         | We've invested some time to improve this situation for the
         | games we port, at least to some extent. Keyboard input is read
         | as a combination of scan code + win32 virtual key information
         | to determine the physical key pressed on your keyboard. This
         | way the keybindings are (almost) independent of the keyboard
         | layout.
         | 
         | However, we also reflect your current key bindings with dynamic
         | button prompts that tell you which key to press in game. For
         | this we translate the determined physical key back through the
         | selected keyboard layout to figure out what the corresponding
         | label on your keyboard might be.
         | 
         | Most of this is just win32 API shenanigans, but the following
         | post provides a bit more detail on reading inputs this way.
         | 
         | https://blog.molecular-matters.com/2011/09/05/properly-handl...
        
       | dezgeg wrote:
       | Another "fun" thing is old joysticks and steering wheels that
       | require calibration. This used to be done in the windows control
       | panel such that not every game needs to implement that... However
       | it seems the latest API in fashion that eg. Unity uses just
       | totally ignores that native calibration totally. (Could just be
       | an Unity side problem also). So bunch of old wheels are broken on
       | Unity.
        
         | gmueckl wrote:
         | What's equallt bad these days is the fact that the calibration
         | UI is hidden in the third or fourth level of nested dialog
         | windows recent versions of the Control Panel. Even finding it
         | is a hunting game.
         | 
         | Many, but not all recent game controllers come with accurate
         | and stable enough calibration so that you don't need to do this
         | very often or at all. It's mostly older hardware that needs to
         | go through the process. Most 10 year old controllers
         | (sticks/wheels etc.) can still be perfectly usable today after
         | calibration!
        
           | vel0city wrote:
           | It was pretty easy to find with the Settings app.
           | 
           | "Find a setting" > type "joy" suggests "Setup USB game
           | controllers". Lists the controllers/joysticks. Click
           | "Properties". Click "Calibrate..."
        
       | zelon88 wrote:
       | > prevent performance collapse by just not processing more than N
       | message queue events per frame. N=5
       | 
       | Why is this an issue? Your mouse is sending raw input 80,000
       | times per second to a screen that can only display 120 pictures
       | per second.
       | 
       | Kinda sounds like an arbitrary problem that people who believe 8k
       | mouses are necessary would worry about.
        
         | maccard wrote:
         | > Your mouse is sending raw input 80,000 times per second to a
         | screen that can only display 120 pictures per second.
         | 
         | 8 thousand, not 80 thousand. Many screens can display (much
         | more) than 120 frames per second - My monitor goes to 240hz,
         | there are 300hz displays available.
         | 
         | Rendering rate is very often not tied to game update rates -
         | games can update their state at significantly higher rates than
         | they display. A decent number of games have a "high level"
         | skill of doing things like "pre-shooting" where the winner of a
         | fight is done by figuring out "who realistically did it first".
         | 
         | Assuming that you can poll at 125hz is wrong.
         | 
         | > Why is this an issue? ... Kinda sounds like an arbitrary
         | problem that people who believe 8k mouses are necessary would
         | worry about.
         | 
         | People have these devices and run our games. We (unfortunately)
         | need to handle them, just like a website needs to handle a
         | poorly behaved client. Also depending on _when_ you sample,
         | (i.e. which 5 messages you handle), you can get incorrect
         | information from the device.
        
           | sumtechguy wrote:
           | Also they probably ended up where they were because if I
           | remember correctly windows will 'smash' mouse move events
           | together for you in some cases. This will look like 'lost
           | messages' (I recognized the peek loop as I have done that
           | same thing once). This is is for two reasons one old not
           | needed as much any more, and the one they found out the hard
           | way. Memory as just scrubbing the mouse around would create a
           | ton of memory objects that need to be pretty much cleaned up
           | right away. The second is performance. As that is a ton of
           | little messages that need to be picked up looked at and
           | something done with. Which zorches your CPU.
           | 
           | The core of the issue is trying to wrap polling style of
           | logic into an event based system (which windows is at its
           | heart). There is no real pretty way to fix it.
        
             | maccard wrote:
             | > The core of the issue is trying to wrap polling style of
             | logic into an event based system (which windows is at its
             | heart).
             | 
             | Well said. The irony being that the event based system on
             | windows is wrapping the polling of the USB device in the
             | first place.
        
             | leni536 wrote:
             | I think it would be probably best to handle it like real
             | time audio, 8kHz is not far off anyway. Just collect mouse
             | sensor data at a fixed sampling rate into a ring buffer,
             | and don't try to have a separate complex object for each
             | sample.
        
         | kevingadd wrote:
         | I've seen high mouse polling rates cause genuine performance
         | problems in real games. It was a surprise to me too, but I
         | ended up dropping my polling rate from 4000 to 500 to fix it.
        
         | VyseofArcadia wrote:
         | Simulation resolution needs to be higher than display
         | resolution. Simulating physics at only 120Hz can lead to jank.
         | This is similarly true in the spacial dimensions, where even
         | old games would run the game simulation at more than 640x480
         | for fidelity.
        
       | wackget wrote:
       | I'm gonna ask here because I've not found a solution anywhere
       | else:
       | 
       | I loved the Middle-earth: Shadow of Mordor game but when I tried
       | to play its sequel, Middle-earth: Shadow of War, I found the
       | mouse input absolutely horrible.
       | 
       | Horrendous mouse lag, floaty camera control, and all the signs of
       | a "mouse emulating gamepad" type situation.
       | 
       | Does anyone know if there's a way to fix this game? I'd love to
       | play it on PC with a mouse but can't stomach it as-is.
        
         | CrimsonRain wrote:
         | Sometimes, enabling "raw mouse input" option in the game solves
         | this completely. Ofc this depends on the game, and also not all
         | games have this option. The ones that don't, you can try
         | reducing your mouse DPI to 400 and polling rate to lowest; I
         | think 125hz. Don't remember.
         | 
         | btw, I never played this particular game but lots of others
         | have this issue.
        
       | okibry wrote:
       | Is the solution look like rare limit in the client side ?
       | 
       | And maybe it will have some missed event between your ticker for
       | processing game logic and fps.
        
       | andrewmcwatters wrote:
       | I know this doesn't address the technical questions asked or the
       | concerns prompted, but if your mouse is causing your games to
       | have performance issues...
       | 
       | It's not a high-end mouse.
       | 
       | Yeah, yeah OK polling rates, etc. Whatever. But honestly, PC
       | gamers have been mostly fine for over 20 years of dealing with
       | mouse input. Some major engines didn't even support raw input
       | until after the mid-2000s.
       | 
       | You can put a V8 on a Corolla... but if the curb weight changes
       | and the torque eats up your tires, well, what did you expect?
       | It's just idiot engineering.
        
         | CrimsonRain wrote:
         | You just don't know what you are talking about. You are
         | essentially saying horse carriage was great for transportation.
         | A car isn't an upgrade. PC gamers were fine with 60hz monitor.
         | 120hz is not high end/is not needed... high end mice are
         | essential for certain games; esp esports ones.
        
           | andrewmcwatters wrote:
           | No they aren't.
        
           | bigstrat2003 wrote:
           | Please, 120 Hz monitors and "high end" mice are the PC gaming
           | equivalent of audiophile equipment. Provides no actual
           | benefit other than the user believing in it.
        
             | ben0x539 wrote:
             | I don't know about mice, but I can't believe you wouldn't
             | notice the difference between 60 fps and 120 fps when
             | rapidly turning the camera in a 3d game.
        
       | phibz wrote:
       | It reads like he is assuming that missing messages from the mouse
       | is not allowable.
       | 
       | I would say think of it this way: what happens when the mouse
       | moves between USB hid messages?
       | 
       | If the mouse moves between messages sent via USB HID do the later
       | messages capture the delta between the last and current message.
       | Including the movement that happened in between?
       | 
       | Do the input messages, both those sent over USB by the mouse as
       | well processed and presented by Windows, give relative or
       | absolute positions?
       | 
       | The messages already represent a discrete sampling if a signal.
       | You should be able to recreate the original information
       | reasonably well without processing every single message.
        
       | SleepyMyroslav wrote:
       | If author reads comments I just wanted to confirm that everything
       | seems to be correct.
       | 
       | The fun parts you might not know is eg. that if you want to ship
       | on steam you will need legacy messages for its overlay to
       | function. Because its a web based thing ^_^
       | 
       | Practical solutions usually include either letting user to pick
       | their perfect input type and assume they know limitations like no
       | windowed mode. Or expecting users to reduce 8k to reasonable
       | number in mouse software. Users already know how to read forums
       | or reddit and games that do now work fine with 4k/8k polling
       | rates are well known and numerous.
       | 
       | There is an alternative that my colleagues going to explore =
       | make it Microsoft problem. There is Microsoft provided library
       | that can do input for you ...
        
         | durante_a wrote:
         | If the library you are alluding to is GameInput, then I tried
         | that and it sadly did not solve the problem.
        
           | SleepyMyroslav wrote:
           | I never said it would. Any engine needs 'basic platform
           | support' style input. And going into extra
           | windows/threads/apis is for 'competitive shooter titles'.
           | 
           | After working on one a bit I would say library way is not
           | good enough :) but it is sure thing cost effective way to
           | support a platform. Or even few platforms shared by same
           | vendor.
        
       | anaisbetts wrote:
       | I would point people to the new GameInput API -
       | https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/inp...
       | 
       | GameInput does everything these older APIs do without having to
       | mix them all together or use a bunch of them to get the
       | information you want
        
         | mmozeiko wrote:
         | Unfortunately not everything. For example, no xbox 360
         | controller support: https://github.com/microsoft/GDK/issues/39
        
         | durante_a wrote:
         | I tried GameInput, sadly it doesn't solve this issue.
         | 
         | You still need legacy input for Window interactions, and the
         | message queue still gets flooded by fast-polling mice.
        
           | dwattttt wrote:
           | I guess if mice are generating too many messages, asking
           | Windows to coalesce them has less impact.
        
           | mananaysiempre wrote:
           | Just wanted to check: what are the messages that cause the
           | problem, exactly? If it's only WM_MOUSEMOVE and
           | WM_NCMOUSEMOVE, then it's important to note that they do not,
           | in fact, become real messages[1] until you GetMessage or
           | PeekMessage:
           | 
           | > When the hardware mouse reports an interrupt, indicating
           | that the physical mouse has moved, Windows determines which
           | thread should receive the mouse move message and sets a flag
           | on that thread's input queue that says, "The mouse moved, in
           | case anybody cares." (Other stuff happens, too, which we will
           | ignore here for now. In particular, if a mouse button event
           | arrives, a lot of bookkeeping happens to preserve the virtual
           | input state.)
           | 
           | > When that thread calls a message retrieval function like
           | GetMessage, and the "The mouse moved" flag is set, Windows
           | inspects the mouse position and does the work that is
           | commonly considered to be part of mouse movement: Determining
           | the window that should receive the message, changing the
           | cursor, and determining what type of message to generate
           | (usually WM_MOUSEMOVE or perhaps WM_NCMOUSEMOVE).
           | 
           | The book version of Raymond Chen's blog[2] elaborates on the
           | subject of messages arriving in an empty forest:
           | 
           | > One of [the] special messages is the WM_MOUSEMOVE message.
           | As you saw earlier, the message is not added as an input
           | message when the mouse moves; instead, a "the mouse moved"
           | flag is set. When the window manager goes looking for an
           | input message and the "the mouse moved" flag is set, it
           | clears the flag and generates a WM_MOUSEMOVE message on the
           | fly, adding it to the list of input messages (or coalescing
           | it with an existing WM_MOUSEMOVE message).
           | 
           | > Other special messages that fall into this "generated on
           | the fly" category are the WM_PAINT, WM_TIMER and WM_QUIT
           | messages. The first two messages are generated even later in
           | the message search process, only after no applicable input
           | message list was found, and only if the message filter
           | indicates that that type of message is being requested. (The
           | WM_QUIT message is even shier than the paint and timer
           | messages, because it emerges only after the posted message
           | list is empty. On the other hand, the WM_QUIT message is also
           | bolder, in that it ignores the message filter.)
           | 
           | Keeping that in mind, using PeekMessage() and thus
           | materializing the pending WM_MOUSEMOVE should be done very
           | carefully (though with PM_REMOVE it shouldn't be a problem).
           | In fact, it seems like unless you care about WM_TIMER,
           | WM_PAINT, or WM_QUIT, the right thing to do upon seeing a
           | WM_MOUSEMOVE (but not a WM_NCMOUSEMOVE) would be to behave as
           | though the message queue is currently empty and proceed to do
           | whatever other processing you need to perform for the current
           | frame.
           | 
           | Still, I don't get why this should be a problem. If you
           | receive a WM_MOUSEMOVE and your only action is to discard it,
           | surely it doesn't take 125 ms to do that? And if it doesn't,
           | you shouldn't see more WM_MOUSEMOVEs that can only get
           | generated at 8 kHz at most.
           | 
           | Suggested experiment because I don't have a fancy mouse: if
           | you insert                 if (msg.hwnd == <root window> &&
           | msg.message == WM_MOUSEMOVE) continue;
           | 
           | before the TranslateMessage call, will the stutter disappear?
           | I know that above I proposed break instead of continue, but
           | continue could be less disruptive to other special messages--
           | if it works.
           | 
           | [1]: https://devblogs.microsoft.com/oldnewthing/20031001-00/?
           | p=42...
           | 
           | [2] https://openlibrary.org/works/OL9256722W
        
       | YetiSpaghetti wrote:
       | I think the author has two issues in their approach.
       | 
       | 1) You should be processing the whole message queue for all types
       | of messages in one go. When using raw input, author is peeking
       | for "not input" event types. To me, this seems suspicious for
       | performance. With a raw input device registered, the message
       | queue is going to be huge.
       | 
       | While I don't know the underlying data structure of the message
       | queue, if we assume an array, then the author's code will do a
       | while loop of O(N) lookups for "not input" messages and remove
       | them.
       | 
       | The correct approach is to dispatch the whole queue and ignore
       | messages of types that you don't care about in your message
       | handler.
       | 
       | 2) You SHOULD be using the legacy input events for games, not raw
       | input. The OS input massaging (ex: acceleration) is something
       | that should remain consistent between applications. If there's
       | acceleration: that's what users expect. You don't want the mouse
       | to suddenly behave different in your application. Your games
       | tuning values (sensitivity, accel) should apply relative to the
       | OS values.
        
         | munchler wrote:
         | > You SHOULD be using the legacy input events for games, not
         | raw input.
         | 
         | The author claims that this generates an overwhelming number of
         | events for a high-performance mouse. Is this not the case?
        
           | YetiSpaghetti wrote:
           | Only when a raw input device is enabled. If I remember
           | correctly, Windows will also send the raw input as legacy
           | input messages. With no raw input device registered, the OG
           | message queue is not bloated.
        
         | Matheus28 wrote:
         | For shooter games, raw input is preferred. You want the same
         | amount of mouse movement to move your camera the same amount
         | every time.
         | 
         | In those type of games, you aren't controlling a cursor, so
         | there's no "expected behavior".
        
           | jamesgeck0 wrote:
           | I'd argue that linear camera movement with mouse _is_ the
           | expected behavior for FPS these days.
        
           | YetiSpaghetti wrote:
           | It's more complex than that. There's no right answer and
           | therefore every answer is wrong :(
           | 
           | For more critical observers, you're right: raw input is
           | preferred. However, most users (casuals) expect similar
           | settings as their OS. It's probably best left up to the user
           | to decide, but to default things to the OS legacy settings. A
           | more advanced player will know to tune the settings while the
           | less advanced just want to launch and go.
        
             | CrimsonRain wrote:
             | No. He's right. No fps gamer expects the game camera speed
             | to "match" mouse movement speed. Raw input-> mouse DPI * in
             | game sense = effective dpi. Everyone has their own
             | preferred edpi. This was you can change mouse or computer
             | or in different games, you always get consistent movement.
        
               | YetiSpaghetti wrote:
               | Everyone plays fps games. This includes people who
               | wouldn't consider themselves "fps gamers". Users who care
               | about mouse input will go into the settings to target the
               | 'correct' settings for them.
               | 
               | For everyone else, there's the OS values.
               | 
               | We're not having the same argument, but I didn't clarify
               | in my initial post properly: It's best to launch your app
               | for the first time with the default OS settings. Let the
               | "power users (fps gamers)" tune settings that enable raw
               | input.
        
           | ben0x539 wrote:
           | Surely even in a shooter game you spend some amount of time
           | in menus where you do have a cursor, right? Is this why I
           | sometimes get completely 'wrong' cursor movement in games?
        
       | Animats wrote:
       | I use winit, which is a Rust crate for dealing with windows
       | (lower case) and keyboard/mouse events. It supports Microsoft
       | Windows, MacOS, Linux/X11, Linux/Wayland, Android, web browsers,
       | and Redox OS. Trying to abstract over all of those works, almost.
       | 
       | Reading keyboard arrows or WASD has timing problems. Although the
       | program gets key code up/down events, the key repeat software
       | seems to interfere with the timing of the events and slows them
       | down. Software repeats can be ignored, but still cause problems.
       | Holding down a repeating key for long periods can cause lost
       | events. X11 is especially bad, but there seem to be some problems
       | with Windows, too.
       | 
       | Another thing nobody has fixed in the Rust game dev ecosystem yet
       | because the developer base is tiny. Rust needs one good first
       | person shooter project with enough push behind it to wring out
       | the performance problems in interactive 3D.
        
       | kazinator wrote:
       | Japanese IME on Windows is insane; it's always switching to A
       | mode. You're always fighting it to go to a.
        
         | Rels wrote:
         | I also hate this behavior. My understanding is that it doesn't
         | get noticed by native users as it's not an issue when the JP
         | input is the only input, so it's mainly an issue for language
         | learners.
         | 
         | It's been on my mind to try the google IME for some time, to
         | see if it fixes this issue, but haven't got around trying it
         | yet.
        
       | kazinator wrote:
       | One thing I'd like to see fixed in computer keyboard input in
       | general is how Shift is handled for capitals.
       | 
       | I find it next to impossible to type "Now" really fast without
       | having it come out as "NOw" much of the time. (Why I'm using this
       | example is that it's the first word of the "Now is the time ..."
       | test sentence).
       | 
       | The timing required is strict. The Shift key must be down before
       | the letter key is down.
       | 
       | Keys activate strictly and immediately on the down event.
       | 
       | Note that virtual buttons on most contemporary GUIs, clicked by
       | mouse, do not work this way. You must click and release the
       | button for it to activate. If you click OK on some dialog, but
       | change your mind while still holding down the mouse button, you
       | can back out of it, by moving the cursor out of the button's
       | area. You also cannot click down outside of the button, then move
       | into the button and release. The button must receive both mouse
       | down and mouse up, without the pointer leaving the area, in order
       | to activate.
       | 
       | I'd like a mode in which the down events of non-modifier keys are
       | deliberately delayed by some configurable number of milliseconds,
       | so that when the user hits a modifier key at around the same
       | time, and that key lands a little bit late, it is still taken
       | into account.
       | 
       | It would also be nice to be able to experiment with a mode in
       | which keystrokes are generated by their up events, not down, and
       | the modifier is sampled at that time.
        
         | akira2501 wrote:
         | > The timing required is strict.
         | 
         | Your keyboard has a serial interface to your computer. Events
         | are generated serially. If you press one first it will register
         | first.
         | 
         | > keystrokes are generated by their up events
         | 
         | We don't do this because then you can't have auto repeat.
        
         | zaat wrote:
         | I can't find any viable alternative. Keyboard is much faster
         | than those click and release interfaces. Keyboards also have
         | repeat keys, when you press a character for a long time you can
         | actually press and depress the shift key and see the change in
         | the line of characters input. This is extremely useful feature
         | in games, graphic design software and other applications.
         | 
         | Generation of keystroke based on the up event, beside been
         | incompatible with repeating keys for long strokes, will slow
         | down typing significantly, as it requires tracking timing
         | pressing keys for longer duration. I'm pretty sure that this
         | isn't only effect of me being used to track keypress timing on
         | the way down, but an unavoidable result of the duration of the
         | action.
         | 
         | Waiting for up event on contemporary GUI, when the contempt UI
         | is a sluggish fit-to-nothing dirty touchscreen in a public
         | kiosk is sensible. When you know an interface will yield more
         | errors than intended input it is only sensible to assume that
         | any input is a mistake unless the user is making an effort to
         | validate it.
        
       | modeless wrote:
       | > Use a separate process to provide raw input. This is a bit of a
       | silly idea
       | 
       | I don't think this is silly at all. People are too timid about
       | using multiple processes in general. It's OK, there's nothing
       | wrong with it! We ought to have more libraries to help make
       | multiprocess apps.
        
       ___________________________________________________________________
       (page generated 2024-09-17 23:00 UTC)