Qt делает приложение всегда на вершине на платформе Weston / Wayland

#python #pyqt5 #flags

#linux #qt #qml #wayland #wmctrl

Вопрос:

Я хотел бы организовать фокус двух приложений в настольной системе wayland-weston. Два приложения:

  1. Написано на Qt / QML, полноэкранный режим
  2. Написано с использованием Wayland Client API OpenGL, полноэкранный режим

Я хотел бы, чтобы приложение № 1 всегда было сверху, а приложение № 2 всегда снизу, даже если я убью и возрожду любое из них. Я также хотел бы сделать это, пока оба они являются полноэкранными приложениями.

Я исследовал и нашел несколько способов добиться этого:

  1. Использование wmctrl для размещения окон в настольной системе: я пробовал это. Тем не менее, я понимаю Cannot open display. . Позже я узнал, что wmctrl это не работает с Weston / XWayland, работает только с X11. Итак, я больше не думаю, что это вариант.
  2. Сделайте приложение № 1 (Qt / QML) всегда на вершине по умолчанию: я попытался решить эту проблему, добавив следующее в свой main.qml:
     ApplicationWindow {
        visible: true
        visibility: "FullScreen"
        width: 1920
        height: 720
        flags: Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint
    
        MainScreen{
            anchors.fill: parent
        }
    }
     
  3. По умолчанию сделайте приложение № 2 (Wayland Client API / OpenGL) всегда снизу. Честно говоря, я не очень хорошо знаком с клиентским API Wayland, но я мог бы изучить его с некоторыми рекомендациями, если что-то подобное вообще возможно.

Прямо сейчас я сосредоточен на том, чтобы приложение Qt всегда было на вершине. Он работает на моем ПК, но не работает на целевой платформе. Мой компьютер — Ubuntu 16.04 с Xorg. Целевая платформа имеет weston compositor с серверной частью xwayland. Я не знаю, почему это не работает в целевой. Возможно, это настольная система. Приветствуются любые рекомендации и идеи. Спасибо

РЕДАКТИРОВАТЬ: main.cpp

     QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
 

РЕДАКТИРОВАТЬ main.qml

 import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
import "app/main"

ApplicationWindow {
    visible: true
    visibility: "FullScreen"
    maximumWidth: 1920
    maximumHeight: 720
    minimumWidth: 1920
    minimumHeight: 720
    width: 1920
    height: 720
    title: qsTr("App")
    flags: Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint

    MainScreen{
        anchors.fill: parent
    }

}
 

РЕДАКТИРОВАТЬ: версия
Qt Qt 5.10.1 на ПК, Qt 5.8.0 на целевой платформе

Комментарии:

1. Вы должны установить событие onActiveChanged (см. Мой ответ)

2. @madduci я уже пробовал это. К сожалению, это не сработало.

Ответ №1:

Я открыл проблему с ошибками Qt и узнал от сотрудника Qt, что это невозможно из-за ограничений от Weston compositor. Итак, я либо создам свой собственный композитор, либо использую другой.

Комментарии:

1. о, это плохо. И будет ли это то же самое в более новых версиях Qt?

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

3. Возможно, оно не поддерживается основными протоколами wayland, но есть протоколы расширения layer-shell, которые его поддерживают. Проект wlroots определил этот протокол, и некоторые разработчики его реализуют, хотя он еще не считается стабильным. В конечном итоге Qt, скорее всего, будет использовать этот или другой подобный протокол, хотя ряд составителей могут не реализовывать их, пока не будет создана система разрешений, позволяющая некоторым приложениям использовать их, а некоторым нет. Так что это не фундаментальное ограничение wayland, и я думаю, что все станет лучше.

Ответ №2:

Вы должны установить флаги в своем основном файле C

Редактировать

Это для приложений на Qt / C :

 setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
showFullScreen();
 

Вы можете следовать руководству здесь:

Флаги Windows

Для QML вы можете использовать, в .qml-файл:

 import QtQuick.Window 2.2 // Window.FullScreen
import QtQuick.Controls 1.3 // ApplicationWindow

ApplicationWindow
{
   id: window
   onActiveChanged: {
       window.visibility = activeFocusItem ? Window.FullScreen :  Window.Minimized;
   }
}    
 

Комментарии:

1. К сожалению, это ничего не изменило. Я добавляю свой файл qml для справки.

2. Это интересный взлом. @mozcelikors, вы находитесь на Qt 5.10, на тот момент реализация xdg-shell v6 не имела поддержки полноэкранного режима, вероятно, поэтому она у вас не работает. Вы можете попробовать обновить или использовать xdg-shell-v5 или wl-shell , установив QT_WAYLAND_SHELL_INTEGRATION в среде.