backends/{x11,wayland}: Rework passing initial configuration to windowed backends
Currently, OutputBackend stores the initial state for windowed backends. It's messy because the backends can have different needs. Instead, make windowed backends take an Options struct with all possible options.
This commit is contained in:
parent
69c9f19973
commit
528abfb00a
9 changed files with 66 additions and 47 deletions
|
@ -534,8 +534,9 @@ void WaylandSeat::destroyTouchDevice()
|
|||
}
|
||||
}
|
||||
|
||||
WaylandBackend::WaylandBackend(QObject *parent)
|
||||
WaylandBackend::WaylandBackend(const WaylandBackendOptions &options, QObject *parent)
|
||||
: OutputBackend(parent)
|
||||
, m_options(options)
|
||||
{
|
||||
#if HAVE_WAYLAND_EGL
|
||||
char const *drm_render_node = "/dev/dri/renderD128";
|
||||
|
@ -570,7 +571,7 @@ WaylandBackend::~WaylandBackend()
|
|||
bool WaylandBackend::initialize()
|
||||
{
|
||||
m_display = std::make_unique<WaylandDisplay>();
|
||||
if (!m_display->initialize(deviceIdentifier())) {
|
||||
if (!m_display->initialize(m_options.socketName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -613,9 +614,9 @@ void WaylandBackend::createOutputs()
|
|||
{
|
||||
// we need to multiply the initial window size with the scale in order to
|
||||
// create an output window of this size in the end
|
||||
const QSize nativeSize = initialWindowSize() * initialOutputScale();
|
||||
for (int i = 0; i < initialOutputCount(); i++) {
|
||||
WaylandOutput *output = createOutput(QStringLiteral("WL-%1").arg(i), nativeSize);
|
||||
const QSize pixelSize = m_options.outputSize * m_options.outputScale;
|
||||
for (int i = 0; i < m_options.outputCount; i++) {
|
||||
WaylandOutput *output = createOutput(QStringLiteral("WL-%1").arg(i), pixelSize, m_options.outputScale);
|
||||
m_outputs << output;
|
||||
Q_EMIT outputAdded(output);
|
||||
output->updateEnabled(true);
|
||||
|
@ -624,10 +625,10 @@ void WaylandBackend::createOutputs()
|
|||
Q_EMIT outputsQueried();
|
||||
}
|
||||
|
||||
WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size)
|
||||
WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size, qreal scale)
|
||||
{
|
||||
WaylandOutput *waylandOutput = new WaylandOutput(name, this);
|
||||
waylandOutput->init(size);
|
||||
waylandOutput->init(size, scale);
|
||||
|
||||
// Wait until the output window is configured by the host compositor.
|
||||
while (!waylandOutput->isReady()) {
|
||||
|
@ -750,7 +751,7 @@ void WaylandBackend::clearDpmsFilter()
|
|||
|
||||
Output *WaylandBackend::createVirtualOutput(const QString &name, const QSize &size, double scale)
|
||||
{
|
||||
return createOutput(name, size * scale);
|
||||
return createOutput(name, size * scale, scale);
|
||||
}
|
||||
|
||||
void WaylandBackend::removeVirtualOutput(Output *output)
|
||||
|
|
|
@ -220,6 +220,14 @@ private:
|
|||
std::unique_ptr<WaylandInputDevice> m_touchDevice;
|
||||
};
|
||||
|
||||
struct WaylandBackendOptions
|
||||
{
|
||||
QString socketName;
|
||||
int outputCount = 1;
|
||||
qreal outputScale = 1;
|
||||
QSize outputSize = QSize(1024, 768);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class encapsulating all Wayland data structures needed by the Egl backend.
|
||||
*
|
||||
|
@ -231,7 +239,7 @@ class KWIN_EXPORT WaylandBackend : public OutputBackend
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WaylandBackend(QObject *parent = nullptr);
|
||||
explicit WaylandBackend(const WaylandBackendOptions &options, QObject *parent = nullptr);
|
||||
~WaylandBackend() override;
|
||||
bool initialize() override;
|
||||
|
||||
|
@ -288,8 +296,9 @@ Q_SIGNALS:
|
|||
private:
|
||||
void createOutputs();
|
||||
void destroyOutputs();
|
||||
WaylandOutput *createOutput(const QString &name, const QSize &size);
|
||||
WaylandOutput *createOutput(const QString &name, const QSize &size, qreal scale);
|
||||
|
||||
WaylandBackendOptions m_options;
|
||||
std::unique_ptr<WaylandDisplay> m_display;
|
||||
std::unique_ptr<WaylandSeat> m_seat;
|
||||
WaylandEglBackend *m_eglBackend = nullptr;
|
||||
|
|
|
@ -103,7 +103,7 @@ RenderLoop *WaylandOutput::renderLoop() const
|
|||
return m_renderLoop.get();
|
||||
}
|
||||
|
||||
void WaylandOutput::init(const QSize &pixelSize)
|
||||
void WaylandOutput::init(const QSize &pixelSize, qreal scale)
|
||||
{
|
||||
m_renderLoop->setRefreshRate(s_refreshRate);
|
||||
|
||||
|
@ -112,7 +112,7 @@ void WaylandOutput::init(const QSize &pixelSize)
|
|||
State initialState;
|
||||
initialState.modes = {mode};
|
||||
initialState.currentMode = mode;
|
||||
initialState.scale = m_backend->initialOutputScale();
|
||||
initialState.scale = scale;
|
||||
setState(initialState);
|
||||
|
||||
m_surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
|
||||
RenderLoop *renderLoop() const override;
|
||||
|
||||
void init(const QSize &pixelSize);
|
||||
void init(const QSize &pixelSize, qreal scale);
|
||||
|
||||
bool isReady() const;
|
||||
KWayland::Client::Surface *surface() const;
|
||||
|
|
|
@ -153,7 +153,8 @@ void X11WindowedInputBackend::initialize()
|
|||
}
|
||||
}
|
||||
|
||||
X11WindowedBackend::X11WindowedBackend()
|
||||
X11WindowedBackend::X11WindowedBackend(const X11WindowedBackendOptions &options)
|
||||
: m_options(options)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,7 @@ bool X11WindowedBackend::initialize()
|
|||
{
|
||||
int screen = 0;
|
||||
xcb_connection_t *c = nullptr;
|
||||
Display *xDisplay = XOpenDisplay(deviceIdentifier().constData());
|
||||
Display *xDisplay = XOpenDisplay(m_options.display.toLatin1().constData());
|
||||
if (xDisplay) {
|
||||
c = XGetXCBConnection(xDisplay);
|
||||
XSetEventQueueOwner(xDisplay, XCBOwnsEventQueue);
|
||||
|
@ -268,12 +269,10 @@ void X11WindowedBackend::createOutputs()
|
|||
|
||||
// we need to multiply the initial window size with the scale in order to
|
||||
// create an output window of this size in the end
|
||||
const int pixelWidth = initialWindowSize().width() * initialOutputScale() + 0.5;
|
||||
const int pixelHeight = initialWindowSize().height() * initialOutputScale() + 0.5;
|
||||
|
||||
for (int i = 0; i < initialOutputCount(); ++i) {
|
||||
const QSize pixelSize = m_options.outputSize * m_options.outputScale;
|
||||
for (int i = 0; i < m_options.outputCount; ++i) {
|
||||
auto *output = new X11WindowedOutput(this);
|
||||
output->init(QSize(pixelWidth, pixelHeight));
|
||||
output->init(pixelSize, m_options.outputScale);
|
||||
|
||||
m_protocols = protocolsAtom;
|
||||
m_deleteWindowProtocol = deleteWindowAtom;
|
||||
|
|
|
@ -81,12 +81,20 @@ private:
|
|||
X11WindowedBackend *m_backend;
|
||||
};
|
||||
|
||||
struct X11WindowedBackendOptions
|
||||
{
|
||||
QString display;
|
||||
int outputCount = 1;
|
||||
qreal outputScale = 1;
|
||||
QSize outputSize = QSize(1024, 768);
|
||||
};
|
||||
|
||||
class KWIN_EXPORT X11WindowedBackend : public OutputBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit X11WindowedBackend();
|
||||
explicit X11WindowedBackend(const X11WindowedBackendOptions &options);
|
||||
~X11WindowedBackend() override;
|
||||
bool initialize() override;
|
||||
|
||||
|
@ -146,6 +154,7 @@ private:
|
|||
void initXInput();
|
||||
X11WindowedOutput *findOutput(xcb_window_t window) const;
|
||||
|
||||
X11WindowedBackendOptions m_options;
|
||||
xcb_connection_t *m_connection = nullptr;
|
||||
xcb_screen_t *m_screen = nullptr;
|
||||
xcb_key_symbols_t *m_keySymbols = nullptr;
|
||||
|
|
|
@ -74,7 +74,7 @@ SoftwareVsyncMonitor *X11WindowedOutput::vsyncMonitor() const
|
|||
return m_vsyncMonitor.get();
|
||||
}
|
||||
|
||||
void X11WindowedOutput::init(const QSize &pixelSize)
|
||||
void X11WindowedOutput::init(const QSize &pixelSize, qreal scale)
|
||||
{
|
||||
const int refreshRate = 60000; // TODO: get refresh rate via randr
|
||||
m_renderLoop->setRefreshRate(refreshRate);
|
||||
|
@ -85,7 +85,7 @@ void X11WindowedOutput::init(const QSize &pixelSize)
|
|||
State initialState;
|
||||
initialState.modes = {mode};
|
||||
initialState.currentMode = mode;
|
||||
initialState.scale = m_backend->initialOutputScale();
|
||||
initialState.scale = scale;
|
||||
setState(initialState);
|
||||
|
||||
const uint32_t eventMask = XCB_EVENT_MASK_KEY_PRESS
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
RenderLoop *renderLoop() const override;
|
||||
SoftwareVsyncMonitor *vsyncMonitor() const;
|
||||
|
||||
void init(const QSize &pixelSize);
|
||||
void init(const QSize &pixelSize, qreal scale);
|
||||
void resize(const QSize &pixelSize);
|
||||
|
||||
xcb_window_t window() const
|
||||
|
|
|
@ -450,7 +450,6 @@ int main(int argc, char *argv[])
|
|||
BackendType backendType;
|
||||
QString pluginName;
|
||||
QSize initialWindowSize;
|
||||
QByteArray deviceIdentifier;
|
||||
int outputCount = 1;
|
||||
qreal outputScale = 1;
|
||||
|
||||
|
@ -459,10 +458,8 @@ int main(int argc, char *argv[])
|
|||
backendType = BackendType::Kms;
|
||||
} else if (parser.isSet(x11DisplayOption)) {
|
||||
backendType = BackendType::X11;
|
||||
deviceIdentifier = parser.value(x11DisplayOption).toUtf8();
|
||||
} else if (parser.isSet(waylandDisplayOption)) {
|
||||
backendType = BackendType::Wayland;
|
||||
deviceIdentifier = parser.value(waylandDisplayOption).toUtf8();
|
||||
} else if (parser.isSet(virtualFbOption)) {
|
||||
backendType = BackendType::Virtual;
|
||||
} else {
|
||||
|
@ -560,31 +557,35 @@ int main(int argc, char *argv[])
|
|||
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
||||
a.setOutputBackend(std::make_unique<KWin::VirtualBackend>());
|
||||
break;
|
||||
case BackendType::X11:
|
||||
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
||||
a.setOutputBackend(std::make_unique<KWin::X11WindowedBackend>());
|
||||
if (deviceIdentifier.isEmpty()) {
|
||||
a.outputBackend()->setDeviceIdentifier(qgetenv("DISPLAY"));
|
||||
} else {
|
||||
a.outputBackend()->setDeviceIdentifier(deviceIdentifier);
|
||||
case BackendType::X11: {
|
||||
QString display = parser.value(x11DisplayOption);
|
||||
if (display.isEmpty()) {
|
||||
display = qgetenv("DISPLAY");
|
||||
}
|
||||
break;
|
||||
case BackendType::Wayland:
|
||||
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
||||
a.setOutputBackend(std::make_unique<KWin::Wayland::WaylandBackend>());
|
||||
if (deviceIdentifier.isEmpty()) {
|
||||
a.outputBackend()->setDeviceIdentifier(qgetenv("WAYLAND_DISPLAY"));
|
||||
} else {
|
||||
a.outputBackend()->setDeviceIdentifier(deviceIdentifier);
|
||||
}
|
||||
a.setOutputBackend(std::make_unique<KWin::X11WindowedBackend>(KWin::X11WindowedBackendOptions{
|
||||
.display = display,
|
||||
.outputCount = outputCount,
|
||||
.outputScale = outputScale,
|
||||
.outputSize = initialWindowSize,
|
||||
}));
|
||||
break;
|
||||
}
|
||||
case BackendType::Wayland: {
|
||||
QString socketName = parser.value(waylandDisplayOption);
|
||||
if (socketName.isEmpty()) {
|
||||
socketName = qgetenv("WAYLAND_DISPLAY");
|
||||
}
|
||||
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
|
||||
a.setOutputBackend(std::make_unique<KWin::Wayland::WaylandBackend>(KWin::Wayland::WaylandBackendOptions{
|
||||
.socketName = socketName,
|
||||
.outputCount = outputCount,
|
||||
.outputScale = outputScale,
|
||||
.outputSize = initialWindowSize,
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
if (initialWindowSize.isValid()) {
|
||||
a.outputBackend()->setInitialWindowSize(initialWindowSize);
|
||||
}
|
||||
a.outputBackend()->setInitialOutputScale(outputScale);
|
||||
a.outputBackend()->setInitialOutputCount(outputCount);
|
||||
|
||||
QObject::connect(&a, &KWin::Application::workspaceCreated, server, &KWin::WaylandServer::initWorkspace);
|
||||
if (!server->socketName().isEmpty()) {
|
||||
|
|
Loading…
Reference in a new issue