Чи можна ввімкнути прокрутку за допомогою перетягування середньої кнопки в OS X?


16

У мене миша з трьома кнопками, але без колеса.

Чи є в OS X якийсь спосіб (можливо, з програмним забезпеченням addon), який дозволив би використовувати мою третю кнопку для прокрутки, утримуючи її та переміщуючи мишу?

Відповіді:


10

Смарт-прокрутка робить те, що ви шукаєте, завдяки своїй функції «Захопити прокрутку». Призначте його "Кнопка 3 (середня)", і перетягування по обох осях працюватиме в таких додатках, як браузери (Chrome), термінал, Adobe Photoshop та Finder - жоден додаток, який я намагався, не працював з ним (використовуючи 4.0 бета-версії та вгору). У ньому є безкоштовна пробна версія.

введіть тут опис зображення


3

Я зробив це з Hammerspoon із наступним сценарієм конфігурації, натхненним цією ниткою: https://github.com/tekezo/Karabiner/isissue/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: змінити "dy" у рядку "local scroll = hs.eventtap.event.newScrollEvent ({- dx * scrollmult, dy * scrollmult}, {}, 'pixel') "to negative (так це було б" -dy * scrollmult ")
im_chc

2

Smooze робить це, серед іншого. (Я розробник)

Що відрізняє його від інших пропозицій, це можливість використовувати його у кожному додатку для Mac, хоча, як і раніше, ідентифікувати посилання. (якщо ви використовуєте середню кнопку перетягування, щоб захопити та кинути, але все ж хочете, щоб натискання середньої кнопки діяло як середня кнопка)

З Smooze більше схоже на grab-drag-кидання, ніж grab-drag. Випуск впливає на імпульс та анімацію прокрутки, подібно до прокрутки iPhone.

введіть тут опис зображення


2

Існує дуже хороший додаток з відкритим кодом під назвою Karabiner, який буде робити це і багато іншого (перескладання клавіатури та миші тощо). Дивіться це питання для деяких прикладів. Також для деяких виробників вони постачають програмне забезпечення для користування, яке може вдосконалювати / модифікувати функціональність (наприклад, Logitech Control Center).

Як зазначалося в коментарях нижче, поки нова версія «Karabiner Elements» була випущена для MacOS Sierra (10.12) і надалі вона передбачає лише перестановку на основі клавіатури - тому в даний час перезавантаження миші не може бути виконано з нею.

Однак Hammerspoon - це ще один безкоштовний інструмент з відкритим кодом, який, крім багатьох інших, може бути використаний для перестановки клавіш миші (та / або клавіатури) на різні функції. Вам необхідно встановити інструмент і поставити його з деякою відповідною конфігурацією - дивіться приклади тут для перепризначення миші.

Щоб перевірити, які типи подій та мишіEventButtonNumbers створюються вашим пристроєм, ви можете запустити це (просто скопіюйте / вставте 4 рядки в консоль) на консолі Hammerspoon (Використовуйте 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 не міг їх бачити. Вам потрібно буде видалити LCC, якщо ви хочете перевстановити кнопки миші за допомогою Hammerspoon.


1
На жаль, Karabiner вже не працює з сучасними OSX. Зараз це є "Карабінер Елементи", але він має половину функціоналу оригіналу, і це одна з речей, яку він не може зробити.
Натан Хорнбі

1
Так, наразі це обмежено, тому я оновив свою відповідь, щоб додати ще одне рішення.
П’єрз

Молоткова ложка - це рішення, на яке я приземлився вчора, тому гарна пропозиція! :) Я чомусь не зміг змусити його прив’язатись до однієї з кнопок миші, але відображення його на ctrl + cmd, здавалося, спрацювало нормально.
Натан Хорнбі

1
Я додав ще одну редагування, оскільки в мене була ця проблема, коли я встановив LCC, але видалення її виправив (колись я працював, які кнопки генерували яку мишуEventButtonNumber - на моїй Мармуровій миші ліва міні-кнопка - 3, а права - 4) .
П’єрз

Я підозрював, що це може бути проблемою! Дякую за підтвердження, я розберуся, коли отримаю можливість.
Натан Хорнбі

1

Це залежить від програмного забезпечення - наприклад, Firefox підтримує його, а Google Chrome - ні.

На жаль, на жаль, не існує програмного забезпечення, яке б дало змогу ввімкнути таку функцію в OS X


Можливо, це не було сумісним із Chrome ще в 2011 році, але, безумовно, у 2014 році, без сумніву, досить декількох доопрацьованих версій, «Скроп прокрутки» Smart Scroll безперебійно працює з Chrome і Opera, я можу підтвердити. Я думаю, що він є загальноосним, як це працює в Finder, Adobe Photoshop і навіть Терміналі. Тому я думаю, що ваші дані застаріли! :)

1

Я використовував інструмент Better Touch, щоб призначити Ctrl + середній клік до PgUp, а Option + Середній клік - PgDown. Це безкоштовно, відмінне програмне забезпечення та працює добре.


1

+1 для Hammerspoon та сценарію, звичайна миша / трекбол змушує мене зле на 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
------------------------------------------------------------------------------------------

Особливість вбивці! Велике спасибі, саме те, що я шукав. Однак одна помилка deltaX = deltaY * -1повинна бути, deltaY = deltaY * -1і я прокоментував це, deltaX = deltaX * -1оскільки не хотів перевернутий вісь X.
Тайлер

Дякуємо, що помітили друк. Я трохи переписав це і змінив опцію лише для зворотного вертикального прокрутки
TIM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.