Escape is used by IME and intercepting it at wxWidgets level to generate
EVT_CHAR_HOOK breaks the IME UI and may result in unexpected loss of data
entered by user.
To work around this, don't generate EVT_CHAR_HOOK for Escape while IME is
active by checking for the special semaphore variable (which could be also
used for other things in the future, see #9102) value.
Closes #11386.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67189
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
#endif // wxHAS_MSW_BACKGROUND_ERASE_HOOK
#endif // wxHAS_MSW_BACKGROUND_ERASE_HOOK
+// If this variable is strictly positive, EVT_CHAR_HOOK is not generated for
+// Escape key presses as it can't be intercepted because it's needed by some
+// currently shown window, e.g. IME entry.
+//
+// This is currently global as we allow using UI from the main thread only
+// anyhow but could be replaced with a thread-specific value in the future if
+// needed.
+int gs_modalEntryWindowCount = 0;
+
} // anonymous namespace
// ---------------------------------------------------------------------------
} // anonymous namespace
// ---------------------------------------------------------------------------
+ case WM_IME_STARTCOMPOSITION:
+ // IME popup needs Escape as it should undo the changes in its
+ // entry window instead of e.g. closing the dialog for which the
+ // IME is used (and losing all the changes in the IME window).
+ gs_modalEntryWindowCount++;
+ break;
+
+ case WM_IME_ENDCOMPOSITION:
+ gs_modalEntryWindowCount--;
+ break;
+
#if wxUSE_HOTKEY
case WM_HOTKEY:
processed = HandleHotKey((WORD)wParam, lParam);
#if wxUSE_HOTKEY
case WM_HOTKEY:
processed = HandleHotKey((WORD)wParam, lParam);
{
wchar_t uc;
int id = wxMSWKeyboard::VKToWX(wParam, lParam, &uc);
{
wchar_t uc;
int id = wxMSWKeyboard::VKToWX(wParam, lParam, &uc);
+
+ // Don't intercept keyboard entry (notably Escape) if a modal window
+ // (not managed by wx, e.g. IME one) is currently opened as more often
+ // than not it needs all the keys for itself.
+ if ( !gs_modalEntryWindowCount )
+ {
+ if ( id != WXK_NONE
- || static_cast<int>(uc) != WXK_NONE
+ || static_cast<int>(uc) != WXK_NONE
- )
- {
- const wxWindow * const win = wxGetActiveWindow();
+ )
+ {
+ const wxWindow * const win = wxGetActiveWindow();
- wxKeyEvent event(wxEVT_CHAR_HOOK);
- MSWInitAnyKeyEvent(event, wParam, lParam, win);
+ wxKeyEvent event(wxEVT_CHAR_HOOK);
+ MSWInitAnyKeyEvent(event, wParam, lParam, win);
- wxEvtHandler * const handler = win ? win->GetEventHandler()
- : wxTheApp;
+ wxEvtHandler * const handler = win ? win->GetEventHandler()
+ : wxTheApp;
- if ( handler && handler->ProcessEvent(event) )
- {
- // processed
- return 1;
+ if ( handler && handler->ProcessEvent(event) )
+ {
+ // processed
+ return 1;
+ }