[PATCH] Optionals single-finger scroll for touchscreens and 2-in-1's

Alyssa Rosenzweig <[email protected]>
Newsgroups gmane.comp.web.dillo.devel
Message-ID <[email protected]>
On touchscreens, the natural way to scroll is by "moving" the page up
and down with the user's finger, mimicking the behaviour of most
touchscreen-aware browsers. Using the scrollbar on these devices is
clunky and imprecise unless the bar is large, which would take precious
screen real estate on small displays.

From Dillo's perspective, this action corresponds to a click-and-drag of
the left mouse button. Dillo already has an option for click-and-drag
scrolling with the middle mouse button; this patch piggybacks on that
functionality to optionally support left-click scrolling as well.

Normally, left-click-and-drag corresponds to text selection. When this
touchscreen drag preference is enabled, text selection requires the
Shift key to be held, which disables scrolling temporarily. The choice
of "Shift" aligns with Firefox's defaults for touchscreens.
Unfortunately, this prevents selection if Dillo is used purely on a
tablet (not a laptop with a touchscreen); perhaps a double-tap-and-drag
would be a more natural gesture.

The functionality of this patch is hidden behind a new preference,
disabled default. It should therefore not cause any regressions. I have
tested both without drag options (the old behaviour) and with
touchscreen drag enabled (this patch); both work as anticipated. I was
unable to check for regressions in the middle mouse drag option, as my
device does not seem to support the middle mouse button.

The code is maybe not ideal, but I'm submitting it in the hopes it could
be useful to someone else; Dillo is perfect for the low-power processors
found in tablets and such today :)

This patch is confirmed working on my Samsung Chromebook Plus (a 2-in-1
laptop) running Debian GNU/Linux.

---

diff -r 0cb3ef492f54 dillorc
--- a/dillorc	Fri Sep 15 18:59:19 2017 +0200
+++ b/dillorc	Sun Jun 10 17:47:57 2018 +0000
@@ -380,6 +380,12 @@
 # Note: You could always paste the URL onto the URL box clear button.
 #middle_click_drags_page=YES
 
+# Left click drags pages.
+# When using a touchscreen or convertible laptop, this
+# eanbles natural scrolling with a single finger gesutre. Text selection is
+# disabled; to select text, hold the shift-key and select as usual.
+#touchscreen_drags_page=NO
+
 # Focus follows new Tabs.
 # You can hold SHIFT to temporarily revert this behaviour.
 #focus_new_tab=YES
diff -r 0cb3ef492f54 dw/fltkviewport.cc
--- a/dw/fltkviewport.cc	Fri Sep 15 18:59:19 2017 +0200
+++ b/dw/fltkviewport.cc	Sun Jun 10 17:47:57 2018 +0000
@@ -69,6 +69,7 @@
    add (vscrollbar);
 
    hasDragScroll = 1;
+   hasTouchScroll = 1;
    scrollX = scrollY = scrollDX = scrollDY = 0;
    horScrolling = verScrolling = dragScrolling = 0;
 
@@ -274,17 +275,15 @@
          if (hscrollbar->handle(event))
             horScrolling = 1;
       } else if (FltkWidgetView::handle(event) == 0 &&
-                 Fl::event_button() == FL_MIDDLE_MOUSE) {
-         if (!hasDragScroll) {
-            /* let the parent widget handle it... */
-            return 0;
-         } else {
-            /* receive FL_DRAG and FL_RELEASE */
-            dragScrolling = 1;
-            dragX = Fl::event_x();
-            dragY = Fl::event_y();
-            setCursor (core::style::CURSOR_MOVE);
-         }
+                 ((hasDragScroll &&
+		   Fl::event_button() == FL_MIDDLE_MOUSE)
+                 || (hasTouchScroll &&
+		   Fl::event_button() == FL_LEFT_MOUSE))) {
+         /* receive FL_DRAG and FL_RELEASE */
+         dragScrolling = 1;
+         dragX = Fl::event_x();
+         dragY = Fl::event_y();
+         setCursor (core::style::CURSOR_MOVE);
       }
       return 1;
       break;
diff -r 0cb3ef492f54 dw/fltkviewport.hh
--- a/dw/fltkviewport.hh	Fri Sep 15 18:59:19 2017 +0200
+++ b/dw/fltkviewport.hh	Sun Jun 10 17:47:57 2018 +0000
@@ -21,7 +21,7 @@
 
    int scrollX, scrollY;
    int scrollDX, scrollDY;
-   int hasDragScroll, dragScrolling, dragX, dragY;
+   int hasDragScroll, hasTouchScroll, dragScrolling, dragX, dragY;
    int horScrolling, verScrolling;
 
    Fl_Scrollbar *vscrollbar, *hscrollbar;
@@ -74,6 +74,7 @@
    void setGadgetOrientation (bool hscrollbarVisible, bool vscrollbarVisible,
                               GadgetOrientation gadgetOrientation);
    void setDragScroll (bool enable) { hasDragScroll = enable ? 1 : 0; }
+   void setTouchScroll (bool enable) { hasTouchScroll = enable ? 1 : 0; }
    void addGadget (Fl_Widget *gadget);
 };
 
diff -r 0cb3ef492f54 dw/layout.hh
--- a/dw/layout.hh	Fri Sep 15 18:59:19 2017 +0200
+++ b/dw/layout.hh	Sun Jun 10 17:47:57 2018 +0000
@@ -441,6 +441,8 @@
 
    inline style::Color* getBgColor () { return bgColor; }
    inline style::StyleImage* getBgImage () { return bgImage; }
+
+   void setTouchScroll(bool active) { selectionState.setTouchScroll(active); }
 };
 
 } // namespace core
diff -r 0cb3ef492f54 dw/selection.cc
--- a/dw/selection.cc	Fri Sep 15 18:59:19 2017 +0200
+++ b/dw/selection.cc	Sun Jun 10 17:47:57 2018 +0000
@@ -24,6 +24,8 @@
 
 #include <string.h>
 
+#include <FL/Fl.H>
+
 using namespace lout;
 
 /*
@@ -132,6 +134,14 @@
          // but we do actually process this event.
          ret = true;
       } else if (event->button == 1) {
+	 // If tablet scrolling is enabled, selecting with the left mouse
+	 // button is disabled, unless the shift modifier is also pressed. This
+	 // behaviour agrees with Firefox's.
+	 if (hasTouchScroll && !(Fl::event_state() & FL_SHIFT)) {
+	    ret = false;
+	    goto out;
+	 }
+
          // normal selection handling
          highlight (false, 0);
          resetSelection ();
@@ -151,6 +161,7 @@
       }
    }
 
+out:
    DBG_OBJ_MSGF ("events", 1, "=> %s", ret ? "true" : "false");
    DBG_OBJ_LEAVE ();
    return ret;
diff -r 0cb3ef492f54 dw/selection.hh
--- a/dw/selection.hh	Fri Sep 15 18:59:19 2017 +0200
+++ b/dw/selection.hh	Sun Jun 10 17:47:57 2018 +0000
@@ -203,6 +203,8 @@
    DeepIterator *link;
    int linkChar, linkNumber;
 
+   bool hasTouchScroll;
+
    void resetSelection ();
    void resetLink ();
    void switchLinkToSelection (Iterator *it, int charPos);
@@ -223,6 +225,7 @@
    ~SelectionState ();
 
    inline void setLayout (Layout *layout) { this->layout = layout; }
+   inline void setTouchScroll (bool active) { hasTouchScroll = active; }
    void reset ();
    bool buttonPress (Iterator *it, int charPos, int linkNo,
                      EventButton *event);
diff -r 0cb3ef492f54 src/prefs.c
--- a/src/prefs.c	Fri Sep 15 18:59:19 2017 +0200
+++ b/src/prefs.c	Sun Jun 10 17:47:57 2018 +0000
@@ -75,6 +75,7 @@
    prefs.load_background_images=FALSE;
    prefs.load_stylesheets=TRUE;
    prefs.middle_click_drags_page = TRUE;
+   prefs.touchscreen_drags_page = FALSE;
    prefs.middle_click_opens_new_tab = TRUE;
    prefs.right_click_closes_tab = FALSE;
    prefs.no_proxy = dStrdup(PREFS_NO_PROXY);
diff -r 0cb3ef492f54 src/prefs.h
--- a/src/prefs.h	Fri Sep 15 18:59:19 2017 +0200
+++ b/src/prefs.h	Sun Jun 10 17:47:57 2018 +0000
@@ -109,6 +109,7 @@
    bool_t show_msg;
    bool_t show_extra_warnings;
    bool_t middle_click_drags_page;
+   bool_t touchscreen_drags_page;
    int penalty_hyphen, penalty_hyphen_2;
    int penalty_em_dash_left, penalty_em_dash_right, penalty_em_dash_right_2;
    int stretchability_factor;
diff -r 0cb3ef492f54 src/prefsparser.cc
--- a/src/prefsparser.cc	Fri Sep 15 18:59:19 2017 +0200
+++ b/src/prefsparser.cc	Sun Jun 10 17:47:57 2018 +0000
@@ -182,6 +182,8 @@
       { "load_stylesheets", &prefs.load_stylesheets, PREFS_BOOL, 0 },
       { "middle_click_drags_page", &prefs.middle_click_drags_page,
         PREFS_BOOL, 0 },
+      { "touchscreen_drags_page", &prefs.touchscreen_drags_page,
+        PREFS_BOOL, 0 },
       { "middle_click_opens_new_tab", &prefs.middle_click_opens_new_tab,
         PREFS_BOOL, 0 },
       { "right_click_closes_tab", &prefs.right_click_closes_tab, PREFS_BOOL, 0 },
diff -r 0cb3ef492f54 src/ui.cc
--- a/src/ui.cc	Fri Sep 15 18:59:19 2017 +0200
+++ b/src/ui.cc	Sun Jun 10 17:47:57 2018 +0000
@@ -788,7 +788,8 @@
    if (!ret) {
       ret = Fl_Group::handle(event);
    }
-   if (!ret && event == FL_PUSH && !prefs.middle_click_drags_page) {
+   if (!ret && event == FL_PUSH && !(prefs.middle_click_drags_page
+			   | prefs.touchscreen_drags_page)) {
       /* nobody claimed FL_PUSH: ask for FL_RELEASE,
        * which is necessary for middle-click paste URL) */
       ret = 1;
diff -r 0cb3ef492f54 src/uicmd.cc
--- a/src/uicmd.cc	Fri Sep 15 18:59:19 2017 +0200
+++ b/src/uicmd.cc	Sun Jun 10 17:47:57 2018 +0000
@@ -604,7 +604,9 @@
    FltkViewport *viewport = new FltkViewport (0, 0, 0, 1);
    viewport->box(FL_NO_BOX);
    viewport->setBufferedDrawing (prefs.buffered_drawing ? true : false);
-   viewport->setDragScroll (prefs.middle_click_drags_page ? true : false);
+   viewport->setDragScroll (prefs.middle_click_drags_page);
+   viewport->setTouchScroll (prefs.touchscreen_drags_page);
+   layout->setTouchScroll (prefs.touchscreen_drags_page);
    layout->attachView (viewport);
    new_ui->set_render_layout(viewport);
    viewport->setScrollStep((int) rint(28.0 * prefs.font_factor));

_______________________________________________
Dillo-dev mailing list
[email protected]
http://lists.dillo.org/cgi-bin/mailman/listinfo/dillo-dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.