| Index: ui/base/ime/character_composer.cc
|
| diff --git a/ui/base/ime/character_composer.cc b/ui/base/ime/character_composer.cc
|
| index d8587cf15241b06bb08175223c9dc2421d6a1464..f47d34e8747f477ba66f65a2e9af8de78e63123c 100644
|
| --- a/ui/base/ime/character_composer.cc
|
| +++ b/ui/base/ime/character_composer.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "ui/base/ime/character_composer.h"
|
|
|
| +#include <X11/Xlib.h>
|
| +
|
| #include <algorithm>
|
| #include <iterator>
|
|
|
| @@ -14,6 +16,7 @@
|
| #include "third_party/gtk+/gdk/gdkkeysyms.h"
|
| #include "ui/base/events/event_constants.h"
|
| #include "ui/base/glib/glib_integers.h"
|
| +#include "ui/base/x/x11_util.h"
|
|
|
| // Note for Gtk removal: gtkimcontextsimpleseqs.h does not #include any Gtk
|
| // headers and only contains one big guint16 array |gtk_compose_seqs_compact|
|
| @@ -349,6 +352,19 @@ bool UTF32CharacterToUTF16(uint32 character, string16* output) {
|
| return true;
|
| }
|
|
|
| +// Converts a X keycode to a X keysym with no modifiers.
|
| +KeySym XKeyCodeToXKeySym(unsigned int keycode) {
|
| + Display* display = ui::GetXDisplay();
|
| + if (!display)
|
| + return NoSymbol;
|
| +
|
| + XKeyEvent x_key_event = {0};
|
| + x_key_event.type = KeyPress;
|
| + x_key_event.display = display;
|
| + x_key_event.keycode = keycode;
|
| + return ::XLookupKeysym(&x_key_event, 0);
|
| +}
|
| +
|
| // Returns an hexadecimal digit integer (0 to 15) corresponding to |keyval|.
|
| // -1 is returned when |keyval| cannot be a hexadecimal digit.
|
| int KeyvalToHexDigit(unsigned int keyval) {
|
| @@ -377,7 +393,8 @@ void CharacterComposer::Reset() {
|
| }
|
|
|
| bool CharacterComposer::FilterKeyPress(unsigned int keyval,
|
| - unsigned int flags) {
|
| + unsigned int keycode,
|
| + int flags) {
|
| composed_character_.clear();
|
| preedit_string_.clear();
|
|
|
| @@ -401,9 +418,9 @@ bool CharacterComposer::FilterKeyPress(unsigned int keyval,
|
| // Filter key press in an appropriate manner.
|
| switch (composition_mode_) {
|
| case KEY_SEQUENCE_MODE:
|
| - return FilterKeyPressSequenceMode(keyval, flags);
|
| + return FilterKeyPressSequenceMode(keyval, keycode, flags);
|
| case HEX_MODE:
|
| - return FilterKeyPressHexMode(keyval, flags);
|
| + return FilterKeyPressHexMode(keyval, keycode, flags);
|
| default:
|
| NOTREACHED();
|
| return false;
|
| @@ -411,7 +428,8 @@ bool CharacterComposer::FilterKeyPress(unsigned int keyval,
|
| }
|
|
|
| bool CharacterComposer::FilterKeyPressSequenceMode(unsigned int keyval,
|
| - unsigned int flags) {
|
| + unsigned int keycode,
|
| + int flags) {
|
| DCHECK(composition_mode_ == KEY_SEQUENCE_MODE);
|
| compose_buffer_.push_back(keyval);
|
|
|
| @@ -436,10 +454,18 @@ bool CharacterComposer::FilterKeyPressSequenceMode(unsigned int keyval,
|
| }
|
|
|
| bool CharacterComposer::FilterKeyPressHexMode(unsigned int keyval,
|
| - unsigned int flags) {
|
| + unsigned int keycode,
|
| + int flags) {
|
| DCHECK(composition_mode_ == HEX_MODE);
|
| const size_t kMaxHexSequenceLength = 8;
|
| - const int hex_digit = KeyvalToHexDigit(keyval);
|
| + int hex_digit = KeyvalToHexDigit(keyval);
|
| + if (hex_digit < 0) {
|
| + // With 101 keyboard, control + shift + 3 produces '#', but a user may
|
| + // have intended to type '3'. So, if a hexadecimal character was not found,
|
| + // suppose a user is holding shift key (and possibly control key, too) and
|
| + // try a character with modifier keys removed.
|
| + hex_digit = KeyvalToHexDigit(XKeyCodeToXKeySym(keycode));
|
| + }
|
|
|
| if (keyval == GDK_KEY_Escape) {
|
| // Cancel composition when ESC is pressed.
|
|
|