MADDISPLAYMANAGER

2026 02 08 20 49 25 Еще одна бесполезная программа в моем арсенале. Фактически, она повторяет функционал встроенного в 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

 

Сырцы