Qt 使应用程序始终在 Weston/Wayland 平台上

Posted

技术标签:

【中文标题】Qt 使应用程序始终在 Weston/Wayland 平台上【英文标题】:Qt Make Application Always on Top on Weston/Wayland Platform 【发布时间】:2019-02-01 07:11:36 【问题描述】:

我想在 wayland-weston 桌面系统中安排两个应用程序的焦点。两个应用程序是:

    用 Qt/QML 编写,全屏 使用 Wayland 客户端 API + OpenGL 编写,全屏

我希望 App#1 始终位于顶部,而 App#2 始终位于底部,即使我杀死并重生了它们中的任何一个。我也想在它们都是全屏应用时这样做。

我已经调查并发现了几种实现此目的的方法:

    使用wmctrl 在桌面系统中排列窗口:我已经尝试过了。但是,我得到Cannot open display.。后来我发现wmctrl 不适用于 Weston/XWayland,仅适用于 X11。所以,我认为这不再是一个选择。

    默认情况下使 App#1 (Qt/QML) 始终位于顶部:我尝试解决此问题的是我在 main.qml 中添加了以下内容:

    ApplicationWindow 
        visible: true
        visibility: "FullScreen"
        width: 1920
        height: 720
        flags: Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint
    
        MainScreen
            anchors.fill: parent
        
    
    

    让 App#2(Wayland 客户端 API/OpenGL)默认始终位于底部。老实说,我对 Wayland 客户端 API 不太熟悉,但如果有可能的话,我可以在一些指导下探索它。

现在,我的重点是让 Qt 应用程序始终处于领先地位。它适用于我的 PC,但不适用于目标平台。我的电脑是 Ubuntu 16.04,带有 Xorg。目标平台具有带有 xwayland 后端的 Weston 合成器。我不知道为什么它在目标中不起作用。它可能是桌面系统。任何指导和想法表示赞赏。谢谢

编辑: 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 版本 PC上的Qt 5.10.1,目标平台上的Qt 5.8.0

【问题讨论】:

你必须设置事件onActiveChanged(见我的回复) @madduci 我已经尝试过了。不幸的是,它不起作用。 【参考方案1】:

我在 Qt Bugs 上打开了一个问题,并从 Qt 员工那里得知,由于 Weston compositor 的限制,这是不可能的。所以,我要么创建自己的合成器,要么使用其他合成器。

【讨论】:

哦,这很糟糕。在较新版本的 Qt 上会不会也一样? 我想是的,我应用了一种解决方法(动画鼠标点击)并解决了它。但是拥有它仍然不是那么好。 核心 Wayland 协议可能不支持它,但有一个扩展协议 layer-shell 确实支持它。 wlroots 项目已经定义了这个协议,并且一些合成器实现了它,尽管它还不是稳定的。最终,Qt 可能会使用这个或其他类似的协议,尽管许多合成器可能不会实现它们,直到存在允许某些应用程序使用它们而某些应用程序不使用它们的权限系统。所以这不是 Wayland 的基本限制,我认为事情会变得更好。【参考方案2】:

您应该在主 C++ 文件中设置标志

编辑

这适用于 Qt/C++ 应用:

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

您可以按照此处的指南进行操作:

Windows Flags

对于 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;
   
    

【讨论】:

不幸的是,它没有改变任何东西。我正在添加我的 qml 文件以供参考。 这是一个有趣的技巧。 @mozcelikors,您使用的是 Qt 5.10,那时 xdg-shell v6 实现没有全屏支持,这可能是它不适合您的原因。您可以通过在环境中设置QT_WAYLAND_SHELL_INTEGRATION 来尝试升级或使用xdg-shell-v5wl-shell

以上是关于Qt 使应用程序始终在 Weston/Wayland 平台上的主要内容,如果未能解决你的问题,请参考以下文章

QT怎么设置控件在窗口大小发生变化的时候,使控件始终居于右上角

强制 OpenGL 渲染始终在 Qt 中的相同 (Q) 线程上运行

在 Linux/X11 上的 Qt 中,如何解决主窗口排序问题?

如何在 Flutter 中创建服务以使应用始终在后台运行?

如何使视图在应用程序的屏幕上始终可见?

Qt 数组的 GLSL 统一始终为零