QtShell Kompositor
QtShell Compositor zeigt, wie man die QtShell Shell-Erweiterung verwendet.
QtShell Compositor ist ein Wayland-Compositor-Beispiel im Desktop-Stil, das eine vollständige Qt Wayland Compositor implementiert, die das spezielle Shell-Erweiterungsprotokoll namens QtShell verwendet.
Der Compositor ist mit Qt Quick und QML implementiert.
Herstellen der Verbindung
Im Beispiel wird QtShell als einzige Erweiterung des WaylandCompositor Objekts aufgeführt. Das bedeutet, dass jeder Client, der eine Verbindung zum Server herstellt, diese Erweiterung ebenfalls unterstützen muss, d.h. es sollte sich um Qt-Anwendungen handeln, die mit der gleichen Qt-Version wie der Compositor laufen.
QtShell { onQtShellSurfaceCreated: (qtShellSurface) => screen.handleShellSurface(qtShellSurface) }
Wenn ein Client eine Verbindung zur Schnittstelle QtShell herstellt, erzeugt er ein QtShellSurface. Der Compositor wird darüber durch die Ausgabe des Signals qtShellSurfaceCreated informiert. Das Beispiel fügt dann die Shell-Oberfläche zu einem ListModel hinzu, um später einen einfachen Zugriff zu ermöglichen.
property ListModel shellSurfaces: ListModel {} function handleShellSurface(shellSurface) { shellSurfaces.append({shellSurface: shellSurface}); }
Die ListModel wird als Modell für eine Repeater verwendet, die die Qt Quick Elemente erstellt, die für die Anzeige der Client-Inhalte auf dem Bildschirm erforderlich sind.
Repeater { id: chromeRepeater model: output.shellSurfaces // Chrome displays a shell surface on the screen (See Chrome.qml) Chrome { shellSurface: modelData onClientDestroyed: { output.shellSurfaces.remove(index) } } }
Es wird der lokale Typ Chrome
verwendet, der Fensterzustände und -dekorationen verwaltet.
Chrome
Chrome
ist der Typ, der sicherstellt, dass der Client-Inhalt sichtbar ist und der auch den Fensterstatus, die Position, die Größe usw. verwaltet. Er verwendet den eingebauten Typ QtShellChrome als Grundlage, der automatisch den Fensterzustand (maximiert, minimiert, Vollbild) und die Fensteraktivierung (Sicherstellung, dass nur ein einziges Fenster aktiv ist) handhabt.
Sein Verhalten kann bis zu einem gewissen Grad angepasst werden, aber es ist auch möglich, die Chrome
-Funktionalität von Grund auf neu zu schreiben, indem man stattdessen auf einem grundlegenden Item -Typ aufbaut. QtShellChrome ist eine Komfortklasse, die typisches Compositor-Verhalten bereitstellt und uns die Zeit erspart, diese Logik im Beispiel zu implementieren.
Wie auch immer die Chrome
geschrieben wird, sie sollte eine ShellSurfaceItem haben, um die Client-Inhalte zu speichern.
ShellSurfaceItem { id: shellSurfaceItemId anchors.top: titleBar.bottom anchors.bottom: bottomResizeHandle.top anchors.left: leftResizeHandle.right anchors.right: rightResizeHandle.left moveItem: chrome staysOnBottom: shellSurface.windowFlags & Qt.WindowStaysOnBottomHint staysOnTop: !staysOnBottom && shellSurface.windowFlags & Qt.WindowStaysOnTopHint } shellSurfaceItem: shellSurfaceItemId
Die ShellSurfaceItem ist die visuelle Darstellung des Client-Inhalts in der Qt Quick Szene. Seine Größe sollte in der Regel mit der Größe des Client-Puffers übereinstimmen, andernfalls könnte er gestreckt oder gequetscht aussehen. QtShellChrome wird automatisch auf die Größe von QtShellSurface's windowGeometry angepasst, was der Größe des Client-Puffers plus der Größe der Frame-Ränder entspricht. Die Rahmenränder sind reservierte Bereiche an den Seiten von Chrome
, die zur Aufnahme von Fensterdekorationen verwendet werden können.
Die ShellSurfaceItem wird daher an den Fensterdekorationen verankert, um den für den Client-Puffer reservierten Bereich zu füllen.
Fensterdekorationen
Die Fensterdekoration ist in der Regel ein Rahmen um den Inhalt eines Clients, der Informationen (z. B. einen Fenstertitel) und die Möglichkeit der Benutzerinteraktion (wie Größenänderung, Schließen, Verschieben des Fensters usw.) hinzufügt.
Bei QtShell werden Fensterdekorationen immer vom Compositor und nicht vom Client gezeichnet. Damit die Größen und Positionen korrekt kommuniziert werden können, muss QtShell auch wissen, wie viel des Fensters für diese Dekorationen reserviert ist. Dies kann automatisch durch QtShellChrome oder manuell durch Setzen von frameMarginLeft, frameMarginRight, frameMarginTop und frameMarginBottom erfolgen.
Für typische Fälle, in denen es Griffe zur Größenänderung um das Fenster herum und eine Titelleiste am oberen Rand gibt, ist es bequemer, sich auf die Standard-Rahmenränder zu verlassen. Das QtShell Compositor-Beispiel tut dies.
Zunächst erstellen wir Qt Quick Elemente, um die verschiedenen Teile der Fensterdekoration darzustellen. Auf der linken Seite sollte es beispielsweise einen Griff zur Größenänderung geben, den der Benutzer greifen und ziehen kann, um die Größe des Fensters zu ändern.
Rectangle { id: leftResizeHandle color: "gray" width: visible ? 5 : 0 anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom }
Im Beispiel ist dies einfach ein fünf Pixel breites Rechteck, das an der oberen, unteren und linken Seite des Chrome
verankert ist.
In ähnlicher Weise fügen wir Qt Quick Elemente hinzu, die die Griffe für die Größenänderung rechts, oben, unten, oben links, oben rechts, unten links und unten rechts darstellen. Wir fügen auch eine Titelleiste hinzu. Wenn die Dekorationen erstellt und korrekt an den Seiten von Chrome
verankert wurden, setzen wir die entsprechenden Eigenschaften in QtShellChrome.
leftResizeHandle: leftResizeHandle rightResizeHandle: rightResizeHandle topResizeHandle: topResizeHandle bottomResizeHandle: bottomResizeHandle bottomLeftResizeHandle: bottomLeftResizeHandle bottomRightResizeHandle: bottomRightResizeHandle topLeftResizeHandle: topLeftResizeHandle topRightResizeHandle: topRightResizeHandle titleBar: titleBar
Wenn die Dekorationseigenschaften festgelegt sind, wird das Standardverhalten zur Größenänderung und Neupositionierung automatisch hinzugefügt. Der Benutzer kann mit den Griffen zur Größenänderung interagieren, um die Größe des Fensters zu ändern, und die Titelleiste ziehen, um sie neu zu positionieren. Die Rahmenränder von QtShellSurface werden ebenfalls automatisch eingestellt, um die Größe der Dekorationen zu berücksichtigen (solange keine der Rahmenrandeigenschaften explizit eingestellt wurde).
Die Sichtbarkeit der Dekorationen wird von QtShellChrome automatisch auf der Grundlage der Fensterflags von QtShellSurface geregelt.
Fenster-Verwaltung
Als Teil der Dekorationen ist es üblich, Werkzeugschaltflächen zu haben, die den Zustand und die Lebensdauer des Fensters verwalten. Im Beispiel werden diese in die Titelleiste eingefügt.
RowLayout { id: rowLayout anchors.right: parent.right anchors.rightMargin: 5 ToolButton { text: "-" Layout.margins: 5 visible: (chrome.windowFlags & Qt.WindowMinimizeButtonHint) != 0 onClicked: { chrome.toggleMinimized() } } ToolButton { text: "+" Layout.margins: 5 visible: (chrome.windowFlags & Qt.WindowMaximizeButtonHint) != 0 onClicked: { chrome.toggleMaximized() } } ToolButton { id: xButton text: "X" Layout.margins: 5 visible: (chrome.windowFlags & Qt.WindowCloseButtonHint) != 0 onClicked: shellSurface.sendClose() } }
Die Sichtbarkeit jeder Schaltfläche hängt vom Fenster-Flag für diese Schaltfläche ab, und wenn eine Schaltfläche angeklickt wird, rufen wir einfach die entsprechende Methode in QtShellChrome auf. Die Ausnahme ist die Schaltfläche "Schließen", die die Methode sendClose() in QtShellSurface aufruft. Dadurch wird der Client angewiesen, sich selbst zu schließen, und es wird ein geordnetes Herunterfahren der Anwendung gewährleistet.
Row { id: taskbar height: 40 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom Repeater { anchors.fill: parent model: output.shellSurfaces ToolButton { anchors.verticalCenter: parent.verticalCenter text: modelData.windowTitle onClicked: { var item = chromeRepeater.itemAt(index) if ((item.windowState & Qt.WindowMinimized) != 0) item.toggleMinimized() chromeRepeater.itemAt(index).activate() } } } }
Als zusätzliches Werkzeug zur Fensterverwaltung verfügt das Beispiel über eine "Taskleiste". Dabei handelt es sich lediglich um eine Reihe von Schaltflächen am unteren Rand mit den Fenstertiteln. Die Schaltflächen können angeklickt werden, um Anwendungen zu minimieren und sie in den Vordergrund zu bringen, wenn sie von anderen Fenstern verdeckt werden. Ähnlich wie bei Chrome
verwenden wir eine Repeater für die Erstellung der Werkzeugschaltflächen und nutzen die Shell-Oberflächenliste als Vorlage dafür. Der Einfachheit halber enthält das Beispiel keine Behandlung des Überlaufs (wenn es zu viele Anwendungen für die Taskleiste gibt), aber in einem richtigen Compositor ist dies auch etwas, das berücksichtigt werden sollte.
Um schließlich zu verhindern, dass maximierte Anwendungen den von der Taskleiste abgedeckten Bereich ausfüllen, erstellen wir ein spezielles Element zur Verwaltung der Teile des WaylandOutput -Bereichs, die für Client-Fenster zur Verfügung stehen.
Item { id: usableArea anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right anchors.bottom: taskbar.top }
Es ist einfach an den Seiten des WaylandOutput verankert, aber sein unterer Anker befindet sich am oberen Rand der Taskleiste.
In Chrome
verwenden wir diesen Bereich, um die maximizedRect des Fensters zu definieren.
maximizedRect: Qt.rect(usableArea.x, usableArea.y, usableArea.width, usableArea.height)
Standardmäßig entspricht diese Eigenschaft der gesamten WaylandOutput. In unserem Fall wollen wir jedoch die Taskleiste nicht in den verfügbaren Bereich einbeziehen, also überschreiben wir die Vorgabe.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.