36 : QAbstractListModel(parent)
37 , m_userModified(false)
38 , m_serverModified(false)
39 , m_serverSideRows(-1)
42 qDBusRegisterMetaType<KWin::DBusDesktopDataStruct>();
43 qDBusRegisterMetaType<KWin::DBusDesktopDataVector>();
45 m_serviceWatcher =
new QDBusServiceWatcher(s_serviceName,
46 QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange);
48 QObject::connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered,
53 QObject::connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered,
55 QDBusConnection::sessionBus().disconnect(
58 s_virtualDesktopsInterface,
59 QStringLiteral(
"desktopCreated"),
63 QDBusConnection::sessionBus().disconnect(
66 s_virtualDesktopsInterface,
67 QStringLiteral(
"desktopRemoved"),
71 QDBusConnection::sessionBus().disconnect(
74 s_virtualDesktopsInterface,
75 QStringLiteral(
"desktopDataChanged"),
79 QDBusConnection::sessionBus().disconnect(
82 s_virtualDesktopsInterface,
83 QStringLiteral(
"rowsChanged"),
253 auto callFinished = [
this](QDBusPendingCallWatcher *call) {
254 QDBusPendingReply<void> reply = *call;
256 if (reply.isError()) {
265 if (m_desktops.count() > m_serverSideDesktops.count()) {
266 auto call = QDBusMessage::createMethodCall(
269 s_virtualDesktopsInterface,
270 QStringLiteral(
"createDesktop"));
272 const int newIndex = m_serverSideDesktops.count();
274 call.setArguments({(uint)newIndex, m_names.value(m_desktops.at(newIndex))});
277 QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(call);
279 const auto *watcher =
new QDBusPendingCallWatcher(pending,
this);
280 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
this, callFinished);
286 if (m_desktops.count() < m_serverSideDesktops.count()) {
287 QStringListIterator i(m_serverSideDesktops);
291 while (i.hasPrevious()) {
292 const QString &previous = i.previous();
294 if (!m_desktops.contains(previous)) {
295 auto call = QDBusMessage::createMethodCall(
298 s_virtualDesktopsInterface,
299 QStringLiteral(
"removeDesktop"));
301 call.setArguments({previous});
304 QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(call);
306 const QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pending,
this);
307 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
this, callFinished);
316 for (
int i = 0; i < m_serverSideDesktops.count(); ++i) {
317 const QString oldId = m_desktops.at(i);
318 const QString &newId = m_serverSideDesktops.at(i);
319 m_desktops[i] = newId;
320 m_names[newId] = m_names.take(oldId);
323 Q_EMIT dataChanged(index(0, 0), index(
rowCount() - 1, 0), QList<int>{Qt::DisplayRole});
326 if (m_names != m_serverSideNames) {
327 QHashIterator<QString, QString> i(m_names);
329 while (i.hasNext()) {
332 if (i.value() != m_serverSideNames.value(i.key())) {
333 auto call = QDBusMessage::createMethodCall(
336 s_virtualDesktopsInterface,
337 QStringLiteral(
"setDesktopName"));
339 call.setArguments({i.key(), i.value()});
342 QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(call);
344 const QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pending,
this);
345 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
this, callFinished);
356 if (m_rows != m_serverSideRows) {
357 auto call = QDBusMessage::createMethodCall(
360 s_fdoPropertiesInterface,
361 QStringLiteral(
"Set"));
363 call.setArguments({s_virtualDesktopsInterface,
364 QStringLiteral(
"rows"), QVariant::fromValue(QDBusVariant(QVariant((uint)m_rows)))});
367 QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(call);
369 const QDBusPendingCallWatcher *watcher =
new QDBusPendingCallWatcher(pending,
this);
370 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
this, callFinished);
432 const QVariantMap &
data = qdbus_cast<QVariantMap>(msg.arguments().at(0).value<QDBusArgument>());
435 data.value(QStringLiteral(
"desktops")).value<QDBusArgument>());
437 const int newServerSideRows =
data.value(QStringLiteral(
"rows")).toUInt();
438 QStringList newServerSideDesktops;
439 QHash<QString, QString> newServerSideNames;
442 newServerSideDesktops.append(d.id);
443 newServerSideNames[d.id] = d.name;
449 if (m_serverSideDesktops != newServerSideDesktops
450 || m_serverSideNames != newServerSideNames
451 || m_serverSideRows != newServerSideRows) {
452 if (!m_serverSideDesktops.isEmpty() || m_userModified) {
453 m_serverModified =
true;
457 m_serverSideDesktops = newServerSideDesktops;
458 m_serverSideNames = newServerSideNames;
459 m_serverSideRows = newServerSideRows;
466 if (!m_userModified || m_desktops.empty()) {
468 m_desktops = m_serverSideDesktops;
469 m_names = m_serverSideNames;
470 m_rows = m_serverSideRows;
478 auto handleConnectionError = [
this]() {
479 m_error = i18n(
"There was an error connecting to the compositor.");
483 bool connected = QDBusConnection::sessionBus().connect(
486 s_virtualDesktopsInterface,
487 QStringLiteral(
"desktopCreated"),
492 handleConnectionError();
497 connected = QDBusConnection::sessionBus().connect(
500 s_virtualDesktopsInterface,
501 QStringLiteral(
"desktopRemoved"),
506 handleConnectionError();
511 connected = QDBusConnection::sessionBus().connect(
514 s_virtualDesktopsInterface,
515 QStringLiteral(
"desktopDataChanged"),
520 handleConnectionError();
525 connected = QDBusConnection::sessionBus().connect(
528 s_virtualDesktopsInterface,
529 QStringLiteral(
"rowsChanged"),
534 handleConnectionError();
633 if (m_desktops.count() == m_serverSideDesktops.count()
634 && m_desktops != m_serverSideDesktops) {
636 for (
int i = 0; i < m_serverSideDesktops.count(); ++i) {
637 const QString oldId = m_desktops.at(i);
638 const QString &newId = m_serverSideDesktops.at(i);
639 m_desktops[i] = newId;
640 m_names[newId] = m_names.take(oldId);
643 Q_EMIT dataChanged(index(0, 0), index(
rowCount() - 1, 0), QList<int>{Qt::DisplayRole});
646 if (m_desktops == m_serverSideDesktops
647 && m_names == m_serverSideNames
648 && m_rows == m_serverSideRows) {
650 m_userModified =
false;
653 m_serverModified =
false;
656 if (m_pendingCalls > 0) {
657 m_serverModified =
false;
662 m_serverModified =
true;
665 m_userModified =
true;