MADDISPLAYMANAGER
Еще одна бесполезная программа в моем арсенале. Фактически, она повторяет функционал встроенного в 11-ю винду DisplaySwitch.exe. Разница лишь в том, что моя программа висит в трее и режим дисплея можно очень быстро поменять кликом мышки. Так я думал, когда начинал ее писать и не знал что DisplaySwitch.exe вызывается сочетанием клавиш Win+P. А позже решил-таки написать нечто подобное для Linux. Самой сложной задрочкой оказалось реализация аналогичного сочетания клавиш для вызова окошка переключалки. Проблема в том, что сигнал не доходит до перехватчика, так как его отлавливает какая-то другая программа. Похоже, глубоко-системная. Решил не компостировать себе голову, оставил тупо Сtrl+P.
Для облегчения попаболи в комплекте с приложением поставляется скрипт установки юнита systemd, который работает в пользовательском режиме, без sudo
bash install.sh
#!/usr/bin/env bash set -euo pipefail APP_REAL="/home/madmentat/Sources/Qt/display-switcher/build/Desktop_Qt_6_10_2-Debug/display-switcher" BIN_DIR="${HOME}/.local/bin" APP_LINK="${BIN_DIR}/display-switcher" UNIT_DIR="${HOME}/.config/systemd/user" UNIT_NAME="display-switcher.service" UNIT_PATH="${UNIT_DIR}/${UNIT_NAME}" echo "[1/7] Проверка бинарника..." if [[ ! -x "$APP_REAL" ]]; then echo "ОШИБКА: бинарник не найден или не исполняемый: $APP_REAL" >&2 exit 1 fi echo "[2/7] Создаю каталог ${BIN_DIR} и симлинк..." mkdir -p "$BIN_DIR" ln -sf "$APP_REAL" "$APP_LINK" echo "[3/7] Создаю user-unit: ${UNIT_PATH}" mkdir -p "$UNIT_DIR" cat > "$UNIT_PATH" <<'EOF' [Unit] Description=Display Switcher (tray app) After=graphical-session.target Wants=graphical-session.target [Service] Type=simple ExecStart=%h/.local/bin/display-switcher Restart=on-failure RestartSec=1 # Чтобы не зависеть от терминала/tty: StandardOutput=journal StandardError=journal # Иногда для Qt tray помогает корректная среда. USER-юниты обычно и так её имеют, # но это не мешает. Если у тебя Wayland/X11 - переменные подхватятся из сессии. # Environment=QT_QPA_PLATFORM=wayland # Environment=QT_QPA_PLATFORM=xcb [Install] WantedBy=default.target EOF echo "[4/7] Перечитываю конфиги systemd --user..." systemctl --user daemon-reload echo "[5/7] Включаю автозапуск сервиса..." systemctl --user enable "$UNIT_NAME" echo "[6/7] Запускаю сервис (в фоне, не привязан к терминалу)..." systemctl --user restart "$UNIT_NAME" echo "[7/7] Статус:" systemctl --user --no-pager --full status "$UNIT_NAME" || true echo echo "Готово." echo "- Иконка должна появиться в системном трее." echo "- Терминал остаётся живым; Ctrl+C тут ничего не убьёт (это не 'run' процесса, а systemd)." echo echo "Полезные команды:" echo " systemctl --user status display-switcher.service" echo " journalctl --user -u display-switcher.service -f" echo " systemctl --user stop display-switcher.service" echo " systemctl --user disable --now display-switcher.service" # Опционально: включить linger, чтобы user systemd мог поднимать сервис без активного логина. # Это требует sudo и может быть не нужно, если сервис нужен только в активной сессии. if command -v loginctl >/dev/null 2>&1; then if sudo -n true 2>/dev/null; then echo echo "Опционально: включаю linger (sudo доступен без пароля)..." sudo loginctl enable-linger "$USER" || true else echo echo "Примечание: если хочешь, чтобы сервис жил/стартовал даже без активной сессии," echo "можно выполнить:" echo " sudo loginctl enable-linger $USER" fi fi
