简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为 Qt 5 on Wayland.

[TOC]


本文初发于 “偕臧的小站“,同步转载于此。


Qt 5工具箱中的Wayland支持在Qt Platform Abstraction(QPA) Wayland插件中进行。构建和使用QtWayland的最低要求是Wayland(和Weston)1.0.0。

如果您还想构建qtwebkit浏览器,则最好遵循从git构建Qt 5的说明,该指南可生成更多内容。init-repository脚本在失败时时候(不幸的是经常失败),会不智能的当地返回错误,因此您需要手动运行它并确保它不会输出错误。

第三个选项是Qt 5 Alpha构建指令,它比git指令更小且更可靠,同时仍包含qtwebkit,但对于Wayland客户端需要LD_PRELOAD:
$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libfontconfig.so.1 ./fancybrowser -platform wayland


获取源代码和编译

要想尝试的话,的首先要克隆 qtbase:

$ mkdir qt; cd qt
$ git clone git://code.qt.io/qt/qtbase.git

编译需要设置一些env变量:

$ export QTVER=qt5
$ export QTDIR=/opt/qt/$QTVER
$ export PATH=$QTDIR/bin/:$PATH
$ export LD_LIBRARY_PATH=$QTDIR/lib/:$LD_LIBRARY_PATH
$ export PKG_CONFIG_PATH=$QTDIR/lib/pkgconfig/:$PKG_CONFIG_PATH
$ export QT_PLUGIN_PATH=$QTDIR/lib/plugins/
$ ./configure -confirm-license -opensource -debug -nomake examples \
   -nomake tests -nomake demos -make libs --prefix ${QTDIR}
$ make
$ sudo make install

在这里,还需要克隆并构建qtdeclarative:

git://code.qt.io/qt/qtdeclarative.git

要构建它们,运行以下命令:

$ qmake
$ make
$ sudo make install

此时,已经准备好了所有需要的Qt库和编译QtWayland平台所需的工具:

$ cd ../
$ git clone git://code.qt.io/qt/qtwayland.git
$ cd qtwayland/
$ qmake
$ make
$ sudo make install

参考:

首先,不能忘了设置XDG目录,以及之前设置的编译Qt的变量,以及重新运行.bashrc:

$ export XDG_RUNTIME_DIR=$HOME/.xdg
$ mkdir $HOME/.xdg

也可以在Wayland和X之间来回跳转(”-platform xcb”),以比较Wayland和X下的应用程序的外观和感觉:

$ cd ../qtbase/examples/opengl/hellowindow
$ qmake
$ make
$ weston &
$ ./hellowindow -platform wayland

移植Qt应用程序

Qt 5的结构是Lighthouse(或Qt Platform)抽象,即窗口系统和设备不可知的架构。这意味着Qt可以根据需要在运行时为不同的窗口系统加载不同的后台插件。例如,一个在Qt上开发的应用,可以分别使用”-platform xcb “和”-platform wayland “来运行XCB或Wayland(或设置QT_QPA_PLATFORM环境变量),在这两个系统上应该有类似的行为,而不需要重新编译。

Qt抽象也向应用开发者公开了Wayland的两个本地资源:wl_displaywl_surface。有了这些,开发者就可以通过接口访问Wayland的内部资源来处理一特殊情况。

void *QPlatformNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)

获取显示全局处理程序很直接,如下例所示:

QPlatformNativeInterface *native =
    QGuiApplication::platformNativeInterface();
struct wl_display *wl_dpy = (struct wl_display *)
    native->nativeResourceForWindow("display", NULL);

wl_surface:

QPlatformNativeInterface *native =
    QGuiApplication::platformNativeInterface();
struct wl_surface *surface = static_cast<struct wl_surface *>(
    native->nativeResourceForWindow("surface", this->windowHandle()));

已知问题


获得帮助和报告问题

在irc.freenode.net上尝试#qt-labs IRC频道