diff --git a/FL/Fl.H b/FL/Fl.H index e54c25628..95c7098c8 100644 --- a/FL/Fl.H +++ b/FL/Fl.H @@ -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(). diff --git a/documentation/src/enumerations.dox b/documentation/src/enumerations.dox index 9e70834fd..c4ff6dfc8 100644 --- a/documentation/src/enumerations.dox +++ b/documentation/src/enumerations.dox @@ -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 n > 0) is pushed. \section enumerations_alignment Alignment Values diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index d724340a0..e8b94aff4 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -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: diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 2fb121ce0..30450ab16 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -65,6 +65,12 @@ #include +// 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: diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 6d1750bb9..bfbbd61ce 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -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); diff --git a/test/keyboard_ui.fl b/test/keyboard_ui.fl index 5c6c807d0..b1d9cdad0 100644 --- a/test/keyboard_ui.fl +++ b/test/keyboard_ui.fl @@ -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 } } }