Fix wxKeyEvent::GetKeyCode() for non-US keyboard layouts
Use the key code corresponding to the key in the US keyboard layout for the key down/up events even when not actually using US layout, as this is much more useful than simply returning 0 as was done before. It also is compatible with the behaviour of the other ports. See #17643, #23379, #23410. (cherry picked from commit 2c0f6a2aa0c8d0650d1f856aa279ce7495925c17)
This commit is contained in:
parent
171369203f
commit
87ae8d5aa7
@ -61,7 +61,7 @@ case $(uname -s) in
|
|||||||
extra_deps='libwebkit2gtk-4.0-dev libgspell-1-dev'
|
extra_deps='libwebkit2gtk-4.0-dev libgspell-1-dev'
|
||||||
;;
|
;;
|
||||||
2) libtoolkit_dev=libgtk2.0-dev
|
2) libtoolkit_dev=libgtk2.0-dev
|
||||||
extra_deps='libwebkitgtk-dev'
|
extra_deps='libwebkitgtk-dev libxkbcommon-dev'
|
||||||
;;
|
;;
|
||||||
*) echo 'Please specify wxGTK_VERSION explicitly.' >&2
|
*) echo 'Please specify wxGTK_VERSION explicitly.' >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
96
configure
vendored
96
configure
vendored
@ -955,6 +955,8 @@ GSPELL_LIBS
|
|||||||
GSPELL_CFLAGS
|
GSPELL_CFLAGS
|
||||||
LIBSECRET_LIBS
|
LIBSECRET_LIBS
|
||||||
LIBSECRET_CFLAGS
|
LIBSECRET_CFLAGS
|
||||||
|
XKBCOMMON_LIBS
|
||||||
|
XKBCOMMON_CFLAGS
|
||||||
GXX_VERSION
|
GXX_VERSION
|
||||||
LIBICONV
|
LIBICONV
|
||||||
CXXFLAGS_VISIBILITY
|
CXXFLAGS_VISIBILITY
|
||||||
@ -1436,6 +1438,8 @@ WAYLAND_EGL_CFLAGS
|
|||||||
WAYLAND_EGL_LIBS
|
WAYLAND_EGL_LIBS
|
||||||
MesaGL_CFLAGS
|
MesaGL_CFLAGS
|
||||||
MesaGL_LIBS
|
MesaGL_LIBS
|
||||||
|
XKBCOMMON_CFLAGS
|
||||||
|
XKBCOMMON_LIBS
|
||||||
LIBSECRET_CFLAGS
|
LIBSECRET_CFLAGS
|
||||||
LIBSECRET_LIBS
|
LIBSECRET_LIBS
|
||||||
GSPELL_CFLAGS
|
GSPELL_CFLAGS
|
||||||
@ -2478,6 +2482,10 @@ Some influential environment variables:
|
|||||||
MesaGL_CFLAGS
|
MesaGL_CFLAGS
|
||||||
C compiler flags for MesaGL, overriding pkg-config
|
C compiler flags for MesaGL, overriding pkg-config
|
||||||
MesaGL_LIBS linker flags for MesaGL, overriding pkg-config
|
MesaGL_LIBS linker flags for MesaGL, overriding pkg-config
|
||||||
|
XKBCOMMON_CFLAGS
|
||||||
|
C compiler flags for XKBCOMMON, overriding pkg-config
|
||||||
|
XKBCOMMON_LIBS
|
||||||
|
linker flags for XKBCOMMON, overriding pkg-config
|
||||||
LIBSECRET_CFLAGS
|
LIBSECRET_CFLAGS
|
||||||
C compiler flags for LIBSECRET, overriding pkg-config
|
C compiler flags for LIBSECRET, overriding pkg-config
|
||||||
LIBSECRET_LIBS
|
LIBSECRET_LIBS
|
||||||
@ -38043,6 +38051,94 @@ $as_echo "$as_me: WARNING: wxFileSystemWatcher won't be available on this platfo
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$wxUSE_GTK" = 1; then
|
||||||
|
if test "$USE_WIN32" != 1 -a "$USE_DARWIN" != 1; then
|
||||||
|
|
||||||
|
pkg_failed=no
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XKBCOMMON" >&5
|
||||||
|
$as_echo_n "checking for XKBCOMMON... " >&6; }
|
||||||
|
|
||||||
|
if test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$XKBCOMMON_CFLAGS"; then
|
||||||
|
pkg_cv_XKBCOMMON_CFLAGS="$XKBCOMMON_CFLAGS"
|
||||||
|
else
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xkbcommon\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "xkbcommon") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_XKBCOMMON_CFLAGS=`$PKG_CONFIG --cflags "xkbcommon" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
if test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$XKBCOMMON_LIBS"; then
|
||||||
|
pkg_cv_XKBCOMMON_LIBS="$XKBCOMMON_LIBS"
|
||||||
|
else
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xkbcommon\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "xkbcommon") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_XKBCOMMON_LIBS=`$PKG_CONFIG --libs "xkbcommon" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test $pkg_failed = yes; then
|
||||||
|
|
||||||
|
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||||
|
_pkg_short_errors_supported=yes
|
||||||
|
else
|
||||||
|
_pkg_short_errors_supported=no
|
||||||
|
fi
|
||||||
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
|
XKBCOMMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "xkbcommon"`
|
||||||
|
else
|
||||||
|
XKBCOMMON_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "xkbcommon"`
|
||||||
|
fi
|
||||||
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
echo "$XKBCOMMON_PKG_ERRORS" >&5
|
||||||
|
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libxkbcommon not found, key codes in key events may be incorrect" >&5
|
||||||
|
$as_echo "$as_me: WARNING: libxkbcommon not found, key codes in key events may be incorrect" >&2;}
|
||||||
|
|
||||||
|
|
||||||
|
elif test $pkg_failed = untried; then
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libxkbcommon not found, key codes in key events may be incorrect" >&5
|
||||||
|
$as_echo "$as_me: WARNING: libxkbcommon not found, key codes in key events may be incorrect" >&2;}
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
XKBCOMMON_CFLAGS=$pkg_cv_XKBCOMMON_CFLAGS
|
||||||
|
XKBCOMMON_LIBS=$pkg_cv_XKBCOMMON_LIBS
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
|
||||||
|
CFLAGS="$XKBCOMMON_CFLAGS $CFLAGS"
|
||||||
|
CXXFLAGS="$XKBCOMMON_CFLAGS $CXXFLAGS"
|
||||||
|
GUI_TK_LIBRARY="$GUI_TK_LIBRARY $XKBCOMMON_LIBS"
|
||||||
|
$as_echo "#define HAVE_XKBCOMMON 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if test "$wxUSE_SECRETSTORE" = "yes"; then
|
if test "$wxUSE_SECRETSTORE" = "yes"; then
|
||||||
if test "$WXGTK1" = "1"; then
|
if test "$WXGTK1" = "1"; then
|
||||||
|
19
configure.in
19
configure.in
@ -5688,6 +5688,25 @@ if test "$wxUSE_FSWATCHER" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------------
|
||||||
|
dnl xkbcommon library for key code translations in wxGTK
|
||||||
|
dnl ---------------------------------------------------------------------------
|
||||||
|
if test "$wxUSE_GTK" = 1; then
|
||||||
|
if test "$USE_WIN32" != 1 -a "$USE_DARWIN" != 1; then
|
||||||
|
PKG_CHECK_MODULES(XKBCOMMON, [xkbcommon],
|
||||||
|
[
|
||||||
|
CFLAGS="$XKBCOMMON_CFLAGS $CFLAGS"
|
||||||
|
CXXFLAGS="$XKBCOMMON_CFLAGS $CXXFLAGS"
|
||||||
|
GUI_TK_LIBRARY="$GUI_TK_LIBRARY $XKBCOMMON_LIBS"
|
||||||
|
AC_DEFINE(HAVE_XKBCOMMON)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_WARN([libxkbcommon not found, key codes in key events may be incorrect])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
dnl ---------------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------------
|
||||||
dnl Secret storage
|
dnl Secret storage
|
||||||
dnl ---------------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------------
|
||||||
|
@ -253,6 +253,7 @@ All (GUI):
|
|||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
- Fix key codes with Shift/on non-US keyboards (Ivan Sorokin, #17643, #23379).
|
||||||
- Dramatically optimize adding many items to wxChoice (Ian McInerney, #23443).
|
- Dramatically optimize adding many items to wxChoice (Ian McInerney, #23443).
|
||||||
- Improve document wxGLCanvas::CreateSurface() (Dan Gudmundsson, #23366).
|
- Improve document wxGLCanvas::CreateSurface() (Dan Gudmundsson, #23366).
|
||||||
- Fix loading WebKit2 extension when using wxWebView (Scott Talbert, #23497).
|
- Fix loading WebKit2 extension when using wxWebView (Scott Talbert, #23497).
|
||||||
|
@ -1246,6 +1246,9 @@
|
|||||||
/* Define if setpriority() is available. */
|
/* Define if setpriority() is available. */
|
||||||
#undef HAVE_SETPRIORITY
|
#undef HAVE_SETPRIORITY
|
||||||
|
|
||||||
|
/* Define if xkbcommon is available */
|
||||||
|
#undef HAVE_XKBCOMMON
|
||||||
|
|
||||||
/* Define if xlocale.h header file exists. */
|
/* Define if xlocale.h header file exists. */
|
||||||
#undef HAVE_XLOCALE_H
|
#undef HAVE_XLOCALE_H
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "wx/settings.h"
|
#include "wx/settings.h"
|
||||||
#include "wx/msgdlg.h"
|
#include "wx/msgdlg.h"
|
||||||
#include "wx/math.h"
|
#include "wx/math.h"
|
||||||
|
#include "wx/module.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/display.h"
|
#include "wx/display.h"
|
||||||
@ -54,6 +55,12 @@ using namespace wxGTKImpl;
|
|||||||
typedef guint KeySym;
|
typedef guint KeySym;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Use libxkbcommon for key code translation if we need and have it.
|
||||||
|
#if (defined (GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WAYLAND)) && defined (HAVE_XKBCOMMON)
|
||||||
|
#define wxHAS_XKB
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __WXGTK4__
|
#ifdef __WXGTK4__
|
||||||
#define wxGTK_HAS_COMPOSITING_SUPPORT 0
|
#define wxGTK_HAS_COMPOSITING_SUPPORT 0
|
||||||
#else
|
#else
|
||||||
@ -225,6 +232,85 @@ static wxWindowGTK *gs_deferredFocusOut = NULL;
|
|||||||
GdkEvent *g_lastMouseEvent = NULL;
|
GdkEvent *g_lastMouseEvent = NULL;
|
||||||
int g_lastButtonNumber = 0;
|
int g_lastButtonNumber = 0;
|
||||||
|
|
||||||
|
#ifdef wxHAS_XKB
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// Global data used for raw key codes translation.
|
||||||
|
class XkbData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XkbData()
|
||||||
|
{
|
||||||
|
m_ctx = NULL;
|
||||||
|
m_keymap = NULL;
|
||||||
|
m_state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the state pointer allocating it on demand if necessary.
|
||||||
|
xkb_state* GetState()
|
||||||
|
{
|
||||||
|
if ( !m_state )
|
||||||
|
{
|
||||||
|
m_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
struct xkb_rule_names names = {0};
|
||||||
|
names.layout = "us";
|
||||||
|
m_keymap = xkb_keymap_new_from_names(m_ctx, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
m_state = xkb_state_new(m_keymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by wxXKBModule::OnExit() to free all our data.
|
||||||
|
void Free()
|
||||||
|
{
|
||||||
|
if ( m_state )
|
||||||
|
{
|
||||||
|
xkb_state_unref(m_state);
|
||||||
|
m_state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_keymap )
|
||||||
|
{
|
||||||
|
xkb_keymap_unref(m_keymap);
|
||||||
|
m_keymap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_ctx )
|
||||||
|
{
|
||||||
|
xkb_context_unref(m_ctx);
|
||||||
|
m_ctx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
xkb_context *m_ctx;
|
||||||
|
xkb_keymap *m_keymap;
|
||||||
|
xkb_state *m_state;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(XkbData);
|
||||||
|
};
|
||||||
|
|
||||||
|
XkbData gs_xkbData;
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
// wxXKBModule: used for freeing global xkb data
|
||||||
|
class wxXKBModule : public wxModule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool OnInit() wxOVERRIDE { return true; }
|
||||||
|
void OnExit() wxOVERRIDE { gs_xkbData.Free(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDECLARE_DYNAMIC_CLASS(wxXKBModule);
|
||||||
|
};
|
||||||
|
|
||||||
|
wxIMPLEMENT_DYNAMIC_CLASS(wxXKBModule, wxModule);
|
||||||
|
|
||||||
|
#endif // wxHAS_XKB
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
static GList* gs_sizeRevalidateList;
|
static GList* gs_sizeRevalidateList;
|
||||||
static GSList* gs_setSizeRequestList;
|
static GSList* gs_setSizeRequestList;
|
||||||
@ -1028,7 +1114,38 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event,
|
|||||||
: wxT("press"),
|
: wxT("press"),
|
||||||
static_cast<unsigned long>(keysym));
|
static_cast<unsigned long>(keysym));
|
||||||
|
|
||||||
long key_code = wxTranslateKeySymToWXKey(keysym, false /* !isChar */);
|
long key_code = 0;
|
||||||
|
|
||||||
|
#ifdef wxHAS_XKB
|
||||||
|
if ( gdk_keyval_to_unicode(gdk_event->keyval) )
|
||||||
|
{
|
||||||
|
// If the event has the corresponding Unicode char, let us set key_code
|
||||||
|
// to character that is generated by that key in the US keyboard layout
|
||||||
|
// (as wxMSW does and because it's useful to be able to identify the
|
||||||
|
// key independently of the current keyboard layout).
|
||||||
|
char key_code_str[64];
|
||||||
|
xkb_state_key_get_utf8(gs_xkbData.GetState(),
|
||||||
|
gdk_event->hardware_keycode,
|
||||||
|
key_code_str,
|
||||||
|
sizeof(key_code_str));
|
||||||
|
if ( strlen(key_code_str) == 1 )
|
||||||
|
{
|
||||||
|
key_code = key_code_str[0];
|
||||||
|
|
||||||
|
// If key_code is a Latin char, it should be in upper register to
|
||||||
|
// match the other ports.
|
||||||
|
if (islower(key_code))
|
||||||
|
{
|
||||||
|
key_code = toupper(key_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxHAS_XKB
|
||||||
|
|
||||||
|
if ( !key_code )
|
||||||
|
{
|
||||||
|
key_code = wxTranslateKeySymToWXKey(keysym, false /* !isChar */);
|
||||||
|
}
|
||||||
|
|
||||||
if ( !key_code )
|
if ( !key_code )
|
||||||
{
|
{
|
||||||
@ -1308,16 +1425,29 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( key_code )
|
const guint32 uniChar = gdk_keyval_to_unicode(keysym);
|
||||||
|
if ( key_code || uniChar )
|
||||||
{
|
{
|
||||||
wxKeyEvent eventChar(wxEVT_CHAR, event);
|
wxKeyEvent eventChar(wxEVT_CHAR, event);
|
||||||
|
|
||||||
wxLogTrace(TRACE_KEYS, wxT("Char event: %ld"), key_code);
|
if ( event.ControlDown() && isalpha(event.m_keyCode) )
|
||||||
|
{
|
||||||
eventChar.m_keyCode = key_code;
|
// Ctrl+letter is handled specially by AdjustCharEventKeyCodes().
|
||||||
|
eventChar.m_keyCode = event.m_keyCode;
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
eventChar.m_uniChar = gdk_keyval_to_unicode(key_code);
|
eventChar.m_uniChar = event.m_uniChar;
|
||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use Unicode values
|
||||||
|
eventChar.m_keyCode = key_code;
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
eventChar.m_uniChar = uniChar;
|
||||||
|
#endif // wxUSE_UNICODE
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace(TRACE_KEYS, wxT("Char event: %ld"), eventChar.m_keyCode);
|
||||||
|
|
||||||
AdjustCharEventKeyCodes(eventChar);
|
AdjustCharEventKeyCodes(eventChar);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user