input: Implement two-fingers natural scrolling (enabled by default)

input touchpad settings header:
- Implement two-fingers natural scrolling (enabled by default)
- Sets scrolling with 2 fingers on the touchpad making
  the content to move in the same direction as the finger.

input preflet:
- Implement 2 fingers natural scrolling

input mouse:
- Handle and provide new settings for 2 finger natural scrolling

input mouse mm:
- Implement two-finger natural scrolling feature
- Implement natural scrolling for two-finger scrolling completely
  separated from reverse scrolling for egde scrolling only.

Change-Id: Idf673ec34a424b20183ed90761f297340d521526
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9919
Reviewed-by: Adrien Destugues <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Samuel Rodríguez Pérez
2026-01-02 11:01:29 +00:00
committed by Adrien Destugues
parent f7598f6461
commit 6d4c0985d4
7 changed files with 39 additions and 12 deletions
+4 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2009, Haiku, Inc. All Rights Reserved. * Copyright 2001-2025, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef TOUCHPAD_SETTINGS_H #ifndef TOUCHPAD_SETTINGS_H
@@ -25,6 +25,7 @@ typedef struct {
int32 trackpad_acceleration; int32 trackpad_acceleration;
bool scroll_reverse; bool scroll_reverse;
bool scroll_twofinger_natural_scrolling;
} touchpad_settings; } touchpad_settings;
@@ -40,7 +41,8 @@ const static touchpad_settings kDefaultTouchpadSettings = {
30, 30,
65536, 65536,
65536, 65536,
false false,
true
}; };
#define TOUCHPAD_SETTINGS_FILE "Touchpad_settings" #define TOUCHPAD_SETTINGS_FILE "Touchpad_settings"
@@ -604,6 +604,9 @@ MouseDevice::_UpdateTouchpadSettings(BMessage* message)
message->FindInt8("tapgesture_sensibility", message->FindInt8("tapgesture_sensibility",
(int8*)&settings.tapgesture_sensibility); (int8*)&settings.tapgesture_sensibility);
message->FindBool("scroll_twofinger_natural_scrolling",
&settings.scroll_twofinger_natural_scrolling);
if (fIsTouchpad) if (fIsTouchpad)
fTouchpadMovementMaker.SetSettings(settings); fTouchpadMovementMaker.SetSettings(settings);
@@ -158,12 +158,12 @@ MovementMaker::GetMovement(uint32 posX, uint32 posY)
void void
MovementMaker::GetScrolling(uint32 posX, uint32 posY) MovementMaker::GetScrolling(uint32 posX, uint32 posY, bool reverse)
{ {
CALLED(); CALLED();
int32 stepsX = 0, stepsY = 0; int32 stepsX = 0, stepsY = 0;
int32 directionMultiplier = fSettings.scroll_reverse ? -1 : 1; int32 directionMultiplier = reverse ? -1 : 1;
_GetRawMovement(posX, posY); _GetRawMovement(posX, posY);
_ComputeAcceleration(fSettings.scroll_acceleration); _ComputeAcceleration(fSettings.scroll_acceleration);
@@ -619,8 +619,9 @@ TouchpadMovement::_CheckScrollingToMovement(const touchpad_movement *event,
|| fSettings.scroll_bottomrange > 0.999999) { || fSettings.scroll_bottomrange > 0.999999) {
isSideScrollingH = true; isSideScrollingH = true;
} }
if (two_fingers(event) bool isTwoFingerScrolling = two_fingers(event)
&& fSettings.scroll_twofinger) { && fSettings.scroll_twofinger;
if (isTwoFingerScrolling) {
// two finger scrolling is enabled // two finger scrolling is enabled
isSideScrollingV = true; isSideScrollingV = true;
isSideScrollingH = fSettings.scroll_twofinger_horizontal; isSideScrollingH = fSettings.scroll_twofinger_horizontal;
@@ -641,7 +642,9 @@ TouchpadMovement::_CheckScrollingToMovement(const touchpad_movement *event,
fScrollingStarted = true; fScrollingStarted = true;
StartNewMovment(); StartNewMovment();
} }
GetScrolling(event->xPosition, event->yPosition); GetScrolling(event->xPosition, event->yPosition, isTwoFingerScrolling
? fSettings.scroll_twofinger_natural_scrolling
: fSettings.scroll_reverse);
movement->wheel_ydelta = make_small(yDelta); movement->wheel_ydelta = make_small(yDelta);
movement->wheel_xdelta = make_small(xDelta); movement->wheel_xdelta = make_small(xDelta);
@@ -26,7 +26,7 @@ public:
protected: protected:
void StartNewMovment(); void StartNewMovment();
void GetMovement(uint32 posX, uint32 posY); void GetMovement(uint32 posX, uint32 posY);
void GetScrolling(uint32 posX, uint32 posY); void GetScrolling(uint32 posX, uint32 posY, bool reverse);
touchpad_specs fSpecs; touchpad_specs fSpecs;
touchpad_settings fSettings; touchpad_settings fSettings;
+6 -1
View File
@@ -70,6 +70,7 @@ TouchpadPref::BuildSettingsMessage()
msg.AddInt16("padblocker_threshold", fSettings.padblocker_threshold); msg.AddInt16("padblocker_threshold", fSettings.padblocker_threshold);
msg.AddInt32("trackpad_speed", fSettings.trackpad_speed); msg.AddInt32("trackpad_speed", fSettings.trackpad_speed);
msg.AddInt32("trackpad_acceleration", fSettings.trackpad_acceleration); msg.AddInt32("trackpad_acceleration", fSettings.trackpad_acceleration);
msg.AddBool("scroll_twofinger_natural_scrolling", fSettings.scroll_twofinger_natural_scrolling);
return msg; return msg;
} }
@@ -152,6 +153,10 @@ TouchpadPref::LoadSettings()
settingsMsg.FindInt32("trackpad_acceleration", &fSettings.trackpad_acceleration); settingsMsg.FindInt32("trackpad_acceleration", &fSettings.trackpad_acceleration);
settingsMsg.FindPoint("window_position", &fWindowPosition); settingsMsg.FindPoint("window_position", &fWindowPosition);
fSettings.scroll_twofinger_natural_scrolling = settingsMsg.GetBool(
"scroll_twofinger_natural_scrolling",
kDefaultTouchpadSettings.scroll_twofinger_natural_scrolling);
return B_OK; return B_OK;
} }
@@ -201,4 +206,4 @@ TouchpadPref::SetAcceleration(int32 accel)
fSettings.trackpad_acceleration = value; fSettings.trackpad_acceleration = value;
UpdateRunningSettings(); UpdateRunningSettings();
} }
} }
@@ -298,10 +298,13 @@ TouchpadPrefView::MessageReceived(BMessage* message)
settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON; settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON;
settings.scroll_twofinger_horizontal settings.scroll_twofinger_horizontal
= fTwoFingerHorizontalBox->Value() == B_CONTROL_ON; = fTwoFingerHorizontalBox->Value() == B_CONTROL_ON;
settings.scroll_twofinger_natural_scrolling
= fTwoFingerNaturalScrollingBox->Value() == B_CONTROL_ON;
settings.scroll_acceleration = fScrollAccelSlider->Value(); settings.scroll_acceleration = fScrollAccelSlider->Value();
settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3; settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3;
settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3; settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3;
fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger); fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger);
fTwoFingerNaturalScrollingBox->SetEnabled(settings.scroll_twofinger);
fRevertButton->SetEnabled(true); fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateRunningSettings(); fTouchpadPref.UpdateRunningSettings();
break; break;
@@ -361,15 +364,19 @@ TouchpadPrefView::AttachedToWindow()
fScrollReverseBox->SetTarget(this); fScrollReverseBox->SetTarget(this);
fTwoFingerBox->SetTarget(this); fTwoFingerBox->SetTarget(this);
fTwoFingerHorizontalBox->SetTarget(this); fTwoFingerHorizontalBox->SetTarget(this);
fTwoFingerNaturalScrollingBox->SetTarget(this);
fScrollStepXSlider->SetTarget(this); fScrollStepXSlider->SetTarget(this);
fScrollStepYSlider->SetTarget(this); fScrollStepYSlider->SetTarget(this);
fScrollAccelSlider->SetTarget(this); fScrollAccelSlider->SetTarget(this);
fPadBlockerSlider->SetTarget(this); fPadBlockerSlider->SetTarget(this);
fTapSlider->SetTarget(this); fTapSlider->SetTarget(this);
fSpeedSlider->SetTarget(this); fSpeedSlider->SetTarget(this);
fAccelSlider->SetTarget(this); fAccelSlider->SetTarget(this);
fDefaultButton->SetTarget(this); fDefaultButton->SetTarget(this);
fRevertButton->SetTarget(this); fRevertButton->SetTarget(this);
BSize size = PreferredSize(); BSize size = PreferredSize();
Window()->ResizeTo(size.width, size.height); Window()->ResizeTo(size.width, size.height);
@@ -438,6 +445,8 @@ TouchpadPrefView::SetupView()
new BMessage(SCROLL_CONTROL_CHANGED)); new BMessage(SCROLL_CONTROL_CHANGED));
fTwoFingerHorizontalBox = new BCheckBox(B_TRANSLATE("Horizontal scrolling"), fTwoFingerHorizontalBox = new BCheckBox(B_TRANSLATE("Horizontal scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED)); new BMessage(SCROLL_CONTROL_CHANGED));
fTwoFingerNaturalScrollingBox = new BCheckBox(B_TRANSLATE("Natural scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED));
float spacing = be_control_look->DefaultItemSpacing(); float spacing = be_control_look->DefaultItemSpacing();
@@ -447,10 +456,11 @@ TouchpadPrefView::SetupView()
.AddStrut(spacing) .AddStrut(spacing)
.Add(fScrollReverseBox) .Add(fScrollReverseBox)
.Add(fTwoFingerBox) .Add(fTwoFingerBox)
.AddGroup(B_HORIZONTAL, 0) .AddGroup(B_VERTICAL, 0)
.AddStrut(spacing * 2) .SetInsets(spacing * 2, 0, 0, 0)
.Add(fTwoFingerHorizontalBox) .Add(fTwoFingerHorizontalBox)
.End() .Add(fTwoFingerNaturalScrollingBox)
.End()
.AddGlue() .AddGlue()
.View(); .View();
@@ -529,6 +539,9 @@ TouchpadPrefView::SetValues(touchpad_settings* settings)
fTwoFingerHorizontalBox->SetValue( fTwoFingerHorizontalBox->SetValue(
settings->scroll_twofinger_horizontal ? B_CONTROL_ON : B_CONTROL_OFF); settings->scroll_twofinger_horizontal ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger); fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger);
fTwoFingerNaturalScrollingBox->SetValue(
settings->scroll_twofinger_natural_scrolling ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerNaturalScrollingBox->SetEnabled(settings->scroll_twofinger);
fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2); fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2);
fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2); fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2);
fScrollAccelSlider->SetValue(settings->scroll_acceleration); fScrollAccelSlider->SetValue(settings->scroll_acceleration);
@@ -98,6 +98,7 @@ private:
BCheckBox* fScrollReverseBox; BCheckBox* fScrollReverseBox;
BCheckBox* fTwoFingerBox; BCheckBox* fTwoFingerBox;
BCheckBox* fTwoFingerHorizontalBox; BCheckBox* fTwoFingerHorizontalBox;
BCheckBox* fTwoFingerNaturalScrollingBox;
BSlider* fScrollStepXSlider; BSlider* fScrollStepXSlider;
BSlider* fScrollStepYSlider; BSlider* fScrollStepYSlider;
BSlider* fScrollAccelSlider; BSlider* fScrollAccelSlider;