Macで右クリック＋トラックボール操作で画面スクロールしたい！→ それ Hammerspoon でできます！

# トラックボールで画面スクロールしたい！ :baseball:
トラックボールマウスは手元のボール操作でマウスカーソルが操作できるので、マウス本体の移動をすることなく操作でき手首に優しいマウスです。:thumbsup:
しかし、画面の上下スクロールはマウスウィールを使用するので、縦に長いサイトの閲覧や、特に頻繁にスクロールを要するエディタなどでは辛いものがあります。

会社では <a href="https://www.amazon.co.jp/%E3%82%B1%E3%83%B3%E3%82%B8%E3%83%B3%E3%83%88%E3%83%B3-%E3%80%90%E6%AD%A3%E8%A6%8F%E5%93%81%E3%83%BB5%E5%B9%B4%E4%BF%9D%E8%A8%BC%E4%BB%98%E3%81%8D-%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%80%91-SlimBlade-72327JP/dp/B004QJYBAG/ref=sr_1_1?s=computers&ie=UTF8&qid=1540721475&sr=1-1&keywords=slimblade">Kensington SlimBlade Trackball</a> を愛用していて、このタイプだとトラックボールの横回転が画面スクロールの操作となる設定のため困らないのですが、自宅では <a href="https://www.amazon.co.jp/%E3%83%AD%E3%82%B8%E3%82%AF%E3%83%BC%E3%83%AB-SW-M570-LOGICOOL-%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9%E3%83%88%E3%83%A9%E3%83%83%E3%82%AF%E3%83%9C%E3%83%BC%E3%83%AB/dp/B07DC88C26/ref=sr_1_2?s=computers&ie=UTF8&qid=1540734807&sr=1-2&keywords=m570t">LOGICOOL M570t</a> を使用していて、画面スクロールは通常のマウスウィール操作となります。Mac にはメーカーが公式でリリースしている Logicool Control Center というドライバが存在しますが、スクロールの進み幅を調整してもイマイチ変化してくれませんでした。:cold_sweat:

そこでトラックボールの操作で画面のスクロールを実現する、というハックなのですが、世間でも一定の需要があり、そのハックに特化したフリーソフトも存在します。

Windows 環境では Wheel Ball とか W10Wheel.NET などのフリーウェアがそれにあたりますが、Mac 環境では対応をしているソフトウェアが見当たりません。:scream:
以前は Keyremap4macbook や Karabinder の設定を駆使して実現できていましたが、 Karabinder-Elements にアップデートされてからは設定ができないようになってしまいました。

結果からですが [Hammerspoon](https://www.hammerspoon.org/) という無料アプリを使用する方法が快適だったので紹介したいと思います。

# 右クリック＋トラックボールで画面スクロールするには

- USB Overdrive を使用する（非推奨）
- Hammerspoon を使用する（推奨）



## USB Overdrive を使用する（非推奨）
http://www.usboverdrive.com/USBOverdrive/News.html

USB Overdrive は老舗のUSBデバイスの汎用ドライバです。
かつてゲームパッドとか Mac 対応が珍しかった時代に重宝しました。
現在もメンテナンスがされていて、Mojave にも対応しています。

<img width="552" alt="スクリーンショット 2018-10-28 0.27.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/208400/95fc9617-0522-d07d-2a56-6291781caf1a.png">
基本はシェアウェアですが、無料でも使用できます。
![スクリーンショット 2018-10-28 0.48.16.png](https://qiita-image-store.s3.amazonaws.com/0/208400/9f378a02-4467-c374-a270-5ac9ca6a7bad.png)
基本的にはデバイスの物理ボタンに対してキーのマッピングをするものなので、右クリックにショートカットをマッピングすることができます。

Karabinder-Elements などのキーボードユーティリティで登録したショートカットをバインドして連携することで右クリック＋トラックボールでの画面スクロールを実現できたはずです。

しかし、USB Overdrive のインストールが原因なのかは不明ですが、マウスの挙動がおかしくなったり、画面スクロールも動きが悪かったのであまりおすすめはしません。:thumbsdown:


## Hammerspoon を使用する（推奨）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/208400/1aae5b42-4c26-32c0-5ae0-bb8e28e58ed8.png)

http://www.hammerspoon.org/

OSの挙動を自動化するツールで、マウス操作やキーボードの操作にバインドしていろいろな操作を実行できます。
Karabinder が macOS に対応していない時期の代替アプリとしても有名です。
Lua 言語で自動化のプログラムを記述します。

以下の Karabinder の GitHub イシューのコメントに、Hammerspoon の Lua があるのでそれをそのまま利用します。
https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

```lua
-- HANDLE SCROLLING

local deferred = false

overrideRightMouseDown = hs.eventtap.new({ hs.eventtap.event.types.rightMouseDown }, function(e)
    --print("down"))
    deferred = true
    return true
end)

overrideRightMouseUp = hs.eventtap.new({ hs.eventtap.event.types.rightMouseUp }, function(e)
    -- print("up"))
    if (deferred) then
        overrideRightMouseDown:stop()
        overrideRightMouseUp:stop()
        hs.eventtap.rightClick(e:location())
        overrideRightMouseDown:start()
        overrideRightMouseUp:start()
        return true
    end

    return false
end)


local oldmousepos = {}
local scrollmult = -4	-- negative multiplier makes mouse work like traditional scrollwheel
dragRightToScroll = hs.eventtap.new({ hs.eventtap.event.types.rightMouseDragged }, function(e)
    -- print("scroll");

    deferred = false

    oldmousepos = hs.mouse.getAbsolutePosition()    

    local dx = e:getProperty(hs.eventtap.event.properties['mouseEventDeltaX'])
    local dy = e:getProperty(hs.eventtap.event.properties['mouseEventDeltaY'])
    local scroll = hs.eventtap.event.newScrollEvent({dx * scrollmult, dy * scrollmult},{},'pixel')
    
    -- put the mouse back
    hs.mouse.setAbsolutePosition(oldmousepos)

    return true, {scroll}
end)

overrideRightMouseDown:start()
overrideRightMouseUp:start()
dragRightToScroll:start()
```

右クリック押下時に `deferred` フラグを立てておき、マウスのドラッグ操作イベントにフックして、操作をハックする内容のようです。
よくある　JavaScript のドラッグ＆ドロップ操作のプログラムに似ています。

このスクリプトを Hammerspoon の Config にペーストし `Reload Config` すると・・・かなりスムーズで快適なスクロール！
マウスの右ボタンをクリックしながらトラックボールを上に転がすと上にスクロール、下に転がすと下にスクロールします。同じく左右スクロールもできるので、エクセルの編集なんかはすごく楽になります。:grinning:

ただ、自分の環境では Mac のスクロールの方向はナチュラルに設定しており、マウスウィールのスクロールが反転してしまうため、[Scroll Reverse](https://pilotmoon.com/scrollreverser/) というアプリを導入して、マウスウィールの挙動を反転していました。
この Lua スクリプトはマウスの動きをエミュレートするものなので、トラックボールの画面スクロールも反転してしまうため、以下の修正を加えています。:twisted_rightwards_arrows:

```lua
-- dy の値を反転
local scroll = hs.eventtap.event.newScrollEvent({dx * scrollmult, -dy * scrollmult},{},'pixel')

```


# まとめ
Hammerspoon すごい
AppleScript も直接実行できるみたいですし、かなりいろんなAPIが用意されているので、いろんなことがキーボードやマウス操作から実行できそう