응용 프로그램 당 마우스 휠 스크롤 속도를 변경하는 방법


9

위에서 실행되는 응용 프로그램 (초점)에 따라 다른 마우스 휠 스크롤 속도를 가질 수 있습니까?

웹 브라우저가 더 빨리 스크롤 할 수 있도록 구이를 위해 스크롤 속도를 느리게하는 것과 같습니다.


터미널을 지진? "마우스 속도"는 무엇과 관련이 있습니까?
Braiam

1
@Braiam OP가 방금 예제로 이것을 선택했다고 생각합니다. 응용 프로그램 이름은 무관하지만, 중요한 부분은 임의의 응용 프로그램 당 스크롤 속도의 변화
세르지 Kolodyazhnyy

@ 응용 프로그램이 마우스 휠 이벤트를 해석하는 방법은 매우 관련이 있습니다. 즉. Firefox는 버튼 5 (xorg가 마우스 스크롤을 아래로 보는 방식)를 "세 줄 아래로 부드럽게 이동"으로 해석합니다. 마찬가지로 다른 응용 프로그램은 다른 기준을 따를 수 있지만 일반적인 것은 3 줄이며 xserver에 의해 제어되지 않습니다.
Braiam

답변:


8

소개

다음 스크립트를 dynamic_mouse_speed.py 사용 하면 사용자 정의 창에 포커스가있을 때 마우스 포인터 및 / 또는 스크롤 속도를 지정해야합니다.

중요 : 스크립트에는 imwheel스크롤 속도를 높이기위한 프로그램이 필요합니다 . 통해 설치하십시오sudo apt-get install imwheel

용법

-h플래그 로 표시된대로 :

usage: dynamic_mouse_speed.py [-h] [-q] [-p POINTER] [-s SCROLL] [-v]

Sets mouse pointer and scroll speed per window

optional arguments:
  -h, --help            show this help message and exit
  -q, --quiet           Blocks GUI dialogs.
  -p POINTER, --pointer POINTER
                        mouse pointer speed,floating point number from -1 to 1
  -s SCROLL, --scroll SCROLL
                        mouse scroll speed,integer value , -10 to 10
                        recommended
  -v, --verbose         prints debugging information on command line

이 스크립트를 사용하면 마우스 클릭으로 추적하려는 창을 선택할 수 있습니다. 마우스 포인터가 십자형으로 바뀌고 원하는 창을 선택할 수 있습니다.

실행 python3 dynamic_mouse_speed.py만 만 팝업 대화 상자를 표시하고 그 자체로 아무것도하지 않습니다.

실행 python3 dynamic_mouse_speed.py -s 5하면 스크롤 속도 python3 dynamic_mouse_speed.py -s -5가 느려지고 스크롤 속도가 느려집니다. python3 dynamic_mouse_speed.py -p -0.9포인터 속도를 python3 dynamic_mouse_speed.py -p 0.9높이 면서 포인터 속도를 줄입니다. -s-p옵션은 혼합 될 수 있습니다. -v명령 행에서 디버깅 정보를 생성합니다.

출처

GitHub 요지 로도 사용 가능

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date:  August 2nd, 2016
Written for: https://askubuntu.com/q/806212/295286
Tested on Ubuntu 16.04 LTS

usage: dynamic_mouse_speed.py [-h] [-q] [-p POINTER] [-s SCROLL] [-v]

Sets mouse pointer and scroll speed per window

optional arguments:
  -h, --help            show this help message and exit
  -q, --quiet           Blocks GUI dialogs.
  -p POINTER, --pointer POINTER
                        mouse pointer speed,floating point number from -1 to 1
  -s SCROLL, --scroll SCROLL
                        mouse scroll speed,integer value , -10 to 10
                        recommended
  -v, --verbose         prints debugging information on command line


"""
from __future__ import print_function
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gtk,Gio
import time
import subprocess
import sys
import os
import argparse


def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError:
        print(">>> subprocess:",cmdlist)
        sys.exit(1)
    else:
        if stdout:
            return stdout



def get_user_window():
    """Select two windows via mouse. 
       Returns integer value of window's id"""
    window_id = None
    while not window_id:
        for line in run_cmd(['xwininfo', '-int']).decode().split('\n'):
            if 'Window id:' in line:
                window_id = line.split()[3]
    return int(window_id)

def gsettings_get(schema,path,key):
    """Get value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema,path)
    return gsettings.get_value(key)

def gsettings_set(schema,path,key,value):
    """Set value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema,path)
    return gsettings.set_double(key,value)

def parse_args():
    """ Parse command line arguments"""
    arg_parser = argparse.ArgumentParser(
                 description="""Sets mouse pointer and scroll """ + 
                             """speed per window """)
    arg_parser.add_argument(
                '-q','--quiet', action='store_true',
                help='Blocks GUI dialogs.',
                required=False)

    arg_parser.add_argument(
                '-p','--pointer',action='store',
                type=float, help=' mouse pointer speed,' + 
                'floating point number from -1 to 1', required=False)

    arg_parser.add_argument(
                '-s','--scroll',action='store',
                type=int, help=' mouse scroll speed,' + 
                'integer value , -10 to 10 recommended', required=False)

    arg_parser.add_argument(
                '-v','--verbose', action='store_true',
                help=' prints debugging information on command line',
                required=False)
    return arg_parser.parse_args()

def get_mouse_id():
    """ returns id of the mouse as understood by
        xinput command. This works only with one
        mouse attatched to the system"""
    devs = run_cmd( ['xinput','list','--id-only']   ).decode().strip()
    for dev_id in devs.split('\n'):
        props = run_cmd( [ 'xinput','list-props', dev_id  ]   ).decode()
        if "Evdev Scrolling Distance" in props:
            return dev_id


def write_rcfile(scroll_speed):
    """ Writes out user-defined scroll speed
        to ~/.imwheelrc file. Necessary for
        speed increase"""

    number = str(scroll_speed)
    user_home = os.path.expanduser('~')
    with open( os.path.join(user_home,".imwheelrc") ,'w'  ) as rcfile:
        rcfile.write( '".*"\n' )
        rcfile.write("None, Up, Button4, " + number + "\n"   )   
        rcfile.write("None, Down, Button5, " + number + "\n")
        rcfile.write("Control_L, Up,   Control_L|Button4 \n" +
                     "Control_L, Down, Control_L|Button5 \n" +
                     "Shift_L,   Up,   Shift_L|Button4 \n" +
                     "Shift_L,   Down, Shift_L|Button5 \n" )



def set_configs(mouse_speed,scroll_speed,mouse_id):
    """ sets user-defined values
        when the desired window is in focus"""
    if mouse_speed:
        gsettings_set('org.gnome.desktop.peripherals.mouse',None, 'speed', mouse_speed)

    if scroll_speed:
       if scroll_speed > 0:
           subprocess.call(['killall','imwheel'])
           # Is it better to write config here
           # or in main ?
           write_rcfile(scroll_speed)
           subprocess.call(['imwheel'])
       else:
           prop="Evdev Scrolling Distance"
           scroll_speed = str(abs(scroll_speed))
           run_cmd(['xinput','set-prop',mouse_id,prop,scroll_speed,'1','1']) 



def set_defaults(mouse_speed,scroll_speed,mouse_id):
    """ restore values , when user-defined window
        looses focus"""
    if mouse_speed:
        gsettings_set('org.gnome.desktop.peripherals.mouse', None, 
                      'speed', mouse_speed)

    if scroll_speed:
        if scroll_speed > 0:
           subprocess.call(['killall','imwheel'])
        if scroll_speed < 0:
           prop="Evdev Scrolling Distance"
           run_cmd(['xinput','set-prop',mouse_id,prop,'1','1','1'])


def main():
    """Entry point for when program is executed directly"""
    args = parse_args()

    # Get a default configs
    # gsettings returns GVariant, but
    # setting same schema and key requires 
    # floating point number
    screen = Gdk.Screen.get_default()
    default_pointer_speed = gsettings_get('org.gnome.desktop.peripherals.mouse', 
                                          None, 
                                          'speed')
    default_pointer_speed = float(str(default_pointer_speed))


    # Ask user for values , or check if those are provided via command line
    if not args.quiet:
       text='--text="Select window to track"'
       mouse_speed = run_cmd(['zenity','--info',text])

    user_window = get_user_window() 

    scroll_speed = args.scroll    
    pointer_speed = args.pointer
    mouse_id = get_mouse_id()

    if pointer_speed: 
        if pointer_speed > 1 or pointer_speed < -1:

           run_cmd(['zenity','--error',
                    '--text="Value out of range:' + 
                    str(pointer_speed) + '"'])
           sys.exit(1)

    # ensure that we will raise the user selected window
    # and activate all the preferences 
    flag = True
    for window in screen.get_window_stack():
        if user_window == window.get_xid():
            window.focus(time.time())
            window.get_update_area()
    try:
        while True:
            time.sleep(0.25) # Necessary for script to catch active window
            if  screen.get_active_window().get_xid() == user_window:
                if flag:
                    set_configs(pointer_speed,scroll_speed,mouse_id) 
                    flag=False

            else:
               if not flag:
                  set_defaults(default_pointer_speed, scroll_speed,mouse_id)
                  flag = True

            if args.verbose: 
                print('ACTIVE WINDOW:',str(screen.get_active_window().get_xid()))
                print('MOUSE_SPEED:', str(gsettings_get(
                                          'org.gnome.desktop.peripherals.mouse',
                                           None, 'speed')))
                print('Mouse ID:',str(mouse_id))
                print("----------------------")
    except:
        print(">>> Exiting main, resetting values")
        set_defaults(default_pointer_speed,scroll_speed,mouse_id)

if __name__ == "__main__":
    main()

노트

  • 여러 스크립트 인스턴스를 사용하면 개별 창마다 속도를 설정할 수 있습니다.
  • 명령 행에서 실행할 때 팝업 대화 상자는 다음 메시지를 생성합니다 Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.. 무시할 수 있습니다.
  • Unity에서 수동으로 새 런처 항목을 편집 / 만들려면 어떻게합니까?를 참조하십시오 . 두 번 클릭으로 시작하려면이 스크립트에 대한 실행기 또는 바탕 화면 바로 가기를 작성하십시오.
  • 쉽게 액세스 할 수 있도록이 스크립트를 키보드 단축키에 연결하려면 키보드 단축키 를 추가하는 방법을 참조하십시오 .
  • 스크립트가 실행될 때 속성 이있는 첫 번째 장치에서 작동하므로 하나의 마우스 만 사용하는 것이 좋습니다.Evdev Scrolling Distance
  • 여러 창을 제어하기 위해 여러 인스턴스를 시작할 수 있지만 성능을 위해 권장하지는 않습니다.

놀라운 답변입니다. 가능하다면 50 회 담당자에게 수여합니다.

4
@luchonacho 언제든지 질문에 현상금을 제공 할 수 있지만 질문이 게시 된 후 2 일 후에 만 ​​사용할 수 있습니다 :)
Sergiy Kolodyazhnyy

2
스크롤 속도 변경에 대한 질문입니다. 그것은이 스크립트가하는 것처럼 보이지는 않지만 그렇게 할 수 있습니다. 실제로 창에 따라 마우스 커서의 이동 속도를 변경하면 대부분의 사용자가 예측할 수없는 방식으로 작동 할 수 있습니다. 속도 변화가 지연 될 때 더욱 그렇습니다.
kasperd

@kasperd 실제로, 질문 제목은 약간 오해의 소지가 있었으며 스크립트는 스크롤 속도가 아닌 포인터 속도를 변경합니다. 그러나 큰 문제는 아니며 실제로 스크롤 속도를 포함하도록 스크립트를 조정할 수 있습니다. 그러나 imwheel패키지를 설치 해야하므로 조금 더 복잡해집니다. 답변을 업데이트하면 알려 드리겠습니다. 예측할 수없는 동작을 찾는 사용자에 대해 말한 내용에 대해서는 예측할 수 없습니다. 더 설명해 주시겠습니까?
Sergiy Kolodyazhnyy

@Serg 사용자가 마우스 커서를 움직일 때 마우스 커서가 바뀌면 실제로 원하는 지점에 닿지 않을 것입니다. 그리고 최대 ¼ 초 지연으로 변경이 발생하면 사용자는 각 속도에서 움직임의 일부가 얼마나 큰지조차 알 수 없습니다. 커서는 250 밀리 초로 아주 멀리 이동할 수 있습니다. 지연은 0에서 250 밀리 초 사이에 균등하게 분산되므로 마우스를 물리적으로 정확히 같은 방식으로 움직여도 매번 동작이 동일하지 않습니다.
kasperd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.