From 982bc2e421bad0715563f8c8bbb5233dbc948ab6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 14 Mar 2011 11:54:51 +0000 Subject: [PATCH] Don't intercept Escape key while IME is active. 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 --- src/msw/window.cpp | 57 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 71e169e0bc..e1d2af0ad7 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -228,6 +228,15 @@ EraseBgHooks gs_eraseBgHooks; #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 // --------------------------------------------------------------------------- @@ -3171,6 +3180,17 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l } break; + 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); @@ -6497,29 +6517,36 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) { wchar_t uc; int id = wxMSWKeyboard::VKToWX(wParam, lParam, &uc); - if ( id != WXK_NONE + + // 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 #if wxUSE_UNICODE - || static_cast(uc) != WXK_NONE + || static_cast(uc) != WXK_NONE #endif // wxUSE_UNICODE - ) - { - 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); - event.m_keyCode = id; + event.m_keyCode = id; #if wxUSE_UNICODE - event.m_uniChar = uc; + event.m_uniChar = uc; #endif // wxUSE_UNICODE - 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; + } } } } -- 2.45.2