[Qt5-feedback] X11 mouse buttons in qt4, qt5, and KDE: please, PLEASE review this design.

Samuel Rødal samuel.rodal at nokia.com
Thu Jul 28 10:16:24 CEST 2011


On 07/27/2011 10:16 PM, ext Rick Stockton wrote:
> We have 3 bits available for enumeration of additional buttons without
> breaking compatibility. I think that the key to getting all 31 possible
> X11 buttons into qt is this: Use only two of them, for the buttons sent
> up from X11 as "Button10" and Button11". (Those are the raw numbers from
> X11, in which the four wheel-scroll "buttons" DID appear as button
> numbers.) Then, instead of using the last bit (x80) to define
> "Button12", give it a name (e.g., Qt::HigherButton) which indicates that
> the Button number (from X11, or another platform interface with good
> button support) is GREATER than the one that which I've tentatively
> enumerating as "Button11". BTW, here's the entire enum which I propose
> to use:
>
> enum MouseButton {
> NoButton = 0x00000000,
> LeftButton = 0x00000001,
> RightButton = 0x00000002,
> MidButton = 0x00000004, // ### Qt 5: remove me
> MiddleButton = MidButton,
> XButton1 = 0x00000008,
> BackButton = XButton1,
> XButton2 = 0x00000010,
> ForwardButton = XButton2,
> Button10 = 0x00000020,
> Button11 = 0x00000040,
> HigherButton = 0x00000080,
> MouseButtonMask = 0x000000ff
> };
> Q_DECLARE_FLAGS(MouseButtons, MouseButton)
>
> I tossed in alternate names for 'XButton1' and XButton2', which were
> introduced in 4.7): By convention, they are almost universally used as
> "BACK and "FORWARD".
>
> When a User wants to receive MouseButtonPress, MouseButtonRelease, or
> MouseButtonDblClick events from higher-numbered buttons, it becomes a
> two-step process: First, receive the event, and recognize that the
> 'HighNumberedButton' value is generic. Then, call a new function which
> I'll add into the class:
>
> int QMouseEvent::ButtonNumber () const
>
> which shall return the INTEGER Button number of the most recent
> Press/Release/DblClick event. BTW, I feel that this function should also
> report the integer values for events which occur with lower-numbered
> button values: It would allow programmers to define their Button-based
> code blocks by branching on integers. (The alternative is to have one
> set of branching control statements built for "low-numbered" buttons,
> using the Enum values; plus another set of branching control statements
> built for high-numbered buttons, using Integers. Code like that would
> look ugly.)

Does it then make sense to add Button10 and Button11 which have terribly 
generic names to the MouseButton enum? Shouldn't those also be reported 
as HigherButton and queried via buttonNumber()?

> The whole idea of using an enum which couldn't contain any more buttons
> than the miserable XI V1.x Button MASK was a *BAD DESIGN* from the
> beginning. Let's support old code without changes, but lets also solve
> the problem by making the design correct.

Agreed. Maybe we can improve things even further in Qt 5?

> I am confused by the "plugin" design which appears to be present in both
> qt4 and qt5. Is the qt5 Wayland plugin really supporting only only THREE
> mouse buttons, per the following code from
> qt5/qtbase/src/plugins/platforms/wayland/qwaylandinputdevice.cpp?
> (a code snippet from gitorious):
>
> ....
> void QWaylandInputDevice::inputHandleButton(void *data,
> struct wl_input_device *input_device,
> uint32_t time, uint32_t button, uint32_t state)
> {
> Q_UNUSED(input_device);
> QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
> QWaylandWindow *window = inputDevice->mPointerFocus;
> Qt::MouseButton qt_button;
>
> if (window == NULL) {
> /* We destroyed the pointer focus surface, but the server
> * didn't get the message yet. */
> return;
> }
>
> switch (button) {
> case 272:
> qt_button = Qt::LeftButton;
> break;
> case 273:
> qt_button = Qt::RightButton;
> break;
> case 274:
> qt_button = Qt::MiddleButton;
> break;
> default:
> return;
> }
> ....
> (end of snippet). Is qt5 going BACKWARDS, rather than forwards, on this
> "mouse buttons" issue?

The various Lighthouse plugins have been in rapid development, so the 
omission is probably not a deliberate design decision here.

One question that popped to my mind, how are multiple mouse buttons 
being pressed at the same time handled in your design? Instead of int 
QMouseEvent::ButtonNumber () const, might we need a QList<int> 
QMouseEvent::buttonNumbers() ?

Also, how does one correlate the button numbers between platforms? What 
if someone uses the same mouse on his Mac / Windows / Linux systems, and 
wants his Qt application to behave similarly across those. Is that 
outside the scope of what we can do with the int-based API? Should we 
require the application developer to include a configuration option to 
map the mouse buttons application side? We still need to standardize the 
common buttons at least, so should we require that the left, middle, and 
right buttons always get the same numbers regardless of platform / plugin?

Currently the Lighthouse plugins report mouse presses by using the 
QWindowSystemInterface API:

static void handleMouseEvent(QWidget *w, const QPoint & local, const 
QPoint & global, Qt::MouseButtons b);

We can easily change this for Qt 5, so your suggestions for how to 
improve this API would be appreciated. To handle the multiple mouse 
button scenario, should we use a list of integers instead?

--
Samuel


More information about the Qt5-feedback mailing list