diff --git a/main_wayland.cpp b/main_wayland.cpp index 786d022e34..5983d45ec3 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -73,7 +73,6 @@ ApplicationWayland::ApplicationWayland(int &argc, char **argv) ApplicationWayland::~ApplicationWayland() { destroyWorkspace(); - delete Wayland::WaylandBackend::self(); if (x11Connection()) { Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT); xcb_disconnect(x11Connection()); @@ -88,21 +87,45 @@ void ApplicationWayland::performStartup() // try creating the Wayland Backend createInput(); - if (!X11WindowedBackend::self()) { - // only create WaylandBackend if we do not use X11WindowedBackend - Wayland::WaylandBackend *backend = Wayland::WaylandBackend::create(); - connect(backend, &Wayland::WaylandBackend::connectionFailed, this, - [] () { - fputs(i18n("kwin_wayland: could not connect to Wayland Server, ensure WAYLAND_DISPLAY is set.\n").toLocal8Bit().constData(), stderr); - ::exit(1); - } - ); - connect(backend, &Wayland::WaylandBackend::outputsChanged, this, &ApplicationWayland::continueStartupWithScreens); - } else { + createBackend(); + if (X11WindowedBackend::self()) { continueStartupWithScreens(); } } +void ApplicationWayland::createBackend() +{ + AbstractBackend *backend = nullptr; + if (m_windowed) { + if (!m_waylandDisplay.isEmpty()) { + Wayland::WaylandBackend *b = Wayland::WaylandBackend::create(m_waylandDisplay, this); + connect(b, &Wayland::WaylandBackend::connectionFailed, this, + [] () { + fputs(i18n("kwin_wayland: could not connect to Wayland Server, ensure WAYLAND_DISPLAY is set.\n").toLocal8Bit().constData(), stderr); + ::exit(1); + } + ); + connect(b, &Wayland::WaylandBackend::outputsChanged, this, &ApplicationWayland::continueStartupWithScreens); + backend = b; + } + if (!backend && !m_x11Display.isEmpty()) { + KWin::X11WindowedBackend *x11Backend = KWin::X11WindowedBackend::create(m_x11Display, m_backendSize, this); + if (x11Backend->isValid()) { + backend = x11Backend; + waylandServer()->seat()->setHasPointer(true); + waylandServer()->seat()->setHasKeyboard(true); + } else { + delete x11Backend; + } + } + } + + if (!backend) { + std::cerr << "FATAL ERROR: could not create a backend, exiting now" << std::endl; + ::exit(1); + } +} + void ApplicationWayland::continueStartupWithScreens() { if (Wayland::WaylandBackend::self()) { @@ -352,6 +375,9 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) QCommandLineOption x11DisplayOption(QStringLiteral("x11-display"), i18n("The X11 Display to use in windowed mode on platform X11."), QStringLiteral("display")); + QCommandLineOption waylandDisplayOption(QStringLiteral("wayland-display"), + i18n("The Wayland Display to use in windowed mode on platform Wayland."), + QStringLiteral("display")); QCommandLineOption widthOption(QStringLiteral("width"), i18n("The width for windowed mode. Default width is 1024."), QStringLiteral("width")); @@ -367,6 +393,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) parser.addOption(waylandSocketOption); parser.addOption(windowedOption); parser.addOption(x11DisplayOption); + parser.addOption(waylandDisplayOption); parser.addOption(widthOption); parser.addOption(heightOption); #if HAVE_INPUT @@ -382,6 +409,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) KWin::Application::setUseLibinput(parser.isSet(libinputOption)); #endif + a.setWindowed(parser.isSet(windowedOption)); if (parser.isSet(windowedOption)) { bool ok = false; const int width = parser.value(widthOption).toInt(&ok); @@ -394,13 +422,17 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) std::cerr << "FATAL ERROR incorrect value for height" << std::endl; return 1; } - KWin::X11WindowedBackend *x11Backend = KWin::X11WindowedBackend::create(parser.value(x11DisplayOption), QSize(width, height), &a); - if (!x11Backend->isValid()) { - std::cerr << "FATAL ERROR failed to connet to X Server" << std::endl; - return 1; + a.setBackendSize(QSize(width, height)); + if (parser.isSet(x11DisplayOption)) { + a.setX11Display(parser.value(x11DisplayOption).toUtf8()); + } else if (!parser.isSet(waylandDisplayOption)) { + a.setX11Display(qgetenv("DISPLAY")); + } + if (parser.isSet(waylandDisplayOption)) { + a.setWaylandDisplay(parser.value(waylandDisplayOption).toUtf8()); + } else if (!parser.isSet(x11DisplayOption)) { + a.setWaylandDisplay(qgetenv("WAYLAND_DISPLAY")); } - server->seat()->setHasPointer(true); - server->seat()->setHasKeyboard(true); } a.setStartXwayland(parser.isSet(xwaylandOption)); diff --git a/main_wayland.h b/main_wayland.h index 9a62282fcb..36387c90c6 100644 --- a/main_wayland.h +++ b/main_wayland.h @@ -34,17 +34,34 @@ public: void setStartXwayland(bool start) { m_startXWayland = start; } + void setBackendSize(const QSize &size) { + m_backendSize = size; + } + void setWindowed(bool set) { + m_windowed = set; + } + void setX11Display(const QByteArray &display) { + m_x11Display = display; + } + void setWaylandDisplay(const QByteArray &display) { + m_waylandDisplay = display; + } protected: void performStartup() override; private: + void createBackend(); void createX11Connection(); void continueStartupWithScreens(); void continueStartupWithX(); bool m_startXWayland = false; int m_xcbConnectionFd = -1; + QSize m_backendSize; + bool m_windowed = false; + QByteArray m_x11Display; + QByteArray m_waylandDisplay; }; } diff --git a/wayland_backend.cpp b/wayland_backend.cpp index e1b2fff92c..4587a06e28 100644 --- a/wayland_backend.cpp +++ b/wayland_backend.cpp @@ -356,14 +356,14 @@ void WaylandCursor::setCursorImage(Qt::CursorShape shape) } WaylandBackend *WaylandBackend::s_self = 0; -WaylandBackend *WaylandBackend::create(QObject *parent) +WaylandBackend *WaylandBackend::create(const QByteArray &display, QObject *parent) { Q_ASSERT(!s_self); - s_self = new WaylandBackend(parent); + s_self = new WaylandBackend(display, parent); return s_self; } -WaylandBackend::WaylandBackend(QObject *parent) +WaylandBackend::WaylandBackend(const QByteArray &display, QObject *parent) : AbstractBackend(parent) , m_display(nullptr) , m_eventQueue(new EventQueue(this)) @@ -374,7 +374,7 @@ WaylandBackend::WaylandBackend(QObject *parent) , m_shellSurface(NULL) , m_seat() , m_shm(new ShmPool(this)) - , m_connectionThreadObject(nullptr) + , m_connectionThreadObject(new ConnectionThread(nullptr)) , m_connectionThread(nullptr) , m_fullscreenShell(new FullscreenShell(this)) , m_subCompositor(new SubCompositor(this)) @@ -423,6 +423,7 @@ WaylandBackend::WaylandBackend(QObject *parent) } ); connect(m_registry, &Registry::interfacesAnnounced, this, &WaylandBackend::createSurface); + m_connectionThreadObject->setSocketName(display); initConnection(); } @@ -459,7 +460,6 @@ void WaylandBackend::destroyOutputs() void WaylandBackend::initConnection() { - m_connectionThreadObject = new ConnectionThread(nullptr); connect(m_connectionThreadObject, &ConnectionThread::connected, this, [this]() { // create the event queue for the main gui thread diff --git a/wayland_backend.h b/wayland_backend.h index ef86b529c5..7a6ca5f7bb 100644 --- a/wayland_backend.h +++ b/wayland_backend.h @@ -165,6 +165,11 @@ public: void installCursorImage(Qt::CursorShape shape) override; void installCursorFromServer() override; + static WaylandBackend *create(const QByteArray &display, QObject *parent = nullptr); + static WaylandBackend *self() { + return s_self; + } + protected: void connectNotify(const QMetaMethod &signal) override; @@ -175,6 +180,7 @@ Q_SIGNALS: void outputsChanged(); void connectionFailed(); private: + explicit WaylandBackend(const QByteArray &display, QObject *parent = nullptr); void initConnection(); void createSurface(); void destroyOutputs(); @@ -195,8 +201,7 @@ private: KWayland::Client::SubCompositor *m_subCompositor; WaylandCursor *m_cursor; bool m_ready = false; - - KWIN_SINGLETON(WaylandBackend) + static WaylandBackend *s_self; }; inline diff --git a/x11windowed_backend.cpp b/x11windowed_backend.cpp index 43d656dedf..bc455afa74 100644 --- a/x11windowed_backend.cpp +++ b/x11windowed_backend.cpp @@ -43,28 +43,28 @@ namespace KWin X11WindowedBackend *X11WindowedBackend::s_self = nullptr; -X11WindowedBackend *X11WindowedBackend::create(const QString &display, const QSize &size, QObject *parent) +X11WindowedBackend *X11WindowedBackend::create(const QByteArray &display, const QSize &size, QObject *parent) { Q_ASSERT(!s_self); s_self = new X11WindowedBackend(display, size, parent); return s_self; } -X11WindowedBackend::X11WindowedBackend(const QString &display, const QSize &size, QObject *parent) +X11WindowedBackend::X11WindowedBackend(const QByteArray &display, const QSize &size, QObject *parent) : AbstractBackend(parent) , m_size(size) { int screen = 0; xcb_connection_t *c = nullptr; #if HAVE_X11_XCB - Display *xDisplay = XOpenDisplay(display.toUtf8().constData()); + Display *xDisplay = XOpenDisplay(display.constData()); if (xDisplay) { c = XGetXCBConnection(xDisplay); XSetEventQueueOwner(xDisplay, XCBOwnsEventQueue); screen = XDefaultScreen(xDisplay); } #else - c = xcb_connect(display.toUtf8().constData(), &screen); + c = xcb_connect(display.constData(), &screen); #endif if (c && !xcb_connection_has_error(c)) { m_connection = c; @@ -97,6 +97,7 @@ X11WindowedBackend::~X11WindowedBackend() } xcb_disconnect(m_connection); } + s_self = nullptr; } void X11WindowedBackend::createWindow() diff --git a/x11windowed_backend.h b/x11windowed_backend.h index 799964b6a1..135f199089 100644 --- a/x11windowed_backend.h +++ b/x11windowed_backend.h @@ -66,13 +66,13 @@ public: void installCursorFromServer() override; static X11WindowedBackend *self(); - static X11WindowedBackend *create(const QString &display, const QSize &size, QObject *parent); + static X11WindowedBackend *create(const QByteArray &display, const QSize &size, QObject *parent); Q_SIGNALS: void sizeChanged(); private: - X11WindowedBackend(const QString &display, const QSize &size, QObject *parent); + X11WindowedBackend(const QByteArray &display, const QSize &size, QObject *parent); void createWindow(); void startEventReading(); void handleEvent(xcb_generic_event_t *event);