Bug 124906 - iPad Hardware-Keyboard in iOS App: Characters appear twice
Summary: iPad Hardware-Keyboard in iOS App: Characters appear twice
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: iOS Editor (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: Other iOS
: medium normal
Assignee: Not Assigned
URL:
Whiteboard: target:6.3.0
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-23 12:06 UTC by Andreas Gruhler
Modified: 2019-05-20 10:23 UTC (History)
1 user (show)

See Also:
Crash report or crash signature:


Attachments
The swiss german hardware keyboards for the iPad which we are using (99.14 KB, image/jpeg)
2019-04-23 12:07 UTC, Andreas Gruhler
Details
Video to reproduce the problem of characters appearing twice after typing an umlaut (11.45 MB, video/mp4)
2019-04-23 12:07 UTC, Andreas Gruhler
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Gruhler 2019-04-23 12:06:47 UTC
Description:
Using the iPad hardware keyboard in the iOS app, characters appear twice (and are also deleted twice) after typing the "¨" symbol. For instance, I try to type the "Ä" character, where I need to press "¨" first, then the "A". Afterwards, each letter is duplicated. So if I press "bcd" afterwards, this looks like: "Äbbccdd". If I delete the characters in this order, deleting once leaves me with "Äbbcc", deleting twice with "Äbb". Every keystroke is applied twice. Reopening the document or tapping the screen at any position in the text solves the problem. See video attached.

Steps to Reproduce:
1. Press the "¨" hardware key on the iPad
2. Press an uppercase key, e.g., "A", "O" or "U" to create an uppercase umlaut
3. Press any other keys and undo by deleting with the "backspace" key

Actual Results:
1. The "¨" character appears
2. The correct umlaut appears, e.g. "Ä", when pressing "¨" + "A"
3. All following characters appear twice. "Backspace" deletes the characters twice as well.

Expected Results:
1. The "¨" character appears
2. The correct umlaut appears, e.g. "Ä", when pressing "¨" + "A". "¨" should no longer be visible, but should become part of the character "Ä".
3. All following keystrokes behave normally and appear only once


Reproducible: Always


User Profile Reset: No



Additional Info:
We are using Swiss German iPad hardware keyboards, see image attached.
Comment 1 Andreas Gruhler 2019-04-23 12:07:11 UTC
Created attachment 150944 [details]
The swiss german hardware keyboards for the iPad which we are using
Comment 2 Andreas Gruhler 2019-04-23 12:07:55 UTC
Created attachment 150945 [details]
Video to reproduce the problem of characters appearing twice after typing an umlaut
Comment 3 Aron Budea 2019-04-24 11:40:03 UTC
Confirmed. It also affects both the app and normal online.

To repro one needs to set German (Switzerland) keyboard layout, and the key for the ¨ (umlaut) character when looking at a keyboard with English layout is "[".
Comment 4 Aron Budea 2019-04-24 11:40:37 UTC
(In reply to Aron Budea from comment #3)
> To repro one needs to set German (Switzerland) keyboard layout, and the key
> for the ¨ (umlaut) character when looking at a keyboard with English layout
> is "[".
That was a typo, actually it's "]".
Comment 5 How can I remove my account? 2019-05-17 14:45:12 UTC
First attempt at fix at https://gerrit.libreoffice.org/#/c/72486/
Comment 6 How can I remove my account? 2019-05-17 16:05:30 UTC
For reference, here is a log from adding console.log calls to the original code. From this can be seen that when I type the keys a ¨ e b , for some reason the keydown, keypress, and keyup events for the b and c keys arrived in duplicate, nested. That caused the b and c characters to be entered twice into the document. What caused this duplication is unknown. Possibly some bug in iOS, possibly some bug in the app (loleaflet) code.

> [Log] ==> onKeyEvents: keydown:a keyCode=65 charCode=0 unoKeyCode=512 _keyHandled=true _isComposing=undefined (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:a keyCode=97 charCode=97 unoKeyCode=257 _keyHandled=false _isComposing=undefined (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=97 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onTextInput: _keyHandled=true (Control.MobileInput.js, line 205)
> [Log] ==> onInput: inputType=insertText (Control.MobileInput.js, line 215)
> [Log] ==> onKeyEvents: keyup:a keyCode=0 charCode=0 unoKeyCode=0 _keyHandled=true _isComposing=undefined (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> [Log] ==> onCompEvents: compositionstart (Control.MobileInput.js, line 188)
> [Log] ==> onCompEvents: compositionupdate (Control.MobileInput.js, line 188)
> [Log] ==> onInput: inputType=insertCompositionText (Control.MobileInput.js, line 215)
> [Log] ==> _postCompositionEvent type=input text="¨" (TileLayer.js, line 1599)
> [Log] ==> onKeyEvents: keydown:ë keyCode=69 charCode=0 unoKeyCode=516 _keyHandled=true _isComposing=true (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:ë keyCode=235 charCode=235 unoKeyCode=235 _keyHandled=false _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=235 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onTextInput: _keyHandled=true (Control.MobileInput.js, line 205)
> [Log] ==> onInput: inputType=insertFromComposition (Control.MobileInput.js, line 215)
> [Log] ==> onCompEvents: compositionend (Control.MobileInput.js, line 188)
> [Log] ==> _postCompositionEvent type=end text="" (TileLayer.js, line 1599)
> [Log] ==> onKeyEvents: keyup:Dead keyCode=69 charCode=0 unoKeyCode=516 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=516 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> [Log] ==> onKeyEvents: keyup:ë keyCode=0 charCode=0 unoKeyCode=0 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> 
> 
> [Log] ==> onKeyEvents: keydown:b keyCode=66 charCode=0 unoKeyCode=513 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:b keyCode=98 charCode=98 unoKeyCode=258 _keyHandled=false _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=98 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onKeyEvents: keydown:b keyCode=66 charCode=0 unoKeyCode=513 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:b keyCode=98 charCode=98 unoKeyCode=258 _keyHandled=false _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=98 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onKeyEvents: keyup:Dead keyCode=66 charCode=0 unoKeyCode=513 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=513 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> [Log] ==> onKeyEvents: keyup:b keyCode=0 charCode=0 unoKeyCode=0 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> [Log] ==> onKeyEvents: keydown:c keyCode=67 charCode=0 unoKeyCode=514 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:c keyCode=99 charCode=99 unoKeyCode=259 _keyHandled=false _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=99 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onKeyEvents: keydown:c keyCode=67 charCode=0 unoKeyCode=514 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log]     _keyHandled := false (Control.MobileInput.js, line 144)
> [Log] ==> onKeyEvents: keypress:c keyCode=99 charCode=99 unoKeyCode=259 _keyHandled=false _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=input charcode=99 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 172)
> [Log] ==> onKeyEvents: keyup:Dead keyCode=67 charCode=0 unoKeyCode=514 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=514 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)
> [Log] ==> onKeyEvents: keyup:c keyCode=0 charCode=0 unoKeyCode=0 _keyHandled=true _isComposing=false (Control.MobileInput.js, line 125)
> [Log] ==> _postKeyboardEvent type=up charcode=0 keycode=0 (TileLayer.js, line 1573)
> [Log]     _keyHandled := true (Control.MobileInput.js, line 182)

When I tested with an extremely minimal HTML page with some Javascript to catch keyboard events, I did not see any corresponding duplication, which would seem to point the finger at our code... But no idea really.

<html>
  <head>
    <title>
      Title
    </title>

    <script>
      var keyeventhandler = function(e) {
	  console.log(e.type + ' "' + e.key + '" ' + e.keyCode + ' ' + e.charCode);
      }

      var textinputeventhandler = function(e) {
	  console.log('textInput: "' + e.data + '"');
      }

      var inputeventhandler = function(e) {
	  console.log(e.inputType);
      }

      var compeventhandler = function(e) {
	  console.log(e.type + ' "' + e.data + '"');
      }

      window.addEventListener('keydown', keyeventhandler);
      window.addEventListener('keypress', keyeventhandler);
      window.addEventListener('keyup', keyeventhandler);

      window.addEventListener('textInput', textinputeventhandler);

      window.addEventListener('input', inputeventhandler);

      window.addEventListener('compositionstart', compeventhandler);
      window.addEventListener('compositionupdate', compeventhandler);
      window.addEventListener('compositionend', compeventhandler);

    </script>

  </head>
  <body>
    Body.
  </body>
</html>
Comment 7 Nicolas Christener 2019-05-17 16:45:00 UTC
I may be wrong, but as far as I remember I also encountered this issue in "online", I think it is not related to iOS.
Comment 8 How can I remove my account? 2019-05-20 08:31:02 UTC
> I also encountered this issue in "online"

Yes, the same JavaScript code is used for the iOS app and a mobile client of Online, and the same issues are apparent.
Comment 9 How can I remove my account? 2019-05-20 08:31:51 UTC
At least for a Mobile Safari (iOS) client of Online, I mean. A mobile Android browser client might work differently.
Comment 10 How can I remove my account? 2019-05-20 08:34:15 UTC
Works better now in the iOS app with https://gerrit.libreoffice.org/#/c/72486/ merged. 

Will fix in the master branch, too, once I have fixed other things that have broken the iOS app when built from the master branch during last week... currently the iOS app does not work at all in the master branch.
Comment 11 Commit Notification 2019-05-20 10:21:16 UTC
Tor Lillqvist committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/online/+/8c15d4f93839adaf93ca197deb7c5818cfa34098%5E%21

tdf#124906: Hack for dead keys in iOS app and iOS Safari against Online
Comment 12 How can I remove my account? 2019-05-20 10:23:08 UTC
Let's resolve for now. The behaviour is not ideal now, but at least the major annoyance (the doubling mentioned in the bug title) is gone. File a separate bug for each remaining issue.