【Hammerspoon】トラックボールで画面スクロールしよう

私はせっかちなので、画面スクロールを爆速でしようとホイールを全力で回し、指が痛くなってきました（汗）
PC設定のホイール感度を上げているにもかかわらずです。

そんな中、トラックボールマウスを使っているので指の中でも強い親指は酷使に耐えられるのではないかと思いました。

## 何をする

**特定のキーまたはボタンを押している間、トラックボールを動かすと画面がスクロールするようにする。**
私はcommandを押している間スクロールモードにしてみています。

:::note warn
※Mac向けの説明になります。
:::

# 設定手順
#### 1. Hammerspoonのインストール
https://www.hammerspoon.org/

画面上部のDownloadボタンを押すとGitHubに飛びます。

GitHubのページ下にある　Hammerspoon-(バージョン).zip　からダウンロード（下図）。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![Qiita](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3290369/6830b0a2-1bdf-b3c2-d48d-a38cbcf54e41.png "Qiita")|
<font color="gray"></font>

ダウンロードできたらzipを展開してアプリを開きましょう。

#### 2. 設定ファイルの書き換え
アプリを起動できたらメニューバーにアプリアイコンが追加されるのでクリック。
OpenConfigで設定ファイルを開きます。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![Qiita](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3290369/e3a23f2c-2b2b-290e-d9cc-778825ca761c.png "Qiita")|
<font color="gray"></font>

そしたらエディタで設定ファイルが開くかと思いますので、そこに以下をペースト。
これはcommandを押している間トラックボールの動きがスクロールになります。

```lua
-- HANDLE SCROLLING
local oldmousepos = {}
local scrollmult = -4	-- negative multiplier makes mouse work like traditional scrollwheel

mousetap = hs.eventtap.new({5}, function(e)
	oldmousepos = hs.mouse.getAbsolutePosition()
	local mods = hs.eventtap.checkKeyboardModifiers()
	if mods['cmd'] then -- ここでキーを選べる　例:ctrl
		-- print ("will scroll")
		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')
		scroll:post()
		
		-- put the mouse back
		hs.mouse.setAbsolutePosition(oldmousepos)
		
		-- return true, {scroll}
		return true
	else
		return false, {}
	end
	-- print ("Mouse moved!")
	-- print (dx)
	-- print (dy)
end)
mousetap:start()
```

#### 3. 設定ファイルのリロード
最後に設定ファイルを上書き保存して、メニューバーからReload Configを押せば設定が反映されます！

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![Qiita](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3290369/91bf5aca-f4af-e6bf-683a-bf81bccc53e0.png "Qiita")|
<font color="gray"></font>

## オプション
- スクロール向きの変更
```lua
local scrollmult = -4
```
の数字を小さくするとスクロールスピードが遅くなります。
マイナスをなくすとスクロールの向きが反対になります。

- キーの変更
```lua
if mods['cmd'] then 
```
のところから変更可能。
```lua
if mods['cmd'] and mods['ctrl'] then 
```
複数のキーを押している間にすることも可能。

## （ちなみに）マウスを右クリック中にスクロールモードにする場合
設定ファイルを以下に書き換える。
片手で済むので楽になりますね。
```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()
```

## その他設定
https://github.com/pqrs-org/Karabiner-archived/issues/814

に色々な設定が書いてありそうでした。
この記事に記載のコードはこちらから抜粋したものです。

## 関連ページ
- https://qiita.com/zyyx-matsushita/items/070f7e9d021ac099b5e2