Changeset View
Changeset View
Standalone View
Standalone View
group.cpp
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Line(s) | |||||
46 | namespace KWin | 46 | namespace KWin | ||
47 | { | 47 | { | ||
48 | 48 | | |||
49 | //******************************************** | 49 | //******************************************** | ||
50 | // Group | 50 | // Group | ||
51 | //******************************************** | 51 | //******************************************** | ||
52 | 52 | | |||
53 | Group::Group(xcb_window_t leader_P) | 53 | Group::Group(xcb_window_t leader_P) | ||
54 | : leader_client(NULL), | 54 | : leader_client(nullptr), | ||
55 | leader_wid(leader_P), | 55 | leader_wid(leader_P), | ||
56 | leader_info(NULL), | 56 | leader_info(nullptr), | ||
57 | user_time(-1U), | 57 | user_time(-1U), | ||
58 | refcount(0) | 58 | refcount(0) | ||
59 | { | 59 | { | ||
60 | if (leader_P != XCB_WINDOW_NONE) { | 60 | if (leader_P != XCB_WINDOW_NONE) { | ||
61 | leader_client = workspace()->findClient(Predicate::WindowMatch, leader_P); | 61 | leader_client = workspace()->findClient(Predicate::WindowMatch, leader_P); | ||
62 | leader_info = new NETWinInfo(connection(), leader_P, rootWindow(), | 62 | leader_info = new NETWinInfo(connection(), leader_P, rootWindow(), | ||
63 | 0, NET::WM2StartupId); | 63 | nullptr, NET::WM2StartupId); | ||
64 | } | 64 | } | ||
65 | effect_group = new EffectWindowGroupImpl(this); | 65 | effect_group = new EffectWindowGroupImpl(this); | ||
66 | workspace()->addGroup(this); | 66 | workspace()->addGroup(this); | ||
67 | } | 67 | } | ||
68 | 68 | | |||
69 | Group::~Group() | 69 | Group::~Group() | ||
70 | { | 70 | { | ||
71 | delete leader_info; | 71 | delete leader_info; | ||
72 | delete effect_group; | 72 | delete effect_group; | ||
73 | } | 73 | } | ||
74 | 74 | | |||
75 | QIcon Group::icon() const | 75 | QIcon Group::icon() const | ||
76 | { | 76 | { | ||
77 | if (leader_client != NULL) | 77 | if (leader_client != nullptr) | ||
78 | return leader_client->icon(); | 78 | return leader_client->icon(); | ||
79 | else if (leader_wid != XCB_WINDOW_NONE) { | 79 | else if (leader_wid != XCB_WINDOW_NONE) { | ||
80 | QIcon ic; | 80 | QIcon ic; | ||
81 | NETWinInfo info(connection(), leader_wid, rootWindow(), NET::WMIcon, NET::WM2IconPixmap); | 81 | NETWinInfo info(connection(), leader_wid, rootWindow(), NET::WMIcon, NET::WM2IconPixmap); | ||
82 | auto readIcon = [&ic, &info, this](int size, bool scale = true) { | 82 | auto readIcon = [&ic, &info, this](int size, bool scale = true) { | ||
83 | const QPixmap pix = KWindowSystem::icon(leader_wid, size, size, scale, KWindowSystem::NETWM | KWindowSystem::WMHints, &info); | 83 | const QPixmap pix = KWindowSystem::icon(leader_wid, size, size, scale, KWindowSystem::NETWM | KWindowSystem::WMHints, &info); | ||
84 | if (!pix.isNull()) { | 84 | if (!pix.isNull()) { | ||
85 | ic.addPixmap(pix); | 85 | ic.addPixmap(pix); | ||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | |||||
135 | { | 135 | { | ||
136 | Q_ASSERT(leader_P->window() == leader_wid); | 136 | Q_ASSERT(leader_P->window() == leader_wid); | ||
137 | leader_client = leader_P; | 137 | leader_client = leader_P; | ||
138 | } | 138 | } | ||
139 | 139 | | |||
140 | void Group::lostLeader() | 140 | void Group::lostLeader() | ||
141 | { | 141 | { | ||
142 | Q_ASSERT(!_members.contains(leader_client)); | 142 | Q_ASSERT(!_members.contains(leader_client)); | ||
143 | leader_client = NULL; | 143 | leader_client = nullptr; | ||
144 | if (_members.isEmpty()) { | 144 | if (_members.isEmpty()) { | ||
145 | workspace()->removeGroup(this); | 145 | workspace()->removeGroup(this); | ||
146 | delete this; | 146 | delete this; | ||
147 | } | 147 | } | ||
148 | } | 148 | } | ||
149 | 149 | | |||
150 | //*************************************** | 150 | //*************************************** | ||
151 | // Workspace | 151 | // Workspace | ||
152 | //*************************************** | 152 | //*************************************** | ||
153 | 153 | | |||
154 | Group* Workspace::findGroup(xcb_window_t leader) const | 154 | Group* Workspace::findGroup(xcb_window_t leader) const | ||
155 | { | 155 | { | ||
156 | Q_ASSERT(leader != XCB_WINDOW_NONE); | 156 | Q_ASSERT(leader != XCB_WINDOW_NONE); | ||
157 | for (GroupList::ConstIterator it = groups.constBegin(); | 157 | for (GroupList::ConstIterator it = groups.constBegin(); | ||
158 | it != groups.constEnd(); | 158 | it != groups.constEnd(); | ||
159 | ++it) | 159 | ++it) | ||
160 | if ((*it)->leader() == leader) | 160 | if ((*it)->leader() == leader) | ||
161 | return *it; | 161 | return *it; | ||
162 | return NULL; | 162 | return nullptr; | ||
163 | } | 163 | } | ||
164 | 164 | | |||
165 | // Client is group transient, but has no group set. Try to find | 165 | // Client is group transient, but has no group set. Try to find | ||
166 | // group with windows with the same client leader. | 166 | // group with windows with the same client leader. | ||
167 | Group* Workspace::findClientLeaderGroup(const Client* c) const | 167 | Group* Workspace::findClientLeaderGroup(const Client* c) const | ||
168 | { | 168 | { | ||
169 | Group* ret = NULL; | 169 | Group* ret = nullptr; | ||
170 | for (ClientList::ConstIterator it = clients.constBegin(); | 170 | for (ClientList::ConstIterator it = clients.constBegin(); | ||
171 | it != clients.constEnd(); | 171 | it != clients.constEnd(); | ||
172 | ++it) { | 172 | ++it) { | ||
173 | if (*it == c) | 173 | if (*it == c) | ||
174 | continue; | 174 | continue; | ||
175 | if ((*it)->wmClientLeader() == c->wmClientLeader()) { | 175 | if ((*it)->wmClientLeader() == c->wmClientLeader()) { | ||
176 | if (ret == NULL || ret == (*it)->group()) | 176 | if (ret == nullptr || ret == (*it)->group()) | ||
177 | ret = (*it)->group(); | 177 | ret = (*it)->group(); | ||
178 | else { | 178 | else { | ||
179 | // There are already two groups with the same client leader. | 179 | // There are already two groups with the same client leader. | ||
180 | // This most probably means the app uses group transients without | 180 | // This most probably means the app uses group transients without | ||
181 | // setting group for its windows. Merging the two groups is a bad | 181 | // setting group for its windows. Merging the two groups is a bad | ||
182 | // hack, but there's no really good solution for this case. | 182 | // hack, but there's no really good solution for this case. | ||
183 | ClientList old_group = (*it)->group()->members(); | 183 | ClientList old_group = (*it)->group()->members(); | ||
184 | // old_group autodeletes when being empty | 184 | // old_group autodeletes when being empty | ||
▲ Show 20 Lines • Show All 246 Lines • ▼ Show 20 Line(s) | |||||
431 | void Client::setTransient(xcb_window_t new_transient_for_id) | 431 | void Client::setTransient(xcb_window_t new_transient_for_id) | ||
432 | { | 432 | { | ||
433 | if (new_transient_for_id != m_transientForId) { | 433 | if (new_transient_for_id != m_transientForId) { | ||
434 | removeFromMainClients(); | 434 | removeFromMainClients(); | ||
435 | Client *transient_for = nullptr; | 435 | Client *transient_for = nullptr; | ||
436 | m_transientForId = new_transient_for_id; | 436 | m_transientForId = new_transient_for_id; | ||
437 | if (m_transientForId != XCB_WINDOW_NONE && !groupTransient()) { | 437 | if (m_transientForId != XCB_WINDOW_NONE && !groupTransient()) { | ||
438 | transient_for = workspace()->findClient(Predicate::WindowMatch, m_transientForId); | 438 | transient_for = workspace()->findClient(Predicate::WindowMatch, m_transientForId); | ||
439 | Q_ASSERT(transient_for != NULL); // verifyTransient() had to check this | 439 | Q_ASSERT(transient_for != nullptr); // verifyTransient() had to check this | ||
440 | transient_for->addTransient(this); | 440 | transient_for->addTransient(this); | ||
441 | } // checkGroup() will check 'check_active_modal' | 441 | } // checkGroup() will check 'check_active_modal' | ||
442 | setTransientFor(transient_for); | 442 | setTransientFor(transient_for); | ||
443 | checkGroup(NULL, true); // force, because transiency has changed | 443 | checkGroup(nullptr, true); // force, because transiency has changed | ||
444 | workspace()->updateClientLayer(this); | 444 | workspace()->updateClientLayer(this); | ||
445 | workspace()->resetUpdateToolWindowsTimer(); | 445 | workspace()->resetUpdateToolWindowsTimer(); | ||
446 | emit transientChanged(); | 446 | emit transientChanged(); | ||
447 | } | 447 | } | ||
448 | } | 448 | } | ||
449 | 449 | | |||
450 | void Client::removeFromMainClients() | 450 | void Client::removeFromMainClients() | ||
451 | { | 451 | { | ||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Line(s) | |||||
508 | // qDebug() << "MN3:" << *it; | 508 | // qDebug() << "MN3:" << *it; | ||
509 | // HACK | 509 | // HACK | ||
510 | // removeFromMainClients() did remove 'this' from transient | 510 | // removeFromMainClients() did remove 'this' from transient | ||
511 | // lists of all group members, but then made windows that | 511 | // lists of all group members, but then made windows that | ||
512 | // were transient for 'this' group transient, which again | 512 | // were transient for 'this' group transient, which again | ||
513 | // added 'this' to those transient lists :( | 513 | // added 'this' to those transient lists :( | ||
514 | ClientList group_members = group()->members(); | 514 | ClientList group_members = group()->members(); | ||
515 | group()->removeMember(this); | 515 | group()->removeMember(this); | ||
516 | in_group = NULL; | 516 | in_group = nullptr; | ||
517 | for (ClientList::ConstIterator it = group_members.constBegin(); | 517 | for (ClientList::ConstIterator it = group_members.constBegin(); | ||
518 | it != group_members.constEnd(); | 518 | it != group_members.constEnd(); | ||
519 | ++it) | 519 | ++it) | ||
520 | (*it)->removeTransient(this); | 520 | (*it)->removeTransient(this); | ||
521 | // qDebug() << "CLEANGROUPING4:" << this; | 521 | // qDebug() << "CLEANGROUPING4:" << this; | ||
522 | // for ( ClientList::ConstIterator it = group_members.begin(); | 522 | // for ( ClientList::ConstIterator it = group_members.begin(); | ||
523 | // it != group_members.end(); | 523 | // it != group_members.end(); | ||
524 | // ++it ) | 524 | // ++it ) | ||
Show All 14 Lines | 538 | if (!(*it1)->groupTransient()) // check all group transients in the group | |||
539 | continue; // TODO optimize to check only the changed ones? | 539 | continue; // TODO optimize to check only the changed ones? | ||
540 | for (ClientList::ConstIterator it2 = group()->members().constBegin(); | 540 | for (ClientList::ConstIterator it2 = group()->members().constBegin(); | ||
541 | it2 != group()->members().constEnd(); | 541 | it2 != group()->members().constEnd(); | ||
542 | ++it2) { // group transients can be transient only for others in the group, | 542 | ++it2) { // group transients can be transient only for others in the group, | ||
543 | // so don't make them transient for the ones that are transient for it | 543 | // so don't make them transient for the ones that are transient for it | ||
544 | if (*it1 == *it2) | 544 | if (*it1 == *it2) | ||
545 | continue; | 545 | continue; | ||
546 | for (AbstractClient* cl = (*it2)->transientFor(); | 546 | for (AbstractClient* cl = (*it2)->transientFor(); | ||
547 | cl != NULL; | 547 | cl != nullptr; | ||
548 | cl = cl->transientFor()) { | 548 | cl = cl->transientFor()) { | ||
549 | if (cl == *it1) { | 549 | if (cl == *it1) { | ||
550 | // don't use removeTransient(), that would modify *it2 too | 550 | // don't use removeTransient(), that would modify *it2 too | ||
551 | (*it2)->removeTransientFromList(*it1); | 551 | (*it2)->removeTransientFromList(*it1); | ||
552 | continue; | 552 | continue; | ||
553 | } | 553 | } | ||
554 | } | 554 | } | ||
555 | // if *it1 and *it2 are both group transients, and are transient for each other, | 555 | // if *it1 and *it2 are both group transients, and are transient for each other, | ||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Line(s) | 622 | } else | |||
623 | new_transient_for = before_search; // nice try | 623 | new_transient_for = before_search; // nice try | ||
624 | // loop detection | 624 | // loop detection | ||
625 | // group transients cannot cause loops, because they're considered transient only for non-transient | 625 | // group transients cannot cause loops, because they're considered transient only for non-transient | ||
626 | // windows in the group | 626 | // windows in the group | ||
627 | int count = 20; | 627 | int count = 20; | ||
628 | xcb_window_t loop_pos = new_transient_for; | 628 | xcb_window_t loop_pos = new_transient_for; | ||
629 | while (loop_pos != XCB_WINDOW_NONE && loop_pos != rootWindow()) { | 629 | while (loop_pos != XCB_WINDOW_NONE && loop_pos != rootWindow()) { | ||
630 | Client* pos = workspace()->findClient(Predicate::WindowMatch, loop_pos); | 630 | Client* pos = workspace()->findClient(Predicate::WindowMatch, loop_pos); | ||
631 | if (pos == NULL) | 631 | if (pos == nullptr) | ||
632 | break; | 632 | break; | ||
633 | loop_pos = pos->m_transientForId; | 633 | loop_pos = pos->m_transientForId; | ||
634 | if (--count == 0 || pos == this) { | 634 | if (--count == 0 || pos == this) { | ||
635 | qCWarning(KWIN_CORE) << "Client " << this << " caused WM_TRANSIENT_FOR loop." ; | 635 | qCWarning(KWIN_CORE) << "Client " << this << " caused WM_TRANSIENT_FOR loop." ; | ||
636 | new_transient_for = rootWindow(); | 636 | new_transient_for = rootWindow(); | ||
637 | } | 637 | } | ||
638 | } | 638 | } | ||
639 | if (new_transient_for != rootWindow() | 639 | if (new_transient_for != rootWindow() | ||
640 | && workspace()->findClient(Predicate::WindowMatch, new_transient_for) == NULL) { | 640 | && workspace()->findClient(Predicate::WindowMatch, new_transient_for) == nullptr) { | ||
641 | // it's transient for a specific window, but that window is not mapped | 641 | // it's transient for a specific window, but that window is not mapped | ||
642 | new_transient_for = rootWindow(); | 642 | new_transient_for = rootWindow(); | ||
643 | } | 643 | } | ||
644 | if (new_property_value != m_originalTransientForId) | 644 | if (new_property_value != m_originalTransientForId) | ||
645 | Xcb::setTransientFor(window(), new_property_value); | 645 | Xcb::setTransientFor(window(), new_property_value); | ||
646 | return new_transient_for; | 646 | return new_transient_for; | ||
647 | } | 647 | } | ||
648 | 648 | | |||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Line(s) | |||||
754 | { | 754 | { | ||
755 | for (auto it = transients().constBegin(); | 755 | for (auto it = transients().constBegin(); | ||
756 | it != transients().constEnd(); | 756 | it != transients().constEnd(); | ||
757 | ++it) | 757 | ++it) | ||
758 | if (AbstractClient* ret = (*it)->findModal(true)) | 758 | if (AbstractClient* ret = (*it)->findModal(true)) | ||
759 | return ret; | 759 | return ret; | ||
760 | if (isModal() && allow_itself) | 760 | if (isModal() && allow_itself) | ||
761 | return this; | 761 | return this; | ||
762 | return NULL; | 762 | return nullptr; | ||
763 | } | 763 | } | ||
764 | 764 | | |||
765 | // Client::window_group only holds the contents of the hint, | 765 | // Client::window_group only holds the contents of the hint, | ||
766 | // but it should be used only to find the group, not for anything else | 766 | // but it should be used only to find the group, not for anything else | ||
767 | // Argument is only when some specific group needs to be set. | 767 | // Argument is only when some specific group needs to be set. | ||
768 | void Client::checkGroup(Group* set_group, bool force) | 768 | void Client::checkGroup(Group* set_group, bool force) | ||
769 | { | 769 | { | ||
770 | Group* old_group = in_group; | 770 | Group* old_group = in_group; | ||
771 | if (old_group != NULL) | 771 | if (old_group != nullptr) | ||
772 | old_group->ref(); // turn off automatic deleting | 772 | old_group->ref(); // turn off automatic deleting | ||
773 | if (set_group != NULL) { | 773 | if (set_group != nullptr) { | ||
774 | if (set_group != in_group) { | 774 | if (set_group != in_group) { | ||
775 | if (in_group != NULL) | 775 | if (in_group != nullptr) | ||
776 | in_group->removeMember(this); | 776 | in_group->removeMember(this); | ||
777 | in_group = set_group; | 777 | in_group = set_group; | ||
778 | in_group->addMember(this); | 778 | in_group->addMember(this); | ||
779 | } | 779 | } | ||
780 | } else if (info->groupLeader() != XCB_WINDOW_NONE) { | 780 | } else if (info->groupLeader() != XCB_WINDOW_NONE) { | ||
781 | Group* new_group = workspace()->findGroup(info->groupLeader()); | 781 | Group* new_group = workspace()->findGroup(info->groupLeader()); | ||
782 | Client *t = qobject_cast<Client*>(transientFor()); | 782 | Client *t = qobject_cast<Client*>(transientFor()); | ||
783 | if (t != NULL && t->group() != new_group) { | 783 | if (t != nullptr && t->group() != new_group) { | ||
784 | // move the window to the right group (e.g. a dialog provided | 784 | // move the window to the right group (e.g. a dialog provided | ||
785 | // by different app, but transient for this one, so make it part of that group) | 785 | // by different app, but transient for this one, so make it part of that group) | ||
786 | new_group = t->group(); | 786 | new_group = t->group(); | ||
787 | } | 787 | } | ||
788 | if (new_group == NULL) // doesn't exist yet | 788 | if (new_group == nullptr) // doesn't exist yet | ||
789 | new_group = new Group(info->groupLeader()); | 789 | new_group = new Group(info->groupLeader()); | ||
790 | if (new_group != in_group) { | 790 | if (new_group != in_group) { | ||
791 | if (in_group != NULL) | 791 | if (in_group != nullptr) | ||
792 | in_group->removeMember(this); | 792 | in_group->removeMember(this); | ||
793 | in_group = new_group; | 793 | in_group = new_group; | ||
794 | in_group->addMember(this); | 794 | in_group->addMember(this); | ||
795 | } | 795 | } | ||
796 | } else { | 796 | } else { | ||
797 | if (Client *t = qobject_cast<Client*>(transientFor())) { | 797 | if (Client *t = qobject_cast<Client*>(transientFor())) { | ||
798 | // doesn't have window group set, but is transient for something | 798 | // doesn't have window group set, but is transient for something | ||
799 | // so make it part of that group | 799 | // so make it part of that group | ||
800 | Group* new_group = t->group(); | 800 | Group* new_group = t->group(); | ||
801 | if (new_group != in_group) { | 801 | if (new_group != in_group) { | ||
802 | if (in_group != NULL) | 802 | if (in_group != nullptr) | ||
803 | in_group->removeMember(this); | 803 | in_group->removeMember(this); | ||
804 | in_group = t->group(); | 804 | in_group = t->group(); | ||
805 | in_group->addMember(this); | 805 | in_group->addMember(this); | ||
806 | } | 806 | } | ||
807 | } else if (groupTransient()) { | 807 | } else if (groupTransient()) { | ||
808 | // group transient which actually doesn't have a group :( | 808 | // group transient which actually doesn't have a group :( | ||
809 | // try creating group with other windows with the same client leader | 809 | // try creating group with other windows with the same client leader | ||
810 | Group* new_group = workspace()->findClientLeaderGroup(this); | 810 | Group* new_group = workspace()->findClientLeaderGroup(this); | ||
811 | if (new_group == NULL) | 811 | if (new_group == nullptr) | ||
812 | new_group = new Group(XCB_WINDOW_NONE); | 812 | new_group = new Group(XCB_WINDOW_NONE); | ||
813 | if (new_group != in_group) { | 813 | if (new_group != in_group) { | ||
814 | if (in_group != NULL) | 814 | if (in_group != nullptr) | ||
815 | in_group->removeMember(this); | 815 | in_group->removeMember(this); | ||
816 | in_group = new_group; | 816 | in_group = new_group; | ||
817 | in_group->addMember(this); | 817 | in_group->addMember(this); | ||
818 | } | 818 | } | ||
819 | } else { // Not transient without a group, put it in its client leader group. | 819 | } else { // Not transient without a group, put it in its client leader group. | ||
820 | // This might be stupid if grouping was used for e.g. taskbar grouping | 820 | // This might be stupid if grouping was used for e.g. taskbar grouping | ||
821 | // or minimizing together the whole group, but as long as it is used | 821 | // or minimizing together the whole group, but as long as it is used | ||
822 | // only for dialogs it's better to keep windows from one app in one group. | 822 | // only for dialogs it's better to keep windows from one app in one group. | ||
823 | Group* new_group = workspace()->findClientLeaderGroup(this); | 823 | Group* new_group = workspace()->findClientLeaderGroup(this); | ||
824 | if (in_group != NULL && in_group != new_group) { | 824 | if (in_group != nullptr && in_group != new_group) { | ||
825 | in_group->removeMember(this); | 825 | in_group->removeMember(this); | ||
826 | in_group = NULL; | 826 | in_group = nullptr; | ||
827 | } | 827 | } | ||
828 | if (new_group == NULL) | 828 | if (new_group == nullptr) | ||
829 | new_group = new Group(XCB_WINDOW_NONE); | 829 | new_group = new Group(XCB_WINDOW_NONE); | ||
830 | if (in_group != new_group) { | 830 | if (in_group != new_group) { | ||
831 | in_group = new_group; | 831 | in_group = new_group; | ||
832 | in_group->addMember(this); | 832 | in_group->addMember(this); | ||
833 | } | 833 | } | ||
834 | } | 834 | } | ||
835 | } | 835 | } | ||
836 | if (in_group != old_group || force) { | 836 | if (in_group != old_group || force) { | ||
837 | for (auto it = transients().constBegin(); | 837 | for (auto it = transients().constBegin(); | ||
838 | it != transients().constEnd(); | 838 | it != transients().constEnd(); | ||
839 | ) { | 839 | ) { | ||
840 | auto *c = *it; | 840 | auto *c = *it; | ||
841 | // group transients in the old group are no longer transient for it | 841 | // group transients in the old group are no longer transient for it | ||
842 | if (c->groupTransient() && c->group() != group()) { | 842 | if (c->groupTransient() && c->group() != group()) { | ||
843 | removeTransientFromList(c); | 843 | removeTransientFromList(c); | ||
844 | it = transients().constBegin(); // restart, just in case something more has changed with the list | 844 | it = transients().constBegin(); // restart, just in case something more has changed with the list | ||
845 | } else | 845 | } else | ||
846 | ++it; | 846 | ++it; | ||
847 | } | 847 | } | ||
848 | if (groupTransient()) { | 848 | if (groupTransient()) { | ||
849 | // no longer transient for ones in the old group | 849 | // no longer transient for ones in the old group | ||
850 | if (old_group != NULL) { | 850 | if (old_group != nullptr) { | ||
851 | for (ClientList::ConstIterator it = old_group->members().constBegin(); | 851 | for (ClientList::ConstIterator it = old_group->members().constBegin(); | ||
852 | it != old_group->members().constEnd(); | 852 | it != old_group->members().constEnd(); | ||
853 | ++it) | 853 | ++it) | ||
854 | (*it)->removeTransient(this); | 854 | (*it)->removeTransient(this); | ||
855 | } | 855 | } | ||
856 | // and make transient for all in the new group | 856 | // and make transient for all in the new group | ||
857 | for (ClientList::ConstIterator it = group()->members().constBegin(); | 857 | for (ClientList::ConstIterator it = group()->members().constBegin(); | ||
858 | it != group()->members().constEnd(); | 858 | it != group()->members().constEnd(); | ||
Show All 12 Lines | 870 | if (!(*it)->isSplash()) | |||
871 | continue; | 871 | continue; | ||
872 | if (!(*it)->groupTransient()) | 872 | if (!(*it)->groupTransient()) | ||
873 | continue; | 873 | continue; | ||
874 | if (*it == this || hasTransient(*it, true)) // TODO indirect? | 874 | if (*it == this || hasTransient(*it, true)) // TODO indirect? | ||
875 | continue; | 875 | continue; | ||
876 | addTransient(*it); | 876 | addTransient(*it); | ||
877 | } | 877 | } | ||
878 | } | 878 | } | ||
879 | if (old_group != NULL) | 879 | if (old_group != nullptr) | ||
880 | old_group->deref(); // can be now deleted if empty | 880 | old_group->deref(); // can be now deleted if empty | ||
881 | checkGroupTransients(); | 881 | checkGroupTransients(); | ||
882 | checkActiveModal(); | 882 | checkActiveModal(); | ||
883 | workspace()->updateClientLayer(this); | 883 | workspace()->updateClientLayer(this); | ||
884 | } | 884 | } | ||
885 | 885 | | |||
886 | // used by Workspace::findClientLeaderGroup() | 886 | // used by Workspace::findClientLeaderGroup() | ||
887 | void Client::changeClientLeaderGroup(Group* gr) | 887 | void Client::changeClientLeaderGroup(Group* gr) | ||
888 | { | 888 | { | ||
889 | // transientFor() != NULL are in the group of their mainwindow, so keep them there | 889 | // transientFor() != NULL are in the group of their mainwindow, so keep them there | ||
890 | if (transientFor() != NULL) | 890 | if (transientFor() != nullptr) | ||
891 | return; | 891 | return; | ||
892 | // also don't change the group for window which have group set | 892 | // also don't change the group for window which have group set | ||
893 | if (info->groupLeader()) | 893 | if (info->groupLeader()) | ||
894 | return; | 894 | return; | ||
895 | checkGroup(gr); // change group | 895 | checkGroup(gr); // change group | ||
896 | } | 896 | } | ||
897 | 897 | | |||
898 | bool Client::check_active_modal = false; | 898 | bool Client::check_active_modal = false; | ||
899 | 899 | | |||
900 | void Client::checkActiveModal() | 900 | void Client::checkActiveModal() | ||
901 | { | 901 | { | ||
902 | // if the active window got new modal transient, activate it. | 902 | // if the active window got new modal transient, activate it. | ||
903 | // cannot be done in AddTransient(), because there may temporarily | 903 | // cannot be done in AddTransient(), because there may temporarily | ||
904 | // exist loops, breaking findModal | 904 | // exist loops, breaking findModal | ||
905 | Client* check_modal = dynamic_cast<Client*>(workspace()->mostRecentlyActivatedClient()); | 905 | Client* check_modal = dynamic_cast<Client*>(workspace()->mostRecentlyActivatedClient()); | ||
906 | if (check_modal != NULL && check_modal->check_active_modal) { | 906 | if (check_modal != nullptr && check_modal->check_active_modal) { | ||
907 | Client* new_modal = dynamic_cast<Client*>(check_modal->findModal()); | 907 | Client* new_modal = dynamic_cast<Client*>(check_modal->findModal()); | ||
908 | if (new_modal != NULL && new_modal != check_modal) { | 908 | if (new_modal != nullptr && new_modal != check_modal) { | ||
909 | if (!new_modal->isManaged()) | 909 | if (!new_modal->isManaged()) | ||
910 | return; // postpone check until end of manage() | 910 | return; // postpone check until end of manage() | ||
911 | workspace()->activateClient(new_modal); | 911 | workspace()->activateClient(new_modal); | ||
912 | } | 912 | } | ||
913 | check_modal->check_active_modal = false; | 913 | check_modal->check_active_modal = false; | ||
914 | } | 914 | } | ||
915 | } | 915 | } | ||
916 | 916 | | |||
917 | } // namespace | 917 | } // namespace |