Привязка мыши к конкретному монитору в двухэкранном режиме с двумя независимыми указателями

Сценарий таков: привязать мой Wacom Bamboo ко второму монитору, а мышь - к первому. Привязка для Wacom Bamboo отлично работает с настройками для планшета. Но как я могу привязать свою мышь к другому монитору?


Мои текущие шаги:

  1. Привязать Wacom Bamboo ко второму монитору

  2. Настройте два независимых указателя

    1. С подключенным Wacom Bamboo и моей мышью, xinput --list шоу

       ~  xinput list
      ⎡ Virtual core pointer                      id=2    [master pointer  (3)]
      ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=8    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=9    [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=13   [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=14   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen stylus                   id=10   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen eraser                   id=11   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen cursor                   id=15   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pad pad                      id=16   [slave  pointer  (2)]
      ⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
          ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
          ↳ Power Button                              id=6    [slave  keyboard (3)]
          ↳ Power Button                              id=7    [slave  keyboard (3)]
          ↳ Razer Razer BlackWidow Ultimate           id=12   [slave  keyboard (3)]
      
    2. Создать новое устройство с

      xinput create-master Bamboo
      
       ~  xinput list                
      ⎡ Virtual core pointer                      id=2    [master pointer  (3)]
      ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=8    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=9    [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=13   [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=14   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen stylus                   id=10   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen eraser                   id=11   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pen cursor                   id=15   [slave  pointer  (2)]
      ⎜   ↳ Wacom Bamboo Pad pad                      id=16   [slave  pointer  (2)]
      ⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
          ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
          ↳ Power Button                              id=6    [slave  keyboard (3)]
          ↳ Power Button                              id=7    [slave  keyboard (3)]
          ↳ Razer Razer BlackWidow Ultimate           id=12   [slave  keyboard (3)]
      ⎡ Bamboo pointer                            id=17   [master pointer  (18)]
      ⎜   ↳ Bamboo XTEST pointer                      id=19   [slave  pointer  (17)]
      ⎣ Bamboo keyboard                           id=18   [master keyboard (17)]
          ↳ Bamboo XTEST keyboard                     id=20   [slave  keyboard (18)]
      
    3. Повторно прикрепите идентификаторы Wacom Bamboo

      xinput reattach 10 "Bamboo pointer"
      xinput reattach 11 "Bamboo pointer"
      xinput reattach 15 "Bamboo pointer"
      xinput reattach 16 "Bamboo pointer"
      
       ~  xinput list
      ⎡ Virtual core pointer                      id=2    [master pointer  (3)]
      ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=8    [slave  pointer  (2)]
      ⎜   ↳ Logitech G9x Laser Mouse                  id=9    [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=13   [slave  pointer  (2)]
      ⎜   ↳ Razer Razer BlackWidow Ultimate           id=14   [slave  pointer  (2)]
      ⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
          ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
          ↳ Power Button                              id=6    [slave  keyboard (3)]
          ↳ Power Button                              id=7    [slave  keyboard (3)]
          ↳ Razer Razer BlackWidow Ultimate           id=12   [slave  keyboard (3)]
      ⎡ Bamboo pointer                            id=17   [master pointer  (18)]
      ⎜   ↳ Wacom Bamboo Pen stylus                   id=10   [slave  pointer  (17)]
      ⎜   ↳ Wacom Bamboo Pen eraser                   id=11   [slave  pointer  (17)]
      ⎜   ↳ Wacom Bamboo Pen cursor                   id=15   [slave  pointer  (17)]
      ⎜   ↳ Wacom Bamboo Pad pad                      id=16   [slave  pointer  (17)]
      ⎜   ↳ Bamboo XTEST pointer                      id=19   [slave  pointer  (17)]
      ⎣ Bamboo keyboard                           id=18   [master keyboard (17)]
          ↳ Bamboo XTEST keyboard                     id=20   [slave  keyboard (18)]
      

1 ответ

Решение

Об ответе

Ответ ниже может потребовать дополнительного редактирования. Чтобы создать двух отдельных мышей, я выполнил шаги, упомянутые в вашем вопросе. Это сработало, но у моей "нормальной" мыши возникли некоторые проблемы. Щелчок левой кнопкой мыши не работает в некоторых ситуациях.

Поскольку вы не упомянули побочный эффект в своем вопросе, я предполагаю, что он имеет отношение к конфликтующим функциональным возможностям аппаратных средств обеих мышей, которых я подключил.

Хорошая новость в том, что xdotool видимо, только "видит" координаты "основной" мыши, что позволяет заблокировать курсор на одном из экранов.

Два сценария

Ниже два сценария:

  1. Скрипт для блокировки указателя на любом из двух экранов.
  2. Сценарий для автоматизации шага 2, как описано в вашем вопросе: настройка двух независимых указателей



1. Скрипт для блокировки курсора на одном экране в настройке двух мониторов.

#!/usr/bin/env python3
import subprocess
import time
import sys

# --- set the loop time below
t = 0.2
# ---

# screen argument should be either left or right
screen = sys.argv[1]

def get(command):
    return subprocess.check_output(command).decode("utf-8")

def condition(x_pos):
    if screen == "right":
        return x_pos < limit
    else:
        return x_pos > limit

def get_pos():
    return [int(s.split(":")[-1]) for s in get(
        ["xdotool", "getmouselocation"]
        ).split()if any(["x" in s, "y" in s])]

limit = sorted([int(s.split("+")[1]) for s in get(
    "xrandr"
    ).split() if s.count("+") == 2])[-1]
limit = limit-3 if screen == "left" else limit+3

while True:
    pos = get_pos(); x_pos = pos[0]
    if condition(x_pos) == True:
        x = limit; y = pos[1]
        subprocess.Popen(["xdotool", "mousemove", str(x), str(y)])
    else:
        pass
    time.sleep(t)

использовать

  • Скрипт использует xdotool:

    sudo apt-get install xdotool
    
  • Скопируйте скрипт в пустой файл, сохраните его как lock_cursor.py

  • Запустить его с экрана (left или же right) в качестве аргумента, либо:

    python3 /path/to/lock_cursor.py left
    

    или же

    python3 /path/to/lock_cursor.py right
    



2. Скрипт для автоматизации настройки двух независимых мышей

Это может быть сложно, так как у меня нет Wacom Bamboo, и я не смог провести "финальный тест" в реальной ситуации. Однако с моей обычной второй мышью все работало нормально (будь то с разными идентификаторами).

Если в вашей ситуации это также работает нормально, оба сценария могут быть объединены для запуска за один вызов; Сценарий ниже действует только в том случае, если настройка двойных мышей еще не была выполнена.

#!/usr/bin/env python3
import subprocess
import os
import sys

new_master = "Bamboo" 
id_string = "Wacom Bamboo"

def get(command):
    return subprocess.check_output(command).decode("utf-8")

def execute(command):
    subprocess.call(["/bin/bash", "-c", command])

def find_ids(xinp_data, id_string):
    return [l.split("=")[1].split()[0]
            for l in xinp_data.splitlines() if id_string in l]

xinput_data = get(["xinput", "list"])

if not "Bamboo pointer" in xinput_data:
    ids = find_ids(xinput_data,id_string)
    if not ids:
        print("Wacom Bamboo seems not to be connected")
    else:
        pass
        execute("xinput create-master "+new_master)
        for n in ids:
            execute("xinput reattach "+n+' "Bamboo pointer"')

Использовать

Просто скопируйте скрипт в пустой файл, сохраните его как setup_bamboo.py, запустите его командой:

python3 /path/to/setup_bamboo.py

Заметки

  • Я не мог найти другой способ заблокировать мышь на одном экране, кроме как использовать xdotool, (Первый) скрипт поэтому блокирует мышь с помощью xdotool, Поскольку он работает в периодическом цикле, положение мыши корректируется, если оно выходит за пределы экрана. Следствием этого является то, что, хотя оно эффективно работает, вы все равно заметите косметическую разницу с "жестким" забором.

    Я потратил некоторое время, пытаясь уменьшить эффект, "умно" увеличивая скорость цикла, когда мышь приближается к границе экрана, или даже делая ее зависимой от направления движения мыши. В конце концов, однако, я пришел к выводу, что полученное улучшение минимально, и простота кодирования должна быть предпочтительной.

Другие вопросы по тегам