Создание диспетчерa отображения на Python с использованием PyQt6 и Xorg, но при инициализации остается черным.

Вопрос или проблема

Я создаю диспетчер отображения (dm) на Python, который ожидает запуска Xorg для работы с графическим интерфейсом.

Python

(исключен ненужный код, такой как виджеты, классы и функции)

import os

(дополнительные импорты PyQt6 и т.д.)
.......

class LoginWindow( QMainWindow ):
    def __init__(self):
        super().__init__()
                
        # Сделать окно в полный экран
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint  | 
                            Qt.WindowType.WindowStaysOnTopHint
                            )

   ..........
   .......... (ненужный код)
        
    def cancel(self, window):
        if not window :
             ...

def start_x11():
    xorg = subprocess.run("Xorg :0 -nolisten tcp -background none -logfile /var/log/mydm/xorg.log vt1", shell=True)
    return xorg

def start_user_session(username) :
    loginctl = subprocess.run(f"loginctl enable-linger {username}", shell=True)# ,capture_output=True)
    #print(loginctl)
    if loginctl.returncode == 0 :
        subprocess.run(f"sudo -u {username} dbus-launch startxfce4", shell=True)

if __name__ == "__main__" :
    
    if start_x11().returncode == 0 : 
        app = QApplication(sys.argv)
        app.setStyleSheet('''
            QPushButton#loginDockButton { 
                border: none;    
                padding: 0px;
                margin: 0px;
            }
        ''')


        window = LoginWindow()
        window.show()

        sys.exit(app.exec())

        

Как вы можете видеть, я использую subprocess.run(), чтобы запустить Xorg.
И когда я обратился к ИИ за решением проблемы, мне было рекомендовано выполнить:

subprocess.run("loginctl enable-linger {username}", shell=True)

По словам этого ИИ, это позволяет дочерним процессам пользователя продолжать работу даже после выхода, чтобы предотвратить закрытие процесса dbus. (хотя все еще интересно, как это может помочь 🤔)

Unit Service

[Unit]
Description=mydm
[email protected]
After=systemd-user-sessions.service plymouth-quit.service
Requires=systemd-logind.service

[Service]
ExecStart=/usr/bin/python3 /etc/mydm/src/mydm_login.py
Restart=always
RestartSec=3
StandardOutput=syslog
StandardError=syslog
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes

[Install]
WantedBy=graphical.target

Я должен признать, что код unit-службы был полностью сгенерирован ИИ, потому что я не имел представления о том, как работают unit-файлы, ни о systemd, ни о systemctl

Logfile

После нескольких минут печали и горя из-за отсутствия моего графического интерфейса, я решил заглянуть в logfile от Xorg и получил следующее :

[  3671.154] Current Operating System: Linux MrDikxon 6.13.2-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 08 Feb 2025 18:54:55 +0000 x86_64
    (WW) предупреждение, (EE) ошибка, (NI) не реализовано, (??) неизвестно.

grep EE /var/log/mydm/xorg.log
[  3671.154] (EE) systemd-logind: не удалось получить сессию: PID 4060 не принадлежит ни одной из известных сессий
[  3671.171] (EE) Не удалось загрузить модуль "fbdev" (модуль не существует, 0)
[  3671.172] (EE) Не удалось загрузить модуль "vesa" (модуль не существует, 0)
[  3671.186] (EE) открыть /dev/dri/card0: Нет такого файла или каталога
[  3671.191] (II) Инициализация расширения MIT-SCREEN-SAVER
[  3671.193] (EE) Ошибка AIGLX: не удалось выполнить dlopen /usr/lib/dri/i965_dri.so (/usr/lib/dri/i965_dri.so: невозможно открыть разделяемый объектный файл: Нет такого файла или каталога)
[  3671.193] (EE) Ошибка AIGLX: невозможно загрузить драйвер i965

grep WW /var/log/mydm/xorg.log 

[  3671.154] (WW) Каталог "/usr/share/fonts/misc" не существует.
[  3671.154] (WW) Каталог "/usr/share/fonts/TTF" не существует.
[  3671.154] (WW) Каталог "/usr/share/fonts/OTF" не существует.
[  3671.154] (WW) Каталог "/usr/share/fonts/Type1" не существует.
[  3671.154] (WW) Каталог "/usr/share/fonts/100dpi" не существует.
[  3671.154] (WW) Каталог "/usr/share/fonts/75dpi" не существует.
[  3671.169] (WW) Open ACPI не удалась (/var/run/acpid.socket) (Нет такого файла или каталога)
[  3671.171] (WW) Предупреждение, не удалось открыть модуль fbdev
[  3671.172] (WW) Предупреждение, не удалось открыть модуль vesa
[  3671.186] (WW) Возвращение к старому методу проверки для настройки режимов

При выполнении (NI,??) не было получено никакого вывода.

Это мой первый опыт работы с Xorg или systemd, поэтому я не знаю, что можно сделать.
Поэтому я еще ничего не попробовал, а темы на unix & linux stackexchange, похоже, не сильно связаны с тем, что мне нужно

Ответ или решение

Создание диспетчера отображения (Display Manager) на Python с использованием PyQt6 и Xorg — задача непростая, особенно для новичка. Ваша текущая проблема заключается в том, что, несмотря на запуск Xorg, окно GUI не отображается и остаётся чёрным. Разберем возможные причины и пути их устранения.

Теория

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

PyQt6 — это инструментарий GUI для Python, который позволяет создавать сложные графические интерфейсы. Используя Xorg в качестве сервера отображения, PyQt6 может рендерить окна на экране.

Примеры

Вы столкнулись с несколькими ошибками, которые видны в логах Xorg. Вот несколько ключевых моментов из ваших логов:

  1. (EE) Ошибка systemd-logind: failed to get session: PID 4060 указывает, что Xorg запущен не в том контексте сессии, в котором работает systemd-logind. Это проблема может возникнуть, если не настроены правильно cgroup или полномочия запуска.

  2. (EE) Отсутствие модулей драйверов fbdev и vesa. Эти драйверы могут быть необязательными, но отсутствие подходящего драйвера может означать, что Xorg не может работать с видеокартой.

  3. (EE) Ошибка при загрузке i965_dri.so, которая нужна для аппаратного ускорения.

  4. (WW) Предупреждения о шрифтах — их отсутствие может быть не критичным, но лучше их установить для полноценного функционирования Xorg.

Применение

Для решения вашей задачи по устранению проблемы черного экрана нужно предпринять несколько шагов:

1. Исправление ошибок в Xorg

  • Убедитесь, что все необходимые модули и драйверы установлены. Например, для драйвера Intel установите mesa пакет, который содержит необходимый файл i965_dri.so.
  • Если ваша видеокарта поддерживает другие драйверы, установите их и внесите изменения в файл конфигурации /etc/X11/xorg.conf или /etc/X11/xorg.conf.d/.

2. Правильная настройка systemd

  • Ваша служба systemd должна быть скорректирована. Проверьте, корректно ли задан параметр User=your-username в разделе [Service]. Возможно, стоит задать User=root, если запуск требует прав администратора для корректного взаимодействия Xorg с аппаратным обеспечением.
  • Советую добавить EnviromentFile, который может содержать конфигурацию для среды пользователя.

3. Доработка исходного кода

  • Проверьте правильность последовательности инициализации Xorg и PyQt в вашем коде. Xorg должен быть запущен и готов принимать подключения до запуска GUI. Возможно, вам стоит вставить условия или дополнительные проверки готовности среды перед началом рендеринга.

Примерно так может выглядеть доработка функции запуска сессии:

if __name__ == "__main__":
    xorg = start_x11()
    if xorg.returncode == 0:
        # Ждём, пока Xorg полностью запустится.
        time.sleep(5)

        app = QApplication(sys.argv)
        window = LoginWindow()
        window.show()

        sys.exit(app.exec())
    else:
        print("Ошибка запуска Xorg:", xorg)

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

Оцените материал
Добавить комментарий

Капча загружается...