Cover photo by Katarina Šikuljak on Unsplash
Cover photo by Katarina Šikuljak on Unsplash

Making the best of MacBook Air touchpad on Ubuntu

— 9 minute read

If you are a long time MacBook (Air) user and recently switch to Linux, I bet one of the things you’ll miss most is the multi-touch touchpad. As I have blogged earlier that I decided to dual boot Ubuntu on this MacBook Air, at first, I also struggled to find the best setup for the touchpad to retain my productivity while not having to rely much on mouse.

In this post, I’m detailing my touchpad setup that I feel best so far and that it is as close to MacOS experience as I can get.

Although libinput is the default driver on latest Linux distros, we’ll switch to mtrack[^1] driver which supports many more of multi-touch gestures with flexible configurations, especially the three finger drag, which is also the main reason for my move. Thanks to this blog post, I got a much faster head start, but there were still a lot of other things I did to get to my current setup.

Before we begin, please be noted that mtrack currently and will only support Xorg environment, which I am fine since I don’t find Wayland is any better in terms of performance and resource usage on current Ubuntu 18.04. I’m staying with Xorg for now (which is default session of Ubuntu 18.04 by the way).

Compile and install mtrack driver permalink

Compile a Linux package by yourself might be a little scary for newbies so you just follow these steps carefully, then get to know the ins and outs later:

First, open terminal and install the necessary tools and dependencies for the compilation of the driver:

# Update Ubuntu to latest packages
sudo apt update && sudo apt upgrade

# These dependencies were noted by me on default Ubuntu 18.04
sudo apt install build-essential git pkg-config libmtdev-dev mtdev-tools xserver-xorg-dev xutils-dev

Then we’ll clone source code and compile the mtrack driver from its currently active repo:

# execute line by line:
cd /tmp
git clone https://github.com/p2rkw/xf86-input-mtrack.git
cd xf86-input-mtrack
./configure --with-xorg-module-dir=/usr/lib/xorg/modules
sudo make

You are most li kely not be able to compile the package at the sudo make command. Look carefully at the error messages which will tell the missing dependencies for it. If you are stuck, post a comment here and I’ll see if I can help.

Finally, install the driver into system:

sudo make install

Configure the new touchpad driver permalink

The new driver won’t be used until there’s a proper config file set up. Create the config file at /usr/share/X11/xorg.conf.d/50-mtrack.conf (root or admin permission needed) and edit it with your favorite text editor. Or use these commands:

sudo touch /usr/share/X11/xorg.conf.d/50-mtrack.conf
sudo gedit /usr/share/X11/xorg.conf.d/50-mtrack.conf

This will open the file with Gedit (Text Editor) with proper permission to save. Then, copy and paste my current mtrack config below:

# Install mtrack driver 0.5.0++
# Save this file to /usr/share/X11/xorg.conf.d/50-mtrack.conf
# This config is specialized for MacBook Air 2012 (5,2)
Section "InputClass"
        MatchIsTouchpad "on"
        Identifier      "Touchpads"
        MatchDevicePath "/dev/input/event*"
        Driver          "mtrack"
        # The faster you move, the more distance pointer will travel, using "polynomial" profile
        Option          "AccelerationProfile" "2"
        # Tweak cursor movement speed with this
        Option          "Sensitivity" "0.05"
        # Pressure at which a finger is detected as a touch
        Option          "FingerHigh" "5"
        # Pressure at which a finger is detected as a release
        Option          "FingerLow" "5"
        # I often use thumb to press down the physical button, so let's not ignore it
        Option          "IgnoreThumb" "false"
        Option          "ThumbRatio" "70"
        Option          "ThumbSize" "25"
        # Ignore palm, with palm takes up to 30% of your touch pad
        Option          "IgnorePalm" "true"
        Option          "PalmSize" "30"
        # Trigger mouse button when tap: 1 finger - left click, 2 finger - right click, 3 - middle click
        Option          "TapButton1" "1"
        Option          "TapButton2" "3"
        Option          "TapButton3" "2"
        Option          "TapButton4" "0"
        Option          "ClickTime" "25"
        # Disable tap-to-drag, we're using three finger drag instead
        Option          "TapDragEnable" "false"
        # While touching the touch pad with # fingers, press the touchpad physical click button
        Option          "ClickFinger1" "1"
        Option          "ClickFinger2" "3"
        Option          "ClickFinger3" "2"
        Option          "ButtonMoveEmulate" "false"
        Option          "ButtonIntegrated" "true"
        # The momentum after scroll fingers released
        Option          "ScrollCoastDuration" "300"
        Option          "ScrollCoastEnableSpeed" ".1"
        # Natural scrolling with two fingers
        Option          "ScrollSmooth" "true"
        Option          "ScrollUpButton" "5"
        Option          "ScrollDownButton" "4"
        Option          "ScrollLeftButton" "7"
        Option          "ScrollRightButton" "6"
        # Tweak scroll sensitivity with ScrollDistance, don't touch ScrollSensitivity
        Option          "ScrollDistance" "250"
        Option          "ScrollClickTime" "10"
        # Three finger drag
        Option          "SwipeDistance" "1"
        Option          "SwipeLeftButton" "1"
        Option          "SwipeRightButton" "1"
        Option          "SwipeUpButton" "1"
        Option          "SwipeDownButton" "1"
        Option          "SwipeClickTime" "0"
        Option          "SwipeSensitivity" "1500"
        # Four finger swipe, 8 & 9 are for browsers navigating back and forth respectively
        Option          "Swipe4LeftButton" "9"
        Option          "Swipe4RightButton" "8"
        # Mouse button >= 10 are not used by Xorg, so we'll map them with xbindkeys and xdotool later
        Option          "Swipe4UpButton" "11"
        Option          "Swipe4DownButton" "10"
        # Mouse buttons triggered by 2-finger pinching gesture
        Option          "ScaleDistance" "300"
        Option          "ScaleUpButton" "12"
        Option          "ScaleDownButton" "13"
        # Mouse buttons trigger by 2-finger rotating gesture, disabled to enhance the pinch gesture
        Option          "RotateLeftButton" "0"
        Option          "RotateRightButton" "0"
EndSection

Few things to note from above config file:

  • This config file is tested on Macbook Air 2012 (5,2)
  • You’ll most likely need to tweak the cursor sensitivity. Do so at Option "Sensitivity" "0.10", replacing value 0.10 to any other values between 0 and 1. The larger, the more movement.
  • You can tweak 2 finger scrolling sensitivity at ScrollDistance.
  • These scroll and swipe are natural, so you may swap the button number if you want the reverse.
  • Click on tap is enabled. If you don’t want that, set those TapButton# value to “0”
  • My config doesn’t ignore thumb. I often press the physical touchpad button with thumb. If you want to ignore thumb, set IgnoreThumb to “true”.

If you want further tweaks, head to the driver’s Github README and read the configuration instructions.

Updated 2019-08-19: I have added AccelerationProfile and tweak Sensitivity and SwipeSensitivity to make the experience with touchpad even more closer to that on macOS.

Updated 2018-09-18: There’s another key point in my notes that I forgot to include: During my first setup with mtrack, the driver didn’t work until I add my current Linux user to the input group. Do so with following command:

sudo adduser "`whoami`" input

After that, log out and log in to your desktop. You’ll know the driver is being used if you can drag or make selection immediately with three fingers on the touchpad.

Disable touchpad while typing with dispad permalink

After using mtrack for a while, I notice one of the annoying things is that touchpad is not disabled while typing which make the caret jump if you accidentally tap on it (and because I enabled tap to click). If you have troubles with this, install the dispad daemon from the original author of mtrack:

# install addition dev dependencies for dispad
sudo apt install libconfuse-dev libxi-dev
# get code
cd /tmp
git clone https://github.com/BlueDragonX/dispad.git
cd dispad
# compile the daemon
./configure
make
sudo make install

Go ahead and start dispad by execute this command in terminal. A config file ~/.dispad[^2] is created for you with default options. You can keep those, or change some options to mine like below:

poll = 48
delay = 500

Lastly, we need to start dispad automatically every time we log in, so go to Activities, search and open Startup Applications. Add new entry, with name as “dispad”, command as /usr/local/bin/dispad and with an optional comment to remind you what it does.

Add more gestures with xbindkeys & xdotool permalink

With above mtrack config, I already have these gestures (if it’s not obvious for you):

  • Left mouse click with one finger tap; right mouse with two fingers tap; middle mouse with three fingers tap
  • Scroll with two fingers (both horizontal & vertical)
  • Drag with three fingers
  • Swipe left and right with 4 fingers will simulate mouse button number 9 & 8. This means I can navigate back and forth in browsers and many applications.

mtrack can simulate mouse button up to 15 with different gestures. However, Ubuntu only uses mouse buttons up to 9. To make use of other gestures, we need 2 additional tools: xbindkeys and xdotool.[^3]

Luckily, there’s no need for manual compilation this time. Just open terminal and install via command:

sudo apt install xbindkeys xdotool

So what are xbindkeys & xdotool? permalink

xbindkeys is a daemon listening to your inputs from any input devices including keyboard, mouse and touchpad. You’ll define a rule at which, if an input or combination of inputs matches, some command can be executed. That’s where xdotool come in. xdotool is the command line tool which is able to simulate other key inputs. So by combining xbindkeys and xdotool, we’ll be able to map high mouse buttons (> 9) to certain shortcuts that suit our needs.

To define the rules, you’ll need to open xbindkeys-config GUI app, from which you’ll define the keys listened and the actions (command). I won’t give the how-to here (which you can look it up here), but will provide my current xbindkeys config which you can copy and save it at ~/.xbindkeysrc:

# Next Workspace
"xdotool key super+Page_Down"
   b:11

# Move Next Workspace
"xdotool key --clearmodifiers super+shift+Page_Down"
   Control + b:11 + release

# Previous Workspace
"xdotool key super+Page_Up"
   b:10

# Move Previous Workspace
"xdotool key --clearmodifiers super+shift+Page_Up"
   Control + b:10 + release

# Zoom in
"xdotool key ctrl+21"
   b:12

# Zoom out
"xdotool key ctrl+20"
   b:13

What are these rules doing then? permalink

Combined with my mtrack config above, and with assumption that default shortcuts in Ubuntu is unchanged, these xbindkeys will allow you:

  • 4 finger swipe up: switch to next workspace
  • 4 finger swipe down: switch to previous workspace
  • While holding ctrl, 4 finger swipe up: Move active window to next workspace
  • While holding ctrl, 4 finger swipe down: Move active window to previous workspace
  • Pinch scaling down (move 2 fingers closer): trigger ctrl and - combination, which is zoom out in browsers and reduce font size in some apps
  • Pinch scaling up (move 2 fingers away): trigger ctrl and = combination, which is zoom in in browsers and enlarge font size in some apps

I haven’t found a use case for rotating gesture (button 14 & 15) so I currently disabled them.

Finally, don’t forget to add this command /usr/bin/xbindkeys_autostart to Startup Applications so that it is automatically started at reboot.

Bonus: pixel perfect scrolling on Firefox permalink

Updated 2018-08-19: FWIW, GTK3+ has started support for pixel perfect scrolling (no jumping, pixel by pixel scrolling) for many of its applications. That has greatly enhanced UX for laptop users or users with trackpad. However, Firefox, the default browser on many Linux distros, still uses the jumping scroll (or fake smooth with easing movement). I have searched a lot for how Firefox will support pixel perfect scrolling, like it does on macOS, but only found answers to current fake smooth option.

Thankfully, I’ve got a hint from a Redditor replying on my post on Reddit. The reply points to this post which I’ll quote here:

I know this works for Firefox 55 or newer, but don’t know the earliest version which supports it. I assume it will be enabled by default at some point, but it isn’t yet in Firefox 58 (the current nightly).

  1. Run this command: echo export MOZ_USE_XINPUT2=1 | sudo tee /etc/profile.d/use-xinput2.sh
  2. Log out and back in.
  3. Firefox should now use xinput 2.
  4. (optional) Open Firefox and go to about:preferences -> Advanced (or about:preferences -> Browsing for Firefox Nightly), and uncheck “Use smooth scrolling”. This disables the old style “smooth scrolling”, which just causes an annoying delay when using xinput2 style scrolling imo.

So by following above steps, pixel pefect scrolling is turned on for latest Firefox 62 and it’s working great.

Final words permalink

That’s my whole setup for multi-touch touchpad and it has made my life on Linux a lot easier! However, I discovered some issues with mtrack driver after a lot of use, but they are trivial and won’t dismiss the whole experience:

  • Scroll coast are sometimes sticky and make scroll move quickly in subsequence scroll gestures
  • Dispad sometimes doesn’t detect typing and lets the caret jump

Finally, this may just be temporary since libinput and Wayland are already chosen to be the future and they are actively developed. I will revisit libinput once it get better multi-touch support and more configurations, but mtrack is the way to go, for now.


[^1]: Here’s a brief touchpad driver 101: There are three known drivers for laptop touchpad on Linux, i.e. synaptics (discontinued), libinput and mtrack. For latest Ubuntu and other popular distros, libinput is the chosen driver because it has decent multi touch support (and being improved) and most importantly, it supports Wayland environment. There are few flaws with current libinput driver though, for example: I cannot adjust the sensitive of scroll with two fingers, I cannot disable tap-and-drag easily (some manual commands involved), I cannot drag with three fingers…

[^2]: The ~/ sign means this file is stored at current user’s home folder.

[^3]: These tools also require Xorg.