Open Source im professionellen Einsatz
Linux-Magazin 01/2017
© Fabian Schmidt, 123RF

© Fabian Schmidt, 123RF

Qt-Anwendungen unter Wayland

Umzugshilfe

Der neue Displayserver Wayland unterschreibt gerade Dauermietverträge bei vielen Linux-Distributionen. Das wirkt sich auf die dort laufenden grafischen Anwendungen aus. Kwin-Entwickler Martin Gräßlin erklärt, wie Qt-Entwickler ihre Programme auch mit Wayland und Xwayland betreiben.

991

Wayland und X11 sind in großen Bereichen kompatibel, was es Xwayland erleichtert, das X11-Protokoll über Wayland anzubieten. Dennoch gibt es Unterschiede, die für Entwickler wichtig sind. Einer davon wirkt sich beispielsweise positiv auf die Sicherheit aus. Das Wayland-Protokoll darf im Gegensatz zu X11 keine Tastatur- und Mauseingaben abfangen. Generell erhält eine Anwendung keine Informationen über die Fenster anderer Anwendungen. Eingaben gehen stets nur an jene Anwendung, die gerade ein Fenster fokussiert. Das beeinflusst auch X11-Anwendungen, nicht zuletzt, weil sie nun nicht mehr alle Ereignisse bemerken, wie Abbildung 1 demonstriert.

Abbildung 1: Steht eine X11-Anwendung gerade nicht im Fokus, erfährt sie auch nichts von Eingabe-Ereignissen. So kann der Klassiker Xeyes dem Mauszeiger nur folgen, wenn dieser ein X-Fenster kreuzt.

Den Portierungsaufwand nach Wayland bestimmt eine Anwendung zum großen Teil selbst. Verwendet sie ein Toolkit wie Qt oder GTK+ und benutzt sie keinen X11-spezifischen Code, braucht sie meist keine Änderung. Benutzt sie hingegen X11-APIs, etwa durch direkten Zugriff auf Xlib oder XCB, sollte der Entwickler diesen Code durch Wayland-spezifischen ersetzen, etwa durch ein abstrahierendes Toolkit. Natürlich besteht auch die Option, eine Anwendung auf X11 zu lassen und auf Xwayland zu vertrauen.

Abbildung 2: Die Anwendung aus Listing 1 läuft auf X11 (mit Xwayland) und Wayland gleichermaßen. Die Methode ist wichtig bei Portierungen.

Qt 5 erlaubt es, das Fenstersystem mit Hilfe der Qt Platform Abstraction (QPA) zur Laufzeit zu wählen. Über die Umgebungsvariable »QT_QPA_PLATFORM« oder das Kommandozeilenargument »--platform« gibt der Entwickler das zu verwendende Fenstersystem an. Zur Laufzeit fragt die Anwendung mittels »QGuiApplication::platformName()« [1] die verwendete Plattform ab, wie es auch Listing 1 zeigt. Abbildung 2 illustriert das Beispiel für die Plattformen Wayland und XCB. Diese Methode spielt beim Portieren eine sehr wichtige Rolle. Im Gegensatz zu einer Portierung nach Windows oder OS X reichen Checks zur Kompilierzeit über »ifdef« nicht aus.

Listing 1

Plattform-Erkennung in Qt

01 #include <QApplication>
02 #include <QLabel>
03
04 int main (int argc, char *argv[])
05 {
06     QApplication app(argc, argv);
07     QLabel label(app.platformName());
08     label.show();
09     return app.exec();
10 }

Wayland bringt ebenfalls Code für X11 mit:

#ifdef HAVE_X11
XFlush(QX11Info::display());
#endif

Führt ihn ein Entwickler allerdings so unter Wayland aus, bringt er die Anwendung zum Absturz. Er muss stets auch die Plattform überprüfen, wobei der folgende Code hilft:

if (qApp->platformName() ==  QLatin1String("xcb"))
    XFlush(QX11Info::display());

Verlinkt er auf »QtX11Extras« , ändert sich das Programm ein wenig:

if (QX11Info::isPlatformX11())
    XFlush(QX11Info::display());

Intern führt »QX11Info::isPlatformX11« [2] den gleichen Stringvergleich aus. Verwendet eine Anwendung an vielen Stellen plattformspezifischen Code, bietet es sich an, den Check in einer boolschen Variablen zu speichern. So wird ein String-Vergleich nicht immer nötig.

Wichtig ist, immer die Plattform zu prüfen und nicht etwa zu checken, ob beispielsweise »QX11Info::display« einen »nullptr« zurückliefert. Ruft eine Anwendung »QX11Info::display« unter Wayland auf, erfolgt ein Cast von »wl_display*« nach »XDisplay*« , der zum Absturz der Anwendung führt.

Will ein Entwickler wissen, ob seine Anwendung unter Wayland läuft, ist das etwas schwieriger. Dank Mir darf er nicht automatisch davon ausgehen, dass er anstelle von X11 stets auf Wayland trifft. Er muss die Plattform erneut überprüfen. Leider verwendet Qt unter Wayland nicht den simplen Namen, sondern ergänzt ihn um zusätzliche Informationen. Kommt Open GL zum Einsatz, lautet der Name »wayland-egl« statt »wayland« . Jedoch beginnt der Name stets mit »wayland« :

if (qApp->platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
    // Wayland-Code
}

Das KDE-Framework »KWindowSystem« bietet seit Version 5.25 eine Abstraktion hierfür an [3], die jedoch aktuell nur X11 und Wayland unterstützt.

Portierung

Bereiche, die Wayland nicht erfasst, deckt auch Qt in seinem abstrahierenden API nicht ab. Wayland nutzt zum Beispiel keine globalen IDs für Fenster, daher liefert »QWindow::winId« [4] keine globale ID zurück, sondern verwendet eine in der Anwendung inkrementierte ID. Diese kennt weder der Compositor, noch eine andere Anwendung. Interaktionen mit anderen Anwendung über Fenster-IDs erlaubt Qt damit nicht mehr, »QWindow::fromWinId« [5] liefert ein Pointer-Literal zurück.

Startet der Entwickler API-Calls, die Wayland nicht ermöglicht, wirft Qt teilweise Warnungen zur Laufzeit aus. So eignet sich »QWindow::setMouseGrabEnabled« [6] nur für Popup-Fenster. Bei anderen Fensterarten warnt Qt: »This plugin supports grabbing the mouse only for popup windows« . Welche Methoden in Wayland fehlen, zeigt der Kasten "Von Wayland nicht erlaubte Methoden".

Von Wayland nicht erlaubte Methoden

  • QWindow::setPosition()
  • QWindow::setMouseGrabEnabled()
  • QWindow::setKeyboardGrabEnabled()
  • QWindow::alert()
  • QWindow::lower()
  • QWindow::raise()
  • QWindow::requestActivate()
  • QScreen::grabWindow()
  • QCursor::setPos()

Eine Alternative gibt es nicht. Entwickler sollten daher überlegen, ob sie die Funktion wirklich brauchen. Sie gilt unter X11 oder Windows als schlechte Idee, denn idealerweise positioniert hier der Fenstermanager eine Anwendung.

Fenstericons

Fast jede Anwendung muss das Setzen des Fenstericons überarbeiten. Unter Wayland platziert der Entwickler es nicht direkt, sondern der Compositor holt es aus der ».desktop« -Datei [7]. Wayland-Fenster übermitteln ihm dafür den Namen der ».desktop« -Datei.

Qt errechnet den Namen laut Standard aus »QCoreApplication::organizationDomain« [8] und dem Namen der ausgeführten Datei, was etwa »org.kate-editor.kate« ergibt. Lautet er nur »org.kde.kate« , kann der Compositor das Fenster keiner Anwendung zuordnen und kein Icon setzen. Anwendungen brauchen also einen passenden ».desktop« -Dateinamen.

Seit Qt 5.7 darf der Entwickler den Namen mit »QGuiApplication::setDesktopFileName« [9] auch direkt angeben. Hat er die Anwendungen gegen die LTS-Version Qt 5.6 gebaut, übermittelt er das Property wahlweise auch über:

qApp->setProperty("desktopFileName",
    QStringLiteral("org.kde.kate"));

Die Verbindung von Fenstern und ».desktop« -Dateien spielt in Desktopumgebungen eine zentrale Rolle, zumindest KDEs Plasma-Desktop nutzt dieses Feature auch unter X11.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Wayland und Weston erreichen Version 1.7.0

    Für Wayland gibt es Änderungen an der Testsuite und der Dokumentation und was die Entwickler mit Weston vorhaben, wissen sie nun auch ungefähr.

  • Wayland und Mir

    Das X-Window-System aus den 1980er Jahren bildet nach wie vor die Basis der grafischen Benutzeroberfläche unter Linux. Beim Umgang damit verzweifeln Entwickler aber an Altlasten und unzeitgemäßer Technologie. Mit Wayland und Mir streben nun gleich zwei vielversprechende Alternativen den Wachwechsel an.

  • Wayland und Weston in Version 1.11.0

    Wayland und Weston sind in Version 1.11.0 erschienen. Während Wayland ein Proxy-Wrapper-API anbietet, lässt sich Weston einfacher mit verschiedenen Backends verwenden.

  • Wayland-Support für Kwin rückt näher

    KDE- und Kwin-Entwickler Martin Gräßlin berichtet in seinem Blog über die Neuerungen für Kwin 5.3. Der Support für Rootless Xwayland sei ein weiterer Schritt auf dem Weg, Wayland-Clients zu handhaben.

  • Zusatzprotokolle für Wayland erreichen Version 1.0

    Auf der Wayland-Devel-Mailingliste hat Entwickler Jonas Adahl die "wayland-protocols" in Version 1.0 angekündigt. Sie erweitern die Kernprotokolle um Zusatzfunktionen.

comments powered by Disqus

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.