View Issue Details

IDProjectCategoryView StatusLast Update
0026115LazarusWidgetsetpublic2016-03-27 18:17
ReporterBart Broersma Assigned ToBart Broersma  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSLinux 
Product Version1.3 (SVN) 
Summary0026115: Typing diactricics (using "dead keys") in TEdit does not trigger OnKeyDown or On(Utf8)KeyPress in QT-Linux
DescriptionWhen you enter a diacritic into a TEdit (an many other controls) using the "dead keys" method there is no OnKeyDown or On(Utf8)KeyPress event triggered.
This is however not the case for TCustomControl derived controls like SynEdit.

By "dead keys" method I mean that in order to compose a "ó" I press 'o on the keyboard.

My Keyboard layout is
Map: US
Layout: English (US)
Variant: English (US, international with dead keys)
Steps To ReproduceAttached sampleprogram shows that no OnKeyDown/OnUtf8KeyPress is triggered in TEdit when typing ó, but it is in TSynEdit
Additional InformationLooking in TQtWidget.SlotKey() this is what happens

Pressing 'o in a TEdit
------------------------------------
TQtWidget.SlotKey Edit2:TEdit
  Text = ´
> TQtWidget.SlotKey dump begin event=QEventKeyRelease
 KEY=16781905 COUNT=2 TEXT=´
 LCLKEY=0 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 48 NATIVEVIRTUALKEY: 65105
Key compression ? TRUE
< TQtWidget.SlotKey dump end event=QEventKeyRelease
TQtWidget.SlotKey Edit2:TEdit
  Text = o
> TQtWidget.SlotKey dump begin event=QEventKeyRelease
 KEY=79 COUNT=1 TEXT=o
 LCLKEY=79 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 32 NATIVEVIRTUALKEY: 111
Key compression ? TRUE
< TQtWidget.SlotKey dump end event=QEventKeyRelease
------------------------------------

Only KeyReleases are sent.
As opposed to:

Pressing a in a TEdit
------------------------------------
TQtWidget.SlotKey Edit2:TEdit
  Text = a
> TQtWidget.SlotKey dump begin event=QEventKeyPress
 KEY=65 COUNT=1 TEXT=a
 LCLKEY=65 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 38 NATIVEVIRTUALKEY: 97
Key compression ? TRUE
< TQtWidget.SlotKey dump end event=QEventKeyPress
TQtWidget.SlotKey Edit2:TEdit
  Text = a
> TQtWidget.SlotKey dump begin event=QEventKeyRelease
 KEY=65 COUNT=1 TEXT=a
 LCLKEY=65 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 38 NATIVEVIRTUALKEY: 97
Key compression ? TRUE
< TQtWidget.SlotKey dump end event=QEventKeyRelease
------------------------------------


Comparing this to a TSynEdit:
TSynEdit: typing 'o to compose ó:
------------------------------------
TQtWidget.SlotKey SynEdit1:TSynEdit
  Text = ´
> TQtWidget.SlotKey dump begin event=QEventKeyRelease
 KEY=16781905 COUNT=2 TEXT=´
 LCLKEY=0 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 48 NATIVEVIRTUALKEY: 65105
Key compression ? FALSE
< TQtWidget.SlotKey dump end event=QEventKeyRelease


> TQtCustomControl.EventFilter event=QEventInputMethod
 commmitString ó len 1 UnicodeChar 243 UnicodeLen 1
TQtWidget.SlotKey SynEdit1:TSynEdit
  Text = ó


TQtWidget.SlotKey SynEdit1:TSynEdit
  Text = ó
> TQtWidget.SlotKey dump begin event=QEventKeyPress
 KEY=243 COUNT=1 TEXT=ó
 LCLKEY=243 SPONTANEOUS FALSE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: FALSE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 0 NATIVEVIRTUALKEY: 0
Key compression ? FALSE
< TQtWidget.SlotKey dump end event=QEventKeyPress

SynEdit1KeyDown: Key = 243
SynEdit1Utf8KeyPress: Utf8Key = ó

TQtWidget.SlotKey SynEdit1:TSynEdit
  Text = o
> TQtWidget.SlotKey dump begin event=QEventKeyRelease
 KEY=79 COUNT=1 TEXT=o
 LCLKEY=79 SPONTANEOUS TRUE
 MODIFIERS: NONE NATIVEMODIFIERS: NONE
 HASEXTENDEDINFO: TRUE ISAUTOREPEAT: FALSE
 NATIVESCANCODE: 32 NATIVEVIRTUALKEY: 111
Key compression ? FALSE
< TQtWidget.SlotKey dump end event=QEventKeyRelease
------------------------------------


Attached patch moves the handling of QEventInputMethod events to QtWidget.EventFilter and fixes the issue
TagsNo tags attached.
Fixed in Revisionr44930
LazTarget-
WidgetsetQT
Attached Files

Activities

Bart Broersma

2014-05-06 13:55

developer  

qtwidgets.diff (4,162 bytes)   
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revision 44929)
+++ lcl/interfaces/qt/qtwidgets.pas	(working copy)
@@ -189,6 +189,7 @@
     function slotDropFiles(Sender: QObjectH; Event: QEventH): Boolean;
     function SlotHover(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
     function SlotKey(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
+    function SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
     function SlotMouse(Sender: QObjectH; Event: QEventH): Boolean; virtual; cdecl;
     procedure SlotNCMouse(Sender: QObjectH; Event: QEventH); cdecl;
     function SlotMouseEnter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
@@ -2480,6 +2481,13 @@
               ((LCLObject <> nil) and (LCLObject is TCustomControl));
         end;
 
+      //Dead keys (used to compose chars like "ó" by pressing 'o)  do not trigger EventKeyPress
+      //and therefore no KeyDown,Utf8KeyPress,KeyPress
+      QEventInputMethod:
+        begin
+          Result := SlotInputMethod(Sender, Event);
+        end;
+
       QEventMouseButtonPress,
       QEventMouseButtonRelease,
       QEventMouseButtonDblClick: Result := SlotMouse(Sender, Event);
@@ -3275,6 +3283,41 @@
   end;
 end;
 
+function TQtWidget.SlotInputMethod(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
+var
+  InputEvent: QInputMethodEventH;
+  WStr: WideString;
+  UnicodeChar: Cardinal;
+  UnicodeOutLen: integer;
+  KeyEvent: QKeyEventH;
+begin
+  Result := True;
+  if not (QEvent_type(Event) = QEventInputMethod) then Exit;
+  {$ifdef VerboseQt}
+    DebugLn('TQtWidget.SlotInputMethod ', dbgsname(LCLObject));
+  {$endif}
+  InputEvent := QInputMethodEventH(Event);
+  QInputMethodEvent_commitString(InputEvent, @WStr);
+  UnicodeChar := UTF8CharacterToUnicode(PChar(WStr), UnicodeOutLen);
+  {$IFDEF VerboseQtKeys}
+  writeln('> TQtWidget.SlotInputMethod ',dbgsname(LCLObject),' event=QEventInputMethod:');
+  writeln('   commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
+    ' UnicodeLen ',UnicodeOutLen);
+  writeln('   sending QEventKeyPress');
+  {$ENDIF}
+
+  KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QApplication_keyboardModifiers, @WStr, False, 1);
+  try
+    // do not send it to queue, just pass it to SlotKey
+    Result := SlotKey(Sender, KeyEvent);
+  finally
+    QKeyEvent_destroy(KeyEvent);
+  end;
+  {$IFDEF VerboseQtKeys}
+  writeln('< TQtWidget.SlotInputMethod End: ',dbgsname(LCLObject),' event=QEventInputMethod, sent QEventKeyPress');
+  {$ENDIF}
+end;
+
 {------------------------------------------------------------------------------
   Function: TQtWidget.SlotMouse
   Params:  None
@@ -15712,12 +15755,6 @@
 end;
 
 function TQtCustomControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
-var
-  InputEvent: QInputMethodEventH;
-  WStr: WideString;
-  UnicodeOutLen: Integer;
-  UnicodeChar: Cardinal;
-  KeyEvent: QKeyEventH;
 begin
   Result := False;
   QEvent_accept(Event);
@@ -15734,28 +15771,6 @@
      (ClassType = TQtCustomControl) then
     Result := False
   else
-  if QEvent_type(Event) = QEventInputMethod then
-  begin
-    InputEvent := QInputMethodEventH(Event);
-    QInputMethodEvent_commitString(InputEvent, @WStr);
-    UnicodeChar := UTF8CharacterToUnicode(PChar(WStr), UnicodeOutLen);
-    {$IFDEF VerboseQtKeys}
-    writeln('> TQtCustomControl.EventFilter event=QEventInputMethod');
-    writeln(' commmitString ',WStr,' len ',length(WStr),' UnicodeChar ',UnicodeChar,
-      ' UnicodeLen ',UnicodeOutLen);
-    {$ENDIF}
-
-    KeyEvent := QKeyEvent_create(QEventKeyPress, PtrInt(UnicodeChar), QApplication_keyboardModifiers, @WStr, False, 1);
-    try
-      // do not send it to queue, just pass it to SlotKey
-      Result := SlotKey(Sender, KeyEvent);
-    finally
-      QKeyEvent_destroy(KeyEvent);
-    end;
-    {$IFDEF VerboseQtKeys}
-    writeln('< TQtCustomControl.EventFilter event=QEventInputMethod sent QEventKeyPress');
-    {$ENDIF}
-  end else
   if QEvent_type(Event) = QEventWheel then
   begin
     if not getEnabled then
qtwidgets.diff (4,162 bytes)   

Issue History

Date Modified Username Field Change
2014-05-06 13:55 Bart Broersma New Issue
2014-05-06 13:55 Bart Broersma Status new => assigned
2014-05-06 13:55 Bart Broersma Assigned To => Bart Broersma
2014-05-06 13:55 Bart Broersma File Added: qtwidgets.diff
2014-05-06 13:59 Bart Broersma Fixed in Revision => r44930
2014-05-06 13:59 Bart Broersma Status assigned => resolved
2014-05-06 13:59 Bart Broersma Resolution open => fixed
2016-03-27 18:17 Bart Broersma Status resolved => closed