Posso abilitare lo scorrimento trascinando il pulsante centrale in OS X?


16

Ho un mouse con tre pulsanti ma nessuna ruota.

In OS X, c'è un modo (forse con il software aggiuntivo) che mi consentirebbe di utilizzare il mio terzo pulsante per scorrere tenendolo e muovendo il mouse?

Risposte:


10

Smart Scroll fa quello che stai cercando, con la sua funzione 'Grab Scroll'. Assegnalo a "Button 3 (Middle)" e il trascinamento su entrambi gli assi funzionerà in app come browser (Chrome), Terminal, Adobe Photoshop e Finder - nessuna app che ho provato non ha funzionato con esso (usando 4.0 beta su e su). Ha una prova gratuita.

inserisci qui la descrizione dell'immagine


3

L'ho fatto con Hammerspoon con il seguente script di configurazione ispirato a questo thread: https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

passi:

  • Installa Hammerspoon
  • Fai clic sull'icona del menu e seleziona Open Config
  • Incolla il seguente luascript nella configurazione:

    -- 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()
    

appena provato e funziona magnificamente.
im_chc,

dato che preferisco fare Y-scroll al contrario, ho cambiato un po 'il codice lua: cambia "dy" nella riga "local scroll = hs.eventtap.event.newScrollEvent ({- dx * scrollmult, dy * scrollmult}, {}, 'pixel') "in negativo (quindi sarebbe" -dy * scrollmult ")
im_chc

2

Smooze lo fa, tra le altre cose. (Sono lo sviluppatore)

Ciò che lo differenzia dagli altri suggerimenti è la possibilità di usarlo in ogni app mac mentre identifica i collegamenti, ad esempio. (nel caso in cui usi il pulsante centrale trascina per afferrare e lanciare, ma desideri comunque che un clic sul pulsante centrale funga da pulsante centrale)

Con Smooze è più come afferrare-trascinare-lanciare che afferrare-trascinare. Il rilascio influenza lo slancio e l'animazione dello scroll, in modo simile allo scroll dell'iPhone.

inserisci qui la descrizione dell'immagine


2

C'è un'app open source molto carina chiamata Karabiner che farà questo e molto altro (rimappatura di tastiera e mouse ecc.). Vedi questa domanda per alcuni esempi. Inoltre per alcuni produttori forniscono software di controllo personalizzato che può consentire funzionalità migliorate / modificate (ad es. Logitech Control Center).

Come menzionato nei commenti seguenti, mentre una nuova versione di "Karabiner Elements" è stata rilasciata per MacOS Sierra (10.12) in poi, prevede solo il rimappatura basata su tastiera finora, quindi al momento non è possibile eseguire la rimappatura del mouse.

Tuttavia Hammerspoon è un altro strumento open source gratuito che può essere utilizzato, tra le altre cose, per rimappare i tasti del mouse (e / o della tastiera) a diverse funzioni. Dovrai installare lo strumento e fornirgli alcune configurazioni appropriate - vedi esempi qui per la rimappatura del mouse.

Per verificare quali tipi di eventi e mouseEventButtonNumbers vengono generati dal tuo dispositivo, puoi eseguirlo (copia / incolla le 4 linee nella console) nella console di Hammerspoon (usa reload configper fermarlo):

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

Nota: se hai installato gli strumenti Logitech Control Center (LCC), acquisisce gli eventi direttamente dai dispositivi Logitech utilizzando il modulo kernel installato in modo che Hammerspoon non possa vederli. Dovrai disinstallare LCC se vuoi rimappare i pulsanti del mouse usando Hammerspoon.


1
Purtroppo Karabiner non funziona più con i moderni OSX. Ora esiste un "Karabiner Elements", ma ha la metà della funzionalità dell'originale e questa è una delle cose che non può fare.
Nathan Hornby,

1
Sì, al momento è limitato, quindi ho aggiornato la mia risposta per aggiungere un'altra soluzione.
Pierz,

Hammerspoon è la soluzione su cui sono arrivato ieri, quindi un buon suggerimento! :) Per qualche motivo non sono riuscito a legarlo a uno dei pulsanti del mouse, ma mapparlo su ctrl + cmd sembrava funzionare bene.
Nathan Hornby,

1
Ho aggiunto un'altra modifica poiché avevo questo problema quando avevo installato LCC ma disinstallandolo ho risolto (una volta che avessi funzionato quali pulsanti generavano quale mouseEventButtonNumber - sul mio mini-pulsante sinistro di Marble Mouse è 3 e quello destro è 4) .
Pierz,

Sospettavo che potesse essere questo il problema! Grazie per la conferma, lo risolverò quando ne avrò la possibilità.
Nathan Hornby,

1

Dipende dal software, ad esempio Firefox lo supporta, mentre Google Chrome no.

Attualmente non esiste alcun software che abiliti tale funzionalità a livello di sistema in OS X, purtroppo.


Forse non era compatibile con Chrome nel 2011, ma certamente nel 2014 dopo alcune revisioni, "Grab Scroll" di Smart Scroll funziona senza problemi con Chrome e Opera, posso confermare. Penso che sia esteso a tutto il sistema operativo in quanto funziona in Finder, Adobe Photoshop e persino Terminal. Quindi penso che i tuoi dati non siano aggiornati! :)

1

Ho usato Better Touch Tool per assegnare Ctrl + tasto centrale a PgUp e Opzione + tasto centrale a PgDown. È gratuito, software eccellente e funziona bene.


1

+1 per Hammerspoon e uno script, un normale mouse / trackball mi fa impazzire su un Mac.

Ne ho scritto uno per scorrere mentre il pulsante centrale del mouse è premuto: più si sposta il mouse più velocemente scorrerà.

Il clic funziona ancora come un normale clic con una zona morta di 5 pixel, quindi non è necessario mantenere il mouse perfettamente fermo tra la pressione e il rilascio della rotellina.

------------------------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------------------------

Funzionalità killer! Grazie mille, esattamente quello che stavo cercando. Un bug tuttavia deltaX = deltaY * -1dovrebbe essere deltaY = deltaY * -1e ho commentato deltaX = deltaX * -1perché non volevo invertire l'asse X.
Tyler,

Grazie per aver notato l'errore di battitura. L'ho riscritto un po 'e ho cambiato l'opzione per invertire solo lo scorrimento verticale
TIM
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.