xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Opened 11 months ago

Last modified 10 months ago

#3005 assigned defect

Unable to write accented characters using Spanish keyboard with HTML5 client

Reported by: alv982 Owned by: Antoine Martin
Priority: major Milestone: 4.2
Component: html5 Version: 4.0.x
Keywords: Cc:

Description

Hi,

The problem is that it's impossible to write any accented character (á, é, etc) using the HTML5 client. Using the desktop client works fine.

I'm using Chrome on Windows to connect to an Ubuntu server using the last beta version (xpra v4.1-r28309), but the problem also reproduces using the last stable version and using Firefox. I'm using a Spanish keyboard (as reference, this is the layout: https://commons.wikimedia.org/wiki/File:KB_Spanish.svg).

The procedure to write for example á is to press and then [a]. The first key is the key to the right to [ñ] in the keyboard.

At the beggining the HTML5 client doesn't send the accent key code and writes an apostrophe, so looking at other issues I added CHARCODE_TO_NAME[222] = "dead_acute" in Keycodes.js.

Then it recognizes the ['] key, but it doesn't write the á character. To write it, I have to press ['] [any other key] [a]. Pressing ['] [a] doesn't generate any output.

This is the output when pressing ['] [a] (no character is written).

2021-01-18 10:23:38,051 client   1 keyboard last keycode pressed= 0 , keycode= 222 , pressed= true , str= Dead
2021-01-18 10:23:38,052 client   1 keyboard processKeyEvent( true ,  [object KeyboardEvent] ) key= Quote keycode= 222
2021-01-18 10:23:38,052 client   1 keyboard _get_keyboard_layout() keyboard_layout= es
2021-01-18 10:23:38,053 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:23:38,053 do_get_keycode(222, 'dead_acute', True, [], 222, 'dead', 0)=48 (level=0, shift=False, mode=0, keysyms=['dead_acute', 'dead_diaeresis', 'braceleft', 'braceleft'])
2021-01-18 10:23:38,053 process_key_action([b'key-action', 1, b'dead_acute', True, (), 222, b'dead', 222, 0]) server keycode=48, group=0
2021-01-18 10:23:38,054 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:23:38,054 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:23:38,055 filtered_modifiers_set([])=set()
2021-01-18 10:23:38,055 filtered_modifiers_set([])=set()
2021-01-18 10:23:38,055 is_modifier(48) not found
2021-01-18 10:23:38,056 handle_key((1, True, 'dead_acute', 222, 48, [], False, True))
2021-01-18 10:23:38,056 handle keycode pressing    48: key 'dead_acute'
2021-01-18 10:23:38,056 fake_key(48, True)
2021-01-18 10:23:38,080 client   1 keyboard last keycode pressed= 222 , keycode= 222 , pressed= false , str= Dead
2021-01-18 10:23:38,080 client   1 keyboard processKeyEvent( false ,  [object KeyboardEvent] ) key= Quote keycode= 222
2021-01-18 10:23:38,081 process_key_action([b'key-action', 1, b'dead_acute', False, (), 222, b'dead', 222, 0]) server keycode=48, group=0
2021-01-18 10:23:38,082 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:23:38,082 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:23:38,083 filtered_modifiers_set([])=set()
2021-01-18 10:23:38,083 filtered_modifiers_set([])=set()
2021-01-18 10:23:38,084 is_modifier(48) not found
2021-01-18 10:23:38,084 handle_key((1, False, 'dead_acute', 222, 48, [], False, True))
2021-01-18 10:23:38,084 handle keycode unpressing  48: key 'dead_acute'
2021-01-18 10:23:38,084 fake_key(48, False)
2021-01-18 10:23:39,890 client   1 keyboard last keycode pressed= 0 , keycode= 65 , pressed= true , str= ??
2021-01-18 10:23:39,890 client   1 keyboard processKeyEvent( true ,  [object KeyboardEvent] ) key= KeyA keycode= 65
2021-01-18 10:23:39,891 client   1 keyboard _get_keyboard_layout() keyboard_layout= es
2021-01-18 10:23:39,892 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:23:39,892 do_get_keycode(65, 'aacute', True, [], 65, '?', 0)=-1, 0 (keyname translation)
2021-01-18 10:23:39,892 process_key_action([b'key-action', 1, b'aacute', True, (), 65, b'\xc3\xa1', 65, 0]) server keycode=-1, group=0
2021-01-18 10:23:39,893 client   1 keyboard last keycode pressed= 65 , keycode= 65 , pressed= false , str= a
2021-01-18 10:23:39,893 filtered_modifiers_set([])=set()
2021-01-18 10:23:39,894 client   1 keyboard processKeyEvent( false ,  [object KeyboardEvent] ) key= KeyA keycode= 65
2021-01-18 10:23:39,894 filtered_modifiers_set([])=set()
2021-01-18 10:23:39,895 process_key_action([b'key-action', 1, b'a', False, (), 65, b'a', 65, 0]) server keycode=-1, group=0

This is the output when I type ['][e][a] (á is written)

2021-01-18 10:26:00,471 client   1 keyboard last keycode pressed= 0 , keycode= 222 , pressed= true , str= Dead
2021-01-18 10:26:00,471 client   1 keyboard processKeyEvent( true ,  [object KeyboardEvent] ) key= Quote keycode= 222
2021-01-18 10:26:00,472 client   1 keyboard _get_keyboard_layout() keyboard_layout= es
2021-01-18 10:26:00,481 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:26:00,482 do_get_keycode(222, 'dead_acute', True, [], 222, 'dead', 0)=48 (level=0, shift=False, mode=0, keysyms=['dead_acute', 'dead_diaeresis', 'braceleft', 'braceleft'])
2021-01-18 10:26:00,482 process_key_action([b'key-action', 1, b'dead_acute', True, (), 222, b'dead', 222, 0]) server keycode=48, group=0
2021-01-18 10:26:00,482 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:26:00,482 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:26:00,483 filtered_modifiers_set([])=set()
2021-01-18 10:26:00,483 filtered_modifiers_set([])=set()
2021-01-18 10:26:00,484 is_modifier(48) not found
2021-01-18 10:26:00,484 handle_key((1, True, 'dead_acute', 222, 48, [], False, True))
2021-01-18 10:26:00,484 handle keycode pressing    48: key 'dead_acute'
2021-01-18 10:26:00,484 fake_key(48, True)
2021-01-18 10:26:00,541 client   1 keyboard last keycode pressed= 222 , keycode= 222 , pressed= false , str= Dead
2021-01-18 10:26:00,541 client   1 keyboard processKeyEvent( false ,  [object KeyboardEvent] ) key= Quote keycode= 222
2021-01-18 10:26:00,543 process_key_action([b'key-action', 1, b'dead_acute', False, (), 222, b'dead', 222, 0]) server keycode=48, group=0
2021-01-18 10:26:00,543 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:26:00,543 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:26:00,544 filtered_modifiers_set([])=set()
2021-01-18 10:26:00,544 filtered_modifiers_set([])=set()
2021-01-18 10:26:00,545 is_modifier(48) not found
2021-01-18 10:26:00,545 handle_key((1, False, 'dead_acute', 222, 48, [], False, True))
2021-01-18 10:26:00,545 handle keycode unpressing  48: key 'dead_acute'
2021-01-18 10:26:00,545 fake_key(48, False)
2021-01-18 10:26:02,319 client   1 keyboard last keycode pressed= 0 , keycode= 69 , pressed= true , str= ??
2021-01-18 10:26:02,320 client   1 keyboard processKeyEvent( true ,  [object KeyboardEvent] ) key= KeyE keycode= 69
2021-01-18 10:26:02,320 client   1 keyboard _get_keyboard_layout() keyboard_layout= es
2021-01-18 10:26:02,321 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:26:02,321 do_get_keycode(69, 'eacute', True, [], 69, '?', 0)=-1, 0 (keyname translation)
2021-01-18 10:26:02,321 process_key_action([b'key-action', 1, b'eacute', True, (), 69, b'\xc3\xa9', 69, 0]) server keycode=-1, group=0
2021-01-18 10:26:02,322 filtered_modifiers_set([])=set()
2021-01-18 10:26:02,322 filtered_modifiers_set([])=set()
2021-01-18 10:26:02,384 client   1 keyboard last keycode pressed= 69 , keycode= 69 , pressed= false , str= e
2021-01-18 10:26:02,384 client   1 keyboard processKeyEvent( false ,  [object KeyboardEvent] ) key= KeyE keycode= 69
2021-01-18 10:26:02,386 process_key_action([b'key-action', 1, b'e', False, (), 69, b'e', 69, 0]) server keycode=-1, group=0
2021-01-18 10:26:02,386 filtered_modifiers_set([])=set()
2021-01-18 10:26:02,387 filtered_modifiers_set([])=set()
2021-01-18 10:26:04,033 client   1 keyboard last keycode pressed= 0 , keycode= 65 , pressed= true , str= a
2021-01-18 10:26:04,035 client   1 keyboard processKeyEvent( true ,  [object KeyboardEvent] ) key= KeyA keycode= 65
2021-01-18 10:26:04,035 client   1 keyboard _get_keyboard_layout() keyboard_layout= es
2021-01-18 10:26:04,036 client   1 keyboard last keycode pressed= 65 , keycode= 65 , pressed= false , str= a
2021-01-18 10:26:04,036 client   1 keyboard processKeyEvent( false ,  [object KeyboardEvent] ) key= KeyA keycode= 65
2021-01-18 10:26:04,036 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:26:04,037 do_get_keycode(65, 'a', True, [], 65, 'a', 0)=38 (level=0, shift=False, mode=0, keysyms=['a', 'A', 'ae', 'AE'])
2021-01-18 10:26:04,037 process_key_action([b'key-action', 1, b'a', True, (), 65, b'a', 65, 0]) server keycode=38, group=0
2021-01-18 10:26:04,037 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:26:04,037 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:26:04,038 filtered_modifiers_set([])=set()
2021-01-18 10:26:04,038 filtered_modifiers_set([])=set()
2021-01-18 10:26:04,039 is_modifier(38) not found
2021-01-18 10:26:04,039 handle_key((1, True, 'a', 65, 38, [], False, True))
2021-01-18 10:26:04,039 handle keycode pressing    38: key 'a'
2021-01-18 10:26:04,039 fake_key(38, True)
2021-01-18 10:26:04,040 process_key_action([b'key-action', 1, b'a', False, (), 65, b'a', 65, 0]) server keycode=38, group=0
2021-01-18 10:26:04,040 set_keyboard_layout_group(0) ignored, no layout groups support
2021-01-18 10:26:04,041 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:26:04,041 filtered_modifiers_set([])=set()
2021-01-18 10:26:04,042 filtered_modifiers_set([])=set()
2021-01-18 10:26:04,042 is_modifier(38) not found
2021-01-18 10:26:04,042 handle_key((1, False, 'a', 65, 38, [], False, True))
2021-01-18 10:26:04,043 handle keycode unpressing  38: key 'a'
2021-01-18 10:26:04,043 fake_key(38, False)

This is the output using the desktop client (works fine, writes á):

2021-01-18 10:41:56,326 client   1 @30.809 mask_to_names(<flags 0 of type Gdk.ModifierType>) GetKeyState(VK_NUMLOCK)=0, names=[]
2021-01-18 10:41:56,346 client   1 @30.811 parse_key_event(<Gdk.EventKey object at 0x000000005b3d0680 (void at 0x0000000047eb20b0)>, True)=<GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': True}>
2021-01-18 10:41:56,347 client   1 @30.811 handle_key_action(ClientWindow(1), <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': True}>) wid=1
2021-01-18 10:41:56,347 client   1 @30.813 key_handled_as_shortcut(ClientWindow(1), 'dead_acute', [], True) shortcuts=None
2021-01-18 10:41:56,348 client   1 @30.814 send_delayed_key() delayed_event=None
2021-01-18 10:41:56,348 client   1 @30.814 send_key_action(1, <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': True}>)
2021-01-18 10:41:56,349 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:41:56,349 do_get_keycode(222, 'dead_acute', True, [], 65105, '', 0)=48 (level=0, shift=False, mode=0, keysyms=['dead_acute', 'dead_diaeresis', 'braceleft', 'braceleft'])
2021-01-18 10:41:56,350 process_key_action(['key-action', 1, b'dead_acute', True, (), 65105, b'', 222, 0]) server keycode=48, group=0
2021-01-18 10:41:56,350 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:41:56,351 filtered_modifiers_set([])=set()
2021-01-18 10:41:56,351 filtered_modifiers_set([])=set()
2021-01-18 10:41:56,351 is_modifier(48) not found
2021-01-18 10:41:56,352 handle_key((1, True, 'dead_acute', 65105, 48, [], False, True))
2021-01-18 10:41:56,352 handle keycode pressing    48: key 'dead_acute'
2021-01-18 10:41:56,352 fake_key(48, True)
2021-01-18 10:41:56,353 scheduling key repeat timer with delay 500 for dead_acute / 48
2021-01-18 10:41:56,389 client   1 @30.872 mask_to_names(<flags 0 of type Gdk.ModifierType>) GetKeyState(VK_NUMLOCK)=0, names=[]
2021-01-18 10:41:56,390 client   1 @30.873 parse_key_event(<Gdk.EventKey object at 0x000000005b3d0680 (void at 0x0000000047a9df20)>, False)=<GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': False}>
2021-01-18 10:41:56,395 client   1 @30.874 handle_key_action(ClientWindow(1), <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': False}>) wid=1
2021-01-18 10:41:56,395 client   1 @30.875 key_handled_as_shortcut(ClientWindow(1), 'dead_acute', [], False) shortcuts=None
2021-01-18 10:41:56,396 client   1 @30.876 send_delayed_key() delayed_event=None
2021-01-18 10:41:56,396 client   1 @30.876 send_key_action(1, <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'dead_acute', 'keyval': 65105, 'keycode': 222, 'group': 0, 'string': '', 'pressed': False}>)
2021-01-18 10:41:56,397 process_key_action(['key-action', 1, b'dead_acute', False, (), 65105, b'', 222, 0]) server keycode=48, group=0
2021-01-18 10:41:56,397 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:41:56,397 filtered_modifiers_set([])=set()
2021-01-18 10:41:56,398 filtered_modifiers_set([])=set()
2021-01-18 10:41:56,398 is_modifier(48) not found
2021-01-18 10:41:56,398 handle_key((1, False, 'dead_acute', 65105, 48, [], False, True))
2021-01-18 10:41:56,399 handle keycode unpressing  48: key 'dead_acute'
2021-01-18 10:41:56,399 fake_key(48, False)
2021-01-18 10:41:56,762 client   1 @31.102 mask_to_names(<flags 0 of type Gdk.ModifierType>) GetKeyState(VK_NUMLOCK)=0, names=[]
2021-01-18 10:41:56,764 filtered_modifiers_set([])=set()
2021-01-18 10:41:56,765 filtered_modifiers_set([])=set()
2021-01-18 10:41:57,047 client   1 @31.533 mask_to_names(<flags 0 of type Gdk.ModifierType>) GetKeyState(VK_NUMLOCK)=0, names=[]
2021-01-18 10:41:57,048 client   1 @31.533 parse_key_event(<Gdk.EventKey object at 0x000000005b3d07c0 (void at 0x0000000047a9ddc0)>, True)=<GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'a', 'keyval': 97, 'keycode': 65, 'group': 0, 'string': 'a', 'pressed': True}>
2021-01-18 10:41:57,075 client   1 @31.533 handle_key_action(ClientWindow(1), <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'a', 'keyval': 97, 'keycode': 65, 'group': 0, 'string': 'a', 'pressed': True}>) wid=1
2021-01-18 10:41:57,075 client   1 @31.534 key_handled_as_shortcut(ClientWindow(1), 'a', [], True) shortcuts=None
2021-01-18 10:41:57,076 client   1 @31.534 send_delayed_key() delayed_event=None
2021-01-18 10:41:57,076 client   1 @31.534 send_key_action(1, <GTKKeyEvent object, contents: {'modifiers': [], 'keyname': 'a', 'keyval': 97, 'keycode': 65, 'group': 0, 'string': 'a', 'pressed': True}>)
2021-01-18 10:41:57,077 will try levels: [0, 4, 1, 5, 2, 6, 3, 7]
2021-01-18 10:41:57,077 do_get_keycode(65, 'a', True, [], 97, 'a', 0)=38 (level=0, shift=False, mode=0, keysyms=['a', 'A', 'ae', 'AE'])
2021-01-18 10:41:57,077 process_key_action(['key-action', 1, b'a', True, (), 97, b'a', 65, 0]) server keycode=38, group=0
2021-01-18 10:41:57,077 set_keyboard_layout_group(0) ignored, value unchanged
2021-01-18 10:41:57,078 filtered_modifiers_set([])=set()
2021-01-18 10:41:57,078 filtered_modifiers_set([])=set()
2021-01-18 10:41:57,079 is_modifier(38) not found
2021-01-18 10:41:57,079 handle_key((1, True, 'a', 97, 38, [], False, True))
2021-01-18 10:41:57,079 handle keycode pressing    38: key 'a'
2021-01-18 10:41:57,079 fake_key(38, True)
2021-01-18 10:41:57,080 scheduling key repeat timer with delay 500 for a / 38

The bug is also present with --no-keyboard-sync. I have attached also setxkbmap info for the server.

If there is anything else I can provide, please let me know.

Regards.

Attachments (2)

setxkbmap-print-server.txt (259 bytes) - added by alv982 11 months ago.
setxkbmap-query-server.txt (87 bytes) - added by alv982 11 months ago.

Download all attachments as: .zip

Change History (7)

Changed 11 months ago by alv982

Attachment: setxkbmap-print-server.txt added

Changed 11 months ago by alv982

Attachment: setxkbmap-query-server.txt added

comment:1 Changed 11 months ago by alv982

Sorry, the formatting deleted a key, it should read: The procedure to write for example á is to press ['] and then [a].

comment:2 Changed 11 months ago by Antoine Martin

Status: newassigned

I think that the correct way to fix this is to send a not aacute, because the server can't find aacute in the keymap:

process_key_action([b'key-action', 1, b'aacute', True, (), 65, b'\xc3\xa1', 65, 0]) server keycode=-1, group=0

We do know it is an a:

client   1 keyboard last keycode pressed= 65 , keycode= 65 , pressed= false , str= a

So then the server will find the keycode and things should just work.

Should this be done for all instances of aacute or just when preceded by a dead key? Is this going to work the same in all browsers? (from past experience, that's unlikely..)
I don't know yet the answer to these questions.

comment:3 in reply to:  2 ; Changed 11 months ago by alv982

In theory, I think I should be done for all the instances of aacute, as it's impossible to write "á" without pressing "'" (right to "Ñ") before. This key is only used to compose accented characters (like á é í, etc).

There is another "'" key right to the "0" in the keyboard image, that writes an apostrophe, and can't be used to compose accented characters. This key has code 219 instead 222 of the "'" to compose accented characters.

Replying to Antoine Martin:

I think that the correct way to fix this is to send a not aacute, because the server can't find aacute in the keymap:

process_key_action([b'key-action', 1, b'aacute', True, (), 65, b'\xc3\xa1', 65, 0]) server keycode=-1, group=0

We do know it is an a:

client   1 keyboard last keycode pressed= 65 , keycode= 65 , pressed= false , str= a

So then the server will find the keycode and things should just work.

Should this be done for all instances of aacute or just when preceded by a dead key? Is this going to work the same in all browsers? (from past experience, that's unlikely..)
I don't know yet the answer to these questions.

comment:4 in reply to:  3 Changed 11 months ago by alv982

Based on your comment, I have tried changing Keyscodes.js, from aacute: 225 to aacute: 65, and added HARCODE_TO_NAME[222] = "dead_acute", and it seems to work fine both in Firefox and Chrome under Windows, and Chrome under Ubuntu (doesn't work in Firefox under Ubuntu, neither with the original file).

Replying to alv982:

In theory, I think I should be done for all the instances of aacute, as it's impossible to write "á" without pressing "'" (right to "Ñ") before. This key is only used to compose accented characters (like á é í, etc).

There is another "'" key right to the "0" in the keyboard image, that writes an apostrophe, and can't be used to compose accented characters. This key has code 219 instead 222 of the "'" to compose accented characters.

Replying to Antoine Martin:

I think that the correct way to fix this is to send a not aacute, because the server can't find aacute in the keymap:

process_key_action([b'key-action', 1, b'aacute', True, (), 65, b'\xc3\xa1', 65, 0]) server keycode=-1, group=0

We do know it is an a:

client   1 keyboard last keycode pressed= 65 , keycode= 65 , pressed= false , str= a

So then the server will find the keycode and things should just work.

Should this be done for all instances of aacute or just when preceded by a dead key? Is this going to work the same in all browsers? (from past experience, that's unlikely..)
I don't know yet the answer to these questions.

comment:5 Changed 10 months ago by migration script

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/3005

Note: See TracTickets for help on using tickets.