Move primary output to Workspace

Primary output is a window management abstraction, not a hardware
abstraction so move it in Workspace where it belongs.
This commit is contained in:
Vlad Zahorodnii 2022-07-30 15:13:35 +03:00
parent 7c22e6435c
commit b0340dc774
8 changed files with 41 additions and 69 deletions

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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) {

View file

@ -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()) {

View file

@ -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<Output *> m_outputs;
Output *m_activeOutput = nullptr;
Output *m_primaryOutput = nullptr;
QString m_outputsHash;
Window *m_activeWindow;

View file

@ -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();

View file

@ -68,7 +68,7 @@ private:
void installSocketNotifier();
void uninstallSocketNotifier();
void updatePrimary(Output *primaryOutput);
void updatePrimary();
bool createX11Connection();
void destroyX11Connection();