Finish "Backport support for mouse buttons 4+5" (#1076, #1068)

- documentation updates, alignment, formatting, version numbers
- fix widget order in test/keyboard_ui.fl
- replace hard-coded bit mask with 'FL_BUTTONS'
- add missing macro definition 'GET_XBUTTON_WPARAM' for MinGW
- reorder 'case' statements for button events (like in master)
This commit is contained in:
Albrecht Schlosser 2024-11-14 14:42:01 +01:00 committed by Albrecht Schlosser
parent f83c0042f3
commit 86a98e2054
6 changed files with 120 additions and 108 deletions

26
FL/Fl.H
View File

@ -681,7 +681,7 @@ int main() {
\retval FL_MIDDLE_MOUSE
\retval FL_RIGHT_MOUSE
\retval FL_BACK_MOUSE
\retval FL_FORWARD_MOUSE.
\retval FL_FORWARD_MOUSE
\see Fl::event_buttons(), Fl::event_state()
*/
static int event_button() {return e_keysym-FL_Button;}
@ -691,8 +691,9 @@ int main() {
This is a bitfield of what shift states were on and what mouse buttons
were held down during the most recent event.
\note FLTK platforms differ in what Fl::event_state() returns when it is called
while a modifier key or mouse button is being pressed or released.
\note FLTK platforms differ in what Fl::event_state() returns when it is called
while a modifier key or mouse button is being pressed or released.
- Under X11 and Wayland, Fl::event_state() indicates the state of the modifier keys and
mouse buttons just \b prior to the event. Thus, during the \c FL_KEYDOWN event generated
when pressing the shift key, for example, the \c FL_SHIFT bit of event_state() is 0 and
@ -704,9 +705,12 @@ int main() {
- X servers do not agree on shift states, and \c FL_NUM_LOCK, \c FL_META, and \c FL_SCROLL_LOCK
may not work.
- The values were selected to match the XFree86 server on Linux.
\note This inconsistency \b may be fixed (on X11 and Wayland) in a later release.
The legal event state bits are:
| Device | State Bit | Function | Since |
| Device | State Bit | Key or Button | Since |
|----------|----------------|-------------------------|--------|
| Keyboard | FL_SHIFT | Shift | |
| Keyboard | FL_CAPS_LOCK | Caps Lock | |
@ -1165,28 +1169,28 @@ int main() {
static int event_alt() {return e_state&FL_ALT;}
/**
Returns the mouse buttons state bits; if non-zero, then at least one
button is pressed now. This function returns the button state at the
time of the event. During an FL_RELEASE event, the state
of the released button will be 0. To find out, which button
button is pressed now. This function returns the button state at the
time of the event. During an FL_RELEASE event, the state
of the released button will be 0. To find out, which button
caused an FL_RELEASE event, you can use Fl::event_button() instead.
\return a bit mask value like { [FL_BUTTON1] | [FL_BUTTON2] | ... | [FL_BUTTON5] }
*/
static int event_buttons() {return e_state&0x7f000000;}
static int event_buttons() {return e_state & FL_BUTTONS;}
/**
Returns non-zero if mouse button 1 is currently held down.
For more details, see Fl::event_buttons().
*/
static int event_button1() {return e_state&FL_BUTTON1;}
static int event_button1() {return e_state & FL_BUTTON1;}
/**
Returns non-zero if mouse button 2 is currently held down.
For more details, see Fl::event_buttons().
*/
static int event_button2() {return e_state&FL_BUTTON2;}
static int event_button2() {return e_state & FL_BUTTON2;}
/**
Returns non-zero if mouse button 3 is currently held down.
For more details, see Fl::event_buttons().
*/
static int event_button3() {return e_state&FL_BUTTON3;}
static int event_button3() {return e_state & FL_BUTTON3;}
/**
Returns non-zero if mouse button 4 is currently held down.
For more details, see Fl::event_buttons().

View File

@ -20,11 +20,11 @@ The FLTK version number is stored in a number of compile-time constants:
- FL_MAJOR_VERSION - The major release number, currently 1
- FL_MINOR_VERSION - The minor release number, currently 3
- FL_PATCH_VERSION - The patch release number, currently 6
- FL_PATCH_VERSION - The patch release number, currently 10
- FL_VERSION - \b [Deprecated] A combined floating-point version number for
the major, minor, and patch release numbers, currently 1.0306
the major, minor, and patch release numbers, currently 1.0310
- FL_API_VERSION - A combined integer version number for the major, minor,
and patch release numbers, currently 10306 (use this instead of
and patch release numbers, currently 10310 (use this instead of
FL_VERSION, if possible)
- FL_ABI_VERSION - A combined integer version number for the application
binary interface (ABI) major, minor, and patch release numbers,
@ -96,9 +96,11 @@ The following constants determine when a callback is performed:
The following constants define the button numbers for FL_PUSH and
FL_RELEASE events:
- FL_LEFT_MOUSE - the left mouse button
- FL_MIDDLE_MOUSE - the middle mouse button
- FL_RIGHT_MOUSE - the right mouse button
- FL_LEFT_MOUSE - the left mouse button
- FL_MIDDLE_MOUSE - the middle mouse button
- FL_RIGHT_MOUSE - the right mouse button
- FL_BACK_MOUSE - the back mouse button (side button 1)
- FL_FORWARD_MOUSE - the forward mouse button (side button 2)
\section enumerations_event_key Fl::event_key() Values
@ -160,7 +162,9 @@ value:
- FL_BUTTON1 - Mouse button 1 is pushed.
- FL_BUTTON2 - Mouse button 2 is pushed.
- FL_BUTTON3 - Mouse button 3 is pushed.
- FL_BUTTONS - Any mouse button is pushed.
- FL_BUTTON4 - Mouse button 4 (back) is pushed.
- FL_BUTTON5 - Mouse button 5 (forward) is pushed.
- FL_BUTTONS - Any mouse button (1..5) is pushed.
- FL_BUTTON(n) - Mouse button \p n ( where <tt>n > 0</tt>) is pushed.
\section enumerations_alignment Alignment Values

View File

@ -1165,8 +1165,8 @@ static void cocoaMouseHandler(NSEvent *theEvent)
else if (btn == 2) Fl::e_state &= ~FL_BUTTON3;
else if (btn == 4) Fl::e_state &= ~FL_BUTTON4;
else if (btn == 5) Fl::e_state &= ~FL_BUTTON5;
}
}
switch ( etype ) {
case NSLeftMouseDown:
case NSRightMouseDown:

View File

@ -65,6 +65,12 @@
#include <winerror.h>
// old versions of MinGW lack definition of GET_XBUTTON_WPARAM:
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
#endif
//
// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
// USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:

View File

@ -2180,7 +2180,7 @@ int fl_handle(const XEvent& thisevent)
set_event_xy();
Fl::e_is_click = 0; }
break;
// Mouse button "press" event:
// ---------------------------
// X11 uses special conventions for mouse "button" numbers:
@ -2195,8 +2195,8 @@ int fl_handle(const XEvent& thisevent)
// mouse buttons 4 (back) and 5 (forward) since X11 doesn't keep their status.
case ButtonPress: {
int mb = xevent.xbutton.button; // mouse button
if (mb < 1 || mb > 9) return 0; // unknown or unsupported button, ignore
int mb = xevent.xbutton.button; // mouse button
if (mb < 1 || mb > 9) return 0; // unknown or unsupported button, ignore
// FIXME(?): here we set some event related variables although we *might*
// ignore an event sent by X because we don't know or want it. This may lead to
@ -2207,24 +2207,24 @@ int fl_handle(const XEvent& thisevent)
Fl::e_keysym = 0; // init: not used (zero) for scroll wheel events
set_event_xy();
Fl::e_dx = Fl::e_dy = 0;
if (mb == Button4 && !Fl::event_shift()) {
Fl::e_dy = -1; // Up
Fl::e_dy = -1; // up
event = FL_MOUSEWHEEL;
} else if (mb == Button5 && !Fl::event_shift()) {
Fl::e_dy = +1; // Down
Fl::e_dy = +1; // down
event = FL_MOUSEWHEEL;
} else if (mb == 6 || mb == Button4 && Fl::event_shift()) {
Fl::e_dx = -1; // Left
event = FL_MOUSEWHEEL;
} else if (mb == 7 || mb == Button5 && Fl::event_shift()) {
Fl::e_dx = +1; // Right
event = FL_MOUSEWHEEL;
} else if (mb < 4 || mb > 7) { // real mouse *buttons*, not scroll wheel
if (mb > 7) // 8 = back, 9 = forward
mb -= 4; // map to 4 and 5, resp.
} else if (mb == 6 || (mb == Button4 && Fl::event_shift())) {
Fl::e_dx = -1; // left
event = FL_MOUSEWHEEL;
} else if (mb == 7 || (mb == Button5 && Fl::event_shift())) {
Fl::e_dx = +1; // right
event = FL_MOUSEWHEEL;
} else if (mb < 4 || mb > 7) { // real mouse *buttons*, not scroll wheel
if (mb > 7) // 8 = back, 9 = forward
mb -= 4; // map to 4 and 5, resp.
Fl::e_keysym = FL_Button + mb;
Fl::e_state |= (FL_BUTTON1 << (mb-1)); // set button state
Fl::e_state |= (FL_BUTTON1 << (mb-1)); // set button state
if (mb == 4) xbutton_state |= FL_BUTTON4; // save extra button state internally
if (mb == 5) xbutton_state |= FL_BUTTON5; // save extra button state internally
event = FL_PUSH;
@ -2235,11 +2235,42 @@ int fl_handle(const XEvent& thisevent)
#if FLTK_CONSOLIDATE_MOTION
fl_xmousewin = window;
#endif
#endif // FLTK_CONSOLIDATE_MOTION
in_a_window = true;
break;
} // ButtonPress
// Mouse button release event: for details see ButtonPress above
case ButtonRelease: {
int mb = xevent.xbutton.button; // mouse button
switch (mb) { // figure out which real button this is
case 1: // left
case 2: // middle
case 3: // right
break; // continue
case 8: // side button 1 (back)
case 9: // side button 2 (forward)
mb -= 4; // map to 4 and 5, respectively
break; // continue
default: // unknown button or scroll wheel:
return 0; // don't send FL_RELEASE event
}
Fl::e_keysym = FL_Button + mb; // == FL_BUTTON1 .. FL_BUTTON5
set_event_xy();
Fl::e_state &= ~(FL_BUTTON1 << (mb-1));
if (mb == 4) xbutton_state &= ~FL_BUTTON4; // clear internal button state
if (mb == 5) xbutton_state &= ~FL_BUTTON5; // clear internal button state
event = FL_RELEASE;
#if FLTK_CONSOLIDATE_MOTION
fl_xmousewin = window;
#endif // FLTK_CONSOLIDATE_MOTION
in_a_window = true;
break;
} // ButtonRelease
case PropertyNotify:
if (xevent.xproperty.atom == fl_NET_WM_STATE) {
int fullscreen_state = 0;
@ -2277,39 +2308,6 @@ int fl_handle(const XEvent& thisevent)
break;
# endif
// Mouse button release event: for details see ButtonPress above
case ButtonRelease: {
int mb = xevent.xbutton.button; // mouse button
switch (mb) { // figure out which real button this is
case 1: // left
case 2: // middle
case 3: // right
break; // continue
case 8: // side button 1 (back)
case 9: // side button 2 (forward)
mb -= 4; // map to 4 and 5, respectively
break; // continue
default: // unknown button or scroll wheel:
return 0; // don't send FL_RELEASE event
}
Fl::e_keysym = FL_Button + mb; // == FL_BUTTON1 .. FL_BUTTON5
set_event_xy();
Fl::e_state &= ~(FL_BUTTON1 << (mb-1));
if (mb == 4) xbutton_state &= ~FL_BUTTON4; // clear internal button state
if (mb == 5) xbutton_state &= ~FL_BUTTON5; // clear internal button state
event = FL_RELEASE;
#if FLTK_CONSOLIDATE_MOTION
fl_xmousewin = window;
#endif // FLTK_CONSOLIDATE_MOTION
in_a_window = true;
break;
} // ButtonRelease
case EnterNotify:
if (xevent.xcrossing.detail == NotifyInferior) break;
// XInstallColormap(fl_display, Fl_X::i(window)->colormap);

View File

@ -9,6 +9,14 @@ Function {make_window()} {open
code0 {\#include "keyboard.h"}
class MyWindow
} {
Fl_Output key_output {
label {Fl::event_key():}
xywh {15 20 170 30} labelsize 9 align 5
}
Fl_Output text_output {
label {Fl::event_text():}
xywh {195 20 190 30} labelsize 9 align 5
}
Fl_Button {} {
label {Esc }
user_data FL_Escape user_data_type {void*}
@ -105,6 +113,28 @@ Function {make_window()} {open
callback key_cb
xywh {365 70 20 20} labelsize 8
}
Fl_Button {} {
label Help
user_data FL_Help user_data_type {void*}
callback key_cb
xywh {400 70 20 20} labelsize 8
}
Fl_Button {} {
label {=}
user_data {FL_KP+'='} user_data_type {void*}
callback key_cb
xywh {420 70 20 20} labelsize 10
}
Fl_Dial roller_x {
label {x:}
callback wheel_cb
xywh {440 70 20 20} box ROUND_UP_BOX selection_color 49 labelsize 9 align 5 step 0.1
}
Fl_Dial roller_y {
label {y:}
callback wheel_cb
xywh {460 70 20 20} box ROUND_UP_BOX selection_color 49 labelsize 9 align 5 step 0.1
}
Fl_Button {} {
label {`}
callback key_cb
@ -584,6 +614,10 @@ Function {make_window()} {open
callback key_cb
xywh {440 180 20 20} labelsize 10
}
Fl_Box {} {
label {Fl::event_state():}
xywh {400 15 80 0} labelsize 9 align 5
}
Fl_Button {} {
label {shift }
user_data FL_SHIFT user_data_type {void*}
@ -662,45 +696,11 @@ Function {make_window()} {open
callback shift_cb selected
xywh {400 45 20 10} box THIN_UP_BOX selection_color 3 labelsize 8
}
Fl_Output text_output {
label {Fl::event_text():}
xywh {195 20 190 30} labelsize 9 align 5
}
Fl_Button {} {
label Help
user_data FL_Help user_data_type {void*}
callback key_cb
xywh {400 70 20 20} labelsize 8
}
Fl_Button {} {
label {=}
user_data {FL_KP+'='} user_data_type {void*}
callback key_cb
xywh {420 70 20 20} labelsize 10
}
Fl_Dial roller_x {
label {x:}
callback wheel_cb
xywh {440 70 20 20} box ROUND_UP_BOX selection_color 49 labelsize 9 align 5 step 0.1
}
Fl_Dial roller_y {
label {y:}
callback wheel_cb
xywh {460 70 20 20} box ROUND_UP_BOX selection_color 49 labelsize 9 align 5 step 0.1
}
Fl_Box {} {
label {Fl::event_state():}
xywh {400 15 80 0} labelsize 9 align 5
}
Fl_Output key_output {
label {Fl::event_key():}
xywh {15 20 170 30} labelsize 9 align 5
}
Fl_Button {} {
label {?}
user_data 0x8000 user_data_type {void*}
user_data 0x2000 user_data_type {void*}
callback shift_cb
xywh {460 45 20 10} box THIN_UP_BOX selection_color 3 labelsize 8
xywh {420 45 20 10} box THIN_UP_BOX selection_color 3 labelsize 8
}
Fl_Button {} {
label {?}
@ -710,9 +710,9 @@ Function {make_window()} {open
}
Fl_Button {} {
label {?}
user_data 0x2000 user_data_type {void*}
user_data 0x8000 user_data_type {void*}
callback shift_cb
xywh {420 45 20 10} box THIN_UP_BOX selection_color 3 labelsize 8
xywh {460 45 20 10} box THIN_UP_BOX selection_color 3 labelsize 8
}
}
}