PREAMBLE:
Hi. I'm the X11-oriented "mouse guy" whom Todd mentioned in his "last call for GSOC, what about shortcuts?" post (Topic #1 in Vol 95, Issue 69).

His focus is within KDE itself, while I'm focusing from the lower layers, moving "up" into KDE Development tools, API, and UI from those lower layers. (X11, the qt-X11 interface, and upwards into signal handling.) I have some ideas about Co-Requisite enhancements to the KDE System Settings Mouse/Pointer Module, and uses within Kwin, Shortcuts, and some other places. This email will NOT address those higher-level KDE modules. There's a lot of fundamental stuff, for which which I will need design advice, and I've been unable to get it so far. I'll be discussing those other areas in follow-up emails, if that's OK.

I'm going to need some direction from KDE visionaries, because there are four alternative "levels" at which we could do this. But first let me show the naming convention which I will be using. "ButtonX" means the button number which gets emitted from X11. Here's the translation layout which I want to use. Please use it, because we'll get the numbers confused if some replies and new comments INCLUDE "wheel events" as numbered buttons, while others EXCLUDE the two pairs. And also, lots of existing hardware is built with "wrong" numbers.

  Button1 = "left button"
  Button2 = "right button", AKA "context menu button"
  Button3 = "middle button"
  Button4 = "scroll wheel up"
  Button5 = "scroll wheel down"
  Button6 = "tilt wheel left", AKA "scroll wheel left"
  Button7 = "tilt wheel right", AKA "scroll wheel right"
  Button8 = "back button", AKA "XButton1"
  Button9 = "forward button" AKA "XButton2"
 Button10 = first additional "gamer" button
 Button11 = 2nd additional "gamer" button
 Button12 = 3rd additional "gamer" button       ... and so on.

Within Qt, the Devs have recognized that Button8 and Button9 are frequently implemented "backwards". Thus they assigned the more cryptic names "XButton1" and "XButton2". But Qt has not considered the possibility of horizontal tilt wheels (or genuine horizontal wheels) implemented on a different pair. And unfortunately, many mice are built with "nonstandard" numbers. (Even products from a single manufacturer can vary. For example, Logitech emits 6/7 from some models, and 13/14 from different ones- usually older models, but still in widespread use.)

Here are the 3 alternatives (within Qt4.x, using XI 1.5) which I've identified for KDE to build upon:

(A) Do absolutely nothing in Qt, simply enhance KWin, KDevelop, and etc. to "support" the buttons which Qt now provides. (B) Add 3 more buttons (Button10 thru Button12), extending the defined enum and mask bits (Qt::MouseButton and QAt::MouseButtons) until they hit a byte boundary.
(C) Use 31, bytes.

- - - - -
ALTERNATIVE (A): DO NOTHING ALL IN QT.

I hate this approach, because it's manifestly easy and risk-free for even a child to "extend" Qt's bit definitions to at least a byte boundary. (With X11; I don't know about other platforms, such as Win32 or OSX, or Symbian. And anyway, OSX support is broken with just 3 buttons, and the authors of the Button8/Button9 updates didn't actually bother with doing the whole job: The automated testing code tools, among other "non-production" parts of Qt, still don't have them.




ALTERNATIVE (B): EXTEND SUPPORT FOR MORE BUTTONS, BUT ONLY TO THE 1ST BYTE BOUNDARY IN THE BUTTON MASK.

Add Button10 through Button12. That's a LOT of buttons (although my "test mouse", like most "gamer" mice, has even more). Very safe, with no possibility of compilers "doing the wrong thing".




ALTERNATIVE (C): DEFINE AND SUPPORT AT LEAST 31 POSSIBLE BUTTONS.

This is my recommendation, but it depends on something I don't know: The current enum for Qt::MouseButton defines all values as 32-bit hex values (with leading zeroes):

Qt::NoButton 0x00000000 The button state does not refer to any button (see QMouseEvent::button <http://doc.qt.nokia.com/4.7-snapshot/qmouseevent.html#button>()). Qt::LeftButton 0x00000001 The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.)
Qt::RightButton         0x00000002      The right button.
Qt::MidButton   0x00000004      The middle button.
Qt::MiddleButton        MidButton       The middle button.
Qt::XButton1    0x00000008      The first X button.
Qt::XButton2    0x00000010      The second X button.


I think that an enumerated item with an explicit value will NEVER be compressed, even though a Compiler which wanted to squeeze an enum of 7 items (defined without specific values) into a SINGLE BYTE would be free to do so. If my understanding is correct on all platforms, then we can safely use the entire Uint32. If it isn't, then we'd better stay with ALTERNATIVE-B. BTW, I don't want to define or support Button32 in Qt -- no existing mouse needs it, and it might be useful as some kind of flag bit within a migration of XI --> XI2.

Finally, let me describe the special "trick" which I'll be using within qapplication_x11.cpp, in order to offer an "ALMOST-reliable" Button State Mask. (As you know, Xinput 1.5 events provide a Button Sate Mask which is only one byte in length.) Credit for this suggestion goes to Daniel Stone: After receiving the event (and deciding not to ignore it), query the state of the core pointer buttons, and use the response to set the mask bits for higher-order buttons which are in "pressed" State. The information isn't absolutely reliable, because Event State precedes Query State in priority (within X11). We wouldn't want to do anything like this for pointer motion, or for keyboard ;) But mouse button states, especially after Qt has "compressed" the X11 wheel events before pushing them up into the state machine, remain constant for relatively long time. This makes a query-based mask pretty reliable -- at least in the *local* case, on a machine which isn't suffering CPU or memory problems.

In the remote case, maybe not so good... but I can't do better without moving to XI2. If the network and machines are really slow, then users will have to learn to hold down any high-order "modifier" mouse buttons until they see the App respond on their screen. And the I think that the situation of an App treating TWO concurrent high-order buttons as a unique event is going to be uncommon- and our doco should advise against it.

Because of the delay, and the lack of reliability, a User who really, really wants to get the FULL Button Mask should do so via a separate function call (new API). With Event and Standard Signals, I think that Qt should present Mask as now stands... with the reliable, low-order mask included (from X11, in Event State), but the higher order bits of other buttons zeroed out. This keeps it fast and efficient for programmers who aren't doing anything crazy.

- - - - -
This portion of "more mouse buttons", the part within Qt, isn't big enough for GSOC. Perhaps the KDE follow-ups are, and I will touch on a few in separate messages. I intend to write and fully document the Qt Updates myself, after I receive your comments and recommendation -- and, I hope, a similar input from a Qt person working in the "input devices" area. (I know that they have other, big things to think about, but I'd hate to do a bunch of work and be told "this isn't the right design" AFTERWARDS.) So, if you can link me up with such a Qt person, please do so. This is a REAL email address and a good contact point for me.

Thanks for reading, and all upcoming replies.

Reply via email to