mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-18 15:09:26 +02:00
Cocoa: LCL scrolling improvements by Zoë Peterson, issue #39477:
1. Better handling of hasPreciseScrollingDeltas and SPI_GETWHEELSCROLLINES. The scrolling in LCL trunk is much too fast and imprecise. This improves the feel of things using both a mouse wheel and the touchpad. I don't like having the 15 for average line height hard coded in it, but I haven't seen any cases where it causes problems.
2. In the case where it sees a scroll in both X and Y directions, it filters it in favor of the last scroll direction. This makes vertical scrolling documents using the touchpad better, since you're less likely to inadvertently scroll horizontally.
3. Msg.WheelDelta is a SmallInt, so this caps the values to High/Low(SmallInt), rather than the underflow/overflow that occurs currently. That fixes the issue this bug report specifically is about.
(cherry picked from commit 8e10ed53af
)
This commit is contained in:
parent
0b9a2099dc
commit
5efbbc0f96
@ -1027,7 +1027,7 @@ function TCocoaWidgetSet.SystemParametersInfo(uiAction: DWord; uiParam: DWord;
|
||||
begin
|
||||
Result := True;
|
||||
case uiAction of
|
||||
SPI_GETWHEELSCROLLLINES: PDword(pvPAram)^ := 3;
|
||||
SPI_GETWHEELSCROLLLINES: PDword(pvPAram)^ := 1;
|
||||
SPI_GETWORKAREA:
|
||||
begin
|
||||
NSToLCLRect(NSScreen(NSScreen.screens.objectAtIndex(0)).visibleFrame
|
||||
|
@ -32,6 +32,7 @@ type
|
||||
FBoundsReportedToChildren: boolean;
|
||||
FIsOpaque:boolean;
|
||||
FIsEventRouting:boolean;
|
||||
FLastWheelWasHorz:boolean;
|
||||
protected
|
||||
function GetHasCaret: Boolean;
|
||||
procedure SetHasCaret(AValue: Boolean);
|
||||
@ -1182,12 +1183,8 @@ var
|
||||
MousePos: NSPoint;
|
||||
MButton: NSInteger;
|
||||
bndPt, clPt, srchPt: TPoint;
|
||||
dx,dy: double;
|
||||
isPrecise: Boolean;
|
||||
const
|
||||
WheelDeltaToLCLY = 1200; // the basic (one wheel-click) is 0.1 on cocoa
|
||||
WheelDeltaToLCLX = 1200; // the basic (one wheel-click) is 0.1 on cocoa
|
||||
LCLStep = 120;
|
||||
scrollDelta: Single;
|
||||
wheelDelta: Integer;
|
||||
begin
|
||||
Result := False; // allow cocoa to handle message
|
||||
|
||||
@ -1210,45 +1207,42 @@ begin
|
||||
Msg.Y := round(clPt.Y);
|
||||
Msg.State := CocoaModifiersToShiftState(Event.modifierFlags, NSEvent.pressedMouseButtons);
|
||||
|
||||
if NSAppKitVersionNumber >= NSAppKitVersionNumber10_7 then
|
||||
begin
|
||||
isPrecise := event.hasPreciseScrollingDeltas;
|
||||
dx := event.scrollingDeltaX;
|
||||
dy := event.scrollingDeltaY;
|
||||
end else
|
||||
begin
|
||||
isPrecise := false;
|
||||
dx := event.deltaX;
|
||||
dy := event.deltaY;
|
||||
end;
|
||||
|
||||
// Some info on event.deltaY can be found here:
|
||||
// https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/
|
||||
// It says that deltaY=1 means 1 line, and in the LCL 1 line is 120
|
||||
if dy <> 0 then
|
||||
if (event.scrollingDeltaY <> 0) and
|
||||
((event.scrollingDeltaX = 0) or not FLastWheelWasHorz) then
|
||||
begin
|
||||
Msg.Msg := LM_MOUSEWHEEL;
|
||||
if isPrecise then
|
||||
Msg.WheelDelta := Round(dy * LCLStep)
|
||||
if event.hasPreciseScrollingDeltas then
|
||||
scrollDelta := event.scrollingDeltaY / 15 // Average line height
|
||||
else
|
||||
Msg.WheelDelta := sign(dy) * LCLStep;
|
||||
scrollDelta := event.scrollingDeltaY;
|
||||
wheelDelta := round(scrollDelta * 120);
|
||||
end
|
||||
else
|
||||
if dx <> 0 then
|
||||
if event.scrollingDeltaX <> 0 then
|
||||
begin
|
||||
Msg.Msg := LM_MOUSEHWHEEL;
|
||||
// see "deltaX" documentation.
|
||||
// on macOS: -1 = right, +1 = left
|
||||
// on LCL: -1 = left, +1 = right
|
||||
if isPrecise then
|
||||
Msg.WheelDelta := Round(-dx * LCLStep)
|
||||
else
|
||||
Msg.WheelDelta := sign(-dx) * LCLStep;
|
||||
wheelDelta := round(-event.scrollingDeltaX * 120);
|
||||
end
|
||||
else
|
||||
// Filter out empty events - See bug 28491
|
||||
Exit;
|
||||
|
||||
// Filter scrolls that affect both X and Y towards whatever the last scroll was
|
||||
FLastWheelWasHorz := (Msg.Msg = LM_MOUSEHWHEEL);
|
||||
|
||||
// Avoid overflow/underflow in message
|
||||
if wheelDelta > High(SmallInt) then
|
||||
wheelDelta := High(SmallInt)
|
||||
else if wheelDelta < Low(SmallInt) then
|
||||
wheelDelta := Low(SmallInt);
|
||||
Msg.WheelDelta := wheelDelta;
|
||||
|
||||
NotifyApplicationUserInput(Target, Msg.Msg);
|
||||
Result := DeliverMessage(Msg) <> 0;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user