From 56bd1e7194de9b9dc45cb24b67166dcedeb3cb73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 24 Nov 2015 13:11:29 +0100 Subject: [PATCH] [wayland] Add support for initial output count for nested compositors Added to x11 backend which creates one window per output. New command line option is called --output-count=. --- abstract_backend.h | 7 +++ backends/x11/x11windowed_backend.cpp | 92 ++++++++++++++-------------- main_wayland.cpp | 18 ++++++ 3 files changed, 72 insertions(+), 45 deletions(-) diff --git a/abstract_backend.h b/abstract_backend.h index 2e12aa0825..effde75737 100644 --- a/abstract_backend.h +++ b/abstract_backend.h @@ -107,6 +107,12 @@ public: void setOutputsEnabled(bool enabled) { m_outputsEnabled = enabled; } + int initialOutputCount() const { + return m_initialOutputCount; + } + void setInitialOutputCount(int count) { + m_initialOutputCount = count; + } public Q_SLOTS: void pointerMotion(const QPointF &position, quint32 time); @@ -170,6 +176,7 @@ private: QByteArray m_deviceIdentifier; bool m_pointerWarping = false; bool m_outputsEnabled = true; + int m_initialOutputCount = 1; }; } diff --git a/backends/x11/x11windowed_backend.cpp b/backends/x11/x11windowed_backend.cpp index e9900392eb..28d5b2ad8d 100644 --- a/backends/x11/x11windowed_backend.cpp +++ b/backends/x11/x11windowed_backend.cpp @@ -106,55 +106,57 @@ void X11WindowedBackend::createWindow() { Xcb::Atom protocolsAtom(QByteArrayLiteral("WM_PROTOCOLS"), false, m_connection); Xcb::Atom deleteWindowAtom(QByteArrayLiteral("WM_DELETE_WINDOW"), false, m_connection); - Output o; - o.window = xcb_generate_id(m_connection); - uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - const uint32_t values[] = { - m_screen->black_pixel, - XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_ENTER_WINDOW | - XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_EXPOSURE - }; - o.size = initialWindowSize(); - if (!m_windows.isEmpty()) { - const auto &p = m_windows.last(); - o.internalPosition = QPoint(p.internalPosition.x() + p.size.width(), 0); - } - xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, o.window, m_screen->root, - 0, 0, o.size.width(), o.size.height(), - 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, mask, values); - - o.winInfo = new NETWinInfo(m_connection, o.window, m_screen->root, NET::WMWindowType, NET::Properties2()); - o.winInfo->setWindowType(NET::Normal); - o.winInfo->setPid(QCoreApplication::applicationPid()); - QIcon windowIcon = QIcon::fromTheme(QStringLiteral("kwin")); - auto addIcon = [&o, &windowIcon] (const QSize &size) { - if (windowIcon.actualSize(size) != size) { - return; + for (int i = 0; i < initialOutputCount(); ++i) { + Output o; + o.window = xcb_generate_id(m_connection); + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + const uint32_t values[] = { + m_screen->black_pixel, + XCB_EVENT_MASK_KEY_PRESS | + XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_POINTER_MOTION | + XCB_EVENT_MASK_ENTER_WINDOW | + XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_EXPOSURE + }; + o.size = initialWindowSize(); + if (!m_windows.isEmpty()) { + const auto &p = m_windows.last(); + o.internalPosition = QPoint(p.internalPosition.x() + p.size.width(), 0); } - NETIcon icon; - icon.data = windowIcon.pixmap(size).toImage().bits(); - icon.size.width = size.width(); - icon.size.height = size.height(); - o.winInfo->setIcon(icon, false); - }; - addIcon(QSize(16, 16)); - addIcon(QSize(32, 32)); - addIcon(QSize(48, 48)); + xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, o.window, m_screen->root, + 0, 0, o.size.width(), o.size.height(), + 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, mask, values); - xcb_map_window(m_connection, o.window); + o.winInfo = new NETWinInfo(m_connection, o.window, m_screen->root, NET::WMWindowType, NET::Properties2()); + o.winInfo->setWindowType(NET::Normal); + o.winInfo->setPid(QCoreApplication::applicationPid()); + QIcon windowIcon = QIcon::fromTheme(QStringLiteral("kwin")); + auto addIcon = [&o, &windowIcon] (const QSize &size) { + if (windowIcon.actualSize(size) != size) { + return; + } + NETIcon icon; + icon.data = windowIcon.pixmap(size).toImage().bits(); + icon.size.width = size.width(); + icon.size.height = size.height(); + o.winInfo->setIcon(icon, false); + }; + addIcon(QSize(16, 16)); + addIcon(QSize(32, 32)); + addIcon(QSize(48, 48)); - m_protocols = protocolsAtom; - m_deleteWindowProtocol = deleteWindowAtom; - xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, o.window, m_protocols, XCB_ATOM_ATOM, 32, 1, &m_deleteWindowProtocol); + xcb_map_window(m_connection, o.window); - m_windows << o; + m_protocols = protocolsAtom; + m_deleteWindowProtocol = deleteWindowAtom; + xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, o.window, m_protocols, XCB_ATOM_ATOM, 32, 1, &m_deleteWindowProtocol); + + m_windows << o; + } updateWindowTitle(); diff --git a/main_wayland.cpp b/main_wayland.cpp index ca4262b14b..45a4a66474 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -426,6 +426,7 @@ int main(int argc, char * argv[]) }; const bool hasWindowedOption = hasPlugin(KWin::s_x11Plugin) || hasPlugin(KWin::s_waylandPlugin); const bool hasSizeOption = hasPlugin(KWin::s_x11Plugin) || hasPlugin(KWin::s_virtualPlugin); + const bool hasOutputCountOption = hasPlugin(KWin::s_x11Plugin); const bool hasX11Option = hasPlugin(KWin::s_x11Plugin); const bool hasVirtualOption = hasPlugin(KWin::s_virtualPlugin); const bool hasWaylandOption = hasPlugin(KWin::s_waylandPlugin); @@ -465,6 +466,10 @@ int main(int argc, char * argv[]) i18n("The height for windowed mode. Default height is 768."), QStringLiteral("height")); heightOption.setDefaultValue(QString::number(768)); + QCommandLineOption outputCountOption(QStringLiteral("output-count"), + i18n("The number of windows to open as outputs in windowed mode. Default value is 1"), + QStringLiteral("height")); + outputCountOption.setDefaultValue(QString::number(1)); QCommandLineParser parser; a.setupCommandLine(&parser); @@ -490,6 +495,9 @@ int main(int argc, char * argv[]) parser.addOption(widthOption); parser.addOption(heightOption); } + if (hasOutputCountOption) { + parser.addOption(outputCountOption); + } #if HAVE_LIBHYBRIS QCommandLineOption hwcomposerOption(QStringLiteral("hwcomposer"), i18n("Use libhybris hwcomposer")); if (hasHwcomposerOption) { @@ -551,6 +559,7 @@ int main(int argc, char * argv[]) QString pluginName; QSize initialWindowSize; QByteArray deviceIdentifier; + int outputCount = 1; #if HAVE_DRM if (hasDrmOption && parser.isSet(drmOption)) { @@ -573,6 +582,14 @@ int main(int argc, char * argv[]) initialWindowSize = QSize(width, height); } + if (hasOutputCountOption) { + bool ok = false; + const int count = parser.value(outputCountOption).toInt(&ok); + if (ok) { + outputCount = qMax(1, count); + } + } + if (hasWindowedOption && parser.isSet(windowedOption)) { if (hasX11Option && parser.isSet(x11DisplayOption)) { deviceIdentifier = parser.value(x11DisplayOption).toUtf8(); @@ -655,6 +672,7 @@ int main(int argc, char * argv[]) if (initialWindowSize.isValid()) { server->backend()->setInitialWindowSize(initialWindowSize); } + server->backend()->setInitialOutputCount(outputCount); QObject::connect(&a, &KWin::Application::workspaceCreated, server, &KWin::WaylandServer::initWorkspace); environment.insert(QStringLiteral("WAYLAND_DISPLAY"), server->display()->socketName());