วิธีเปลี่ยนความเร็วล้อเลื่อนของเม้าส์ต่อแอพพลิเคชั่น


9

เป็นไปได้ไหมที่ความเร็วล้อเลื่อนของเมาส์จะแตกต่างกันขึ้นอยู่กับแอพพลิเคชั่นที่ทำงานอยู่ด้านบน (เน้น)

ชอบความเร็วในการเลื่อนที่ช้าลงเพื่อให้อ่านได้ง่ายขึ้นและสูงขึ้นสำหรับเว็บเบราว์เซอร์เพื่อเลื่อนเร็วขึ้น


ไหวเทอร์มินัล สิ่งที่ต้องทำ "ความเร็วของเมาส์" กับอะไร?
Braiam

1
@Braiam ฉันคิดว่า OP แค่เลือกสิ่งเหล่านี้เป็นตัวอย่าง ชื่อแอปพลิเคชันไม่เกี่ยวข้อง แต่ส่วนที่สำคัญคือการเปลี่ยนความเร็วการเลื่อนต่อแอปพลิเคชันโดยพลการ
Sergiy Kolodyazhnyy

@Serg ว่าแอปพลิเคชันตีความเหตุการณ์ล้อเลื่อนของเมาส์มีความเกี่ยวข้องกันอย่างไร กล่าวคือ Firefox ตีความปุ่ม 5 (วิธีที่ xorg เห็นว่าเมาส์ของฉันเลื่อนลง) เป็น "เลื่อนสามบรรทัดลงอย่างราบรื่น" แอปพลิเคชันอื่น ๆ สามารถปฏิบัติตามเกณฑ์อื่น ๆ ได้ แต่สิ่งที่พบโดยทั่วไปคือ 3 บรรทัด
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 reps หากเป็นไปได้

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.