Puis-je activer le défilement avec glisser le bouton du milieu dans OS X?

16

J'ai une souris avec trois boutons mais pas de molette.

Sous OS X, existe-t-il un moyen (peut-être avec un logiciel complémentaire) qui me permettrait d'utiliser mon troisième bouton pour faire défiler en le tenant et en déplaçant la souris?

kdt
la source

Réponses:

10

Smart Scroll fait ce que vous recherchez, avec sa fonction 'Grab Scroll'. Attribuez-le au `` Bouton 3 (milieu) '' et faites-le glisser sur les deux axes pour fonctionner dans des applications telles que les navigateurs (Chrome), Terminal, Adobe Photoshop et Finder - aucune application que j'ai essayée n'a fonctionné avec elle (en utilisant le 4.0 bêtas de plus en plus). Il a un essai gratuit.

entrez la description de l'image ici

Ishan
la source
3

Je l'ai fait avec Hammerspoon avec le script de configuration suivant inspiré de ce fil: https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

Pas:

  • Installer Hammerspoon
  • Cliquez sur son icône de menu et sélectionnez Open Config
  • Collez le luascript suivant dans la configuration:

    -- 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()
    
Alex Burdusel
la source
viens de l'essayer et cela fonctionne à merveille.
im_chc
comme je préfère faire le Y-scroll dans l'autre sens, j'ai un peu changé le code lua: changez "dy" dans la ligne "local scroll = hs.eventtap.event.newScrollEvent ({- dx * scrollmult, dy * scrollmult}, {}, 'pixel') "à négatif (ce serait donc" -dy * scrollmult ")
im_chc
2

Smooze fait cela, entre autres. (Je suis le développeur)

Ce qui le différencie des autres suggestions, c'est la possibilité de l'utiliser dans chaque application Mac tout en identifiant les liens, par exemple. (dans le cas où vous utilisez votre bouton du milieu glisser pour saisir et lancer mais que vous souhaitez toujours qu'un clic sur le bouton du milieu agisse comme un bouton du milieu)

Avec Smooze, cela ressemble plus à un drag-grab-throw qu'à un grab-drag. La version affecte l'élan et l'animation du défilement, similaire au défilement iPhone.

entrez la description de l'image ici

Segev
la source
2

Il y a une très belle application open source appelée Karabiner qui fera cela et bien plus encore (remappage du clavier et de la souris, etc.). Voir cette question pour quelques exemples. De plus, pour certains fabricants, ils fournissent un logiciel de contrôle personnalisé qui peut permettre des fonctionnalités améliorées / modifiées (par exemple, Logitech Control Center).

Comme mentionné dans les commentaires ci-dessous, même si une nouvelle version de `` Karabiner Elements '' a été publiée pour MacOS Sierra (10.12), elle ne prévoit pour l'instant que le remappage basé sur le clavier - donc le remappage de la souris ne peut actuellement pas être fait avec.

Cependant, Hammerspoon est un autre outil open source gratuit qui peut être utilisé, entre autres, pour remapper les touches de la souris (et / ou du clavier) à différentes fonctions. Vous devrez installer l'outil et lui fournir une configuration appropriée - voir les exemples ici pour le remappage de la souris.

Pour vérifier quels types d'événements et mouseEventButtonNumbers sont générés par votre appareil, vous pouvez exécuter cela (il suffit de copier / coller les 4 lignes dans la console) dans la console Hammerspoon (à utiliser reload configpour l'arrêter):

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

Remarque: Si vous avez installé les outils Logitech Control Center (LCC) - il saisit les événements directement à partir des périphériques Logitech à l'aide de leur module de noyau installé afin que Hammerspoon ne puisse pas les voir. Vous devrez désinstaller LCC si vous souhaitez remapper les boutons de la souris à l'aide de Hammerspoon.

Pierz
la source
1
Malheureusement, Karabiner ne fonctionne plus avec OSX moderne. Il y a maintenant un «Karabiner Elements», mais il a la moitié des fonctionnalités de l'original, et c'est l'une des choses qu'il ne peut pas faire.
Nathan Hornby
1
Oui, il est actuellement limité, j'ai donc mis à jour ma réponse pour ajouter une autre solution.
Pierz
Hammerspoon est la solution sur laquelle j'ai atterri hier, donc bonne suggestion! :) Pour une raison quelconque, je n'ai pas réussi à le lier à l'un des boutons de la souris, mais le mapper à ctrl + cmd semblait bien fonctionner.
Nathan Hornby
1
J'ai ajouté une autre modification car j'ai eu ce problème lorsque j'ai installé LCC mais le désinstaller l'a corrigé (une fois que j'avais travaillé quels boutons ont généré quel mouseEventButtonNumber - sur mon mini-bouton gauche de Marble Mouse est 3 et celui de droite est 4) .
Pierz
Je soupçonnais que cela pourrait être le problème! Merci pour la confirmation, je réglerai cela quand j'en aurai l'occasion.
Nathan Hornby
1

Cela dépend du logiciel - par exemple, Firefox le prend en charge, contrairement à Google Chrome.

Malheureusement, il n'existe actuellement aucun logiciel permettant d'activer une telle fonctionnalité à l'échelle du système sous OS X.


la source
Peut-être qu'il n'était pas compatible avec Chrome en 2011, mais certainement en 2014, après quelques révisions sans doute, le `` Grab Scroll '' de Smart Scroll fonctionne parfaitement avec Chrome et Opera, je peux le confirmer. Je pense qu'il est également valable pour l'ensemble du système d'exploitation, car il fonctionne dans Finder, Adobe Photoshop et même Terminal. Je pense donc que vos données sont obsolètes! :)
1

J'ai utilisé Better Touch Tool pour affecter Ctrl + clic milieu à PgUp et Option + clic milieu à PgDown. C'est un excellent logiciel gratuit qui fonctionne bien.

ezrock
la source
1

+1 pour Hammerspoon et un script, une souris / trackball normale me rend fou sur un Mac.

J'en ai écrit un pour faire défiler pendant que le bouton central de la souris est enfoncé - plus vous déplacez la souris plus vite elle défilera.

Le clic fonctionne toujours comme un clic normal avec une zone morte de 5 pixels, vous n'avez donc pas besoin de garder la souris parfaitement immobile entre le fait d'appuyer et de relâcher la molette.

------------------------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------------------------
TIM
la source
Fonction tueur! Merci beaucoup, exactement ce que je cherchais. Un bug deltaX = deltaY * -1devrait cependant être deltaY = deltaY * -1et j'ai commenté deltaX = deltaX * -1parce que je ne voulais pas que l'axe X soit inversé.
Tyler
Merci d'avoir repéré la faute de frappe. Je l'ai réécrit un peu et j'ai changé l'option pour inverser le défilement vertical uniquement
TIM