From 9f8b8c97319d17f63b5d7984ece07c196b32ab62 Mon Sep 17 00:00:00 2001 From: Julius Zint Date: Fri, 21 Jan 2022 13:29:46 +0100 Subject: [PATCH] Add desiredScreen property to LayerShellQt::Window If the property is set, the compositor will try to put the window on the given output. If not set, the compositer will decide where to put the window (usually the active output). The motivation for this change is the ability for KRunner to always appear on the active output. --- src/interfaces/window.cpp | 11 +++++++++++ src/interfaces/window.h | 9 +++++++++ src/qwaylandlayersurface.cpp | 21 +++++++++++++-------- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp index 81e0d39..0632c7a 100644 --- a/src/interfaces/window.cpp +++ b/src/interfaces/window.cpp @@ -28,6 +28,7 @@ public: Window::Layer layer = Window::LayerTop; QMargins margins; QWaylandLayerSurface *getSurface() const; + QPointer desiredOutput; }; static QMap s_map; @@ -113,6 +114,16 @@ Window::Layer Window::layer() const return d->layer; } +QScreen *Window::desiredOutput() const +{ + return d->desiredOutput; +} + +void Window::setDesiredOutput(QScreen *output) +{ + d->desiredOutput = output; +} + Window::Window(QWindow *window) : QObject(window) , d(new WindowPrivate(window)) diff --git a/src/interfaces/window.h b/src/interfaces/window.h index 33c46b0..2410682 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -9,6 +9,7 @@ #define LAYERSHELLQTWINDOW_H #include +#include #include #include "layershellqt_export.h" @@ -68,6 +69,14 @@ public: void setLayer(Layer layer); Layer layer() const; + /** + * If set, the compositor will try to put the window on the given screen. + * If its not set, then the compositor will decide where to put the window. + * Under normal circumstances, this should be the active output. + */ + void setDesiredOutput(QScreen *output); + QScreen *desiredOutput() const; + /** * Sets a string based identifier for this window. * This may be used by a compositor to determine stacking diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index 5a95d74..1e6af6d 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -6,9 +6,9 @@ */ #include "interfaces/shell.h" +#include "layershellqt_logging.h" #include "qwaylandlayershell_p.h" #include "qwaylandlayersurface_p.h" -#include "layershellqt_logging.h" #include #include @@ -23,14 +23,19 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandC LayerShellQt::Window *interface = Window::get(window->window()); Q_ASSERT(interface); - // 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 - QtWaylandClient::QWaylandScreen *screen = window->waylandScreen(); - if (screen->isPlaceholder()) { - qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly"; + wl_output *output = nullptr; + QScreen *screen = interface->desiredOutput(); + if (screen) { + auto waylandScreen = dynamic_cast(screen->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) { + qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly"; + } else { + output = waylandScreen->output(); + } } - - init(shell->get_layer_surface(window->waylandSurface()->object(), screen->isPlaceholder() ? nullptr : screen->output(), interface->layer(), interface->scope())); + init(shell->get_layer_surface(window->waylandSurface()->object(), output, interface->layer(), interface->scope())); Window::Anchors anchors = interface->anchors();