我可以让 Linux 上的鼠标中键滚动更像 Windows 上的自动滚动吗?

我可以让 Linux 上的鼠标中键滚动更像 Windows 上的自动滚动吗?

对于任何不知道自动滚动是什么的人,您可以在 Chromium 中体验它自动滚动扩展(速度设置为 3),在 Firefox 中则启用“使用自动滚动”选项。

启用鼠标中键滚动并不难,事实上我所要做的就是这样:

xinput set-prop 8 "libinput Scroll Method Enabled" 0, 0, 1 

然而它的行为根本不符合我想要的方式。

我想要的功能:

  • 单击时,它会启用“锁定滚动”,因此在不按住按钮的情况下向上或向下移动鼠标应该滚动。直到再次按下鼠标中键。
  • 单击或按住时,会出现一个指示起始位置的符号。
  • 单击或按住时,从单击的初始点向上/向下移动鼠标应该会在该方向上启用“自动滚动”,其速度取决于您移动鼠标的距离,将鼠标移回起点会停止滚动

我拥有的功能:

  • 单击时它不执行任何操作(嗯,执行 DE 必须执行的操作,我想禁用该选项,因为我完全习惯使用 ctrl+v 来粘贴内容)
  • 按住时,鼠标移动的行为类似于滚轮,例如滚动需要鼠标不断移动,没有可用的“自动滚动”。

正如您所看到的,缺少很多功能。当然,我可以在开始时使用 chrome 的自动滚动扩展,并且它对 chrome 有效。但我想要在整个系统范围内使用它,这就是它在 Windows 中的工作方式。

现在,也许要在系统范围内获得完整的自动滚动功能需要做一些工作(或者会吗?我不知道......),并且根据它的实现方式,它可能会在某些使用中键鼠标的应用程序中导致问题键绑定按钮(覆盖应用程序键绑定肯定是一个很大的禁忌)。

但如果我能够在按住鼠标中键时启用自动滚动,我会非常高兴,即使可能不是完整的功能,但它已经足够接近了。

答案1

除了我改进了(在我看来) cestarian 提供的脚本之外,我没有更好的答案,我想要水平滚动,而且我还遇到了罗技鼠标未正确拾取的问题。

我也没有看到有这么多循环的原因,其中单个循环会快得多并且允许在同一周期上进行多方向滚动:D

在 xUbuntu 18.04.2 LTS 上测试

sudo apt install xdotool xsel sxhkd

〜/.config/sxkhd/sxhkdrc

~button2
    "~/.config/sxkhd/autoscroll.sh"
@button2

~control + c
    echo -n | xsel -n -i
~control + shift + c
    echo -n | xsel -n -i
~control + x
    echo -n | xsel -n -i

〜/.config/sxkhd/autoscroll.sh

#!/bin/dash
# Autoscroll (hold only)

middlemousebutton=2

mousescrollup=4
mousescrolldown=5
mousescrollleft=6
mousescrollright=7

enableverticalscroll=1
enablehorizontalscroll=1

## Danger below :D

echo -n | xsel -n -i
eval $(xdotool getmouselocation --shell)
starty=$Y
startx=$X
toggle=$middlemousebutton
while [ $toggle -eq $middlemousebutton ]
do
    eval $(xdotool getmouselocation --shell)
    curry=$Y
    currx=$X
    if [ $enableverticalscroll -eq 1 ]
    then
        if [ $curry -gt $starty ]
        then
            speedy=$(expr $curry / 100 - $starty / 100)
            if [ $speedy -gt 0 ]
            then
                xdotool click --repeat $speedy --delay 1 $mousescrolldown
            fi
        else
            speedy=$(expr $curry / 100  - $starty / 100  | sed 's:-::')
            if [ $speedy -gt 0 ]
            then
                xdotool click --repeat $speedy --delay 1 $mousescrollup
            fi
        fi
    fi

    if [ $enablehorizontalscroll -eq 1 ]
    then
        if [ $currx -gt $startx ]
        then
            speedx=$(expr $currx / 100 - $startx / 100)
            if [ $speedx -gt 0 ]
            then
                xdotool click --repeat $speedx --delay 1 $mousescrollright
            fi
        else
            speedx=$(expr $currx / 100  - $startx / 100  | sed 's:-::')
            if [ $speedx -gt 0 ]
            then
                xdotool click --repeat $speedx --delay 1 $mousescrollleft
            fi
        fi
    fi

    toggle=$(xinput --list "Virtual core pointer" | grep -i -m 1 "Button state:" | grep -o "[$middlemousebutton]\+")
    sleep 0.02
done

chmod +x ~/.config/sxkhd/autoscroll.sh

确保将 sxhkd 添加到Session and Startup -> Autostart Applications

下次启动时一切都应该正常

答案2

(这里的脚本已经得到了很大的改进艾泽拉斯, 此外这是进一步修改的版本我添加了一些解决方法和技巧,并添加了单击滚动功能(默认情况下禁用它,但您只需在文件顶部设置“enableclickscroll=1”即可获得它)并进行一些重大改进。该脚本默认使用 bash 但与 dash 兼容)

我有一个 bash 脚本形式的工作解决方案,它并不是很完美,但它完成了工作,至少对于我的目的而言。

该脚本需要xdo工具x输入谢尔sxhkd是将脚本绑定到鼠标中键的推荐解决方案。

(注:脚本是短跑兼容、改变#!/bin/bash#!/bin/破折号使用更快的解释器(如果已安装)

#!/bin/bash
#Autoscroll (hold only)
echo -n | xsel -n -i
eval $(xdotool getmouselocation --shell)
starty=$Y
mouseid=$(xinput --list | grep -i -m 1 'mouse' | grep -o 'id=[0-9]\+' | grep -o '[0-9]\+')
toggle=0

while [ $toggle -eq 0 ]
do
    sleep 0.02
    mmouse=$(xinput --query-state $mouseid | grep 'button\[2' | cut -d \= -f2)
    toggle=$(xinput --query-state $mouseid | grep 'button\[2' | grep -c up)
    eval $(xdotool getmouselocation --shell)
    curry=$Y

    #Scroll down
    while [ $curry -gt $starty ] && [ $toggle -eq 0 ]
    do
        eval $(xdotool getmouselocation --shell)
        curry=$Y
        speed=$(expr $curry / 100 - $starty / 100)
        xdotool click --repeat $speed --delay 1 5
        toggle=$(xinput --query-state $mouseid | grep 'button\[2' | grep -c up)
        sleep 0.02
    done

    #Scroll up
    while [ $curry -lt $starty ] && [ $toggle -eq 0 ]
    do
        eval $(xdotool getmouselocation --shell)
        curry=$Y
        speed=$(expr $curry / 100  - $starty / 100  | sed 's:-::')
        xdotool click --repeat $speed --delay 1 4
        toggle=$(xinput --query-state $mouseid | grep 'button\[2' | grep -c up)
        sleep 0.02
    done

done

这是 sxhkd 配置:./.config/.sxhkd/sxhkdrc

~button2
    "/path/to/autoscroll"
@button2

~control + c
    echo -n | xsel -n -i
~control + shift + c
    echo -n | xsel -n -i
~control + x
    echo -n | xsel -n -i

上述脚本由 sxhkd 触发时将允许系统范围内的自动滚动,但仅限于按住鼠标中键时。单击鼠标中键将正常工作,但粘贴功能被禁用(除非您不使用 ctrl+c 或 ctrl+x 来复制内容)。

如果您希望启用中键单击粘贴(不推荐,除非您喜欢意外粘贴内容),请改用以下命令:

~button2
    "/path/to/autoscroll"
@button2

并且还注释掉或删除自动滚动脚本的第一行(回声-n | xsel -n -i 线)我使用的原因有几个sxhkd并不是xbindkeys

  • sxhkd 允许您在触发脚本之前首先正常单击绑定按钮(这就是 ~button2 所做的),这使得鼠标中键能够在执行此脚本的同时保持其先前的功能。
  • 出于某种原因,对于 sxhkd 和 xbindkeys 来说,如果我尝试将脚本绑定到鼠标中键,则只有在打开 libinput 鼠标滚轮模拟时才有效,如果我将其关闭,脚本将无法通过这些程序运行(即使如果它自己工作得很好)简而言之,解决这个问题的方法是 sxhkd 的 @ 前缀,因此是 @button2。

好消息是,按住鼠标中键滚动可以完美地工作(只要您不介意无法使用鼠标中键粘贴内容)。

坏消息是,单击鼠标中键切换自动滚动存在一些非常严重的问题,这就是为什么我没有将其保留在默认脚本中。

为了启用单击以切换自动滚动,请替换以下所有实例:

toggle=$(xinput --query-state $mouseid | grep 'button\[2' | grep -c up)

和:

if [ "$mmouse" = "down" ]; then
    toggle=$(xinput --query-state $mouseid | grep 'button\[2' | grep -c up)
else
    toggle=$(xinput --query-state $mouseid | grep 'button\[' | sort | grep -c down)
fi

按住并单击滚动的问题:

  • 它以最低速度滚动相当快,虽然可能适合大多数用户,但我个人更喜欢较慢的速度。最可能的解决方案是降低 libinput 的滚动速度,遗憾的是这并不像应有的那么容易(因此我尚未测试)。
  • 水平滚动没有实现,但是它很容易实现(我只是从来没有使用过它,所以我没有理由这样做)。目前,整个脚本基于 Y 轴,复制此处已有的内容并包括 X 轴将是一件简单的事情,您可以使用鼠标按钮 6 和 7,而不是用于垂直滚动的鼠标按钮 4 和 5。水平滚动。 (固定在艾泽拉斯版本& 修改后的版本
  • 没有图标指示滚动的起始位置,也没有光标变化指示滚动处于活动状态。我认为这应该不难解决,但我之前假设错误......
  • 如果您的鼠标光标位于可滚动位置(例如浏览器选项卡或任务栏,您可以在任务/选项卡之间滚动),则当您释放按钮时,它会意外地滚动。 (通过解决方法缓解修改后的版本

仅单击滚动时出现问题:

  • 并不总是触发(这是 sxhkd 当前配置的错误,如果我只使用 @button2 作为脚本并省略 ~button2,它工作得很好,但是,这也意味着你不能再使用鼠标中键来说打开浏览器中新选项卡中的链接,因为点击将不再被转发)(已修复修改后的版本通过添加“clickdelay”变量来控制宽限期,您必须释放鼠标中键才能激活单击滚动)
  • 不检测中键单击何时实际用于其他用途。 (例如,如果您使用中键单击在新选项卡中打开链接,则滚动很可能会作为中键单击的副作用而被激活,一个可能的解决方案是使用一个程序来检测光标状态并仅激活如果光标处于中性或悬停文本,或者至少在悬停链接时不会激活脚本,但我不知道这样的软件)
  • 再次按鼠标中键停止滚动不起作用(但是,您可以按任何其他鼠标按钮来停止滚动,例如左键或右键单击,所以这实际上没什么大不了的)这可能可以通过稍微摆弄脚本来解决但我没有抽出时间去做。 (固定在修改后的版本
  • 滚动并不绑定到光标的起始位置,而是绑定到光标本身(按住按钮时这不是问题)。这意味着,假设您在浏览器中并且使用此自动滚动脚本,如果您将鼠标在屏幕上移得太高,您将开始滚动选项卡,而不是在当前页面上上下滚动,这肯定不太理想,因为这意味着您在滚动时必须小心移动光标的位置。 (缓解于修改后的版本

第一个问题可以通过配置来解决./.config/.sxhkd/sxhkdrc像这样

@button2
    "/path/to/autoscroll"

然而,这不仅会破坏您按住滚动的能力,您的鼠标中键将仅用于自动滚动,如果没有 ~button2 行,您将无法再使用鼠标中键在新选项卡中打开链接。如果您从不使用该功能并且从不使用鼠标中键来粘贴内容,这可能很适合您,但否则我建议您不要这样做。

最重要的是,它非常适合按住鼠标中键自动滚动,而对于单击以切换自动滚动则效果不佳(这就是我将其禁用的原因)

这满足了OP要求的我的需求,但是如果有人碰巧有更好的解决方案,在我将此答案标记为解决方案之前,我将等待一段时间以获得更好的答案。

相关内容