Bisakah saya mengaktifkan pengguliran dengan seret tombol tengah di OS X?


16

Saya punya mouse dengan tiga tombol tetapi tidak ada roda.

Di OS X, apakah ada cara (mungkin dengan perangkat lunak addon) yang akan memungkinkan saya untuk menggunakan tombol ketiga untuk menggulir dengan memegang dan menggerakkan mouse?

Jawaban:


10

Smart Scroll melakukan apa yang Anda cari, dengan fitur 'Grab Scroll'. Tetapkan ke 'Tombol 3 (Tengah)' dan menyeret pada kedua sumbu akan bekerja di aplikasi seperti browser (Chrome), Terminal, Adobe Photoshop, dan Finder - tidak ada aplikasi yang saya coba belum bekerja dengan itu (menggunakan 4.0 betas ke atas). Ini memiliki uji coba gratis.

masukkan deskripsi gambar di sini


3

Saya melakukannya dengan Hammerspoon dengan skrip konfigurasi berikut yang terinspirasi oleh utas ini: https://github.com/tekezo/Karabiner/issues/814#issuecomment-337643019

Langkah:

  • Instal Hammerspoon
  • Klik ikon menu dan pilih Open Config
  • Rekatkan luaskrip berikut ke dalam konfigurasi:

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

coba saja dan itu bekerja dengan indah.
im_chc

karena saya lebih suka membuat Y-scroll sebaliknya, saya telah mengubah sedikit kode lua: ubah "dy" di baris "local scroll = hs.eventtap.event.newScrollEvent ({- dx * scrollmult, dy * scrollmult}, {}, 'pixel') "menjadi negatif (jadi" -dy * scrollmult ")
im_chc

2

Smooze melakukan itu, antara lain. (Saya pengembang)

Apa yang membedakannya dari saran lain adalah kemampuan untuk menggunakannya di setiap aplikasi mac sambil mengidentifikasi tautan, misalnya. (jika Anda menggunakan seret tombol tengah untuk meraih dan melempar, tetapi tetap ingin bahwa klik tombol tengah akan bertindak sebagai tombol tengah)

Dengan Smooze lebih mirip grab-drag-throw daripada grab-drag. Rilis ini mempengaruhi momentum dan animasi dari gulir, mirip dengan gulir iPhone.

masukkan deskripsi gambar di sini


2

Ada aplikasi open source yang sangat bagus bernama Karabiner yang akan melakukan ini dan banyak lagi (Keyboard dan mouse remapping dll). Lihat pertanyaan ini untuk beberapa contoh. Juga untuk produsen tertentu mereka menyediakan perangkat lunak kontrol kustom yang memungkinkan untuk fungsionalitas yang ditingkatkan / dimodifikasi (misalnya Pusat Kontrol Logitech).

Seperti disebutkan dalam komentar di bawah ini bahwa sementara versi baru 'Karabiner Elements' telah dirilis untuk MacOS Sierra (10.12) dan seterusnya, hanya menyediakan remapping berbasis keyboard sejauh ini - jadi saat ini remapping mouse tidak dapat dilakukan dengan itu.

Namun Hammerspoon adalah alat open source gratis lain yang dapat digunakan, di antara banyak hal lain, untuk memetakan kembali tombol pada mouse (dan / atau keyboard) ke berbagai fungsi. Anda harus menginstal alat dan menyediakannya dengan beberapa konfigurasi yang sesuai - lihat contoh di sini untuk memetakan ulang mouse.

Untuk memeriksa jenis acara dan mouseEventButtonNumber yang sedang dibuat oleh perangkat Anda, Anda dapat menjalankan ini (cukup salin / tempel 4 baris ke konsol) di konsol Hammerspoon (Gunakan reload configuntuk menghentikannya):

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

Catatan: Jika Anda telah menginstal alat Logitech Control Center (LCC) - itu mengambil peristiwa langsung dari perangkat Logitech menggunakan modul kernel yang terpasang sehingga Hammerspoon tidak dapat melihatnya. Anda harus menghapus LCC jika Anda ingin memetakan kembali tombol mouse menggunakan Hammerspoon.


1
Sayangnya Karabiner tidak lagi bekerja dengan OSX modern. Sekarang ada 'Elemen Karabiner' yang berfungsi, tetapi ia memiliki setengah fungsi dari yang asli, dan ini adalah salah satu hal yang tidak dapat dilakukannya.
Nathan Hornby

1
Ya itu saat ini terbatas sehingga saya telah memperbarui jawaban saya untuk menambahkan solusi lain.
Pierz

Hammerspoon adalah solusi yang saya dapatkan kemarin, saran yang sangat bagus! :) Untuk beberapa alasan saya tidak bisa mengikatnya ke salah satu tombol mouse, tetapi memetakannya ke ctrl + cmd sepertinya berfungsi dengan baik.
Nathan Hornby

1
Saya telah menambahkan suntingan lain karena saya memiliki masalah ini ketika saya menginstal LCC tetapi menghapusnya memperbaikinya (setelah saya bekerja tombol mana yang dihasilkan mouseEventButtonNumber - pada tombol mini kiri Mouse Marmer saya adalah 3 dan yang kanan adalah 4) .
Pierz

Saya menduga itu mungkin masalahnya! Terima kasih atas konfirmasi, saya akan mengatasinya ketika saya mendapatkan kesempatan.
Nathan Hornby

1

Tergantung pada perangkat lunak - misalnya, Firefox mendukungnya, sedangkan Google Chrome tidak.

Sayangnya, saat ini tidak ada perangkat lunak untuk mengaktifkan fitur sistem seperti itu di OS X.


Mungkin itu tidak kompatibel dengan Chrome pada tahun 2011, tapi tentu saja pada tahun 2014 setelah beberapa revisi, Smart Scroll 'Grab Scroll' bekerja dengan lancar dengan Chrome dan Opera, saya dapat mengonfirmasi. Saya pikir itu OS-lebar juga karena berfungsi di Finder, Adobe Photoshop, dan bahkan Terminal. Jadi saya pikir data Anda kedaluwarsa! :)

1

Saya menggunakan Better Touch Tool untuk menetapkan Ctrl + klik tengah ke PgUp, dan Option + klik tengah ke PgDown. Ini gratis, perangkat lunak luar biasa, dan berfungsi dengan baik.


1

+1 untuk Hammerspoon dan skrip, mouse / trackball yang normal membuat saya marah pada Mac.

Saya menulis satu untuk menggulir sementara tombol tengah mouse ditekan ke bawah - semakin jauh Anda menggerakkan mouse semakin cepat akan bergulir.

Klik masih berfungsi seperti klik normal dengan zona mati 5 piksel sehingga Anda tidak perlu menjaga mouse tetap diam antara menekan dan melepaskan roda.

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

Fitur pembunuh! Terima kasih banyak, persis apa yang saya cari. Namun satu bug deltaX = deltaY * -1seharusnya deltaY = deltaY * -1dan saya berkomentar deltaX = deltaX * -1karena saya tidak ingin sumbu X terbalik.
Tyler

Terima kasih telah menemukan kesalahan ketik. Saya menulis ulang sedikit dan mengubah opsi untuk membalikkan hanya pengguliran vertikal
TIM
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.