OS Xで中ボタンのドラッグでスクロールを有効にできますか?


16

3つのボタンを備えたマウスがありますが、ホイールはありません。

OS Xでは、3番目のボタンを押したままマウスを動かしてスクロールするための3番目のボタンを使用できる方法(おそらくアドオンソフトウェア)がありますか?

回答:


10

Smart Scrollは、「Grab Scroll」機能を使用して、探していることを実行します。これを「ボタン3(中央)」に割り当てると、両方の軸でのドラッグは、ブラウザー(Chrome)、ターミナル、Adobe Photoshop、Finderなどのアプリで機能します-私が試したアプリは動作しません(4.0を使用)ベータ版)。無料試用版があります。

ここに画像の説明を入力してください


3

このスレッドに触発された次の構成スクリプトを使用して、Hammerspoonでそれを行いました:https : //github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

手順:

  • Hammerspoonをインストールする
  • メニューアイコンをクリックして選択します Open Config
  • 次のluaスクリプトを構成に貼り付けます。

    -- HANDLE SCROLLING WITH MOUSE BUTTON PRESSED
    local scrollMouseButton = 2
    local deferred = false
    
    overrideOtherMouseDown = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(e)
        -- print("down")
        local pressedMouseButton = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
        if scrollMouseButton == pressedMouseButton 
            then 
                deferred = true
                return true
            end
    end)
    
    overrideOtherMouseUp = hs.eventtap.new({ hs.eventtap.event.types.otherMouseUp }, function(e)
        -- print("up")
        local pressedMouseButton = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
        if scrollMouseButton == pressedMouseButton 
            then 
                if (deferred) then
                    overrideOtherMouseDown:stop()
                    overrideOtherMouseUp:stop()
                    hs.eventtap.otherClick(e:location(), pressedMouseButton)
                    overrideOtherMouseDown:start()
                    overrideOtherMouseUp:start()
                    return true
                end
                return false
            end
            return false
    end)
    
    local oldmousepos = {}
    local scrollmult = -4   -- negative multiplier makes mouse work like traditional scrollwheel
    
    dragOtherToScroll = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDragged }, function(e)
        local pressedMouseButton = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
        -- print ("pressed mouse " .. pressedMouseButton)
        if scrollMouseButton == pressedMouseButton 
            then 
                -- 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}
            else 
                return false, {}
            end 
    end)
    
    overrideOtherMouseDown:start()
    overrideOtherMouseUp:start()
    dragOtherToScroll:start()
    

試してみただけで、うまく機能します。
im_chc

Yスクロールを逆方向​​にしたいので、luaコードを少し変更しました。「local scroll = hs.eventtap.event.newScrollEvent({-dx * scrollmult、 dy * scrollmult}、{}、 'pixel') "を負に(したがって、「
dy

2

Smoozeは、特にそれを行います。(私は開発者です)

他の提案と異なる点は、たとえばリンクを特定しながら、すべてのMacアプリで使用できることです。(中ボタンをドラッグしてつかんで投げるが、中ボタンのクリックが中ボタンとして機能するようにしたい場合)

Smoozeでは、grab-dragよりもgrab-drag-throwに似ています。このリリースは、iPhoneのスクロールと同様に、スクロールの勢いとアニメーションに影響します。

ここに画像の説明を入力してください


2

Karabinerと呼ばれる非常に素晴らしいオープンソースアプリがあり、これを実行するほか、さらに多く(キーボードやマウスの再マッピングなど)を行います。いくつかの例については、この質問を参照してください。また、特定のメーカーに対しては、機能の改善/変更が可能なカスタム制御ソフトウェアを提供しています(Logitech Control Centerなど)。

以下のコメントで述べられているように、MacOS Sierra(10.12)向けに 'Karabiner Elements'の新しいバージョンがリリースされていますが、これまでのところキーボードベースの再マッピングのみを提供しています。

ただし、Hammerspoonは、マウス(および/またはキーボード)のキーをさまざまな機能に再マッピングするために使用できる別の無料のオープンソースツールです。例を参照してください-あなたはツールをインストールし、いくつかの適切な設定とそれを供給する必要がありますここでは、マウスの再マッピングのために。

デバイスによってどのイベントタイプとmouseEventButtonNumbersが生成されているかを確認するには、Hammerspoonコンソールでこれを実行します(コンソールに4行をコピー/貼り付けします)(使用reload configして停止します)。

hs.eventtap.new({"all"},function(e)
print(e,"mouseEventButtonNumber:",
e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']))
end):start()

注:Logitech Control Center(LCC)ツールをインストールした場合、インストールされたカーネルモジュールを使用してLogitechデバイスからイベントを直接取得するため、Hammerspoonはそれらを見ることができません。Hammerspoonを使用してマウスボタンを再マップする場合は、LCCをアンインストールする必要があります。


1
残念ながら、カラビナは最新のOSXでは動作しません。現在は「Karabiner Elements」がありますが、オリジナルの半分の機能しかありません。これはできないことの1つです。
ネイサンホーンビー

1
はい、現在は制限されているため、回答を更新して別のソリューションを追加しました。
ピアス

ハンマースプーンは昨日上陸した解決策なので、良い提案です!:)何らかの理由で、マウスボタンの1つにバインドすることができませんでしたが、ctrl + cmdへのマッピングはうまく機能しているように見えました。
ネイサンホーンビー

1
LCCをインストールしたときにこの問題が発生したため、別の編集を追加しましたが、それをアンインストールして修正しました(どのボタンがmouseEventButtonNumberを生成したかを働いた後、Marble Mouseの左のミニボタンは3で、右のボタンは4です) 。
ピアス

私はそれが問題かもしれないと疑った!確認のおかげで、機会があればそれを整理します。
ネイサンホーンビー

1

ソフトウェアに依存します-たとえば、Firefoxはそれをサポートしますが、Google Chromeはサポートしません。

残念ながら、OS Xにはそのような機能をシステム全体で有効にするソフトウェアはありません。


おそらく2011年にはChromeと互換性がなかったかもしれませんが、確かに2014年にはかなりの数の改訂が行われた後、Smart Scrollの「Grab Scroll」はChromeとOperaでスムーズに動作することを確認できます。Finder、Adobe Photoshop、さらにはTerminalでも機能するため、OS全体にも対応していると思います。だから私はあなたのデータが古いと思います!:)

1

Better Touch Toolを使用して、Ctrl +中クリックをPgUpに、Option +中クリックをPgDownに割り当てました。無料の優れたソフトウェアであり、うまく機能します。


1

Hammerspoonとスクリプトの+1。通常のマウス/トラックボールはMacで私を怒らせます。

マウスの中央ボタンが押されている間にスクロールするように書きました-マウスをさらに動かすと、スクロールが速くなります。

クリックは5ピクセルのデッドゾーンを持つ通常のクリックのように機能するため、ホイールを押してから離すまでマウスを完全に静止させる必要はありません。

------------------------------------------------------------------------------------------
-- AUTOSCROLL WITH MOUSE WHEEL BUTTON
-- timginter @ GitHub
------------------------------------------------------------------------------------------

-- id of mouse wheel button
local mouseScrollButtonId = 2

-- scroll speed and direction config
local scrollSpeedMultiplier = 0.1
local scrollSpeedSquareAcceleration = true
local reverseVerticalScrollDirection = false
local mouseScrollTimerDelay = 0.01

-- circle config
local mouseScrollCircleRad = 10
local mouseScrollCircleDeadZone = 5

------------------------------------------------------------------------------------------

local mouseScrollCircle = nil
local mouseScrollTimer = nil
local mouseScrollStartPos = 0
local mouseScrollDragPosX = nil
local mouseScrollDragPosY = nil

overrideScrollMouseDown = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(e)
    -- uncomment line below to see the ID of pressed button
    --print(e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']))

    if e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']) == mouseScrollButtonId then
        -- remove circle if exists
        if mouseScrollCircle then
            mouseScrollCircle:delete()
            mouseScrollCircle = nil
        end

        -- stop timer if running
        if mouseScrollTimer then
            mouseScrollTimer:stop()
            mouseScrollTimer = nil
        end

        -- save mouse coordinates
        mouseScrollStartPos = hs.mouse.getAbsolutePosition()
        mouseScrollDragPosX = mouseScrollStartPos.x
        mouseScrollDragPosY = mouseScrollStartPos.y

        -- start scroll timer
        mouseScrollTimer = hs.timer.doAfter(mouseScrollTimerDelay, mouseScrollTimerFunction)

        -- don't send scroll button down event
        return true
    end
end)

overrideScrollMouseUp = hs.eventtap.new({ hs.eventtap.event.types.otherMouseUp }, function(e)
    if e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']) == mouseScrollButtonId then
        -- send original button up event if released within 'mouseScrollCircleDeadZone' pixels of original position and scroll circle doesn't exist
        mouseScrollPos = hs.mouse.getAbsolutePosition()
        xDiff = math.abs(mouseScrollPos.x - mouseScrollStartPos.x)
        yDiff = math.abs(mouseScrollPos.y - mouseScrollStartPos.y)
        if (xDiff < mouseScrollCircleDeadZone and yDiff < mouseScrollCircleDeadZone) and not mouseScrollCircle then
            -- disable scroll mouse override
            overrideScrollMouseDown:stop()
            overrideScrollMouseUp:stop()

            -- send scroll mouse click
            hs.eventtap.otherClick(e:location(), mouseScrollButtonId)

            -- re-enable scroll mouse override
            overrideScrollMouseDown:start()
            overrideScrollMouseUp:start()
        end

        -- remove circle if exists
        if mouseScrollCircle then
            mouseScrollCircle:delete()
            mouseScrollCircle = nil
        end

        -- stop timer if running
        if mouseScrollTimer then
            mouseScrollTimer:stop()
            mouseScrollTimer = nil
        end

        -- don't send scroll button up event
        return true
    end
end)

overrideScrollMouseDrag = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDragged }, function(e)
    -- sanity check
    if mouseScrollDragPosX == nil or mouseScrollDragPosY == nil then
        return true
    end

    -- update mouse coordinates
    mouseScrollDragPosX = mouseScrollDragPosX + e:getProperty(hs.eventtap.event.properties['mouseEventDeltaX'])
    mouseScrollDragPosY = mouseScrollDragPosY + e:getProperty(hs.eventtap.event.properties['mouseEventDeltaY'])

    -- don't send scroll button drag event
    return true
end)

function mouseScrollTimerFunction()
    -- sanity check
    if mouseScrollDragPosX ~= nil and mouseScrollDragPosY ~= nil then
        -- get cursor position difference from original click
        xDiff = math.abs(mouseScrollDragPosX - mouseScrollStartPos.x)
        yDiff = math.abs(mouseScrollDragPosY - mouseScrollStartPos.y)

        -- draw circle if not yet drawn and cursor moved more than 'mouseScrollCircleDeadZone' pixels
        if mouseScrollCircle == nil and (xDiff > mouseScrollCircleDeadZone or yDiff > mouseScrollCircleDeadZone) then
            mouseScrollCircle = hs.drawing.circle(hs.geometry.rect(mouseScrollStartPos.x - mouseScrollCircleRad, mouseScrollStartPos.y - mouseScrollCircleRad, mouseScrollCircleRad * 2, mouseScrollCircleRad * 2))
            mouseScrollCircle:setStrokeColor({["red"]=0.3, ["green"]=0.3, ["blue"]=0.3, ["alpha"]=1})
            mouseScrollCircle:setFill(false)
            mouseScrollCircle:setStrokeWidth(1)
            mouseScrollCircle:show()
        end

        -- send scroll event if cursor moved more than circle's radius
        if xDiff > mouseScrollCircleRad or yDiff > mouseScrollCircleRad then
            -- get real xDiff and yDiff
            deltaX = mouseScrollDragPosX - mouseScrollStartPos.x
            deltaY = mouseScrollDragPosY - mouseScrollStartPos.y

            -- use 'scrollSpeedMultiplier'
            deltaX = deltaX * scrollSpeedMultiplier
            deltaY = deltaY * scrollSpeedMultiplier

            -- square for better scroll acceleration
            if scrollSpeedSquareAcceleration then
                -- mod to keep negative values
                deltaXDirMod = 1
                deltaYDirMod = 1

                if deltaX < 0 then
                    deltaXDirMod = -1
                end
                if deltaY < 0 then
                    deltaYDirMod = -1
                end

                deltaX = deltaX * deltaX * deltaXDirMod
                deltaY = deltaY * deltaY * deltaYDirMod
            end

            -- math.floor - scroll event accepts only integers
            deltaX = math.floor(deltaX)
            deltaY = math.floor(deltaY)

            -- reverse Y scroll if 'reverseVerticalScrollDirection' set to true
            if reverseVerticalScrollDirection then
                deltaY = deltaY * -1
            end

            -- send scroll event
            hs.eventtap.event.newScrollEvent({-deltaX, deltaY}, {}, 'pixel'):post()
        end
    end

    -- restart timer
    mouseScrollTimer = hs.timer.doAfter(mouseScrollTimerDelay, mouseScrollTimerFunction)
end

-- start override functions
overrideScrollMouseDown:start()
overrideScrollMouseUp:start()
overrideScrollMouseDrag:start()

------------------------------------------------------------------------------------------
-- END OF AUTOSCROLL WITH MOUSE WHEEL BUTTON
------------------------------------------------------------------------------------------

キラー機能!本当にありがとう、まさに私が探していたもの。ただし、1つのバグがあるdeltaX = deltaY * -1はずです。X軸を反転させたくないのでdeltaY = deltaY * -1コメントしましdeltaX = deltaX * -1た。
タイラー

タイプミスを見つけてくれてありがとう。私はそれを少し書き直しのみ垂直方向のスクロールを逆にするオプションを変更する
TIM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.