View Issue Details

IDProjectCategoryView StatusLast Update
0035942LazarusLCLpublic2019-08-14 14:13
ReporterAnthony WalterAssigned ToJuha Manninen 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionno change required 
PlatformGtk2OSUbuntuOS Version16.04
Product Version2.0.4Product Build 
Target VersionFixed in Version 
Summary0035942: Arrow keys don't work correctly with Gtk2 (and Gtk3?) and custom controls
DescriptionIf you write a control that requires processing of the arrow keys in Gtk2 (and also likely Gtk3) the Gtk system may change the input focus of your control instead of allowing it to process arrow key presses.

This bug will present itself only in controls that do not have scroll bars.

See this example video (bug description are 3:00): https://cache.getlazarus.org/videos/scrabble.mp4
Steps To ReproduceCreate a custom control, add the following code:

// interface
    procedure WMGetDlgCode(var Msg: TLMNoParams); message LM_GETDLGCODE;

// implementation
procedure TYourControl.WMGetDlgCode(var Msg: TLMNoParams);
begin
  Msg.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;

Add an edit box to the form and align to top.
Add TYourControl and align to client.
Click you control to set the input focus.
Press left, right, down, then up.
When up is pressed, instead of your control handling the up key, Gtk will see the edit box above your control and change the focus to the edit control.

What should happen is that you control handles all arrow key events without losing input focus.

Note: This bug will not present itself if the control has scrollbars, hence it's not a problem for the grid controls in Lazarus, but it is for any control in Lazarus with gtk2 that wants to handle the arrow keys and does not have scroll bars.
Additional InformationSee this discussion about the problem: https://mail.gnome.org/archives/gtk-list/1999-May/msg00663.html

My small fix is yet another band aid on an already terrible LCL callback. Really this entire thing should be redesigned to not patch every control in one main Gtk signal handler:

in gtk2proc.inc procedure EmulateEatenKeys add this to the end for a fix:

    if (
        GtkWidgetIsA(TargetWidget, gtk_type_entry) or
        GtkWidgetIsA(TargetWidget, gtk_type_text_view) or
        GtkWidgetIsA(TargetWidget, gtk_type_tree_view)
       )
       and
      (gdk_event_get_type(AEvent) = GDK_KEY_PRESS) and
      ((VKey = VK_RETURN) or (VKey = VK_TAB)) then
    begin
      // DebugLn(['EmulateKeysEatenByGtk ']);
      FillChar(Msg, SizeOf(Msg), 0);
      Msg.CharCode := VKey;
      if SysKey then
        Msg.msg := LM_SYSKEYDOWN
      else
        Msg.msg := LM_KEYDOWN;
      Msg.KeyData := CommonKeyData or (Flags shl 16) or $0001 {TODO: repeatcount};

      // send the (Sys)KeyDown message directly to the LCL
      NotifyApplicationUserInput(TControl(TargetObj), Msg.Msg);
      DeliverKeyMessage(TargetObj, Msg);
    end;
    // fix arrow keys start
    if VKey in [VK_LEFT..VK_DOWN] then
    begin
      Msg.Msg := LM_GETDLGCODE;
      TObject(TargetObj).Dispatch(Msg);
      EventStopped := Msg.Result and DLGC_WANTARROWS = DLGC_WANTARROWS;
    end;
    // fix arrow keys end
  end;
TagsNo tags attached.
Fixed in Revision
LazTarget-
WidgetsetGTK 2
Attached Files

Activities

Juha Manninen

2019-08-11 11:29

developer   ~0117640

How about using the events OnKeyPress, OnKeyDown and OnKeyUp, or overriding the related virtual methods KeyPress, KeyDown and KeyUp which are defined in TWinControl?
They are compatible with Delphi VCL which clearly was designed to be cross-platform from the beginning, although it didn't happen until Kylix and CLX.
The simulated Windows messages that you use will always be a challenge in a cross-platform component.

Anthony Walter

2019-08-13 19:33

reporter   ~0117662

Per your suggestion I tested a fix. It seems that overriding KeyDown methods inside a control and setting "Key := 0" if an arrow key is pressed prevents the underlying OS system from changing the focus. Tested on Linux Gtk and Windows as workable. Please close this issue and thank you for the suggestion.

Juha Manninen

2019-08-14 14:13

developer   ~0117670

Ok, resolving. Thanks.

Issue History

Date Modified Username Field Change
2019-08-09 09:25 Anthony Walter New Issue
2019-08-11 11:29 Juha Manninen Assigned To => Juha Manninen
2019-08-11 11:29 Juha Manninen Status new => feedback
2019-08-11 11:29 Juha Manninen LazTarget => -
2019-08-11 11:29 Juha Manninen Note Added: 0117640
2019-08-13 19:33 Anthony Walter Note Added: 0117662
2019-08-13 19:33 Anthony Walter Status feedback => assigned
2019-08-14 14:13 Juha Manninen Status assigned => resolved
2019-08-14 14:13 Juha Manninen Resolution open => no change required
2019-08-14 14:13 Juha Manninen Widgetset GTK 2 => GTK 2
2019-08-14 14:13 Juha Manninen Note Added: 0117670