Skip to content

Commit

Permalink
Merge pull request #1583 from unxed/fix-alt-keys
Browse files Browse the repository at this point in the history
latin key guess to work even if english kb layout not installed
  • Loading branch information
elfmz committed Apr 2, 2023
2 parents b5f7ba3 + 3ba3509 commit ee35e5f
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 51 deletions.
48 changes: 30 additions & 18 deletions WinPort/src/Backend/TTY/TTYX/TTYX.cpp
Expand Up @@ -33,13 +33,13 @@ class TTYX
int _screen;
Window _root_window;
Window _window;
XkbDescPtr _xkb_en = nullptr;
Atom _targets_atom;
Atom _text_atom;
Atom _utf8_atom;
Atom _clipboard_atom;
Atom _xsel_data_atom;
int _display_fd;
int _eng_group_id = 0; // use default kb layout if English one is not found

#ifdef TTYXI
const std::chrono::time_point<std::chrono::steady_clock> _never;
Expand Down Expand Up @@ -157,8 +157,34 @@ class TTYX
const XIRawEvent *ev = (const XIRawEvent *)cookie->data;
//fprintf(stderr, "TTYXi: !!!!! %d %d\n", cookie->evtype == XI_RawKeyPress, ev->detail);

KeySym ks = XkbKeycodeToKeysym(_display, ev->detail, _eng_group_id, 0);
if (!ks) { ks = XkbKeycodeToKeysym(_display, ev->detail, 0, 0); } // fallback
if (!_xkb_en) {
char keycodes[] = "evdev";
char types[] = "complete";
char compat[] = "complete";
char symbols[] = "pc+us+inet(evdev)";

XkbComponentNamesRec component_names = {
.keycodes = keycodes,
.types = types,
.compat = compat,
.symbols = symbols
};

_xkb_en = XkbGetKeyboardByName(
_display, XkbUseCoreKbd, &component_names,
XkbGBN_AllComponentsMask, XkbGBN_AllComponentsMask, False);

XkbGetControls(_display, XkbGroupsWrapMask, _xkb_en);
XkbGetNames(_display, XkbGroupNamesMask, _xkb_en);
}

KeySym ks;
if (_xkb_en) {
unsigned int mods;
XkbTranslateKeyCode(_xkb_en, ev->detail, 0, &mods, &ks);
} else {
ks = XkbKeycodeToKeysym(_display, ev->detail, 0, 0); // fallback to old method
}

if (cookie->evtype == XI_RawKeyPress) {
_xi_keys[ks] = std::chrono::steady_clock::now();
Expand Down Expand Up @@ -418,21 +444,6 @@ class TTYX
auto color = BlackPixel(_display, _screen);
_window = XCreateSimpleWindow(_display, _root_window, 0, 0, 1, 1, 0, color, color);

// searching for group id of English keyboard layout
XkbDescPtr xkb = XkbGetMap(_display, 0, XkbUseCoreKbd);
XkbGetControls(_display, XkbGroupsWrapMask, xkb);
XkbGetNames(_display, XkbGroupNamesMask, xkb);
for (int i = 0; i < xkb->ctrls->num_groups; i++) {
char *layout = XGetAtomName(_display, xkb->names->groups[i]);
if (strstr(layout, "English")) {
// English kb layout found, let's use it for translations
_eng_group_id = i;
break;
}
XFree(layout);
}
XkbFreeKeyboard(xkb, 0, True);

#ifdef TTYXI
_xi = true;
// Test for XInput 2 extension
Expand Down Expand Up @@ -494,6 +505,7 @@ class TTYX

~TTYX()
{
if (_xkb_en) { XkbFreeKeyboard(_xkb_en, 0, True); }
XDestroyWindow(_display, _window);
XCloseDisplay(_display);
}
Expand Down
80 changes: 47 additions & 33 deletions WinPort/src/Backend/WX/wxWinTranslations.cpp
Expand Up @@ -421,47 +421,61 @@ static int X11KeyCodeLookupUncached(wxUint32 keyflags)
{
int key_code = 0;
Display *display = XOpenDisplay(NULL);
XkbDescPtr xkb = XkbGetMap(display, 0, XkbUseCoreKbd);

if (!display) {
return 0;
}

char keycodes[] = "evdev";
char types[] = "complete";
char compat[] = "complete";
char symbols[] = "pc+us+inet(evdev)";

XkbComponentNamesRec component_names = {
.keycodes = keycodes,
.types = types,
.compat = compat,
.symbols = symbols
};

XkbDescPtr xkb = XkbGetKeyboardByName(
display, XkbUseCoreKbd, &component_names, XkbGBN_AllComponentsMask, XkbGBN_AllComponentsMask, False);

if (!xkb) {
XCloseDisplay(display);
return 0;
}

XkbGetControls(display, XkbGroupsWrapMask, xkb);
XkbGetNames(display, XkbGroupNamesMask, xkb);

// searching for group id of English keyboard layout
int group = -1;
for (int i = 0; i < xkb->ctrls->num_groups; i++) {
char *layout = XGetAtomName(display, xkb->names->groups[i]);
if (strstr(layout, "English")) {
// English kb layout found, let's use it for translations
group = i;
break;
}
XFree(layout);
}
KeySym ks;
unsigned int mods;
XkbTranslateKeyCode(xkb, keyflags, 0, &mods, &ks);

// if English keyboard layout is not found, we should not do anything to avoid wrong translations
if (group != -1) {
KeySym ks = XkbKeycodeToKeysym(display, keyflags, group, 0);
const char *keysymstr = XKeysymToString(ks);
const char *keysymstr = XKeysymToString(ks);

if (keysymstr[0] && !keysymstr[1]) {
// char key
key_code = toupper(*keysymstr);
}
switch (ks) {
case XK_minus: key_code = '-'; break;
case XK_equal: key_code = '='; break;
case XK_bracketleft: key_code = '['; break;
case XK_bracketright: key_code = ']'; break;
case XK_semicolon: key_code = ';'; break;
case XK_apostrophe: key_code = '\''; break;
case XK_grave: key_code = '`'; break;
case XK_backslash: key_code = '\\'; break;
case XK_comma: key_code = ','; break;
case XK_period: key_code = '.'; break;
case XK_slash: key_code = '/'; break;
}
if (keysymstr[0] && !keysymstr[1]) {
// char key
key_code = toupper(*keysymstr);
}
switch (ks) {
case XK_minus: key_code = '-'; break;
case XK_equal: key_code = '='; break;
case XK_bracketleft: key_code = '['; break;
case XK_bracketright: key_code = ']'; break;
case XK_semicolon: key_code = ';'; break;
case XK_apostrophe: key_code = '\''; break;
case XK_grave: key_code = '`'; break;
case XK_backslash: key_code = '\\'; break;
case XK_comma: key_code = ','; break;
case XK_period: key_code = '.'; break;
case XK_slash: key_code = '/'; break;
}

XkbFreeKeyboard(xkb, 0, True);
XCloseDisplay(display);

return key_code;
}

Expand Down

0 comments on commit ee35e5f

Please sign in to comment.