FIX: File panel - fix touch/pen double-tap navigation on Windows

LCL's CheckMouseButtonDownUp (controls.pp) applies a hardcoded 3px
position check on top of Windows' own WM_LBUTTONDBLCLK detection.
Touch/pen taps routinely land 4-10px apart, causing the double-click
to be silently downgraded to a single click before DC sees it; Total
Commander (native Win32) handles WM_LBUTTONDBLCLK directly without
this extra filter, so it works correctly.

Two fixes, both Windows-only (LCLWIN32 guards, zero effect on Linux):

1. Raise Mouse.DragThreshold from 5px to 10px at startup.
   Touch/pen wobble during a tap easily exceeds 5px, accidentally
   starting a drag and swallowing the click. 10 logical pixels is
   sub-millimetre for a mouse and imperceptible in practice.

2. In MainControlMouseDown, track the last left-button-down time and
   position. On a second tap that arrives within GetDoubleClickTime
   and within 10 logical pixels but without ssDouble in Shift (i.e.
   LCL rejected it), call DoMainControlFileWork directly. The guard
   gMouseSingleClickStart = 0 prevents double execution in
   single-click mode, where MouseUp already handles the open.
This commit is contained in:
heredie 2026-05-26 15:12:16 -06:00
commit d4228bab22

View file

@ -87,6 +87,12 @@ type
private
{$IFDEF LCLGTK2}
FLastDoubleClickTime : TDateTime;
{$ENDIF}
{$IFDEF LCLWIN32}
{en Last left-button-down timestamp and client position, used to detect
touch/pen double-taps that LCL's 3 px double-click threshold rejected. }
FLastTouchClickTime : QWord;
FLastTouchClickPoint: TPoint;
{$ENDIF}
FMainControl: TWinControl;
@ -513,6 +519,14 @@ begin
FHintFileIndex := -1;
{$IFDEF LCLGTK2}
FLastDoubleClickTime := Now;
{$ENDIF}
{$IFDEF LCLWIN32}
// Touch/pen input on Windows generates finger/nib wobble that easily
// exceeds the LCL default drag threshold (5px), turning simple taps into
// accidental drag operations. 10 logical pixels is still tiny for a mouse
// (sub-millimetre) but absorbs normal touch jitter at 1080p/2K/4K.
if Mouse.DragThreshold < 10 then
Mouse.DragThreshold := 10;
{$ENDIF}
FStartDrag := False;
@ -986,6 +1000,27 @@ begin
{$IF DEFINED(LCLWIN32)}
FMouseFocus:= MainControl.Focused;
SetFocus;
// Touch/pen double-tap fix: LCL's CheckMouseButtonDownUp (controls.pp)
// applies its own 3px position check on top of Windows' WM_LBUTTONDBLCLK,
// silently downgrading it to LM_LBUTTONDOWN when two taps land >3px apart
// (very common with fingers/pen). We compensate with 10 logical pixels,
// which is DPI-invariant and correct at 1080p, 2K and 4K.
// Only acts when ssDouble is absent (LCL rejected the dblclick) and we are
// in double-click mode; single-click mode already opens items on MouseUp so
// the fix is not needed there and would cause a double execution.
if (Button = mbLeft) and (not (ssDouble in Shift)) and (gMouseSingleClickStart = 0) then
begin
if (GetTickCount64 - FLastTouchClickTime <= QWord(GetDoubleClickTime)) and
(Abs(X - FLastTouchClickPoint.X) <= 10) and
(Abs(Y - FLastTouchClickPoint.Y) <= 10) then
begin
FLastTouchClickTime := 0; // consume - prevent accidental triple-fire
DoMainControlFileWork;
Exit;
end;
FLastTouchClickTime := GetTickCount64;
FLastTouchClickPoint := Classes.Point(X, Y);
end;
{$ELSEIF DEFINED(LCLCOCOA)}
FMouseFocus:= MainControl.Focused;
MainControl.Invalidate;