Xorg: двигаем мышку

27 Feb 2022

Теги: shell linux bash X

Категории: HowTo

mouse pointer

Это какая-то напасть. Мониторы стаповятся больше, мониторов становится больше. А курсор мыши так и остался крохотным.

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

Что делать? Сделать хоткей, который будет пригонять курсор в центр конкретного экрана.

#!/usr/bin/env bash

SCREEN=${1:-0}
GEOMETRY=`xdotool getdisplaygeometry --screen ${SCREEN}`

while read w h
do
    xdotool mousemove --screen $SCREEN $((w/2)) $((h/2))
done < <(echo $GEOMETRY)

В качестве аргумента скрипт принимает номер монитора на который хочется пригнать курсор.

Что полезного можно тут увидеть?

Первое - это подстановки. В качестве примера инициализация SCREEN.

Выражение parameter parameter parameter
в скрипте: установлен и не Null установлен и Null не установлен
${parameter:-word} подставит parameter подставит word подставит word
${parameter-word} подставит parameter подставит null подставит word
${parameter:=word} подставит parameter присвоит word присвоит word
${parameter=word} подставит parameter подставит null присвоит word
${parameter:?word} подставит parameter ошибка, exit ошибка, exit
${parameter?word} подставит parameter подставит null ошибка, exit
${parameter:+word} подставит word подставит null подставит null
${parameter+word} подставит word подставит word подставит null

Тут нужно обратить внимание на то, как раскрывается это выражение интерпретатором и что подстановка и присвоение - это разные вещи.

Подстановка возвращает выбранное значение word вместо переменной parameter. Присвоение же устанавливает parameter значение word.

Пример.

Выражение parameter parameter parameter
в скрипте: установлен и не Null установлен и Null не установлен
${FOO:-hello} world hello hello
${FOO-hello} world ”” hello
${FOO:=hello} world FOO=hello FOO=hello
${FOO=hello} world ”” FOO=hello
${FOO:?hello} world ошибка, exit ошибка, exit
${FOO?hello} world ”” ошибка, exit
${FOO:+hello} hello ”” ””
${FOO+hello} hello hello ””

А так же неименованные каналы. Про именованые каналы я уже писал. А неименованые отличаются тем, что не надо делать его вручную.

Литература:

Shell: генерируем последовательность дат

04 Sep 2021

Теги: shell linux bash

Категории: HowTo

Простой случай когда надо сгенерировать последовательность дат. Например для генерации шаблона партиций в бд.

$ seq \
  `date -d "2021-02-01 00:00:00" "+%s"` \
  86400 \
  `date -d "2021-09-01 00:00:00" "+%s"` \
  | xargs -I{} date -d @{} +%Y-%m-%d
$ seq \
 `date -d "2021-02-01 00:00:00" "+%s"` \
 86400 \
 `date -d "2021-02-12 00:00:00" "+%s"` \
 | xargs -I{} date -d @{} +%Y-%m-%d
2021-02-01
2021-02-02
2021-02-03
2021-02-04
2021-02-05
2021-02-06
2021-02-07
2021-02-08
2021-02-09
2021-02-10
2021-02-11
2021-02-12

Sed: полезные советы

21 Aug 2021

Теги: shell linux обработка текста

Категории: HowTo

Всем известен потоковый редактор sed.

Как мы его используем чаще всего? Взять регулярку и заменить что-то на что-то глобально.

$ seq 1 10 | sed 's/1/one/'
one
2
3
4
5
6
7
8
9
one0

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

Как работает типичный флоу:

 ____      -----------------------      ----
|file| -> |прочесть строку в буфер| -> |line|
 ----     |    (pattern space)    |     ----
    ^     -----------------------
    |                 \/
    |      -----------------------      -------------
    |     |  Выполнить команду 1  | -> |modified line|
    |      -----------------------      -------------
    |                 \/
    |                ....
    |                 \/
    |      -----------------------      -------------
    |     |  Выполнить команду N  | -> |modified line|
    |      -----------------------     | N-iteration |
    |                 \/                -------------
    |      -----------------------      -------------
    |     |   Записать результат  | -> |modified line|
    |      -----------------------     | N-iteration |
    |                 ||                -------------
    |                 \/
    |    --------------------------
    ----| повторить до конца файла |
         --------------------------

Под записью резльтата подразумевается не только вывод, но и запись в файл при in-place редактирвоании.

Стоп! А почему команд больше одной? Мы же с вам знаем только одно регулярное выражение?

Systemd: Перезагружаем pipewire после спячки

20 Jul 2021

Теги: pipewire linux systemd

Категории: HowTo

Начиная с Fedora 34 pipewire пришел на замену pulseaudio и стал довольно интересной альтернативой jackd. Так как теперь не требуется каких-либо телодвижений для того, чтобы все корректно заработало.

Конечно же без проблем не обошлось. В моём случае после спячки сервер перестает видеть докстанцию со встроенной звуковухой.

$ journalctl --user -u pipewire
...
дек 12 01:25:28 xxx pipewire[2846]: [E][000338392.259201][alsa-pcm.c:33 spa_alsa_open()] 'hw:Dock,1': playback open failed: Device or resource busy
дек 12 01:25:28 xxx pipewire[2850]: [E][000338392.261614][core.c:71 core_event_error()] core 0x56217c2f48e0: proxy 0x56217c42e9c0 id:72: bound:68 seq:1022 res:-16 (Device or resource busy) msg:"enum params id:3 (Spa:Enum:ParamId:EnumFormat) failed"
дек 12 01:25:28 xxx pipewire[2850]: [E][000338392.261651][media-session.c:1971 core_error()] error id:72 seq:1022 res:-16 (Device or resource busy): enum params id:3 (Spa:Enum:ParamId:EnumFormat) failed
...

В деве вроде бы проблему чинили, но в стейбле федоры - нет.

Единственный вариант, который приходит на ум - перезагружать сервер после спячки. Делать это каждый раз руками лень.

Сделаем сервис, который будет делать это за нас!

Однако, не все так просто. Проблема заключается в том, что systemd от пользователя запускается как отдельный процесс и не имеет доступа к системным таргетам вроде sleep/suspend и т.п.

Поэтому придется решать еще и эту проблему.

Кастомный sleep.target в юзерспейсе

  1. Скрипт ~/.local/bin/sleep_mon
    #!/bin/bash
    
    dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Manager',member=PrepareForSleep" | while read x; do
        case "$x" in
            *"boolean false"*) systemctl --user --no-block stop sleep.target;;
            *"boolean true"*) systemctl --user --no-block start sleep.target;;
        esac
    done
    
  2. Таргет ~/.config/systemd/user/sleep.target
    [Unit]
    Description=User level sleep target
    StopWhenUnneeded=yes
    
  3. Скрипт для активации таргета ~/.config/systemd/user/user-sleep.service
    [Unit]
    Description=watch for sleep signal to start sleep.target
    
    [Service]
    ExecStart=%h/.local/bin/sleep_mon
    Restart=on-failure
    
    [Install]
    WantedBy=default.target
    
  4. Активируем и запускаем новый сервис
    $ systemctl --user enable user-sleep.service
    $ systemctl --user start user-sleep.service
    

Непосредственно сам сервис для перезапуска pipewire

  1. Создаем файл restart-pw.service по пути ~/.config/systemd/user.
    [Unit]
    Description=Restart pipewire after resume
    StopWhenUnneeded=true
    
    [Service]
    Type=oneshot
    RemainAfterExit=true
    ExecStop=/usr/bin/systemctl --no-block --user restart pipewire pipewire-pulse
    
    [Install]
    WantedBy=sleep.target
    
  2. Добавляем юнит в запускаемые.
    $ systemctl --user enable restart-pw.service
    
  3. Стартуем юнит
    $ systemctl --user start restart-pw.service
    
  4. Можно посмотреть статус
    $ systemctl --user status restart-pw.service
    

Литература:

MIDI: Превращаем сообщения в нажатия кнопок клавиатуры

20 Dec 2020

Теги: jackd linux midi

Категории: HowTo

Как конвертировать сообщения от midi-клавиатуры в нажатия кнопок на клавиатуре?

Где это может потребоваться - это в приложениях, которые не умеют в миди, но умеют в хоткеи. Например musescore - это приложение очень плохо умеет в миди.

Создадим простейший скрипт midi-to-keyboard. Все что он делает - это слушает события на шине и транслирует их в нажатия кнопок клавиатуры.

#!/usr/bin/env bash
THROTTLE=150
old_time=0
last_change=0
#aseqdump -p "Arturia MiniLab mkII" | \
aseqdump -p "System" | \
while IFS=" ," read src ev1 ev2 ch label1 data1 label2 data2 rest; do
    current_time=$(($(date +%s%N)/1000000))
    diff=$(($current_time-$old_time))
    if [[ $diff -gt $THROTTLE && "$ch" = 15 ]]; then
        # тротлинг событий обязателен
        change=0
        case $data1 in
            48 ) # effects 1
                if [[ $data2 -gt 64 ]]; then
                    xdotool key Right
                    change=1
                elif [[ $data2 -lt 64 ]]; then
                    xdotool key Left
                    change=1
                fi
            ;;
            49 ) # effects 2
                if [[ $data2 -gt 64 ]]; then
                    xdotool key Up
                    change=1
                elif [[ $data2 -lt 64 ]]; then
                    xdotool key Down
                    change=1
                fi
            ;;
        esac
        if [[ change -eq 1 ]]; then
            echo "Change after $(($current_time-$old_time))"
            old_time=$current_time
        fi
    fi
done

Литература: