input: Implement edge motion (enabled by default on tap drag)

input headers:
- Add edge motion constants

input touchpad settings header:
- Edge motion (enabled by default as on tap drag)
- Help moving the cursor and the primary finger transitions
  from one place of the touchpad to its edge and then stays
  on the edge for some time.
  The default matches the current hardcoded behaviour.

input preflet:
- Implement edge motion options

input mouse:
- Handle and provide new setting for edge motion

input mouse mm:
- Enable edge motion on tap drag based on settings instead of being hardcoded
- Some users who didn't have a chance to read the users' documentation could
  wrognly believe that this feature is a bug by not understanting why
  unexpected cursor movement happen at constant speed on some scenarios
  sometimes not even realising that it happens when the finger is approaching
  to the edges of the touch area by mistake.

  At least, even if this is the current default setting at the moment, this
  enables the chance to change it instead of being a obscure hardcoded feature.

input mouse mm:
- Enhance edge motion with extra behaviours
- Support for other edge motion aids apart from "on tap drag only".

Change-Id: Ice50139f9f8001494f7e2a46bb1521a1e525cade
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9921
Reviewed-by: Adrien Destugues <[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 6d4c0985d4
commit 696c694dbb
7 changed files with 61 additions and 3 deletions
@@ -128,6 +128,13 @@ typedef struct {
#define B_PEN 0x08
#define B_EDGE_MOTION_DISABLED 0x00
#define B_EDGE_MOTION_ON_MOVE 0x01
#define B_EDGE_MOTION_ON_TAP_DRAG 0x02
#define B_EDGE_MOTION_ON_BUTTON_CLICK_MOVE 0x04
#define B_EDGE_MOTION_ON_BUTTON_CLICK_DRAG 0x08
typedef struct {
uint16 edgeMotionWidth;
+9 -1
View File
@@ -26,6 +26,13 @@ typedef struct {
bool scroll_reverse;
bool scroll_twofinger_natural_scrolling;
uint8 edge_motion; // 0: disabled
// or combined flags of:
// 0x01: edge motion on move
// 0x02: edge motion on tap drag
// 0x04: edge motion on button click move
// 0x08: edge motion on button click drag
} touchpad_settings;
@@ -42,7 +49,8 @@ const static touchpad_settings kDefaultTouchpadSettings = {
65536,
65536,
false,
true
true,
0x02
};
#define TOUCHPAD_SETTINGS_FILE "Touchpad_settings"
@@ -606,6 +606,8 @@ MouseDevice::_UpdateTouchpadSettings(BMessage* message)
message->FindBool("scroll_twofinger_natural_scrolling",
&settings.scroll_twofinger_natural_scrolling);
message->FindInt8("edge_motion",
(int8*)&settings.edge_motion);
if (fIsTouchpad)
fTouchpadMovementMaker.SetSettings(settings);
@@ -366,7 +366,9 @@ TouchpadMovement::EventToMovement(const touchpad_movement* event, mouse_movement
fTapClicks = 0;
fTapdragStarted = false;
fTapStarted = false;
fValidEdgeMotion = false;
if ((fSettings.edge_motion
& (B_EDGE_MOTION_ON_BUTTON_CLICK_MOVE | B_EDGE_MOTION_ON_BUTTON_CLICK_DRAG)) != 0)
fValidEdgeMotion = false;
}
if (event->zPressure >= fSpecs.minPressure
@@ -563,9 +565,14 @@ TouchpadMovement::_MoveToMovement(const touchpad_movement *event, mouse_movement
movement->buttons = kLeftButton;
movement->clicks = 0;
fValidEdgeMotion = _EdgeMotion(event, movement, fValidEdgeMotion);
if (fSettings.edge_motion & B_EDGE_MOTION_ON_TAP_DRAG
|| (event->buttons && (fSettings.edge_motion & B_EDGE_MOTION_ON_BUTTON_CLICK_DRAG)))
fValidEdgeMotion = _EdgeMotion(event, movement, fValidEdgeMotion);
TRACE("TouchpadMovement: tap drag\n");
} else {
if (fSettings.edge_motion & B_EDGE_MOTION_ON_MOVE
|| (event->buttons && (fSettings.edge_motion & B_EDGE_MOTION_ON_BUTTON_CLICK_MOVE)))
fValidEdgeMotion = _EdgeMotion(event, movement, fValidEdgeMotion);
TRACE("TouchpadMovement: movement set buttons\n");
movement->buttons = event->buttons;
}
@@ -71,6 +71,7 @@ TouchpadPref::BuildSettingsMessage()
msg.AddInt32("trackpad_speed", fSettings.trackpad_speed);
msg.AddInt32("trackpad_acceleration", fSettings.trackpad_acceleration);
msg.AddBool("scroll_twofinger_natural_scrolling", fSettings.scroll_twofinger_natural_scrolling);
msg.AddInt8("edge_motion", fSettings.edge_motion);
return msg;
}
@@ -156,6 +157,9 @@ TouchpadPref::LoadSettings()
fSettings.scroll_twofinger_natural_scrolling = settingsMsg.GetBool(
"scroll_twofinger_natural_scrolling",
kDefaultTouchpadSettings.scroll_twofinger_natural_scrolling);
fSettings.edge_motion = settingsMsg.GetInt8(
"edge_motion",
kDefaultTouchpadSettings.edge_motion);
return B_OK;
}
@@ -309,6 +309,12 @@ TouchpadPrefView::MessageReceived(BMessage* message)
fTouchpadPref.UpdateRunningSettings();
break;
case EDGE_MOTION_CHANGED:
settings.edge_motion = fEdgeMotionOptionPopUp->Value();
fRevertButton->SetEnabled(true);
fTouchpadPref.UpdateRunningSettings();
break;
case TAP_CONTROL_CHANGED:
settings.tapgesture_sensibility = fTapSlider->Value();
fRevertButton->SetEnabled(true);
@@ -369,6 +375,8 @@ TouchpadPrefView::AttachedToWindow()
fScrollStepYSlider->SetTarget(this);
fScrollAccelSlider->SetTarget(this);
fEdgeMotionOptionPopUp->SetTarget(this);
fPadBlockerSlider->SetTarget(this);
fTapSlider->SetTarget(this);
fSpeedSlider->SetTarget(this);
@@ -448,6 +456,22 @@ TouchpadPrefView::SetupView()
fTwoFingerNaturalScrollingBox = new BCheckBox(B_TRANSLATE("Natural scrolling"),
new BMessage(SCROLL_CONTROL_CHANGED));
fEdgeMotionOptionPopUp = new BOptionPopUp("edge_motion",
B_TRANSLATE("Edge motion:"), new BMessage(EDGE_MOTION_CHANGED));
fEdgeMotionOptionPopUp->AddOption(B_TRANSLATE("Disabled"), B_EDGE_MOTION_DISABLED);
#if 0
// Not exposed in the UI because it makes little sense to have this enabled on move but not
// on drag
fEdgeMotionOptionPopUp->AddOption(B_TRANSLATE("On move"), B_EDGE_MOTION_ON_MOVE);
#endif
fEdgeMotionOptionPopUp->AddOption(B_TRANSLATE("On tap-drag only"), B_EDGE_MOTION_ON_TAP_DRAG);
fEdgeMotionOptionPopUp->AddOption(B_TRANSLATE("When dragging"),
B_EDGE_MOTION_ON_TAP_DRAG
| B_EDGE_MOTION_ON_BUTTON_CLICK_MOVE | B_EDGE_MOTION_ON_BUTTON_CLICK_DRAG);
fEdgeMotionOptionPopUp->AddOption(B_TRANSLATE("Always"),
B_EDGE_MOTION_ON_MOVE | B_EDGE_MOTION_ON_TAP_DRAG
| B_EDGE_MOTION_ON_BUTTON_CLICK_MOVE | B_EDGE_MOTION_ON_BUTTON_CLICK_DRAG);
float spacing = be_control_look->DefaultItemSpacing();
BView* scrollPrefLeftLayout
@@ -509,6 +533,8 @@ TouchpadPrefView::SetupView()
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_WINDOW_SPACING)
.Add(scrollBox)
.Add(fEdgeMotionOptionPopUp)
.Add(new BSeparatorView(B_HORIZONTAL))
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(fTapSlider)
@@ -542,6 +568,7 @@ TouchpadPrefView::SetValues(touchpad_settings* settings)
fTwoFingerNaturalScrollingBox->SetValue(
settings->scroll_twofinger_natural_scrolling ? B_CONTROL_ON : B_CONTROL_OFF);
fTwoFingerNaturalScrollingBox->SetEnabled(settings->scroll_twofinger);
fEdgeMotionOptionPopUp->SetValue(settings->edge_motion);
fScrollStepXSlider->SetValue(20 - settings->scroll_xstepsize / 2);
fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2);
fScrollAccelSlider->SetValue(settings->scroll_acceleration);
@@ -16,6 +16,7 @@
#include <CheckBox.h>
#include <GroupView.h>
#include <Invoker.h>
#include <OptionPopUp.h>
#include <Slider.h>
#include <StringView.h>
#include <View.h>
@@ -39,6 +40,7 @@ const uint REVERT_SETTINGS = '&rse';
const uint PADBLOCK_TIME_CHANGED = '&ptc';
const uint PAD_SPEED_CHANGED = '&psc';
const uint PAD_ACCELERATION_CHANGED = '&pac';
const uint EDGE_MOTION_CHANGED = '&emc';
class DeviceListView;
@@ -106,6 +108,7 @@ private:
BSlider* fTapSlider;
BSlider* fSpeedSlider;
BSlider* fAccelSlider;
BOptionPopUp* fEdgeMotionOptionPopUp;
BButton* fDefaultButton;
BButton* fRevertButton;
};