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:
parent
caef3ffacc
commit
982bc2e421
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user