Changeset View
Changeset View
Standalone View
Standalone View
virtualdesktops.cpp
Show All 21 Lines | |||||
22 | #include "input.h" | 22 | #include "input.h" | ||
23 | // KDE | 23 | // KDE | ||
24 | #include <KConfigGroup> | 24 | #include <KConfigGroup> | ||
25 | #include <KGlobalAccel> | 25 | #include <KGlobalAccel> | ||
26 | #include <KLocalizedString> | 26 | #include <KLocalizedString> | ||
27 | #include <NETWM> | 27 | #include <NETWM> | ||
28 | // Qt | 28 | // Qt | ||
29 | #include <QAction> | 29 | #include <QAction> | ||
30 | #include <QUuid> | ||||
30 | 31 | | |||
31 | #include <algorithm> | 32 | #include <algorithm> | ||
32 | 33 | #include <QDebug> | |||
33 | namespace KWin { | 34 | namespace KWin { | ||
34 | 35 | | |||
35 | extern int screen_number; | 36 | extern int screen_number; | ||
36 | 37 | | |||
37 | VirtualDesktop::VirtualDesktop(QObject *parent) | 38 | VirtualDesktop::VirtualDesktop(QObject *parent) | ||
38 | : QObject(parent) | 39 | : QObject(parent) | ||
39 | { | 40 | { | ||
40 | } | 41 | } | ||
Show All 23 Lines | 61 | { | |||
64 | m_name = name; | 65 | m_name = name; | ||
65 | emit nameChanged(); | 66 | emit nameChanged(); | ||
66 | } | 67 | } | ||
67 | 68 | | |||
68 | VirtualDesktopGrid::VirtualDesktopGrid() | 69 | VirtualDesktopGrid::VirtualDesktopGrid() | ||
69 | : m_size(1, 2) // Default to tow rows | 70 | : m_size(1, 2) // Default to tow rows | ||
70 | , m_grid(QVector<QVector<VirtualDesktop*>>{QVector<VirtualDesktop*>{}, QVector<VirtualDesktop*>{}}) | 71 | , m_grid(QVector<QVector<VirtualDesktop*>>{QVector<VirtualDesktop*>{}, QVector<VirtualDesktop*>{}}) | ||
71 | { | 72 | { | ||
73 | | ||||
zzag: Unrelated change. | |||||
72 | } | 74 | } | ||
73 | 75 | | |||
74 | VirtualDesktopGrid::~VirtualDesktopGrid() = default; | 76 | VirtualDesktopGrid::~VirtualDesktopGrid() = default; | ||
75 | 77 | | |||
76 | void VirtualDesktopGrid::update(const QSize &size, Qt::Orientation orientation, const QVector<VirtualDesktop*> &desktops) | 78 | void VirtualDesktopGrid::update(const QSize &size, Qt::Orientation orientation, const QVector<VirtualDesktop*> &desktops) | ||
77 | { | 79 | { | ||
78 | // Set private variables | 80 | // Set private variables | ||
79 | m_size = size; | 81 | m_size = size; | ||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Line(s) | |||||
320 | VirtualDesktop *VirtualDesktopManager::desktopForX11Id(uint id) const | 322 | VirtualDesktop *VirtualDesktopManager::desktopForX11Id(uint id) const | ||
321 | { | 323 | { | ||
322 | if (id == 0 || id > count()) { | 324 | if (id == 0 || id > count()) { | ||
323 | return nullptr; | 325 | return nullptr; | ||
324 | } | 326 | } | ||
325 | return m_desktops.at(id - 1); | 327 | return m_desktops.at(id - 1); | ||
326 | } | 328 | } | ||
327 | 329 | | |||
330 | VirtualDesktop *VirtualDesktopManager::desktopForId(const QByteArray &id) const | ||||
331 | { | ||||
332 | auto desk = std::find_if( m_desktops.constBegin(), | ||||
333 | m_desktops.constEnd(), | ||||
334 | [id]( const VirtualDesktop *desk ){ return desk->id() == id; } ); | ||||
zzag: Would be great to reformat it. | |||||
335 | if (desk != m_desktops.constEnd()) { | ||||
336 | return *desk; | ||||
337 | } else { | ||||
zzag: IMHO, one shall not put `else` after `return`. | |||||
338 | return nullptr; | ||||
339 | } | ||||
340 | } | ||||
341 | | ||||
342 | VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint number, const QString &name) | ||||
343 | { | ||||
344 | //too many, can't insert new ones | ||||
345 | if ((uint)m_desktops.count() == VirtualDesktopManager::maximum()) { | ||||
346 | return nullptr; | ||||
347 | } | ||||
348 | | ||||
349 | const uint actualNumber = qBound<uint>(0, number, VirtualDesktopManager::maximum()); | ||||
350 | auto vd = new VirtualDesktop(this); | ||||
I suggest to put * and not deduce raw pointer types because (a) it improves readability int x = 42; const auto foo = &x; *foo = 3; // totally fine, foo is of type int *const const auto *bar = &x; *bar = 3; // compilation error, bar is of type const int * Still, it would be great to get ack on this topic from Martin. :-) zzag: I suggest to put `*` and not deduce raw pointer types because
(a) it improves readability
(b)… | |||||
351 | vd->setX11DesktopNumber(actualNumber); | ||||
352 | //TODO: depend on Qt 5.11, use toString(QUuid::WithoutBraces) | ||||
353 | vd->setId(QUuid::createUuid().toString().toUtf8()); | ||||
354 | vd->setName(name); | ||||
355 | if (m_rootInfo) { | ||||
356 | connect(vd, &VirtualDesktop::nameChanged, this, | ||||
357 | [this, vd]() { | ||||
358 | if (m_rootInfo) { | ||||
359 | m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); | ||||
360 | } | ||||
361 | } | ||||
362 | ); | ||||
363 | m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); | ||||
364 | } | ||||
365 | | ||||
366 | //update the id of displaced desktops | ||||
367 | for (uint i = actualNumber; i < (uint)m_desktops.count(); ++i) { | ||||
368 | m_desktops[i]->setX11DesktopNumber(i + 1); | ||||
369 | if (m_rootInfo) { | ||||
370 | m_rootInfo->setDesktopName(i + 1, m_desktops[i]->name().toUtf8().data()); | ||||
371 | } | ||||
372 | } | ||||
373 | | ||||
374 | m_desktops.insert(actualNumber - 1, vd); | ||||
375 | save(); | ||||
376 | | ||||
377 | emit desktopCreated(vd); | ||||
378 | emit countChanged(m_desktops.count()-1, m_desktops.count()); | ||||
379 | return vd; | ||||
380 | } | ||||
381 | | ||||
382 | void VirtualDesktopManager::removeVirtualDesktop(const QByteArray &id) | ||||
383 | { | ||||
384 | //don't end up without any desktop | ||||
385 | if (m_desktops.count() == 1) { | ||||
386 | return; | ||||
387 | } | ||||
388 | auto desktop = desktopForId(id); | ||||
389 | if (!desktop) { | ||||
390 | return; | ||||
391 | } | ||||
392 | | ||||
393 | const uint oldCurrent = m_current->x11DesktopNumber(); | ||||
394 | const uint i = desktop->x11DesktopNumber() - 1; | ||||
395 | m_desktops.remove(i); | ||||
396 | | ||||
397 | for (uint j = i; j < (uint)m_desktops.count(); ++j) { | ||||
398 | m_desktops[j]->setX11DesktopNumber(j + 1); | ||||
399 | if (m_rootInfo) { | ||||
400 | m_rootInfo->setDesktopName(j + 1, m_desktops[j]->name().toUtf8().data()); | ||||
401 | } | ||||
402 | } | ||||
403 | | ||||
404 | const uint newCurrent = qMin(oldCurrent, (uint)m_desktops.count()); | ||||
405 | m_current = m_desktops.at(newCurrent - 1); | ||||
406 | if (oldCurrent != newCurrent) { | ||||
407 | emit currentChanged(oldCurrent, newCurrent); | ||||
408 | } | ||||
409 | | ||||
410 | emit desktopRemoved(desktop); | ||||
411 | | ||||
412 | desktop->deleteLater(); | ||||
413 | } | ||||
414 | | ||||
328 | uint VirtualDesktopManager::current() const | 415 | uint VirtualDesktopManager::current() const | ||
329 | { | 416 | { | ||
330 | return m_current ? m_current->x11DesktopNumber() : 0; | 417 | return m_current ? m_current->x11DesktopNumber() : 0; | ||
331 | } | 418 | } | ||
332 | 419 | | |||
333 | VirtualDesktop *VirtualDesktopManager::currentDesktop() const | 420 | VirtualDesktop *VirtualDesktopManager::currentDesktop() const | ||
334 | { | 421 | { | ||
335 | return m_current; | 422 | return m_current; | ||
Show All 23 Lines | |||||
359 | 446 | | |||
360 | void VirtualDesktopManager::setCount(uint count) | 447 | void VirtualDesktopManager::setCount(uint count) | ||
361 | { | 448 | { | ||
362 | count = qBound<uint>(1, count, VirtualDesktopManager::maximum()); | 449 | count = qBound<uint>(1, count, VirtualDesktopManager::maximum()); | ||
363 | if (count == uint(m_desktops.count())) { | 450 | if (count == uint(m_desktops.count())) { | ||
364 | // nothing to change | 451 | // nothing to change | ||
365 | return; | 452 | return; | ||
366 | } | 453 | } | ||
454 | QList<VirtualDesktop *> newDesktops; | ||||
367 | const uint oldCount = m_desktops.count(); | 455 | const uint oldCount = m_desktops.count(); | ||
368 | const uint oldCurrent = current(); | 456 | //this explicit check makes it more readable | ||
369 | while (uint(m_desktops.count()) > count) { | 457 | if ((uint)m_desktops.count() > count) { | ||
370 | delete m_desktops.takeLast(); | 458 | const auto desktopsToRemove = m_desktops.mid(count-1); | ||
459 | m_desktops.resize(count); | ||||
460 | int oldCurrent = current(); | ||||
461 | for (auto desktop : desktopsToRemove) { | ||||
462 | emit desktopRemoved(desktop); | ||||
463 | desktop->deleteLater(); | ||||
464 | } | ||||
465 | int newCurrent = qMin(oldCurrent, m_desktops.count()); | ||||
466 | m_current = m_desktops.at(newCurrent - 1); | ||||
467 | if (oldCurrent != newCurrent) { | ||||
468 | emit currentChanged(oldCurrent, newCurrent); | ||||
371 | } | 469 | } | ||
470 | } else { | ||||
372 | while (uint(m_desktops.count()) < count) { | 471 | while (uint(m_desktops.count()) < count) { | ||
373 | auto vd = new VirtualDesktop(this); | 472 | auto vd = new VirtualDesktop(this); | ||
374 | vd->setX11DesktopNumber(m_desktops.count() + 1); | 473 | vd->setX11DesktopNumber(m_desktops.count() + 1); | ||
474 | if (!m_isLoading) { | ||||
475 | vd->setId(QUuid::createUuid().toString().toUtf8()); | ||||
476 | } | ||||
375 | m_desktops << vd; | 477 | m_desktops << vd; | ||
478 | newDesktops << vd; | ||||
479 | if (m_rootInfo) { | ||||
480 | connect(vd, &VirtualDesktop::nameChanged, this, | ||||
481 | [this, vd]() { | ||||
482 | if (m_rootInfo) { | ||||
483 | m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); | ||||
484 | } | ||||
485 | } | ||||
486 | ); | ||||
487 | m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); | ||||
488 | } | ||||
376 | } | 489 | } | ||
377 | if (oldCount > count) { | | |||
378 | handleDesktopsRemoved(oldCount, oldCurrent); | | |||
379 | } | 490 | } | ||
380 | 491 | | |||
381 | updateRootInfo(); | 492 | updateRootInfo(); | ||
382 | 493 | | |||
383 | save(); | 494 | save(); | ||
384 | emit countChanged(oldCount, m_desktops.count()); | 495 | for (auto vd : newDesktops) { | ||
496 | emit desktopCreated(vd); | ||||
385 | } | 497 | } | ||
386 | 498 | emit countChanged(oldCount, m_desktops.count()); | |||
387 | void VirtualDesktopManager::handleDesktopsRemoved(uint previousCount, uint previousCurrent) | | |||
388 | { | | |||
389 | if (!m_current) { | | |||
390 | m_current = m_desktops.last(); | | |||
391 | emit currentChanged(previousCurrent, m_current->x11DesktopNumber()); | | |||
392 | } | | |||
393 | emit desktopsRemoved(previousCount); | | |||
394 | } | 499 | } | ||
395 | 500 | | |||
396 | void VirtualDesktopManager::updateRootInfo() | 501 | void VirtualDesktopManager::updateRootInfo() | ||
397 | { | 502 | { | ||
398 | if (!m_rootInfo) { | 503 | if (!m_rootInfo) { | ||
399 | // Make sure the layout is still valid | 504 | // Make sure the layout is still valid | ||
400 | updateLayout(); | 505 | updateLayout(); | ||
401 | return; | 506 | return; | ||
Show All 30 Lines | |||||
432 | static bool s_loadingDesktopSettings = false; | 537 | static bool s_loadingDesktopSettings = false; | ||
433 | 538 | | |||
434 | void VirtualDesktopManager::load() | 539 | void VirtualDesktopManager::load() | ||
435 | { | 540 | { | ||
436 | s_loadingDesktopSettings = true; | 541 | s_loadingDesktopSettings = true; | ||
437 | if (!m_config) { | 542 | if (!m_config) { | ||
438 | return; | 543 | return; | ||
439 | } | 544 | } | ||
545 | //FIXME: how to avoid this? | ||||
546 | m_isLoading = true; | ||||
440 | QString groupname; | 547 | QString groupname; | ||
441 | if (screen_number == 0) { | 548 | if (screen_number == 0) { | ||
442 | groupname = QStringLiteral("Desktops"); | 549 | groupname = QStringLiteral("Desktops"); | ||
443 | } else { | 550 | } else { | ||
444 | groupname.sprintf("Desktops-screen-%d", screen_number); | 551 | groupname.sprintf("Desktops-screen-%d", screen_number); | ||
445 | } | 552 | } | ||
446 | KConfigGroup group(m_config, groupname); | 553 | KConfigGroup group(m_config, groupname); | ||
447 | const int n = group.readEntry("Number", 1); | 554 | const int n = group.readEntry("Number", 1); | ||
448 | setCount(n); | 555 | setCount(n); | ||
449 | if (m_rootInfo) { | 556 | //Use kactivitymanagerdrc directly? | ||
557 | | ||||
450 | for (int i = 1; i <= n; i++) { | 558 | for (int i = 1; i <= n; i++) { | ||
451 | QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i)); | 559 | QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i)); | ||
560 | if (m_rootInfo) { | ||||
Eww, definitely not. What I assumed we would do would be have kwin start up with 1VD. (ksplash is on all anyway) davidedmundson: Eww, definitely not.
What I assumed we would do would be have kwin start up with 1VD. (ksplash… | |||||
452 | m_rootInfo->setDesktopName(i, s.toUtf8().data()); | 561 | m_rootInfo->setDesktopName(i, s.toUtf8().data()); | ||
562 | } | ||||
563 | m_desktops[i-1]->setName(s.toUtf8().data()); | ||||
564 | | ||||
565 | s = group.readEntry(QStringLiteral("Id_%1").arg(i), QString()); | ||||
566 | if (s.isEmpty()) { | ||||
567 | s = QUuid::createUuid().toString(); | ||||
568 | } | ||||
569 | //load gets called 2 times, see workspace.cpp line 416 and BUG 385260 | ||||
570 | if (m_desktops[i-1]->id().isEmpty()) { | ||||
571 | m_desktops[i-1]->setId(s.toUtf8().data()); | ||||
572 | } else { | ||||
573 | Q_ASSERT(m_desktops[i-1]->id() == s.toUtf8().data()); | ||||
574 | } | ||||
575 | | ||||
453 | // TODO: update desktop focus chain, why? | 576 | // TODO: update desktop focus chain, why? | ||
454 | // m_desktopFocusChain.value()[i-1] = i; | 577 | // m_desktopFocusChain.value()[i-1] = i; | ||
455 | } | 578 | } | ||
456 | 579 | | |||
580 | if (m_rootInfo) { | ||||
457 | int rows = group.readEntry<int>("Rows", 2); | 581 | int rows = group.readEntry<int>("Rows", 2); | ||
458 | rows = qBound(1, rows, n); | 582 | rows = qBound(1, rows, n); | ||
459 | // avoid weird cases like having 3 rows for 4 desktops, where the last row is unused | 583 | // avoid weird cases like having 3 rows for 4 desktops, where the last row is unused | ||
460 | int columns = n / rows; | 584 | int columns = n / rows; | ||
461 | if (n % rows > 0) { | 585 | if (n % rows > 0) { | ||
462 | columns++; | 586 | columns++; | ||
463 | } | 587 | } | ||
464 | m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, columns, rows, NET::DesktopLayoutCornerTopLeft); | 588 | m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, columns, rows, NET::DesktopLayoutCornerTopLeft); | ||
465 | m_rootInfo->activate(); | 589 | m_rootInfo->activate(); | ||
466 | } | 590 | } | ||
591 | | ||||
467 | s_loadingDesktopSettings = false; | 592 | s_loadingDesktopSettings = false; | ||
593 | m_isLoading = false; | ||||
468 | } | 594 | } | ||
469 | 595 | | |||
470 | void VirtualDesktopManager::save() | 596 | void VirtualDesktopManager::save() | ||
471 | { | 597 | { | ||
472 | if (s_loadingDesktopSettings) { | 598 | if (s_loadingDesktopSettings) { | ||
473 | return; | 599 | return; | ||
474 | } | 600 | } | ||
475 | if (!m_config) { | 601 | if (!m_config) { | ||
Show All 21 Lines | 613 | for (uint i = 1; i <= count(); ++i) { | |||
497 | if (s != defaultvalue) { | 623 | if (s != defaultvalue) { | ||
498 | group.writeEntry(QStringLiteral("Name_%1").arg(i), s); | 624 | group.writeEntry(QStringLiteral("Name_%1").arg(i), s); | ||
499 | } else { | 625 | } else { | ||
500 | QString currentvalue = group.readEntry(QStringLiteral("Name_%1").arg(i), QString()); | 626 | QString currentvalue = group.readEntry(QStringLiteral("Name_%1").arg(i), QString()); | ||
501 | if (currentvalue != defaultvalue) { | 627 | if (currentvalue != defaultvalue) { | ||
502 | group.deleteEntry(QStringLiteral("Name_%1").arg(i)); | 628 | group.deleteEntry(QStringLiteral("Name_%1").arg(i)); | ||
503 | } | 629 | } | ||
504 | } | 630 | } | ||
631 | | ||||
632 | group.writeEntry(QStringLiteral("Id_%1").arg(i), m_desktops[i-1]->id()); | ||||
505 | } | 633 | } | ||
506 | 634 | | |||
507 | // Save to disk | 635 | // Save to disk | ||
508 | group.sync(); | 636 | group.sync(); | ||
509 | } | 637 | } | ||
510 | 638 | | |||
511 | QString VirtualDesktopManager::defaultName(int desktop) const | 639 | QString VirtualDesktopManager::defaultName(int desktop) const | ||
512 | { | 640 | { | ||
▲ Show 20 Lines • Show All 139 Lines • Show Last 20 Lines |
Unrelated change.