Come modificare la velocità di scorrimento della rotellina del mouse per applicazione


9

È possibile avere diverse velocità di scorrimento della rotellina del mouse in base all'applicazione in esecuzione (focalizzata).

Come una velocità di scorrimento più bassa per guake per una facile lettura e maggiore per il browser Web per scorrere più velocemente.


Terremoti il ​​terminale? Cosa c'entra la "velocità del mouse" con qualsiasi cosa?
Braiam

1
@Braiam Penso che OP abbia appena scelto questi come esempi. Il nome dell'applicazione è irrilevante, ma la parte importante è il cambiamento della velocità di scorrimento per applicazione arbitraria
Sergiy Kolodyazhnyy,

@Serg come le applicazioni interpretano gli eventi della rotellina del mouse è estremamente rilevante. vale a dire. Firefox interpreta un pulsante 5 (come xorg vede il mio mouse scorrere verso il basso) come "sposta tre linee verso il basso senza intoppi", allo stesso modo altre applicazioni possono seguire altri criteri, ma quella comune è di 3 linee e questo non è controllato da xserver.
Braiam,

Risposte:


8

introduzione

Il seguente script dynamic_mouse_speed.py consente di specificare quale puntatore del mouse e / o velocità di scorrimento dovrebbero essere quando la finestra definita dall'utente ha lo stato attivo.

Importante : lo script richiede un imwheelprogramma per aumentare la velocità di scorrimento. Si prega di installarlo tramitesudo apt-get install imwheel

uso

Come mostrato dalla -hbandiera:

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

Lo script consente all'utente di selezionare la finestra che desidera monitorare con il clic del mouse. Il puntatore del mouse si trasforma in croce e l'utente può selezionare la finestra che desidera.

L'esecuzione python3 dynamic_mouse_speed.pyda sola mostra solo finestre di dialogo popup e non fa nulla da sola.

La corsa python3 dynamic_mouse_speed.py -s 5aumenta la velocità di scorrimento, mentre la python3 dynamic_mouse_speed.py -s -5velocità di scorrimento diminuisce. python3 dynamic_mouse_speed.py -p -0.9diminuisce la velocità del puntatore, mentre python3 dynamic_mouse_speed.py -p 0.9aumenta la velocità del puntatore. -se le -popzioni possono essere mescolate. -vproduce informazioni di debug sulla riga di comando.

fonte

Disponibile anche come versione 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()

Appunti

  • più istanze di script consentono di impostare la velocità per ogni finestra separata.
  • Quando si esegue dalla riga di comando, le finestre di dialogo popup generano il seguente messaggio: Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.Questi possono essere ignorati.
  • Consulta Come posso modificare / creare manualmente nuovi elementi di avvio in Unity? per creare un programma di avvio o un collegamento sul desktop per questo script, se si desidera avviarlo con un doppio clic
  • Per collegare questo script a una scorciatoia da tastiera per un facile accesso, consultare Come aggiungere scorciatoie da tastiera?
  • Si consiglia di utilizzare solo un mouse quando lo script è in esecuzione, poiché opera sul primo dispositivo in cui è stata rilevata la Evdev Scrolling Distanceproprietà
  • È possibile avviare più istanze per controllare più finestre, ma non è consigliabile per motivi di prestazioni

Risposta incredibile. Se possibile, ti assegnerei 50 ripetizioni.

4
@luchonacho Se lo desideri, puoi sempre offrire taglie sulla domanda, ma è disponibile solo dopo 2 giorni da quando la domanda è stata pubblicata :)
Sergiy Kolodyazhnyy

2
La domanda si pone sulla modifica della velocità di scorrimento. Non sembra che questo sia ciò che fa questo script, ma forse può essere adattato per farlo. La modifica effettiva della velocità con cui il cursore del mouse si sposta in base alla finestra probabilmente si comporterebbe in modo che la maggior parte degli utenti trova imprevedibile. Ancora di più quando i cambiamenti di velocità si verificano con un ritardo.
Kasperd,

@kasperd In effetti, il titolo della domanda era un po 'fuorviante e lo script cambia la velocità del puntatore, piuttosto che la velocità di scorrimento. Tuttavia, non è un grosso problema, e in effetti posso adattare lo script per includere la velocità di scorrimento. Ciò tuttavia richiede l'installazione del imwheelpacchetto, il che lo renderà un po 'più complicato. Ti farò sapere una volta che avrò aggiornato la mia risposta. Per quanto riguarda ciò che hai detto sull'imprevedibilità del comportamento degli utenti, non vedo come sia imprevedibile. Potresti spiegare di più?
Sergiy Kolodyazhnyy,

@Serg Se il cursore del mouse cambia nel mezzo di un utente che lo sposta, è improbabile che colpirà il punto a cui effettivamente mirava. E se la modifica avviene con un ritardo fino a ¼ di secondo, l'utente non può nemmeno sapere quanto una parte del movimento avvenga ad ogni velocità. Il cursore può spostarsi abbastanza lontano in 250 millisecondi. E il comportamento non sarà lo stesso ogni volta, anche se si sposta fisicamente il mouse esattamente allo stesso modo, poiché il ritardo verrà distribuito uniformemente tra 0 e 250 millisecondi.
Kasperd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.