From 66526adf7a916bb3fa009a4cce966c5b214f912b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 29 Sep 2019 14:57:59 +0200 Subject: [PATCH] Document issues with event handlers called when mouse is captured Notably mention that showing modal dialogs won't work in this case. Also link to this explanation from wxListCtrl documentation as wxEVT_LIST_ITEM_SELECTED is one of the perhaps less expected cases in which this problem arises. See #9973. --- docs/doxygen/overviews/eventhandling.h | 26 ++++++++++++++++++++++++++ interface/wx/listctrl.h | 8 ++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/doxygen/overviews/eventhandling.h b/docs/doxygen/overviews/eventhandling.h index 9dbf1fceb4..658ec2741b 100644 --- a/docs/doxygen/overviews/eventhandling.h +++ b/docs/doxygen/overviews/eventhandling.h @@ -865,6 +865,32 @@ If you use wxNewId() consistently in your application, you can be sure that your identifiers don't conflict accidentally. +@subsection overview_events_with_mouse_capture Event Handlers and Mouse Capture + +Some events are generated in response to a user action performed using the +mouse and, often, the mouse will be captured (see wxWindow::CaptureMouse()) by +the window generating the event in this case. This happens when the user is +dragging the mouse, i.e. for all events involving resizing something (e.g. @c +EVT_SPLITTER_SASH_POS_CHANGING), but also, perhaps less obviously, when +selecting items (e.g. @c EVT_LIST_ITEM_SELECTED). + +When the mouse is captured, the control sending events will continue receiving +all mouse events, meaning that the event handler can't do anything relying on +getting them in any other window. Most notably, simply showing a modal dialog +won't work as expected, as the dialog won't receive any mouse input and appear +unresponsive to the user. + +The best solution is to avoid showing modal dialogs from such event handlers +entirely, as it can be jarring for the user to be interrupted in their workflow +by a dialog suddenly popping up. However if it's really indispensable to show a +dialog, you need to forcefully break the existing mouse capture by capturing +(and then releasing, because you don't really need the capture) it yourself: +@code + dialog.CaptureMouse(); + dialog.ReleaseMouse(); +@endcode + + @subsection overview_events_custom_generic Generic Event Table Macros @beginTable diff --git a/interface/wx/listctrl.h b/interface/wx/listctrl.h index 8ccaad95b1..0ce697c8bc 100644 --- a/interface/wx/listctrl.h +++ b/interface/wx/listctrl.h @@ -213,7 +213,9 @@ enum All items were deleted. Processes a @c wxEVT_LIST_DELETE_ALL_ITEMS event type. @event{EVT_LIST_ITEM_SELECTED(id, func)} - The item has been selected. + The item has been selected. Notice that the mouse is captured by the + control itself when this event is generated, see @ref + overview_events_with_mouse_capture "event handling overview". Processes a @c wxEVT_LIST_ITEM_SELECTED event type. @event{EVT_LIST_ITEM_DESELECTED(id, func)} The item has been deselected. @@ -1426,7 +1428,9 @@ protected: @event{EVT_LIST_DELETE_ALL_ITEMS(id, func)} Delete all items. @event{EVT_LIST_ITEM_SELECTED(id, func)} - The item has been selected. + The item has been selected. Notice that the mouse is captured by the + control itself when this event is generated, see @ref + overview_events_with_mouse_capture "event handling overview". @event{EVT_LIST_ITEM_DESELECTED(id, func)} The item has been deselected. @event{EVT_LIST_ITEM_ACTIVATED(id, func)}