[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=<int>.
This commit is contained in:
parent
1e3013b58c
commit
56bd1e7194
3 changed files with 72 additions and 45 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue