diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp index 0389d51..7ea290d 100644 --- a/src/interfaces/window.cpp +++ b/src/interfaces/window.cpp @@ -34,7 +34,8 @@ public: Window::Layer layer = Window::LayerTop; QMargins margins; QSize desiredSize = QSize(0, 0); - Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; + QPointer screen; + bool wantsToBeOnActiveScreen = false; bool closeOnDismissed = true; bool activateOnShow = true; }; @@ -152,14 +153,46 @@ Window::Layer Window::layer() const return d->layer; } -Window::ScreenConfiguration Window::screenConfiguration() const +void Window::setWantsToBeOnActiveScreen(bool set) { - return d->screenConfiguration; + if (d->wantsToBeOnActiveScreen == set) { + return; + } + + d->wantsToBeOnActiveScreen = set; + + if (d->wantsToBeOnActiveScreen && d->screen) { + d->screen = nullptr; + Q_EMIT screenChanged(); + } + + Q_EMIT wantsToBeOnActiveScreenChanged(); } -void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration) +bool Window::wantsToBeOnActiveScreen() const { - d->screenConfiguration = screenConfiguration; + return d->wantsToBeOnActiveScreen; +} + +void Window::setScreen(QScreen *screen) +{ + if (d->screen == screen) { + return; + } + + d->screen = screen; + + if (d->screen && d->wantsToBeOnActiveScreen) { + d->wantsToBeOnActiveScreen = false; + Q_EMIT wantsToBeOnActiveScreenChanged(); + } + + Q_EMIT screenChanged(); +} + +QScreen *Window::screen() const +{ + return d->screen; } bool Window::closeOnDismissed() const diff --git a/src/interfaces/window.h b/src/interfaces/window.h index b9e4824..2c2e1c8 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -27,8 +27,9 @@ class LAYERSHELLQT_EXPORT Window : public QObject Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged) Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged) Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged) - Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration) Q_PROPERTY(bool activateOnShow READ activateOnShow WRITE setActivateOnShow) + Q_PROPERTY(bool wantsToBeOnActiveScreen READ wantsToBeOnActiveScreen WRITE setWantsToBeOnActiveScreen NOTIFY wantsToBeOnActiveScreenChanged) + Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged) public: ~Window() override; @@ -64,17 +65,6 @@ public: }; Q_ENUM(KeyboardInteractivity) - /** - * This enum type is used to specify which screen to place the surface on. - * ScreenFromQWindow (the default) reads QWindow::screen() while ScreenFromCompositor - * passes nil and lets the compositor decide. - */ - enum ScreenConfiguration { - ScreenFromQWindow = 0, - ScreenFromCompositor = 1, - }; - Q_ENUM(ScreenConfiguration) - void setAnchors(Anchors anchor); Anchors anchors() const; @@ -96,8 +86,29 @@ public: void setLayer(Layer layer); Layer layer() const; - void setScreenConfiguration(ScreenConfiguration screenConfiguration); - ScreenConfiguration screenConfiguration() const; + /** + * Indicates whether the layer shell surface should be placed on the active screen based on @a set. + * + * The active screen depends on the compositor policies. + * + * If the screen() is @c null and the wantsToBeOnActiveScreen() is @c false, then the + * QWindow::screen() will be used to decide what screen the layer shell surface should be placed on. + * + * The screen() will be reset if @a set is @c true. + */ + void setWantsToBeOnActiveScreen(bool set); + bool wantsToBeOnActiveScreen() const; + + /** + * Indicates that the layer shell surface should be placed on the specified @a screen. + * + * If the screen() is @c null and the wantsToBeOnActiveScreen() is @c false, then the + * QWindow::screen() will be used to decide what screen the layer shell surface should be placed on. + * + * The wantsToBeOnActiveScreen() will be reset to @c false after calling this function. + */ + void setScreen(QScreen *screen); + QScreen *screen() const; /** * Sets a string based identifier for this window. @@ -148,6 +159,8 @@ Q_SIGNALS: void desiredSizeChanged(); void keyboardInteractivityChanged(); void layerChanged(); + void wantsToBeOnActiveScreenChanged(); + void screenChanged(); private: void initializeShell(); diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index 440929f..4c86abb 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -27,8 +27,13 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell, , m_window(window) { wl_output *output = nullptr; - if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) { - auto waylandScreen = dynamic_cast(window->window()->screen()->handle()); + if (!m_interface->wantsToBeOnActiveScreen()) { + QScreen *desiredScreen = m_interface->screen(); + if (!desiredScreen) { + desiredScreen = window->window()->screen(); + } + + auto waylandScreen = dynamic_cast(desiredScreen->handle()); // Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created // this will not cast to a QWaylandScreen if (!waylandScreen) {