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