diff --git a/include/nana/gui/detail/general_events.hpp b/include/nana/gui/detail/general_events.hpp index cdb6ac3a..a6f17bc6 100644 --- a/include/nana/gui/detail/general_events.hpp +++ b/include/nana/gui/detail/general_events.hpp @@ -427,11 +427,12 @@ namespace nana ::nana::point pos; ///< cursor position in the event window ::nana::mouse button; ///< indicates a button which triggers the event - bool left_button; ///< mouse left button is pressed? - bool mid_button; ///< mouse middle button is pressed? - bool right_button; ///< mouse right button is pressed? - bool shift; ///< keyboard Shift is pressed? - bool ctrl; ///< keyboard Ctrl is pressed? + bool left_button; ///< mouse left button is pressed? + bool mid_button; ///< mouse middle button is pressed? + bool right_button; ///< mouse right button is pressed? + bool alt; ///< keyboard alt is pressed? + bool shift; ///< keyboard Shift is pressed? + bool ctrl; ///< keyboard Ctrl is pressed? /// Checks if left button is operated, bool is_left_button() const @@ -521,7 +522,7 @@ namespace nana struct arg_click : public event_arg { ::nana::window window_handle; ///< A handle to the event window - bool by_mouse; ///< Determines whether the event is emitted by clicking mouse button + const arg_mouse* mouse_args; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise. }; /// provides some fundamental events that every widget owns. diff --git a/source/gui/detail/linux_X11/bedrock.cpp b/source/gui/detail/linux_X11/bedrock.cpp index 2bcf5715..991cf8ef 100644 --- a/source/gui/detail/linux_X11/bedrock.cpp +++ b/source/gui/detail/linux_X11/bedrock.cpp @@ -467,8 +467,9 @@ namespace detail arg.left_button = ((Button1Mask & mask_state) != 0) || (::nana::mouse::left_button == arg.button) ; arg.right_button = ((Button2Mask & mask_state) != 0) || (::nana::mouse::right_button == arg.button); arg.mid_button = ((Button3Mask & mask_state) != 0) || (::nana::mouse::middle_button == arg.button); - arg.shift = (ShiftMask & mask_state); - arg.ctrl = (ControlMask & mask_state); + arg.alt = ((Mod1Mask & mask_state) != 0); + arg.shift = ги(ShiftMask & mask_state) != 0); + arg.ctrl = ги(ControlMask & mask_state) != 0); } @@ -815,21 +816,24 @@ namespace detail { auto retain = msgwnd->together.events_ptr; - arg_mouse arg; + ::nana::arg_mouse arg; assign_arg(arg, msgwnd, message, xevent); + ::nana::arg_click click_arg; + + //the window_handle of click_arg is used as a flag to determinate whether to emit click event. + click_arg.window_handle = nullptr; + click_arg.mouse_args = &arg; + const bool hit = msgwnd->dimension.is_hit(arg.pos); - bool fire_click = false; if(msgwnd == pressed_wd) { if((arg.button == ::nana::mouse::left_button) && hit) { msgwnd->flags.action = mouse_action::over; - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; + + click_arg.window_handle = reinterpret_cast(msgwnd); emit_drawer(&drawer::click, msgwnd, arg, &context); - fire_click = true; } } @@ -845,13 +849,8 @@ namespace detail arg.evt_code = event_code::mouse_up; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - if(fire_click) - { - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; - evt_ptr->click.emit(arg); - } + if(click_arg.window_handle) + evt_ptr->click.emit(click_arg); if (brock.wd_manager().available(msgwnd)) { @@ -859,13 +858,9 @@ namespace detail evt_ptr->mouse_up.emit(arg); } } - else if(fire_click) - { - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; - msgwnd->together.events_ptr->click.emit(arg); - } + else if(click_arg.window_handle) + msgwnd->together.events_ptr->click.emit(click_arg); + brock.wd_manager().do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 2a68f95a..7cdd1b5f 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -536,6 +536,7 @@ namespace detail { arg.pos.x = pmdec.mouse.x - wd->pos_root.x; arg.pos.y = pmdec.mouse.y - wd->pos_root.y; + arg.alt = (::GetKeyState(VK_MENU) < 0); arg.shift = pmdec.mouse.button.shift; arg.ctrl = pmdec.mouse.button.ctrl; arg.left_button = pmdec.mouse.button.left; @@ -1001,20 +1002,22 @@ namespace detail { auto retain = msgwnd->together.events_ptr; - nana::arg_mouse arg; + ::nana::arg_mouse arg; assign_arg(arg, msgwnd, message, pmdec); - bool fire_click = false; + ::nana::arg_click click_arg; + + //the window_handle of click_arg is used as a flag to determinate whether to emit click event + click_arg.window_handle = nullptr; + click_arg.mouse_args = &arg; + if (msgwnd->dimension.is_hit(arg.pos)) { msgwnd->flags.action = mouse_action::over; if (::nana::mouse::left_button == arg.button) { - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; - emit_drawer(&drawer::click, msgwnd, arg, &context); - fire_click = true; + click_arg.window_handle = reinterpret_cast(msgwnd); + emit_drawer(&drawer::click, msgwnd, click_arg, &context); } } @@ -1024,13 +1027,8 @@ namespace detail arg.evt_code = event_code::mouse_up; emit_drawer(&drawer::mouse_up, msgwnd, arg, &context); - if (fire_click) - { - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; - retain->click.emit(arg); - } + if (click_arg.window_handle) + retain->click.emit(click_arg); if (brock.wd_manager().available(msgwnd)) { @@ -1038,13 +1036,9 @@ namespace detail retain->mouse_up.emit(arg); } } - else if (fire_click) - { - arg_click arg; - arg.window_handle = reinterpret_cast(msgwnd); - arg.by_mouse = true; - retain->click.emit(arg); - } + else if (click_arg.window_handle) + retain->click.emit(click_arg); + brock.wd_manager().do_lazy_refresh(msgwnd, false); } pressed_wd = nullptr; diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index e68d9a3b..65972433 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -373,7 +373,7 @@ namespace nana{ namespace drawerbase { arg_click arg; arg.window_handle = wdg_->handle(); - arg.by_mouse = false; + arg.mouse_args = nullptr; API::emit_event(event_code::click, arg.window_handle, arg); }