diff --git a/src/platform.cpp b/src/platform.cpp index e6b80bad90..c406357bf6 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -43,24 +43,6 @@ Platform::Platform(QObject *parent) : QObject(parent) , m_eglDisplay(EGL_NO_DISPLAY) { - connect(this, &Platform::outputDisabled, this, [this](Output *output) { - if (m_primaryOutput == output) { - Output *primary = nullptr; - const auto candidates = outputs(); - for (Output *output : candidates) { - if (output->isEnabled()) { - primary = output; - break; - } - } - setPrimaryOutput(primary); - } - }); - connect(this, &Platform::outputEnabled, this, [this](Output *output) { - if (!m_primaryOutput) { - setPrimaryOutput(output); - } - }); } Platform::~Platform() @@ -316,14 +298,4 @@ void Platform::setSceneEglGlobalShareContext(EGLContext context) m_globalShareContext = context; } -void Platform::setPrimaryOutput(Output *primary) -{ - if (primary == m_primaryOutput) { - return; - } - Q_ASSERT(kwinApp()->isTerminating() || primary->isEnabled()); - m_primaryOutput = primary; - Q_EMIT primaryOutputChanged(primary); -} - -} +} // namespace KWin diff --git a/src/platform.h b/src/platform.h index 53932af1f6..e2bd5f7ba6 100644 --- a/src/platform.h +++ b/src/platform.h @@ -320,19 +320,6 @@ public: virtual Output *createVirtualOutput(const QString &name, const QSize &size, qreal scaling); virtual void removeVirtualOutput(Output *output); - /** - * @returns the primary output amomg the enabled outputs - */ - Output *primaryOutput() const - { - return m_primaryOutput; - } - - /** - * Assigns a the @p primary output among the enabled outputs - */ - void setPrimaryOutput(Output *primary); - /** * Applies the output changes. Default implementation only sets values common between platforms */ @@ -367,8 +354,6 @@ Q_SIGNALS: */ void outputDisabled(Output *output); - void primaryOutputChanged(Output *primaryOutput); - protected: explicit Platform(QObject *parent = nullptr); void setReady(bool ready); @@ -400,7 +385,6 @@ private: EGLContext m_globalShareContext = EGL_NO_CONTEXT; bool m_supportsGammaControl = false; CompositingType m_selectedCompositor = NoCompositing; - Output *m_primaryOutput = nullptr; }; } // namespace KWin diff --git a/src/wayland/outputmanagement_v2_interface.cpp b/src/wayland/outputmanagement_v2_interface.cpp index 2e9a621b31..faef084585 100644 --- a/src/wayland/outputmanagement_v2_interface.cpp +++ b/src/wayland/outputmanagement_v2_interface.cpp @@ -228,21 +228,10 @@ void OutputConfigurationV2Interface::kde_output_configuration_v2_apply(Resource } if (kwinApp()->platform()->applyOutputChanges(config)) { - if (primaryOutput.has_value() || !kwinApp()->platform()->primaryOutput()->isEnabled()) { + if (primaryOutput.has_value()) { auto requestedPrimaryOutput = (*primaryOutput)->handle(); if (requestedPrimaryOutput && requestedPrimaryOutput->isEnabled()) { - kwinApp()->platform()->setPrimaryOutput(requestedPrimaryOutput); - } else { - Output *defaultPrimaryOutput = nullptr; - const auto candidates = kwinApp()->platform()->outputs(); - for (Output *output : candidates) { - if (output->isEnabled()) { - defaultPrimaryOutput = output; - break; - } - } - qCWarning(KWIN_CORE) << "Requested invalid primary screen, using" << defaultPrimaryOutput; - kwinApp()->platform()->setPrimaryOutput(defaultPrimaryOutput); + workspace()->setPrimaryOutput(requestedPrimaryOutput); } } Q_EMIT workspace()->screens()->changed(); diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 2c8c1ea888..7f7145f8aa 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -533,12 +533,13 @@ void WaylandServer::initWorkspace() }); } - connect(kwinApp()->platform(), &Platform::primaryOutputChanged, this, [this](Output *primaryOutput) { - m_primary->setPrimaryOutput(primaryOutput ? primaryOutput->name() : QString()); - }); - if (auto primaryOutput = kwinApp()->platform()->primaryOutput()) { + if (auto primaryOutput = workspace()->primaryOutput()) { m_primary->setPrimaryOutput(primaryOutput->name()); } + connect(workspace(), &Workspace::primaryOutputChanged, this, [this]() { + const Output *primaryOutput = workspace()->primaryOutput(); + m_primary->setPrimaryOutput(primaryOutput ? primaryOutput->name() : QString()); + }); const auto availableOutputs = kwinApp()->platform()->outputs(); for (Output *output : availableOutputs) { diff --git a/src/workspace.cpp b/src/workspace.cpp index cb5712d561..0d7f5f5741 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -670,7 +670,7 @@ void Workspace::updateOutputConfiguration() qCWarning(KWIN_CORE) << "Applying KScreen config failed!"; return; } - kwinApp()->platform()->setPrimaryOutput(primaryOutput); + setPrimaryOutput(primaryOutput); } void Workspace::setupWindowConnections(Window *window) @@ -1388,6 +1388,9 @@ void Workspace::slotOutputEnabled(Output *output) if (!m_activeOutput) { m_activeOutput = output; } + if (!m_primaryOutput) { + setPrimaryOutput(output); + } m_outputs.append(output); @@ -1413,6 +1416,9 @@ void Workspace::slotOutputDisabled(Output *output) if (m_activeOutput == output) { m_activeOutput = outputAt(output->geometry().center()); } + if (m_primaryOutput == output) { + setPrimaryOutput(m_outputs.constFirst()); + } disconnect(output, &Output::geometryChanged, this, &Workspace::desktopResized); desktopResized(); @@ -2553,6 +2559,19 @@ Output *Workspace::xineramaIndexToOutput(int index) const return nullptr; } +Output *Workspace::primaryOutput() const +{ + return m_primaryOutput; +} + +void Workspace::setPrimaryOutput(Output *output) +{ + if (m_primaryOutput != output) { + m_primaryOutput = output; + Q_EMIT primaryOutputChanged(); + } +} + Output *Workspace::activeOutput() const { if (options->activeMouseScreen()) { diff --git a/src/workspace.h b/src/workspace.h index 44b6042bb1..389327bb00 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -172,6 +172,9 @@ public: Output *xineramaIndexToOutput(int index) const; + Output *primaryOutput() const; + void setPrimaryOutput(Output *output); + Output *activeOutput() const; void setActiveOutput(Output *output); void setActiveOutput(const QPointF &pos); @@ -564,6 +567,7 @@ Q_SIGNALS: void deletedRemoved(KWin::Deleted *); void configChanged(); void showingDesktopChanged(bool showing, bool animated); + void primaryOutputChanged(); void outputAdded(KWin::Output *); void outputRemoved(KWin::Output *); /** @@ -650,6 +654,7 @@ private: QList m_outputs; Output *m_activeOutput = nullptr; + Output *m_primaryOutput = nullptr; QString m_outputsHash; Window *m_activeWindow; diff --git a/src/xwayland/xwayland.cpp b/src/xwayland/xwayland.cpp index 4ff7086b06..78de5845d1 100644 --- a/src/xwayland/xwayland.cpp +++ b/src/xwayland/xwayland.cpp @@ -24,6 +24,7 @@ #include "utils/common.h" #include "utils/xcbutils.h" #include "wayland_server.h" +#include "workspace.h" #include "x11eventfilter.h" #include "xwayland_logging.h" @@ -69,7 +70,7 @@ XrandrEventFilter::XrandrEventFilter(Xwayland *backend) bool XrandrEventFilter::event(xcb_generic_event_t *event) { Q_ASSERT((event->response_type & ~0x80) == Xcb::Extensions::self()->randrNotifyEvent()); - m_backend->updatePrimary(kwinApp()->platform()->primaryOutput()); + m_backend->updatePrimary(); return false; } @@ -150,7 +151,7 @@ void Xwayland::uninstallSocketNotifier() void Xwayland::handleXwaylandFinished() { - disconnect(kwinApp()->platform(), &Platform::primaryOutputChanged, this, &Xwayland::updatePrimary); + disconnect(workspace(), &Workspace::primaryOutputChanged, this, &Xwayland::updatePrimary); delete m_xrandrEventsFilter; m_xrandrEventsFilter = nullptr; @@ -198,8 +199,8 @@ void Xwayland::handleXwaylandReady() qputenv("XAUTHORITY", m_launcher->xauthority().toLatin1()); m_app->setProcessStartupEnvironment(env); - connect(kwinApp()->platform(), &Platform::primaryOutputChanged, this, &Xwayland::updatePrimary); - updatePrimary(kwinApp()->platform()->primaryOutput()); + connect(workspace(), &Workspace::primaryOutputChanged, this, &Xwayland::updatePrimary); + updatePrimary(); Xcb::sync(); // Trigger possible errors, there's still a chance to abort @@ -207,7 +208,7 @@ void Xwayland::handleXwaylandReady() m_xrandrEventsFilter = new XrandrEventFilter(this); } -void Xwayland::updatePrimary(Output *primaryOutput) +void Xwayland::updatePrimary() { Xcb::RandR::ScreenResources resources(kwinApp()->x11RootWindow()); xcb_randr_crtc_t *crtcs = resources.crtcs(); @@ -215,6 +216,7 @@ void Xwayland::updatePrimary(Output *primaryOutput) return; } + Output *primaryOutput = workspace()->primaryOutput(); for (int i = 0; i < resources->num_crtcs; ++i) { Xcb::RandR::CrtcInfo crtcInfo(crtcs[i], resources->config_timestamp); const QRect geometry = crtcInfo.rect(); diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index d8d9537c1d..67243b51a3 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -68,7 +68,7 @@ private: void installSocketNotifier(); void uninstallSocketNotifier(); - void updatePrimary(Output *primaryOutput); + void updatePrimary(); bool createX11Connection(); void destroyX11Connection();