I have been investigating why TCustomEdit descendents (such as TDBDateEdit) do not appear to obey AutoSelect when selected using a mouse click. On the other hand, AutoSelect appears to work when tab is used to select the control. I am using Linux Mint 17/AMD64/GTK2 and, if you read on, the issue does seem to be with the GTK2 interface.

Investigation:

TCustomEdit appears to have two cases where AutoSelect is applied, the DoEnter and MouseUp methods and both have similar code:

DoEnter:
if (FAutoSelect and not (csLButtonDown in ControlState)) then
  begin
    SelectAll;
    if (SelText = Text) then FAutoSelected := True;
  end;

MouseUp:
if (FAutoSelect and not FAutoSelected) then
    begin
      SelectAll;
      if (SelText = Text) then FAutoSelected := True;
    end;

Note that DoEnter is not expected to call SelectAll if it occurs during a mouse click. This seems correct as otherwise FAutoSelected will be true when MouseUp is called and hence will not call SelectAll. The mouse click will override the SelectAll in DoEnter and just position the cursor.

However, running the debugger it seems that DoEnter is called before TControl.WndProc which is where the ControlState is updated to include csLButtonDown. Hence, it will fire even during a mouse click.

For this to happen, it means that CM_ENTER (and hence LM_FOCUS) occurs before LM_LBUTTONDOWN, which seems intuitively wrong. It was the mouse click that caused the focus to move to the control!

However, this does seem to be deliberate with GTK2. Line 2193 of ./lcl/interfaces/gtk/gtkcallback.inc (Lazarus 1.4RC2) contains the comment:

{always send LM_SETFOCUS first}

and true enough, this is followed by :

    if ((MessI.Msg = LM_LBUTTONDOWN) or (MessI.Msg = LM_RBUTTONDOWN) or
      (MessI.Msg = LM_MBUTTONDOWN) or (MessI.Msg = LM_LBUTTONDBLCLK)) and
      not AWinControl.Focused and AWinControl.CanFocus and
not (csDesigning in AWinControl.ComponentState) and (AWinControl is TCustomEdit) then
    begin
      ...
      LCLIntf.SetFocus(AWinControl.Handle);
     ...
    end;

    // send the message directly to the LCL
    NotifyApplicationUserInput(AWinControl, MessI.Msg);
    Result := DeliverMessage(AWinControl, MessI);


Clearly, this seems to be the cause of TCustomEdit.AutoSelect not functioning as expected, but is also deliberate. Does this solve another problem or is this a case of what seemed like a good idea at the time?



--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to