Input: add touchpad speed, accel, and scroll settings

See #17265; adds speed and acceleration sliders, as well as a reverse
scroll option. Tested on a Dell XPS 15. Only affects touchpad prefs,
not mouse prefs

Also, fix issues where revert button wasn't being enabled sometimes
when it should have been.

Also, switch to using a BMessage to store touchpad settings in their
file.

(a previous version of this patch added only the scroll setting)

Change-Id: I4d5ed3fadfd5bae1f7b686c904959f6e168b84a0
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8756
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: John Scipione <jscipione@gmail.com>
This commit is contained in:
PawanYr 2025-01-13 20:01:41 -05:00 committed by waddlesplash
parent 3e2f510808
commit c1b2086dfd
10 changed files with 216 additions and 74 deletions

View File

@ -18,8 +18,13 @@ typedef struct {
uint8 scroll_acceleration; // from 0 to 20
uint8 tapgesture_sensibility; // 0 : no tapgesture
// 20: very light tip is enough (default)
// 20: very light tap is enough (default)
uint16 padblocker_threshold; //0 to 100
int32 trackpad_speed;
int32 trackpad_acceleration;
bool scroll_reverse;
} touchpad_settings;
@ -32,7 +37,10 @@ const static touchpad_settings kDefaultTouchpadSettings = {
10,
10,
20,
30
30,
65536,
65536,
false
};
#define TOUCHPAD_SETTINGS_FILE "Touchpad_settings"

View File

@ -379,15 +379,22 @@ MouseDevice::_ControlThread()
BPath path;
status_t status = _GetTouchpadSettingsPath(path);
BFile settingsFile(path.Path(), B_READ_ONLY);
if (status == B_OK && settingsFile.InitCheck() == B_OK) {
if (settingsFile.Read(&settings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
BMessage settingsMsg;
status = settingsMsg.Unflatten(&settingsFile);
if (status != B_OK) {
off_t size;
settingsFile.Seek(0, SEEK_SET);
if (settingsFile.GetSize(&size) == B_OK && size == 28) {
if (settingsFile.Read(&settings, 20) != 20)
TRACE("failed to load old settings\n");
} else
TRACE("failed to load settings\n");
}
}
fTouchpadMovementMaker.SetSettings(settings);
} else
_UpdateTouchpadSettings(&settingsMsg);
fTouchpadMovementMaker.SetSpecs(touchpadSpecs);
fTouchpadMovementMaker.SetSettings(settings);
}
_UpdateSettings();
@ -461,10 +468,9 @@ MouseDevice::_ControlThread()
_UpdateTouchpadSettings(fTouchpadSettingsMessage);
delete fTouchpadSettingsMessage;
fTouchpadSettingsMessage = NULL;
} else
_UpdateSettings();
} else
_UpdateSettings();
}
}
_UpdateSettings();
}
uint32 buttons = lastButtons ^ movements.buttons;
@ -606,6 +612,7 @@ status_t
MouseDevice::_UpdateTouchpadSettings(BMessage* message)
{
touchpad_settings settings;
message->FindBool("scroll_reverse", &settings.scroll_reverse);
message->FindBool("scroll_twofinger", &settings.scroll_twofinger);
message->FindBool("scroll_twofinger_horizontal",
&settings.scroll_twofinger_horizontal);

View File

@ -80,12 +80,13 @@ void
MovementMaker::GetScrolling(uint32 posX, uint32 posY)
{
int32 stepsX = 0, stepsY = 0;
int32 directionMultiplier = fSettings.scroll_reverse ? -1 : 1;
_GetRawMovement(posX, posY);
_ComputeAcceleration(fSettings.scroll_acceleration);
if (fSettings.scroll_xstepsize > 0) {
scrolling_x += xDelta;
scrolling_x += directionMultiplier * xDelta;
stepsX = make_small(scrolling_x / fSettings.scroll_xstepsize);
@ -95,8 +96,9 @@ MovementMaker::GetScrolling(uint32 posX, uint32 posY)
scrolling_x = 0;
xDelta = 0;
}
if (fSettings.scroll_ystepsize > 0) {
scrolling_y += yDelta;
scrolling_y += directionMultiplier * yDelta;
stepsY = make_small(scrolling_y / fSettings.scroll_ystepsize);

View File

@ -75,7 +75,6 @@ class PadBlocker : public BInputServerFilter
bigtime_t _lastKeyUp; //timestamp of last B_KEY_DOWN
bigtime_t _threshold;
status_t GetSettingsPath(BPath& path);
BPoint fWindowPosition;
};
@ -102,24 +101,28 @@ PadBlocker::PadBlocker()
#endif
BPath path;
status_t status = GetSettingsPath(path);
if (status == B_OK)
{
if (status == B_OK) {
BFile settingsFile(path.Path(), B_READ_ONLY);
status = settingsFile.InitCheck();
if (status == B_OK)
{
if (settingsFile.Read(&settings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("failed to load settings\n");
status = B_ERROR;
}
if (settingsFile.Read(&fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
LOG("failed to load settings\n");
status = B_ERROR;
}
if (status == B_OK) {
BMessage settingsMsg;
status = settingsMsg.Unflatten(&settingsFile);
if (status != B_OK) {
off_t size;
settingsFile.Seek(0, SEEK_SET);
if (settingsFile.GetSize(&size) == B_OK && size == 28) {
if (settingsFile.Read(&settings, 20) != 20) {
LOG("failed to load old settings\n");
status = B_ERROR;
} else
status = B_OK;
} else {
LOG("failed to load settings\n");
status = B_ERROR;
}
} else
settingsMsg.FindInt16("padblocker_threshold",
(int16*)&settings.padblocker_threshold);
}
}

View File

@ -57,6 +57,8 @@ InputApplication::MessageReceived(BMessage* message)
case SCROLL_AREA_CHANGED:
case SCROLL_CONTROL_CHANGED:
case TAP_CONTROL_CHANGED:
case PAD_SPEED_CHANGED:
case PAD_ACCELERATION_CHANGED:
case DEFAULT_SETTINGS:
case REVERT_SETTINGS:
{

View File

@ -1,13 +1,15 @@
/*
* Copyright 2019, Haiku, Inc.
* Copyright 2019-2025, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Authors:
* Preetpal Kaur <preetpalok123@gmail.com>
* Pawan Yerramilli <me@pawanyerramilli.com>
*/
#include "InputTouchpadPref.h"
#include "InterfaceDefs.h"
#include <Entry.h>
#include <File.h>
@ -45,13 +47,16 @@ void
TouchpadPref::Revert()
{
fSettings = fStartSettings;
set_mouse_speed(fTouchPad->Name(), fSettings.trackpad_speed);
set_mouse_acceleration(fTouchPad->Name(), fSettings.trackpad_acceleration);
}
status_t
TouchpadPref::UpdateSettings()
BMessage
TouchpadPref::BuildSettingsMessage()
{
BMessage msg;
msg.AddBool("scroll_reverse", fSettings.scroll_reverse);
msg.AddBool("scroll_twofinger", fSettings.scroll_twofinger);
msg.AddBool(
"scroll_twofinger_horizontal", fSettings.scroll_twofinger_horizontal);
@ -61,16 +66,27 @@ TouchpadPref::UpdateSettings()
msg.AddInt16("scroll_ystepsize", fSettings.scroll_ystepsize);
msg.AddInt8("scroll_acceleration", fSettings.scroll_acceleration);
msg.AddInt8("tapgesture_sensibility", fSettings.tapgesture_sensibility);
msg.AddInt32("padblocker_threshold", fSettings.padblocker_threshold);
msg.AddInt16("padblocker_threshold", fSettings.padblocker_threshold);
msg.AddInt32("trackpad_speed", fSettings.trackpad_speed);
msg.AddInt32("trackpad_acceleration", fSettings.trackpad_acceleration);
return fTouchPad->Control(B_SET_TOUCHPAD_SETTINGS, &msg);
return msg;
}
status_t
TouchpadPref::UpdateRunningSettings()
{
BMessage msg = BuildSettingsMessage();
return fTouchPad->Control(B_SET_TOUCHPAD_SETTINGS, &msg);
}
void
TouchpadPref::Defaults()
{
fSettings = kDefaultTouchpadSettings;
set_mouse_speed(fTouchPad->Name(), fSettings.trackpad_speed);
set_mouse_acceleration(fTouchPad->Name(), fSettings.trackpad_acceleration);
}
@ -98,16 +114,42 @@ TouchpadPref::LoadSettings()
if (status != B_OK)
return status;
if (settingsFile.Read(&fSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("failed to load settings\n");
return B_ERROR;
BMessage settingsMsg;
status = settingsMsg.Unflatten(&settingsFile);
// Load an old settings file if we have that instead; remove after Beta 6?
if (status != B_OK) {
off_t size;
settingsFile.Seek(0, SEEK_SET);
// Old settings were 20 bytes, BPoint added 8
if (settingsFile.GetSize(&size) == B_OK && size == 28) {
if (settingsFile.Read(&fSettings, 20) != 20) {
LOG("failed to load old settings\n");
return B_ERROR;
} else {
fSettings.scroll_reverse = kDefaultTouchpadSettings.scroll_reverse;
fSettings.trackpad_speed = kDefaultTouchpadSettings.trackpad_speed;
fSettings.trackpad_acceleration = kDefaultTouchpadSettings.trackpad_acceleration;
return B_OK;
}
} else {
LOG("failed to load settings\n");
return B_ERROR;
}
}
if (settingsFile.Read(&fWindowPosition, sizeof(BPoint)) != sizeof(BPoint)) {
LOG("failed to load settings\n");
return B_ERROR;
}
settingsMsg.FindBool("scroll_reverse", &fSettings.scroll_reverse);
settingsMsg.FindBool("scroll_twofinger", &fSettings.scroll_twofinger);
settingsMsg.FindBool("scroll_twofinger_horizontal", &fSettings.scroll_twofinger_horizontal);
settingsMsg.FindFloat("scroll_rightrange", &fSettings.scroll_rightrange);
settingsMsg.FindFloat("scroll_bottomrange", &fSettings.scroll_bottomrange);
settingsMsg.FindInt16("scroll_xstepsize", (int16*)&fSettings.scroll_xstepsize);
settingsMsg.FindInt16("scroll_ystepsize", (int16*)&fSettings.scroll_ystepsize);
settingsMsg.FindInt8("scroll_acceleration", (int8*)&fSettings.scroll_acceleration);
settingsMsg.FindInt8("tapgesture_sensibility", (int8*)&fSettings.tapgesture_sensibility);
settingsMsg.FindInt16("padblocker_threshold", (int16*)&fSettings.padblocker_threshold);
settingsMsg.FindInt32("trackpad_speed", &fSettings.trackpad_speed);
settingsMsg.FindInt32("trackpad_acceleration", &fSettings.trackpad_acceleration);
settingsMsg.FindPoint("window_position", &fWindowPosition);
return B_OK;
}
@ -126,17 +168,36 @@ TouchpadPref::SaveSettings()
if (status != B_OK)
return status;
if (settingsFile.Write(&fSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("can't save settings\n");
return B_ERROR;
}
BMessage settingsMsg = BuildSettingsMessage();
settingsMsg.AddPoint("window_position", fWindowPosition);
if (settingsFile.Write(&fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
LOG("can't save window position\n");
return B_ERROR;
status = settingsMsg.Flatten(&settingsFile);
if (status != B_OK) {
LOG("can't save settings\n");
return status;
}
return B_OK;
}
void
TouchpadPref::SetSpeed(int32 speed)
{
int32 value = (int32)pow(2, speed * 6.0 / 1000) * 8192;
// slow = 8192, fast = 524287; taken from InputMouse.cpp
if (set_mouse_speed(fTouchPad->Name(), value) == B_OK) {
fSettings.trackpad_speed = value;
UpdateRunningSettings();
}
}
void
TouchpadPref::SetAcceleration(int32 accel)
{
int32 value = (int32)pow(accel * 4.0 / 1000, 2) * 16384;
// slow = 0, fast = 262144; taken from InputMouse.cpp
if (set_mouse_acceleration(fTouchPad->Name(), value) == B_OK) {
fSettings.trackpad_acceleration = value;
UpdateRunningSettings();
}
}

View File

@ -40,11 +40,16 @@ public:
touchpad_settings& Settings()
{ return fSettings; }
status_t UpdateSettings();
BMessage BuildSettingsMessage();
status_t LoadSettings();
status_t UpdateRunningSettings();
void SetSpeed(int32 value);
void SetAcceleration(int32 value);
private:
status_t GetSettingsPath(BPath& path);
status_t LoadSettings();
status_t SaveSettings();
BInputDevice* fTouchPad;

View File

@ -1,9 +1,10 @@
/*
* Copyright 2019, Haiku, Inc.
* Copyright 2019-2025, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Authors:
* Preetpal Kaur <preetpalok123@gmail.com>
* Pawan Yerramilli <me@pawanyerramilli.com>
*/
@ -287,10 +288,12 @@ TouchpadPrefView::MessageReceived(BMessage* message)
case SCROLL_AREA_CHANGED:
settings.scroll_rightrange = fTouchpadView->GetRightScrollRatio();
settings.scroll_bottomrange = fTouchpadView->GetBottomScrollRatio();
fTouchpadPref.UpdateSettings();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateRunningSettings();
break;
case SCROLL_CONTROL_CHANGED:
settings.scroll_reverse = fScrollReverseBox->Value() == B_CONTROL_ON;
settings.scroll_twofinger = fTwoFingerBox->Value() == B_CONTROL_ON;
settings.scroll_twofinger_horizontal
= fTwoFingerHorizontalBox->Value() == B_CONTROL_ON;
@ -298,12 +301,14 @@ TouchpadPrefView::MessageReceived(BMessage* message)
settings.scroll_xstepsize = (20 - fScrollStepXSlider->Value()) * 3;
settings.scroll_ystepsize = (20 - fScrollStepYSlider->Value()) * 3;
fTwoFingerHorizontalBox->SetEnabled(settings.scroll_twofinger);
fTouchpadPref.UpdateSettings();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateRunningSettings();
break;
case TAP_CONTROL_CHANGED:
settings.tapgesture_sensibility = fTapSlider->Value();
fTouchpadPref.UpdateSettings();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateRunningSettings();
break;
case PADBLOCK_TIME_CHANGED:
@ -313,19 +318,31 @@ TouchpadPrefView::MessageReceived(BMessage* message)
if (settings.padblocker_threshold == 1000)
settings.padblocker_threshold = 0;
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateSettings();
fTouchpadPref.UpdateRunningSettings();
break;
case PAD_SPEED_CHANGED:
{
fTouchpadPref.SetSpeed(fSpeedSlider->Value());
fRevertButton->SetEnabled(true);
break;
}
case PAD_ACCELERATION_CHANGED:
{
fTouchpadPref.SetAcceleration(fAccelSlider->Value());
fRevertButton->SetEnabled(true);
break;
}
case DEFAULT_SETTINGS:
fTouchpadPref.Defaults();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateSettings();
fTouchpadPref.UpdateRunningSettings();
SetValues(&settings);
break;
case REVERT_SETTINGS:
fTouchpadPref.Revert();
fTouchpadPref.UpdateSettings();
fTouchpadPref.UpdateRunningSettings();
fRevertButton->SetEnabled(false);
SetValues(&settings);
break;
@ -340,6 +357,7 @@ void
TouchpadPrefView::AttachedToWindow()
{
fTouchpadView->SetTarget(this);
fScrollReverseBox->SetTarget(this);
fTwoFingerBox->SetTarget(this);
fTwoFingerHorizontalBox->SetTarget(this);
fScrollStepXSlider->SetTarget(this);
@ -347,6 +365,8 @@ TouchpadPrefView::AttachedToWindow()
fScrollAccelSlider->SetTarget(this);
fPadBlockerSlider->SetTarget(this);
fTapSlider->SetTarget(this);
fSpeedSlider->SetTarget(this);
fAccelSlider->SetTarget(this);
fDefaultButton->SetTarget(this);
fRevertButton->SetTarget(this);
BSize size = PreferredSize();
@ -379,14 +399,14 @@ TouchpadPrefView::SetupView()
fTouchpadView = new TouchpadView(BRect(0, 0, 130, 120));
fTouchpadView->SetExplicitMaxSize(BSize(130, 120));
// Create the "Mouse Speed" slider...
// Create the scrolling acceleration slider...
fScrollAccelSlider = new BSlider("scroll_accel",
B_TRANSLATE("Acceleration"),
new BMessage(SCROLL_CONTROL_CHANGED), 0, 20, B_HORIZONTAL);
fScrollAccelSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fScrollAccelSlider->SetHashMarkCount(7);
fScrollAccelSlider->SetLimitLabels(
B_TRANSLATE("Slow"), B_TRANSLATE("Fast"));
B_TRANSLATE("Low"), B_TRANSLATE("High"));
fScrollAccelSlider->SetExplicitMinSize(BSize(150, B_SIZE_UNSET));
fScrollStepXSlider = new BSlider("scroll_stepX", B_TRANSLATE("Horizontal"),
@ -411,6 +431,8 @@ TouchpadPrefView::SetupView()
fPadBlockerSlider->SetLimitLabels(
B_TRANSLATE("Quick"), B_TRANSLATE("Never"));
fScrollReverseBox = new BCheckBox(B_TRANSLATE("Reverse scroll direction"),
new BMessage(SCROLL_CONTROL_CHANGED));
fTwoFingerBox = new BCheckBox(B_TRANSLATE("Two finger scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED));
fTwoFingerHorizontalBox = new BCheckBox(B_TRANSLATE("Horizontal scrolling"),
@ -422,6 +444,7 @@ TouchpadPrefView::SetupView()
= BLayoutBuilder::Group<>(B_VERTICAL, 0)
.Add(fTouchpadView)
.AddStrut(spacing)
.Add(fScrollReverseBox)
.Add(fTwoFingerBox)
.AddGroup(B_HORIZONTAL, 0)
.AddStrut(spacing * 2)
@ -452,6 +475,18 @@ TouchpadPrefView::SetupView()
fTapSlider->SetHashMarkCount(7);
fTapSlider->SetLimitLabels(B_TRANSLATE("Off"), B_TRANSLATE("High"));
fSpeedSlider = new BSlider("pad_speed", B_TRANSLATE("Trackpad speed"),
new BMessage(PAD_SPEED_CHANGED), 0, 1000, B_HORIZONTAL);
fSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fSpeedSlider->SetHashMarkCount(7);
fSpeedSlider->SetLimitLabels(B_TRANSLATE("Slow"), B_TRANSLATE("Fast"));
fAccelSlider = new BSlider("pad_accel", B_TRANSLATE("Trackpad acceleration"),
new BMessage(PAD_ACCELERATION_CHANGED), 0, 1000, B_HORIZONTAL);
fAccelSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fAccelSlider->SetHashMarkCount(7);
fAccelSlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High"));
fDefaultButton
= new BButton(B_TRANSLATE("Defaults"), new BMessage(DEFAULT_SETTINGS));
@ -463,25 +498,33 @@ TouchpadPrefView::SetupView()
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_WINDOW_SPACING)
.Add(scrollBox)
.Add(fTapSlider)
.Add(fPadBlockerSlider)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(fTapSlider)
.Add(fPadBlockerSlider)
.End()
.Add(new BSeparatorView(B_VERTICAL))
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(fSpeedSlider)
.Add(fAccelSlider)
.End()
.End()
.Add(new BSeparatorView(B_HORIZONTAL))
.AddGroup(B_HORIZONTAL)
.Add(fDefaultButton)
.Add(fRevertButton)
.AddGlue()
.End()
.End();
.End()
.End();
}
void
TouchpadPrefView::SetValues(touchpad_settings* settings)
{
fTouchpadView->SetValues(
settings->scroll_rightrange, settings->scroll_bottomrange);
fTwoFingerBox->SetValue(
settings->scroll_twofinger ? B_CONTROL_ON : B_CONTROL_OFF);
fTouchpadView->SetValues(settings->scroll_rightrange, settings->scroll_bottomrange);
fScrollReverseBox->SetValue(settings->scroll_reverse ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerBox->SetValue(settings->scroll_twofinger ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerHorizontalBox->SetValue(
settings->scroll_twofinger_horizontal ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerHorizontalBox->SetEnabled(settings->scroll_twofinger);
@ -490,4 +533,8 @@ TouchpadPrefView::SetValues(touchpad_settings* settings)
fScrollAccelSlider->SetValue(settings->scroll_acceleration);
fTapSlider->SetValue(settings->tapgesture_sensibility);
fPadBlockerSlider->SetValue(settings->padblocker_threshold);
int32 value = int32((log(settings->trackpad_speed / 8192.0) / log(2)) * 1000 / 6);
fSpeedSlider->SetValue(value);
value = int32(sqrt(settings->trackpad_acceleration / 16384.0) * 1000 / 4);
fAccelSlider->SetValue(value);
}

View File

@ -36,6 +36,8 @@ const uint TAP_CONTROL_CHANGED = '&tcc';
const uint DEFAULT_SETTINGS = '&dse';
const uint REVERT_SETTINGS = '&rse';
const uint PADBLOCK_TIME_CHANGED = '&ptc';
const uint PAD_SPEED_CHANGED = '&psc';
const uint PAD_ACCELERATION_CHANGED = '&pac';
class DeviceListView;
@ -92,6 +94,7 @@ public:
private:
TouchpadPref fTouchpadPref;
TouchpadView* fTouchpadView;
BCheckBox* fScrollReverseBox;
BCheckBox* fTwoFingerBox;
BCheckBox* fTwoFingerHorizontalBox;
BSlider* fScrollStepXSlider;
@ -99,6 +102,8 @@ private:
BSlider* fScrollAccelSlider;
BSlider* fPadBlockerSlider;
BSlider* fTapSlider;
BSlider* fSpeedSlider;
BSlider* fAccelSlider;
BButton* fDefaultButton;
BButton* fRevertButton;
};

View File

@ -87,6 +87,8 @@ InputWindow::MessageReceived(BMessage* message)
case SCROLL_AREA_CHANGED:
case SCROLL_CONTROL_CHANGED:
case TAP_CONTROL_CHANGED:
case PAD_SPEED_CHANGED:
case PAD_ACCELERATION_CHANGED:
case DEFAULT_SETTINGS:
case REVERT_SETTINGS:
{