<div>As a game developer who recently had to implement mouse/keyboard input for Windows, Linux (core and XI2) and Mac OS X, let me try to describe how an ideal input system would work. This will be slightly gaming-centric but I believe the following also covers VMWare&#39;s use case completely.<br>

</div><div><br></div><div>There&#39;s some brainstorming going on here, so please bear with me.</div><div><br></div><div>1. Absolute vs relative motion</div><div><br></div><div>Most games require either relative or absolute motion events. The former are generally used in 3d games with 360 degree cameras (e.g. first-person shooters) that require movement unbound by the window size. The latter are generally used in 2d or top-down games (e.g. real-time strategy) where the pointer always corresponds to a specific on-screen pixel.</div>

<div><br></div><div>A game may require seamless changes from absolute to relative motion or vice versa at any point. For instance, first-person shooters (relative) also have menus (absolute), whereas strategy games (absolute) also have grab&amp;pan modes (relative).</div>

<div><br></div><div>A few, more uncommon, games may also require absolute and relative events at the same time. Whereas independent absolute/relative modes can be emulated even on systems without such support (e.g. core X11), the latter mode *cannot* be implemented without explicit support. This is why the Wine project encounters issues emulating specific Windows games: core X11 only supports absolute events, while Windows supports both absolute and relative. (XInput2 solves this issue, but more on that later).</div>

<div><br></div><div>In short, we need a way to get both the current location of the pointer on screen *and* the relative raw motion (regardless of whether the pointer actually moved or not).</div><div><br></div><div>Windows has two distinct input systems: one absolute and one relative/absolute depending on the device (raw input mouse vs tablet). Core X11 only supports absolute events. XInput2 provides both relative and absolute events, as does Mac OS X.</div>

<div><br></div><div>2. Raw vs scaled input</div><div><br></div><div>Absolute events should always be scaled by the acceleration curve of the server. Relative events should be reported both with and without acceleration applied.</div>

<div><br></div><div>XInput2 gets this 100% right. Windows only provide unscaled raw events but allow you to apply the acceleration curve manually (although the API is rather hairy). As far as I can tell, Mac OS X only provides scaled values, which is a disadvantage for games and applications that apply their own acceleration curves (like the guest OS in VMWare).</div>

<div><br></div><div>3. Constrained vs unconstrained input</div><div><br></div><div>Applications should have a way to indicate that they don&#39;t want the pointer to leave a specific rectangular region. The pointer will stop moving when it hits a boundary of the region (but relative events will continue to be generated).</div>

<div><br></div><div>This is useful for games and applications that require both absolute and relative events (e.g. strategy games or VMWare with a cursor grab).</div><div><br></div><div>4. Mouse warping</div><div><br></div>

<div>This is an important accessibility feature and is provided by all operating systems. The question is whether the waring function should generate motion events.</div><div><br></div><div>The X protocol requires that motion events be reported as if the user had moved the mouse. This feature is ill-designed and has led to untold numbers of hacks. Three solutions: provide an explicit way to suppress those events; set a property to indicate that the motion event is synthesized; or generate absolute events but do not generate relative events.</div>

<div><br></div><div>Windows follows the second solution. Mac OS X follows the third solution. The XInput2 people are considering the first solution. My vote goes for the second: applications keep working without any explicit change and any application that needs to suppress synthesized events can do so.</div>

<div><br></div><div>5. Mouse tracking</div><div><br></div><div>Applications should be able to receive motion events even when the pointer leaves the application window if desired. This feature should be disabled by default and enabled by the application under specific circumstances (e.g. drag&amp;drop motions).</div>

<div><br></div><div>6. Cursor grabs</div><div><br></div><div>On X11, cursor grabs are (ab)used to implement features #1, #3 and #5. With explicit support for those features, cursor grabs lose their value - which is a great thing, considering that grabs have extremely annoying side effects when an application hangs (user cannot click away) or when you are debugging an application (your mouse becomes useless once you hit a breakpoint).</div>

<div><br></div><div>A grab mode might be desirable for password entries. In that case, it should really be called &quot;password mode&quot;, whereupon all input events are redirected to the requesting window. Applications with elevated permissions (like the WM) should be able to break out of a password mode but applications with lower or equal permissions should not.</div>

<div><br></div><div>In any case, it should be made very clear that password mode should be used sparingly and with great care.</div><div><br></div><div>7. Foreground vs background windows</div><div><br></div><div>Background windows should be able to receive input events if explicitly requested but should not be able to constrain the cursor or initiate password mode. It might be desirable to allow mouse warping to work for accessibility reasons.</div>

<div><br></div><div>When a foreground window moves to the background, its constraining region should be disabled. A foreground window in password mode should remain uninterruptible unless explicitly requested by an elevated process (for instance: the user presses &#39;alt-tab&#39; or &#39;minimize&#39; and instructs the (elevated) WM to interrupt password mode).</div>

<div><br></div><div>Any other mutable input settings (like acceleration curves or screen resolution) should be application-specific and the server should restore them once the application loses focus or exits. Permanent changes should only be possible through elevated applications.</div>

<div><br></div><div>8. Multiple pointers</div><div><br></div><div>By default, pointer events should be reported as the aggregate of all individual pointing devices. Applications should be able to request reporting of individual events via a simple API. In that case, moving an individual device would generate an event for both that device and the aggregate (virtual / master) device.</div>

<div><br></div><div>XInput2 has an elaborate master/slave system, where multiple slave devices are attached to master devices and events can be selected for either. This is the most flexible solution but whether this kind of flexibility is actually useful is another matter entirely. Maybe YAGNI is the best approach here: provide only what cannot be implemented directly in applications (multiple master devices *can* be implemented client-side without too much work. Multiple individual devices, however, require server support).</div>

<div><br></div><div>9. Mouse wheel(s)</div><div><br></div><div>For the love of god, mouse wheels are *axes* not *buttons*. Both core X11 and XInput2 get this completely wrong and expose wheels as buttons. This is evil, this is wrong and this makes wheel acceleration impossible to implement in any feasible way. It also makes reliable mouse polling impossible on X11 (since wheel button events have a duration of 0).</div>

<div><br></div><div>To reiterate, wheels should be treated as additional, stateful axes (z, w, ...). Their absolute and relative values should be reported in events with acceleration curves should be applied just like in the x and y axes (and feature #2).</div>

<div><br></div><div>10. Acceleration curves</div><div><br></div><div>These probably belong to the server, in order to ensure consistency. It should be possible to specify different curves for each axis. Applications should be able to modify those curves for while they are alive and in focus. Only elevated applications should be able to modify those globally.</div>

<div><br></div><div><br></div><div>This is all I can think of right now. Feel free to criticize and/or flame, I&#39;ll might be able to help with all this once I can get Wayland running in VirtualBox.</div>