diff --git a/build/jam/images/definitions/regular b/build/jam/images/definitions/regular index 6b8803c12c..643c77a810 100644 --- a/build/jam/images/definitions/regular +++ b/build/jam/images/definitions/regular @@ -276,3 +276,6 @@ AddDirectoryToHaikuImage home config settings printers Preview : home-config-settings-printers-preview.rdef ; AddDirectoryToHaikuImage home config settings printers "Save as PDF" : home-config-settings-printers-save-as-pdf.rdef ; + +# padblocker +AddDirectoryToHaikuImage home config settings touchpad ; \ No newline at end of file diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku index 275557bec3..9d4de494ec 100644 --- a/build/jam/packages/Haiku +++ b/build/jam/packages/Haiku @@ -235,7 +235,7 @@ AddSymlinkToPackage add-ons Tracker AddFilesToPackage add-ons input_server devices : keyboard mouse tablet wacom ; AddFilesToPackage add-ons input_server filters - : screen_saver shortcut_catcher switch_workspace ; + : padblocker screen_saver shortcut_catcher switch_workspace ; AddDirectoryToPackage add-ons input_server methods ; AddFilesToPackage add-ons kernel network : notifications stack ; diff --git a/headers/private/input/touchpad_settings.h b/headers/private/input/touchpad_settings.h index ebacbd5222..b63b63105a 100644 --- a/headers/private/input/touchpad_settings.h +++ b/headers/private/input/touchpad_settings.h @@ -19,6 +19,7 @@ typedef struct { uint8 tapgesture_sensibility; // 0 : no tapgesture // 20: very light tip is enough (default) + uint16 padblocker_threshold; //0 to 100 } touchpad_settings; @@ -30,10 +31,10 @@ const static touchpad_settings kDefaultTouchpadSettings = { 7, 10, 10, - 20 + 20, + 30 }; #define TOUCHPAD_SETTINGS_FILE "Touchpad_settings" - #endif /* TOUCHPAD_SETTINGS_H */ diff --git a/src/add-ons/input_server/filters/Jamfile b/src/add-ons/input_server/filters/Jamfile index 1ad77e3b28..3cf8d7903d 100644 --- a/src/add-ons/input_server/filters/Jamfile +++ b/src/add-ons/input_server/filters/Jamfile @@ -4,3 +4,4 @@ SubInclude HAIKU_TOP src add-ons input_server filters minimize_all ; SubInclude HAIKU_TOP src add-ons input_server filters screen_saver ; SubInclude HAIKU_TOP src add-ons input_server filters shortcut_catcher ; SubInclude HAIKU_TOP src add-ons input_server filters switch_workspace ; +SubInclude HAIKU_TOP src add-ons input_server filters padblocker ; diff --git a/src/add-ons/input_server/filters/padblocker/Jamfile b/src/add-ons/input_server/filters/padblocker/Jamfile new file mode 100644 index 0000000000..37d2378578 --- /dev/null +++ b/src/add-ons/input_server/filters/padblocker/Jamfile @@ -0,0 +1,10 @@ +SubDir HAIKU_TOP src add-ons input_server filters padblocker ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +UsePrivateHeaders app ; + +Addon padblocker + : PadBlocker.cpp + : be input_server [ TargetLibstdc++ ] [ TargetLibsupc++ ] + ; diff --git a/src/add-ons/input_server/filters/padblocker/PadBlocker.cpp b/src/add-ons/input_server/filters/padblocker/PadBlocker.cpp new file mode 100644 index 0000000000..e090df6811 --- /dev/null +++ b/src/add-ons/input_server/filters/padblocker/PadBlocker.cpp @@ -0,0 +1,200 @@ +/* + Touchpad sensitivity filter + Most windows/mac/etc laptops have a sensitivity filter/mechanism + which protects the user from accidently rubbing the + touchpad while typing and thus deleting text or moving + the cursor to a new insertion point. I've been grousing + about this to myself for months, and finally decided to + write something for BeOS which other people might benefit + from. + + Just an input_server add_on. I wrote it in < hour. Works on + my inspiron 3500, but I imagine it would work fine on any BeOS + machine. Not that desktops would benefit. Compiled under 4.5.2 + + Do what you want with it. Enjoy. + + --Shamyl Zakariya + --March 22 2000 + --zakariya@earthlink.net + + Note: + reads Touchpad_settings file in home/config/settings . + padblocker_threshold value represents the delay between the last + B_KEY_UP message and when the filter will allow + a B_MOUSE_DOWN message. Eg, if less than _threshold has + transpired between a B_KEY_DOWN and a B_MOUSE_DOWN, the mouse + down event will be skipped, cast into oblivion. + + Kudos to the people at Be for making this kind of thing + so damnably easy to do. Bravo! + + And a hearty thanks to Magnus Landahl for his superb + debug console, without which I wouldn't have ever known if + this damn thing worked at all. + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if DEBUG +# define LOG(text...) PRINT((text)) +#else +# define LOG(text...) +#endif + +//#define Z_DEBUG 1 + + +#if Z_DEBUG +#include +#endif + +extern "C" _EXPORT BInputServerFilter* instantiate_input_filter(); + +class PadBlocker : public BInputServerFilter +{ + public: + PadBlocker(); + virtual ~PadBlocker(); + virtual filter_result Filter(BMessage *message, BList *outList); + + private: + bigtime_t _lastKeyUp; //timestamp of last B_KEY_DOWN + bigtime_t _threshold; + status_t GetSettingsPath(BPath& path); + BPoint fWindowPosition; +}; + + +status_t +PadBlocker::GetSettingsPath(BPath &path) +{ + status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (status < B_OK) + return status; + + return path.Append(TOUCHPAD_SETTINGS_FILE); +} + + +PadBlocker::PadBlocker() +{ + _lastKeyUp = 0; + _threshold = 300; //~one third of a second? + + touchpad_settings settings; + + #if Z_DEBUG + BeDC dc("PadBlocker"); + #endif + BPath path; + status_t status = GetSettingsPath(path); + 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; + } + } + } + + //load settings file + + if (status == B_OK) + { + #if Z_DEBUG + dc.SendMessage("Settings file Exists"); + #endif + _threshold = settings.padblocker_threshold; + } + + + + _threshold *= 1000; //I'd rather keep the number in the file in thousandths + + #ifdef Z_DEBUG + dc.SendInt(_threshold, "Touchpad threshold."); + #endif +} + + +PadBlocker::~PadBlocker() +{ +} + + +filter_result PadBlocker::Filter(BMessage *message, BList *outList) +{ + filter_result res = B_DISPATCH_MESSAGE; + + switch (message->what) + { + case B_KEY_UP: case B_KEY_DOWN: + { + _lastKeyUp = system_time(); //update timestamp + break; + } + + case B_MOUSE_DOWN: + { + // do nothing if disabled + if (threshold == 0) + break; + + bigtime_t now = system_time(); + // if less than the threshold has passed, tell input server + // to ignore this message + if ((now - _lastKeyUp) < _threshold) res = B_SKIP_MESSAGE; + break; + } + + default: + { + //we don't want to mess with anybody else + break; + } + } + + #if Z_DEBUG + if (res == B_SKIP_MESSAGE) + { + BeDC dc("PadBlocker"); + dc.SendMessage("Skipping mouse down event"); + } + #endif + + return (res); +} + + +//************************************************************************* +//Exported instantiator + +BInputServerFilter* instantiate_input_filter() +{ + return new (std::nothrow) PadBlocker(); +} diff --git a/src/add-ons/input_server/filters/padblocker/PadBlocker.rdef b/src/add-ons/input_server/filters/padblocker/PadBlocker.rdef new file mode 100644 index 0000000000..e13f007b68 --- /dev/null +++ b/src/add-ons/input_server/filters/padblocker/PadBlocker.rdef @@ -0,0 +1,11 @@ +resource app_version { + major = 1, + middle = 0, + minor = 0, + + variety = B_APPV_FINAL, + internal = 0, + + short_info = "A filter to block the touchpad while typing", + long_info = "An input_server filter to block the touchpad while typing." +}; diff --git a/src/preferences/input/InputTouchpadPref.cpp b/src/preferences/input/InputTouchpadPref.cpp index 8b31085543..09e53dcbc2 100644 --- a/src/preferences/input/InputTouchpadPref.cpp +++ b/src/preferences/input/InputTouchpadPref.cpp @@ -9,15 +9,18 @@ #include "InputTouchpadPref.h" -#include +#include #include #include +#include #include #include -TouchpadPref::TouchpadPref() +TouchpadPref::TouchpadPref(BInputDevice* device) + : + fTouchPad(device) { // default center position fWindowPosition.x = -1; @@ -58,6 +61,7 @@ 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); return fTouchPad->Control(MS_SET_TOUCHPAD_SETTINGS, &msg); } @@ -136,4 +140,4 @@ TouchpadPref::SaveSettings() } return B_OK; -} \ No newline at end of file +} diff --git a/src/preferences/input/InputTouchpadPref.h b/src/preferences/input/InputTouchpadPref.h index fb1b67f162..e139e7e1cd 100644 --- a/src/preferences/input/InputTouchpadPref.h +++ b/src/preferences/input/InputTouchpadPref.h @@ -27,7 +27,7 @@ class TouchpadPref { public: - TouchpadPref(); + TouchpadPref(BInputDevice* device); virtual ~TouchpadPref(); void Revert(); @@ -55,4 +55,4 @@ private: }; -#endif // TOUCHPAD_PREF_H \ No newline at end of file +#endif // TOUCHPAD_PREF_H diff --git a/src/preferences/input/InputTouchpadPrefView.cpp b/src/preferences/input/InputTouchpadPrefView.cpp index a3eeb2dbe1..aaaa95b87f 100644 --- a/src/preferences/input/InputTouchpadPrefView.cpp +++ b/src/preferences/input/InputTouchpadPrefView.cpp @@ -266,7 +266,8 @@ TouchpadView::DrawSliders() TouchpadPrefView::TouchpadPrefView(BInputDevice* dev) : - BGroupView() + BGroupView(), + fTouchpadPref(dev) { SetupView(); // set view values @@ -307,6 +308,16 @@ TouchpadPrefView::MessageReceived(BMessage* message) fTouchpadPref.UpdateSettings(); break; + case PADBLOCK_TIME_CHANGED: + settings.padblocker_threshold = fPadBlockerSlider->Value(); + // The maximum value means "disabled", but in the settings file that + // must be stored as 0 + if (settings.padblocker_threshold == 1000) + settings.padblocker_threshold = 0; + fRevertButton->SetEnabled(true); + fTouchpadPref.UpdateSettings(); + break; + case DEFAULT_SETTINGS: fTouchpadPref.Defaults(); fRevertButton->SetEnabled(true); @@ -336,6 +347,7 @@ TouchpadPrefView::AttachedToWindow() fScrollStepXSlider->SetTarget(this); fScrollStepYSlider->SetTarget(this); fScrollAccelSlider->SetTarget(this); + fPadBlockerSlider->SetTarget(this); fTapSlider->SetTarget(this); fDefaultButton->SetTarget(this); fRevertButton->SetTarget(this); @@ -396,6 +408,14 @@ TouchpadPrefView::SetupView() fScrollStepYSlider->SetLimitLabels(B_TRANSLATE("Slow"), B_TRANSLATE("Fast")); + fPadBlockerSlider = new BSlider("padblocker", + B_TRANSLATE("Keyboard Lock Delay"), + new BMessage(PADBLOCK_TIME_CHANGED), 5, 1000, B_HORIZONTAL); + fPadBlockerSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); + fPadBlockerSlider->SetHashMarkCount(10); + fPadBlockerSlider->SetLimitLabels(B_TRANSLATE("Quick"), + B_TRANSLATE("Never")); + fTwoFingerBox = new BCheckBox(B_TRANSLATE("Two finger scrolling"), new BMessage(SCROLL_CONTROL_CHANGED)); fTwoFingerHorizontalBox = new BCheckBox( @@ -432,22 +452,12 @@ TouchpadPrefView::SetupView() * 1.5)); scrollPrefLayout->AddView(scrollPrefRightLayout); - BBox* tapBox = new BBox("tapbox"); - tapBox->SetLabel(B_TRANSLATE("Tapping")); - - BGroupLayout* tapPrefLayout = new BGroupLayout(B_HORIZONTAL); - tapPrefLayout->SetInsets(spacing, tapBox->TopBorderOffset() * 2 + spacing, - spacing, spacing); - tapBox->SetLayout(tapPrefLayout); - - fTapSlider = new BSlider("tap_sens", B_TRANSLATE("Sensitivity"), + fTapSlider = new BSlider("tap_sens", B_TRANSLATE("Tapping sensitivity"), new BMessage(TAP_CONTROL_CHANGED), 0, spacing * 2, B_HORIZONTAL); fTapSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fTapSlider->SetHashMarkCount(7); fTapSlider->SetLimitLabels(B_TRANSLATE("Off"), B_TRANSLATE("High")); - tapPrefLayout->AddView(fTapSlider); - fDefaultButton = new BButton(B_TRANSLATE("Defaults"), new BMessage(DEFAULT_SETTINGS)); @@ -459,14 +469,15 @@ TouchpadPrefView::SetupView() BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_WINDOW_SPACING) .Add(scrollBox) - .Add(tapBox) - .Add(new BSeparatorView(B_HORIZONTAL)) - .AddGroup(B_HORIZONTAL) - .Add(fDefaultButton) - .Add(fRevertButton) - .AddGlue() - .End() - .End(); + .Add(fTapSlider) + .Add(fPadBlockerSlider) + .Add(new BSeparatorView(B_HORIZONTAL)) + .AddGroup(B_HORIZONTAL) + .Add(fDefaultButton) + .Add(fRevertButton) + .AddGlue() + .End() + .End(); } @@ -484,4 +495,5 @@ TouchpadPrefView::SetValues(touchpad_settings* settings) fScrollStepYSlider->SetValue(20 - settings->scroll_ystepsize / 2); fScrollAccelSlider->SetValue(settings->scroll_acceleration); fTapSlider->SetValue(settings->tapgesture_sensibility); -} \ No newline at end of file + fPadBlockerSlider->SetValue(settings->padblocker_threshold); +} diff --git a/src/preferences/input/InputTouchpadPrefView.h b/src/preferences/input/InputTouchpadPrefView.h index 130091e031..19d2cc319d 100644 --- a/src/preferences/input/InputTouchpadPrefView.h +++ b/src/preferences/input/InputTouchpadPrefView.h @@ -35,6 +35,7 @@ const uint SCROLL_CONTROL_CHANGED = '&scc'; const uint TAP_CONTROL_CHANGED = '&tcc'; const uint DEFAULT_SETTINGS = '&dse'; const uint REVERT_SETTINGS = '&rse'; +const uint PADBLOCK_TIME_CHANGED = '&ptc'; class DeviceListView; @@ -96,9 +97,10 @@ private: BSlider* fScrollStepXSlider; BSlider* fScrollStepYSlider; BSlider* fScrollAccelSlider; + BSlider* fPadBlockerSlider; BSlider* fTapSlider; BButton* fDefaultButton; BButton* fRevertButton; }; -#endif // TOUCHPAD_PREF_VIEW_H \ No newline at end of file +#endif // TOUCHPAD_PREF_VIEW_H