Могу ли я включить прокрутку с помощью перетаскивания средней кнопкой в OS X?

Вопрос или проблема

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

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

Я сделал это с помощью Hammerspoon с помощью следующего скрипта конфигурации, вдохновленного этой темой: https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

Шаги:

  • Установите Hammerspoon
  • Нажмите на его значок меню и выберите Open Config
  • Вставьте следующий lua скрипт в конфигурацию:

    -- УПРАВЛЕНИЕ ПРОКРУТКОЙ С УДЕРЖИВАНИЕМ КНОПКИ МЫШИ
    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   -- отрицательный множитель заставляет мышь работать как традиционное колесо прокрутки
    
    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')
                -- возвращаем мышь на место
                hs.mouse.setAbsolutePosition(oldmousepos)
                return true, {scroll}
            else 
                return false, {}
            end 
    end)
    
    overrideOtherMouseDown:start()
    overrideOtherMouseUp:start()
    dragOtherToScroll:start()
    

Smart Scroll делает то, что вам нужно, с помощью функции ‘Grab Scroll’. Назначьте её на ‘Button 3 (Middle)’, и перетаскивание по обеим осям будет работать в таких приложениях, как браузеры (Chrome), Terminal, Adobe Photoshop и Finder – ни одно приложение, с которым я пробовал, не работало с этим (используя бета-версии 4.0 и выше). У него есть бесплатная пробная версия.

Скриншот Smart Scroll

Smooze делает это, среди прочего. (Я разработчик)

С Smooze это больше похоже на захват-перетаскивание-бросок, чем на захват-перетаскивание. Освобождение влияет на движение и анимацию прокрутки, похоже на прокрутку iPhone.

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

Обновлено (2022): Появилось новое программное обеспечение с открытым исходным кодом под названием Karabiner Elements, которое сделает это и много другого – оно может переназначить клавиатуру и переназначение мыши и т.д.

Это заменяет старое приложение ‘Karabiner’ (Смотрите этот вопрос для [старых] некоторых примеров) и теперь действительно предоставляет возможность переназначить как мышь, так и клавиатуру, как упомянул @Nathan в комментариях.

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

Чтобы проверить, какие типы событий и mouseEventButtonNumbers генерируются вашим устройством, вы можете запустить это (просто скопируйте/вставьте 4 строки в консоли) в консоли Hammerspoon (используйте reload config, чтобы остановить его):

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

Примечание: Если вы установили инструменты Logitech Control Centre (LCC) – они захватывают события напрямую из устройств Logitech с использованием их установленного модульного ядра, так что Hammerspoon не может их видеть. Вам нужно удалить LCC, если вы хотите переназначить кнопки мыши с помощью Hammerspoon.

+1 за Hammerspoon и скрипт, обычная мышь/трекбол сводит меня с ума на Mac.

Я написал один скрипт, чтобы прокручивать, пока нажата средняя кнопка мыши – чем дальше вы двигаете мышь, тем быстрее она прокручивается.

Щелчок по-прежнему работает как обычный щелчок с мертвой зоной 5 пикселей, так что вам не нужно держать мышь абсолютно неподвижной между нажатиями и отпусканием колеса.

------------------------------------------------------------------------------------------
-- АВТОПРОКРУТКА С КНОПКИ КОЛЕСА МЫШИ
-- timginter @ GitHub
------------------------------------------------------------------------------------------

-- идентификатор кнопки колеса мыши
local mouseScrollButtonId = 2

-- конфигурация скорости и направления прокрутки
local scrollSpeedMultiplier = 0.1
local scrollSpeedSquareAcceleration = true
local reverseVerticalScrollDirection = false
local mouseScrollTimerDelay = 0.01

-- конфигурация круга
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)
    -- раскомментируйте строку ниже, чтобы увидеть идентификатор нажатой кнопки
    --print(e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']))

    if e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber']) == mouseScrollButtonId then
        -- удалите круг, если он существует
        if mouseScrollCircle then
            mouseScrollCircle:delete()
            mouseScrollCircle = nil
        end

        -- остановите таймер, если он работает
        if mouseScrollTimer then
            mouseScrollTimer:stop()
            mouseScrollTimer = nil
        end

        -- сохраните координаты мыши
        mouseScrollStartPos = hs.mouse.absolutePosition()
        mouseScrollDragPosX = mouseScrollStartPos.x
        mouseScrollDragPosY = mouseScrollStartPos.y

        -- начните таймер прокрутки
        mouseScrollTimer = hs.timer.doAfter(mouseScrollTimerDelay, mouseScrollTimerFunction)

        -- не отправляйте событие нажатия кнопки прокрутки
        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
        -- отправьте оригинальное событие отпускания кнопки, если оно было отпущено в пределах 'mouseScrollCircleDeadZone' пикселей от оригинальной позиции и цикл прокрутки не существует
        mouseScrollPos = hs.mouse.absolutePosition()
        xDiff = math.abs(mouseScrollPos.x - mouseScrollStartPos.x)
        yDiff = math.abs(mouseScrollPos.y - mouseScrollStartPos.y)
        if (xDiff < mouseScrollCircleDeadZone and yDiff < mouseScrollCircleDeadZone) and not mouseScrollCircle then
            -- отключите переопределение мыши прокрутки
            overrideScrollMouseDown:stop()
            overrideScrollMouseUp:stop()

            -- отправьте щелчок мыши прокрутки
            hs.eventtap.otherClick(e:location(), mouseScrollButtonId)

            -- повторно включите переопределение мыши прокрутки
            overrideScrollMouseDown:start()
            overrideScrollMouseUp:start()
        end

        -- удалите круг, если он существует
        if mouseScrollCircle then
            mouseScrollCircle:delete()
            mouseScrollCircle = nil
        end

        -- остановите таймер, если он работает
        if mouseScrollTimer then
            mouseScrollTimer:stop()
            mouseScrollTimer = nil
        end

        -- не отправляйте событие отпускания кнопки прокрутки
        return true
    end
end)

overrideScrollMouseDrag = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDragged }, function(e)
    -- проверка разумности
    if mouseScrollDragPosX == nil or mouseScrollDragPosY == nil then
        return true
    end

    -- обновите координаты мыши
    mouseScrollDragPosX = mouseScrollDragPosX + e:getProperty(hs.eventtap.event.properties['mouseEventDeltaX'])
    mouseScrollDragPosY = mouseScrollDragPosY + e:getProperty(hs.eventtap.event.properties['mouseEventDeltaY'])

    -- не отправляйте событие перетаскивания кнопки прокрутки
    return true
end)

function mouseScrollTimerFunction()
    -- проверка разумности
    if mouseScrollDragPosX ~= nil and mouseScrollDragPosY ~= nil then
        -- получите разность координат курсора относительно оригинального нажатия
        xDiff = math.abs(mouseScrollDragPosX - mouseScrollStartPos.x)
        yDiff = math.abs(mouseScrollDragPosY - mouseScrollStartPos.y)

        -- нарисуйте круг, если он еще не нарисован и курсор переместился более чем на 'mouseScrollCircleDeadZone' пикселей
        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

        -- отправьте событие прокрутки, если курсор переместился более чем на радиус круга
        if xDiff > mouseScrollCircleRad or yDiff > mouseScrollCircleRad then
            -- получите реальное значение xDiff и yDiff
            deltaX = mouseScrollDragPosX - mouseScrollStartPos.x
            deltaY = mouseScrollDragPosY - mouseScrollStartPos.y

            -- используйте 'scrollSpeedMultiplier'
            deltaX = deltaX * scrollSpeedMultiplier
            deltaY = deltaY * scrollSpeedMultiplier

            -- квадрат для лучшего ускорения прокрутки
            if scrollSpeedSquareAcceleration then
                -- модификация, чтобы сохранить отрицательные значения
                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.ceil / math.floor - событие прокрутки принимает только целые числа
             deltaXRounding = math.ceil
             deltaYRounding = math.ceil

             if deltaX < 0 then
                 deltaXRounding = math.floor
             end
             if deltaY < 0 then
                 deltaYRounding = math.floor
             end

             deltaX = deltaXRounding(deltaX)
             deltaY = deltaYRounding(deltaY)

            -- измените направление Y прокрутки, если 'reverseVerticalScrollDirection' установлено в true
            if reverseVerticalScrollDirection then
                deltaY = deltaY * -1
            end

            -- отправьте событие прокрутки
            hs.eventtap.event.newScrollEvent({-deltaX, deltaY}, {}, 'pixel'):post()
        end
    end

    -- перезапустите таймер
    mouseScrollTimer = hs.timer.doAfter(mouseScrollTimerDelay, mouseScrollTimerFunction)
end

-- запустите функции переопределения
overrideScrollMouseDown:start()
overrideScrollMouseUp:start()
overrideScrollMouseDrag:start()

------------------------------------------------------------------------------------------
-- КОНЕЦ АВТОПРОКРУТКИ С КНОПКИ КОЛЕСА МЫШИ
------------------------------------------------------------------------------------------

Это зависит от программного обеспечения - например, Firefox поддерживает это, а Google Chrome - нет.

В настоящее время нет программного обеспечения, чтобы включить такую функцию на уровне системы в OS X, к сожалению.

Я использовал Better Touch Tool, чтобы назначить Ctrl+средний щелчок на PgUp, а Option+средний щелчок на PgDown. Это бесплатное, отличное программное обеспечение, которое работает хорошо.

Karabiner-Elements имеет это реализованным.

Установите его, затем перейдите на эту страницу пользовательских модификаций и импортируйте правило "Изменить движение мыши на прокрутку". введите описание изображения здесь

Я написал небольшую программу для этой цели: https://github.com/emreyolcu/drag-scroll. Это более легкое решение по сравнению с Hammerspoon.

Она либо переключает прокрутку, когда нажата кнопка мыши 5, либо временно активирует прокрутку, пока удерживается клавиша Shift. Вы можете настроить кнопку мыши и модификаторы, которые она использует.

Ответ или решение

Вопрос о том, возможно ли активировать прокрутку с помощью средней кнопки мыши в операционной системе macOS, актуален для многих пользователей, которые используют мыши без колеса прокрутки. Ниже приведены детальные рекомендации и возможные решения, которые помогут вам реализовать эту функциональность.

1. Использование Hammerspoon

Hammerspoon — это мощный инструмент для автоматизации, который позволяет вам настраивать работу клавиатуры и мыши в macOS. Для реализации функции прокрутки с помощью средней кнопки мыши можно воспользоваться следующим Lua-скриптом:

Шаги по установке:

  1. Скачать и установить Hammerspoon с официального сайта: Hammerspoon.
  2. Открыть конфигурационный файл Hammerspoon через меню в строке задач.
  3. Скопировать и вставить приведённый ниже скрипт в конфигурационный файл:
-- Установка кнопки для прокрутки
local scrollMouseButton = 2
local deferred = false

overrideOtherMouseDown = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(e)
    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)
    local pressedMouseButton = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
    if scrollMouseButton == pressedMouseButton then 
        if (deferred) then
            -- дополнительные действия для прокрутки
            return true
        end
        return false
    end
    return false
end)

local oldmousepos = {}
local scrollmult = -4

dragOtherToScroll = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDragged }, function(e)
    local pressedMouseButton = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
    if scrollMouseButton == pressedMouseButton then
        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')
        hs.mouse.setAbsolutePosition(oldmousepos)
        return true, {scroll}
    else 
        return false, {}
    end 
end)

overrideOtherMouseDown:start()
overrideOtherMouseUp:start()
dragOtherToScroll:start()

Этот скрипт позволит вам использовать среднюю кнопку для прокрутки при её удерживании и движении мыши.

2. Использование Smart Scroll

Smart Scroll — это приложение, предоставляющее функциональность «Grab Scroll». Оно позволяет назначить использование третьей кнопки мыши для прокрутки, и оно работает во множестве приложений, таких как браузеры (например, Google Chrome), терминал и другие. Вы можете скачать пробную версию: Smart Scroll.

3. Smooze

Smooze — ещё одно решение, которое предоставляет гибкие опции прокрутки с помощью средней кнопки мыши. Оно отличается от других решений тем, что сохраняет возможность взаимодействия со ссылками и позволяет настраивать поведение прокрутки. Программа имеет множество полезных функций, начиная от простого захвата прокрутки и заканчивая анимацией прокрутки, напоминающей поведение на iPhone Smooze.

4. Karabiner-Elements

Karabiner-Elements — это приложение для переприсвоения клавиш и кнопок мыши. Оно позволяет настраивать многие параметры, включая прокрутку на основе движения мыши. Для установки и настройки вам нужно:

  1. Скачать Karabiner-Elements: Karabiner-Elements.
  2. Перейти на страницу правил Custom Complex Modifications и импортировать правило «Change mouse motion to scroll».

Заключение

Каждое из предложенных решений имеет свои преимущества и недостатки, поэтому выбор зависит от ваших личных предпочтений и задач. Установка одного из этих приложений позволит вам включить прокрутку путем перетаскивания с помощью средней кнопки мыши в macOS. Настройка может занять некоторое время, но в итоге обеспечит значительно более удобный интерфейс работы с вашим компьютером.

Если у вас остались вопросы или требуется дополнительная помощь, обратитесь к сообществу пользователей или специализированным форумам, где вы сможете получить более детальные советы.

Оцените материал
Добавить комментарий

Капча загружается...