Kann ich das Scrollen mit gedrückter mittlerer Maustaste in OS X aktivieren?

15

Ich habe eine Maus mit drei Tasten, aber kein Rad.

Gibt es unter OS X eine Möglichkeit (möglicherweise mit Add-On-Software), mit der ich meine dritte Taste zum Scrollen verwenden kann, indem ich sie gedrückt halte und die Maus bewege?

kdt
quelle

Antworten:

10

Smart Scroll macht das, wonach Sie suchen, mit der Funktion "Bildlauf". Weisen Sie es "Taste 3 (Mitte)" zu, und ziehen Sie es auf beiden Achsen, um in Apps wie Browsern (Chrome), Terminal, Adobe Photoshop und Finder zu arbeiten betas up and up). Es ist eine kostenlose Testversion.

Bildbeschreibung hier eingeben

Ishan
quelle
2

Smooze macht das unter anderem. (Ich bin der Entwickler)

Was es von anderen Vorschlägen unterscheidet, ist die Möglichkeit, es in jeder Mac-App zu verwenden, während beispielsweise noch Links identifiziert werden. (Falls Sie mit der mittleren Taste ziehen, um zu greifen und zu werfen, aber dennoch möchten, dass ein Klick auf die mittlere Taste als mittlere Taste fungiert.)

Mit Smooze ist mehr wie greifen-ziehen-werfen als greifen-ziehen. Die Freigabe beeinflusst den Schwung und die Animation des Bildlaufs, ähnlich wie beim iPhone-Bildlauf.

Bildbeschreibung hier eingeben

Segev
quelle
2

Es gibt eine sehr schöne Open-Source- App namens Karabiner, die dies und noch viel mehr erledigt (Tastatur- und Maus-Remapping usw.). In dieser Frage finden Sie einige Beispiele. Für bestimmte Hersteller wird auch kundenspezifische Steuerungssoftware geliefert, die möglicherweise eine verbesserte / geänderte Funktionalität ermöglicht (z. B. Logitech Control Center).

Wie in den Kommentaren unten erwähnt, ist eine neue Version von 'Karabiner Elements' ab MacOS Sierra (10.12) nur noch für tastaturbasiertes Remapping vorgesehen - daher kann derzeit kein Maus-Remapping durchgeführt werden.

Allerdings Hammerspoon ist ein weiteres freies Open - Source - Tool , das verwendet werden kann, unter vielen anderen Dingen, die Tasten auf der Maus neu zuzuordnen (und / oder Tastatur) auf verschiedene Funktionen. Sie müssen das Tool installieren und es mit einigen geeigneten Konfiguration liefern - siehe Beispiele hier für Maus Remapping.

Um zu überprüfen, welche Ereignistypen und mouseEventButtonNumbers von Ihrem Gerät generiert werden, können Sie dies in der Hammerspoon-Konsole ausführen (kopieren Sie die 4 Zeilen in die Konsole, und fügen Sie reload configsie ein):

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

Hinweis: Wenn Sie die Logitech Control Center (LCC) -Tools installiert haben, werden die Ereignisse mit dem installierten Kernelmodul direkt von den Logitech-Geräten abgerufen, sodass Hammerspoon sie nicht sehen kann. Sie müssen LCC deinstallieren, wenn Sie die Maustasten mit Hammerspoon neu zuordnen möchten.

Pierz
quelle
1
Leider funktioniert Karabiner nicht mehr mit modernem OSX. Es gibt jetzt einen "Karabiner Elements", der die Hälfte der Funktionalität des Originals hat, und dies ist eines der Dinge, die er nicht kann.
Nathan Hornby
1
Ja, es ist derzeit begrenzt, daher habe ich meine Antwort aktualisiert, um eine weitere Lösung hinzuzufügen.
Pierz
Hammerspoon ist die Lösung, auf der ich gestern gelandet bin, also guter Vorschlag! :) Aus irgendeinem Grund konnte ich es nicht an eine der Maustasten binden, aber die Zuordnung zu Strg + Cmd schien gut zu funktionieren.
Nathan Hornby
1
Ich habe eine weitere Bearbeitung hinzugefügt, da ich dieses Problem hatte, als ich LCC installiert hatte, aber es deinstallierte, um es zu beheben. .
Pierz
Ich vermutete, dass dies das Problem sein könnte! Vielen Dank für die Bestätigung, ich werde das klären, wenn ich die Chance bekomme.
Nathan Hornby
2

Ich habe es mit Hammerspoon mit dem folgenden Konfigurationsskript gemacht, das von diesem Thread inspiriert wurde: https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

Schritte:

  • Installieren Sie Hammerspoon
  • Klicken Sie auf das Menüsymbol und wählen Sie Open Config
  • Fügen Sie das folgende luaSkript in die Konfiguration ein:

    -- 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
quelle
habe es gerade ausprobiert und es funktioniert wunderbar.
im_chc
da ich das y-scroll lieber umgekehrt machen möchte, habe ich den lua code ein wenig geändert: ändere "dy" in der zeile "local scroll = hs.eventtap.event.newScrollEvent ({- dx * scrollmult, dy * scrollmult}, {}, 'pixel') "zu negativ (also wäre es" -dy * scrollmult ")
im_chc
1

Dies hängt von der Software ab. Firefox unterstützt dies beispielsweise, Google Chrome jedoch nicht.

Derzeit gibt es leider keine Software, die eine solche Funktion systemweit in OS X ermöglicht.


quelle
Vielleicht war es 2011 nicht mit Chrome kompatibel, aber 2014 funktioniert Smart Scrolls 'Grab Scroll' ohne Zweifel reibungslos mit Chrome und Opera, kann ich bestätigen. Ich denke, es ist auch OS-weit, da es in Finder, Adobe Photoshop und sogar Terminal funktioniert. Ich denke, Ihre Daten sind veraltet! :)
1

Ich habe Better Touch Tool verwendet , um PgUp Strg + Mittelklick und PgDown Wahltaste + Mittelklick zuzuweisen. Es ist kostenlos, ausgezeichnete Software und funktioniert gut.

Ezrock
quelle
1

+1 für Hammerspoon und ein Skript, eine normale Maus / Trackball macht mich auf einem Mac verrückt.

Ich habe einen geschrieben, um bei gedrückter mittlerer Maustaste zu scrollen - je weiter Sie die Maus bewegen, desto schneller wird gescrollt.

Das Klicken funktioniert immer noch wie ein normales Klicken mit einer 5-Pixel-Totzone, sodass Sie die Maus zwischen dem Drücken und Loslassen des Rads nicht vollkommen ruhig halten müssen.

------------------------------------------------------------------------------------------
-- 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
quelle
Killer-Funktion! Vielen Dank, genau das, wonach ich gesucht habe. Ein Fehler deltaX = deltaY * -1sollte jedoch sein deltaY = deltaY * -1und ich habe auskommentiert, deltaX = deltaX * -1weil ich nicht wollte, dass die X-Achse invertiert wird.
Tyler
Vielen Dank, dass Sie den Tippfehler entdeckt haben. Ich habe es ein wenig umgeschrieben und die Option geändert, nur vertikales Scrollen umzukehren
TIM