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
This commit is contained in:
Vadim Zeitlin 2011-03-14 11:54:51 +00:00
parent caef3ffacc
commit 982bc2e421

View File

@ -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
#if wxUSE_UNICODE
|| static_cast<int>(uc) != WXK_NONE
#endif // wxUSE_UNICODE
)
// 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 )
{
const wxWindow * const win = wxGetActiveWindow();
wxKeyEvent event(wxEVT_CHAR_HOOK);
MSWInitAnyKeyEvent(event, wParam, lParam, win);
event.m_keyCode = id;
if ( id != WXK_NONE
#if wxUSE_UNICODE
event.m_uniChar = uc;
|| static_cast<int>(uc) != WXK_NONE
#endif // wxUSE_UNICODE
)
{
const wxWindow * const win = wxGetActiveWindow();
wxKeyEvent event(wxEVT_CHAR_HOOK);
MSWInitAnyKeyEvent(event, wParam, lParam, win);
event.m_keyCode = id;
#if wxUSE_UNICODE
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;
}
}
}
}