weston: add more libinput config options
authorEric Toombs <3672-ewtoombs@users.noreply.gitlab.freedesktop.org>
Fri, 1 Feb 2019 02:53:25 +0000 (21:53 -0500)
committerPekka Paalanen <pq@iki.fi>
Wed, 6 Feb 2019 08:23:02 +0000 (08:23 +0000)
This is so that, for instance, people using weston as their main Wayland
compositor can invert the sense of two finger scrolling or change
pointer acceleration using weston.ini, rather than having to edit C
code.

All of the options that libinput itself exposes through its API are now
exposed in weston.ini.  The new options are called `tap-and-drag`,
`tap-and-drag-lock`, `disable-while-typing`, `middle-emulation`,
`left-handed`, `rotation`, `accel-profile`, `accel-speed`,
`scroll-method`, `natural-scroll`, and `scroll-button`. I have
successfully tested everything except for `rotation`, out of a lack of
hardware support.

weston now depends directly on libevdev for turning button name strings into
kernel input codes. This was needed for the `scroll-button` config
option. (weston already depends indirectly on libevdev through
libinput, so I figured people would be OK with this.) As a practical
matter for debian-style packagers, weston now has a build dependency on
libevdev-dev.

Right now, the code applies the same options to all attached devices
that a given option is relevant for. There are plans for multiple
[libinput] sections, each with different device filters, for users who
need more control here.

Signed-off-by: Eric Toombs <3672-ewtoombs@users.noreply.gitlab.freedesktop.org>
.gitlab-ci.yml
Makefile.am
compositor/main.c
compositor/meson.build
configure.ac
man/weston.ini.man
meson.build
weston.ini.in

index c6007d1d8abbbbe8fbe9fef08deeee666bfec960..f4b56d48306623d6c45b8a20ec8d71c3cfa9fa2d 100644 (file)
@@ -11,7 +11,7 @@ before_script:
   - chmod +x /usr/sbin/policy-rc.d
   - echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list
   - apt-get update
-  - apt-get -y --no-install-recommends install build-essential automake autoconf libtool pkg-config libexpat1-dev libffi-dev libxml2-dev libpixman-1-dev libpng-dev libjpeg-dev libcolord-dev mesa-common-dev libglu1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libwayland-dev libxcb1-dev libxcb-composite0-dev libxcb-xfixes0-dev libxcb-xkb-dev libx11-xcb-dev libx11-dev libudev-dev libgbm-dev libxkbcommon-dev libcairo2-dev libpango1.0-dev libgdk-pixbuf2.0-dev libxcursor-dev libmtdev-dev libpam0g-dev libvpx-dev libsystemd-dev libinput-dev libwebp-dev libjpeg-dev libva-dev liblcms2-dev git libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev freerdp2-dev curl python3-pip python3-setuptools ninja-build
+  - apt-get -y --no-install-recommends install build-essential automake autoconf libtool pkg-config libexpat1-dev libffi-dev libxml2-dev libpixman-1-dev libpng-dev libjpeg-dev libcolord-dev mesa-common-dev libglu1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libwayland-dev libxcb1-dev libxcb-composite0-dev libxcb-xfixes0-dev libxcb-xkb-dev libx11-xcb-dev libx11-dev libudev-dev libgbm-dev libxkbcommon-dev libcairo2-dev libpango1.0-dev libgdk-pixbuf2.0-dev libxcursor-dev libmtdev-dev libpam0g-dev libvpx-dev libsystemd-dev libevdev-dev libinput-dev libwebp-dev libjpeg-dev libva-dev liblcms2-dev git libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev freerdp2-dev curl python3-pip python3-setuptools ninja-build
   - pip3 install --user git+https://github.com/mesonbuild/meson.git@0.49
   - mkdir -p /tmp/.X11-unix
   - chmod 777 /tmp/.X11-unix
index 6036dbf51535953a621cfe494af2fbe5f03609a8..24561a58b9d6c2dd401007425d0ea2d8b56374ca 100644 (file)
@@ -187,12 +187,13 @@ weston_LDFLAGS = -export-dynamic
 weston_CPPFLAGS = $(AM_CPPFLAGS) -DMODULEDIR='"$(moduledir)"' \
                                 -DXSERVER_PATH='"@XSERVER_PATH@"'
 weston_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS) $(LIBINPUT_BACKEND_CFLAGS) \
-       $(PTHREAD_CFLAGS)
+       $(PTHREAD_CFLAGS) $(LIBEVDEV_CFLAGS)
 weston_LDADD = libshared.la libweston-@LIBWESTON_MAJOR@.la \
        $(COMPOSITOR_LIBS) \
        $(DL_LIBS) $(LIBINPUT_BACKEND_LIBS) \
        $(CLOCK_GETRES_LIBS) \
        $(PTHREAD_LIBS) \
+       $(LIBEVDEV_LIBS) \
        -lm
 
 weston_SOURCES =                                       \
index 6fdb6bae1571448a4f8dfc0e3b7b3183d66b8c83..34d2e7153ad65d228e4b59b672ff483463f8a95f 100644 (file)
@@ -41,6 +41,8 @@
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <libinput.h>
+#include <libevdev/libevdev.h>
+#include <linux/input-event-codes.h>
 #include <sys/time.h>
 #include <linux/limits.h>
 
@@ -1458,6 +1460,114 @@ wet_set_simple_head_configurator(struct weston_compositor *compositor,
                                                &wet->heads_changed_listener);
 }
 
+static void
+configure_input_device_accel(struct weston_config_section *s,
+               struct libinput_device *device)
+{
+       char *profile_string = NULL;
+       int is_a_profile = 1;
+       uint32_t profiles;
+       enum libinput_config_accel_profile profile;
+       double speed;
+
+       if (weston_config_section_get_string(s, "accel-profile",
+                                            &profile_string, NULL) == 0) {
+               if (strcmp(profile_string, "flat") == 0)
+                       profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
+               else if (strcmp(profile_string, "adaptive") == 0)
+                       profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
+               else {
+                       weston_log("warning: no such accel-profile: %s\n",
+                                  profile_string);
+                       is_a_profile = 0;
+               }
+
+               profiles = libinput_device_config_accel_get_profiles(device);
+               if (is_a_profile && (profile & profiles) != 0) {
+                       weston_log("          accel-profile=%s\n",
+                                  profile_string);
+                       libinput_device_config_accel_set_profile(device,
+                                       profile);
+               }
+       }
+
+       if (weston_config_section_get_double(s, "accel-speed",
+                                            &speed, 0) == 0 &&
+           speed >= -1. && speed <= 1.) {
+               weston_log("          accel-speed=%.3f\n", speed);
+               libinput_device_config_accel_set_speed(device, speed);
+       }
+
+       free(profile_string);
+}
+
+static void
+configure_input_device_scroll(struct weston_config_section *s,
+               struct libinput_device *device)
+{
+       int natural;
+       char *method_string = NULL;
+       uint32_t methods;
+       enum libinput_config_scroll_method method;
+       char *button_string = NULL;
+       int button;
+
+       if (libinput_device_config_scroll_has_natural_scroll(device) &&
+           weston_config_section_get_bool(s, "natural-scroll",
+                                          &natural, 0) == 0) {
+               weston_log("          natural-scroll=%s\n",
+                          natural ? "true" : "false");
+               libinput_device_config_scroll_set_natural_scroll_enabled(
+                               device, natural);
+       }
+
+       if (weston_config_section_get_string(s, "scroll-method",
+                                            &method_string, NULL) != 0)
+               goto done;
+       if (strcmp(method_string, "two-finger") == 0)
+               method = LIBINPUT_CONFIG_SCROLL_2FG;
+       else if (strcmp(method_string, "edge") == 0)
+               method = LIBINPUT_CONFIG_SCROLL_EDGE;
+       else if (strcmp(method_string, "button") == 0)
+               method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
+       else if (strcmp(method_string, "none") == 0)
+               method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
+       else {
+               weston_log("warning: no such scroll-method: %s\n",
+                          method_string);
+               goto done;
+       }
+
+       methods = libinput_device_config_scroll_get_methods(device);
+       if (method != LIBINPUT_CONFIG_SCROLL_NO_SCROLL &&
+           (method & methods) == 0)
+               goto done;
+
+       weston_log("          scroll-method=%s\n", method_string);
+       libinput_device_config_scroll_set_method(device, method);
+
+       if (method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
+               if (weston_config_section_get_string(s, "scroll-button",
+                                                    &button_string,
+                                                    NULL) != 0)
+                       goto done;
+
+               button = libevdev_event_code_from_name(EV_KEY, button_string);
+               if (button == -1) {
+                       weston_log("          Bad scroll-button: %s\n",
+                                  button_string);
+                       goto done;
+               }
+
+               weston_log("          scroll-button=%s\n", button_string);
+               libinput_device_config_scroll_set_button(device, button);
+       }
+
+done:
+       free(method_string);
+       free(button_string);
+}
+
 static void
 configure_input_device(struct weston_compositor *compositor,
                       struct libinput_device *device)
@@ -1466,6 +1576,15 @@ configure_input_device(struct weston_compositor *compositor,
        struct weston_config *config = wet_get_config(compositor);
        int has_enable_tap = 0;
        int enable_tap;
+       int disable_while_typing;
+       int middle_emulation;
+       int tap_and_drag;
+       int tap_and_drag_lock;
+       int left_handed;
+       unsigned int rotation;
+
+       weston_log("libinput: configuring device \"%s\".\n",
+                  libinput_device_get_name(device));
 
        s = weston_config_get_section(config,
                                      "libinput", NULL, NULL);
@@ -1482,10 +1601,65 @@ configure_input_device(struct weston_compositor *compositor,
                if (weston_config_section_get_bool(s, "enable-tap",
                                                   &enable_tap, 0) == 0)
                        has_enable_tap = 1;
-               if (has_enable_tap)
+               if (has_enable_tap) {
+                       weston_log("          enable-tap=%s.\n",
+                                  enable_tap ? "true" : "false");
                        libinput_device_config_tap_set_enabled(device,
                                                               enable_tap);
+               }
+               if (weston_config_section_get_bool(s, "tap-and-drag",
+                                                  &tap_and_drag, 0) == 0) {
+                       weston_log("          tap-and-drag=%s.\n",
+                                  tap_and_drag ? "true" : "false");
+                       libinput_device_config_tap_set_drag_enabled(device,
+                                       tap_and_drag);
+               }
+               if (weston_config_section_get_bool(s, "tap-and-drag-lock",
+                                              &tap_and_drag_lock, 0) == 0) {
+                       weston_log("          tap-and-drag-lock=%s.\n",
+                                  tap_and_drag_lock ? "true" : "false");
+                       libinput_device_config_tap_set_drag_lock_enabled(
+                                       device, tap_and_drag_lock);
+               }
+       }
+
+       if (libinput_device_config_dwt_is_available(device) &&
+           weston_config_section_get_bool(s, "disable-while-typing",
+                                          &disable_while_typing, 0) == 0) {
+               weston_log("          disable-while-typing=%s.\n",
+                          disable_while_typing ? "true" : "false");
+               libinput_device_config_dwt_set_enabled(device,
+                                                      disable_while_typing);
        }
+
+       if (libinput_device_config_middle_emulation_is_available(device) &&
+           weston_config_section_get_bool(s, "middle-button-emulation",
+                                          &middle_emulation, 0) == 0) {
+               weston_log("          middle-button-emulation=%s\n",
+                          middle_emulation ? "true" : "false");
+               libinput_device_config_middle_emulation_set_enabled(
+                               device, middle_emulation);
+       }
+
+       if (libinput_device_config_left_handed_is_available(device) &&
+           weston_config_section_get_bool(s, "left-handed",
+                                          &left_handed, 0) == 0) {
+               weston_log("          left-handed=%s\n",
+                          left_handed ? "true" : "false");
+               libinput_device_config_left_handed_set(device, left_handed);
+       }
+
+       if (libinput_device_config_rotation_is_available(device) &&
+           weston_config_section_get_uint(s, "rotation",
+                                          &rotation, 0) == 0) {
+               weston_log("          rotation=%u\n", rotation);
+               libinput_device_config_rotation_set_angle(device, rotation);
+       }
+
+       if (libinput_device_config_accel_is_available(device))
+               configure_input_device_accel(s, device);
+
+       configure_input_device_scroll(s, device);
 }
 
 static int
index 88bea8d8488777c9a68c7d09c8e72cf337cbb735..994b5877f57c6ce74539c73ca613d223c63e6e99 100644 (file)
@@ -14,6 +14,7 @@ deps_weston = [
        dep_libshared,
        dep_libweston,
        dep_libinput,
+       dep_libevdev,
        dep_libdl,
        dep_threads,
 ]
index 225d6692d23303915022ed093a095503e970ed49..00066eaecfb4d3f2082e3eb9dd701dbb7def2f64 100644 (file)
@@ -235,6 +235,7 @@ if test x$enable_remoting = xyes; then
 fi
 
 
+PKG_CHECK_MODULES(LIBEVDEV, [libevdev])
 PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.8.0])
 PKG_CHECK_MODULES(COMPOSITOR, [$COMPOSITOR_MODULES])
 
index dea80ca0794c6f5cd6a5d5ae8dd8598191bd7983..5c0f1097eda77246bcf73426f9eee2a4e420572a 100644 (file)
@@ -212,12 +212,80 @@ There is also a command line option to do the same.
 The
 .B libinput
 section is used to configure input devices when using the libinput input device
-backend.
+backend. The defaults are determined by libinput and vary according to what is
+most sensible for any given device.
 .PP
 Available configuration are:
 .TP 7
-.BI "enable-tap=" true
-enables tap to click on touchpad devices
+.BI "enable-tap=" false
+Enables tap to click on touchpad devices.
+.TP 7
+.BI "tap-and-drag=" false
+For touchpad devices with \fBenable-tap\fR enabled. If the user taps, then
+taps a second time, this time holding, the virtual mouse button stays down for
+as long as the user keeps their finger on the touchpad, allowing the user to
+click and drag with taps alone.
+.TP 7
+.BI "tap-and-drag-lock=" false
+For touchpad devices with \fBenable-tap\fR and \fBtap-and-drag\fR enabled.
+In the middle of a tap-and-drag, if the user releases the touchpad for less
+than a certain number of milliseconds, then touches it again, the virtual mouse
+button will remain pressed and the drag can continue.
+.TP 7
+.BI "disable-while-typing=" true
+For devices that may be accidentally triggered while typing on the keyboard,
+causing a disruption of the typing.  Disables them while the keyboard is in
+use.
+.TP 7
+.BI "middle-button-emulation=" false
+For pointer devices with left and right buttons, but no middle button.  When
+enabled, a middle button event is emitted when the left and right buttons are
+pressed simultaneously.
+.TP 7
+.BI "left-handed=" false
+Configures the device for use by left-handed people. Exactly what this option
+does depends on the device. For pointers with left and right buttons, the
+buttons are swapped. On tablets, the tablet is logically turned upside down,
+because it will be physically turned upside down.
+.TP 7
+.BI "rotation=" n
+Changes the direction of the logical north, rotating it \fIn\fR degrees
+clockwise away from the default orientation, where \fIn\fR is a whole
+number between 0 and 359 inclusive. Needed for trackballs, mainly. Allows the
+user to orient the trackball sideways, for example.
+.TP 7
+.BI "accel-profile=" "{flat,adaptive}"
+Set the pointer acceleration profile. The pointer's screen speed is
+proportional to the physical speed with a certain constant of proportionality.
+Call that constant alpha. \fIflat\fR keeps alpha fixed. See \fBaccel-speed\fR.
+\fIadaptive\fR causes alpha to increase with physical speed, giving the user
+more control when the speed is slow, and more reach when the speed is high.
+\fIadaptive\fR is the default.
+.TP 7
+.BI "accel-speed=" v
+If \fBaccel-profile\fR is set to \fIflat\fR, it simply sets the value of alpha.
+If \fBaccel-profile\fR is set to \fIadaptive\fR, the effect is more
+complicated, but generally speaking, it will change the pointer's speed.
+\fIv\fR is normalised and must lie in the range [-1, 1]. The exact mapping
+between \fIv\fR and alpha is hardware-dependent, but higher values cause higher
+cursor speeds.
+.TP 7
+.BI "natural-scroll=" false
+Enables natural scrolling, mimicking the behaviour of touchscreen scrolling.
+That is, if the wheel, finger, or fingers are moved down, the surface is
+scrolled up instead of down, as if the finger, or fingers were in contact with
+the surface being scrolled.
+.TP 7
+.BI "scroll-method=" {two-finger,edge,button,none}
+Sets the scroll method. \fItwo-finger\fR scrolls with two fingers on a
+touchpad. \fIedge\fR scrolls with one finger on the right edge of a touchpad.
+\fIbutton\fR scrolls when the pointer is moved while a certain button is
+pressed. See \fBscroll-button\fR. \fInone\fR disables scrolling altogether.
+.TP 7
+.BI "scroll-button=" {BTN_LEFT,BTN_RIGHT,BTN_MIDDLE,...}
+For devices with \fBscroll-method\fR set to \fIbutton\fR. Specifies the
+button that will trigger scrolling. See /usr/include/linux/input-event-codes.h
+for the complete list of possible values.
 .TP 7
 .BI "touchscreen_calibrator=" true
 Advertise the touchscreen calibrator interface to all clients. This is a
index 7826dbb037ed6c1cefe69fcf3800e2174da91ed6..12fa7433a51fd61e5152874e35b29d7656b9207e 100644 (file)
@@ -143,6 +143,7 @@ dep_wayland_server = dependency('wayland-server', version: '>= 1.12.0')
 dep_wayland_client = dependency('wayland-client', version: '>= 1.12.0')
 dep_pixman = dependency('pixman-1', version: '>= 0.25.2')
 dep_libinput = dependency('libinput', version: '>= 0.8.0')
+dep_libevdev = dependency('libevdev')
 dep_libm = cc.find_library('m')
 dep_libdl = cc.find_library('dl')
 dep_libdrm = dependency('libdrm', version: '>= 2.4.68')
index 1a9acee418f50e83eda46be6440335f5b1bd5d07..846ef746bc301c95e424376f6dc4fe9ff6bde8aa 100644 (file)
@@ -61,6 +61,19 @@ path=@libexecdir@/weston-keyboard
 
 #[libinput]
 #enable-tap=true
+#tap-and-drag=true
+#tap-and-drag-lock=true
+#disable-while-typing=false
+#middle-button-emulation=true
+#left-handed=true
+#rotation=90
+#accel-profile=flat
+#accel-speed=.9
+#natural-scroll=true
+#scroll-method=edge
+# For button-triggered scrolling:
+#scroll-method=button
+#scroll-button=BTN_RIGHT
 
 #[touchpad]
 #constant_accel_factor = 50