Changeset View
Changeset View
Standalone View
Standalone View
deleted.cpp
Show All 16 Lines | |||||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | 20 | | |||
21 | #include "deleted.h" | 21 | #include "deleted.h" | ||
22 | 22 | | |||
23 | #include "workspace.h" | 23 | #include "workspace.h" | ||
24 | #include "client.h" | 24 | #include "client.h" | ||
25 | #include "group.h" | ||||
25 | #include "netinfo.h" | 26 | #include "netinfo.h" | ||
26 | #include "shadow.h" | 27 | #include "shadow.h" | ||
28 | #include "shell_client.h" | ||||
27 | #include "decorations/decoratedclient.h" | 29 | #include "decorations/decoratedclient.h" | ||
28 | #include "decorations/decorationrenderer.h" | 30 | #include "decorations/decorationrenderer.h" | ||
29 | 31 | | |||
30 | #include <QDebug> | 32 | #include <QDebug> | ||
31 | 33 | | |||
32 | namespace KWin | 34 | namespace KWin | ||
33 | { | 35 | { | ||
34 | 36 | | |||
35 | Deleted::Deleted() | 37 | Deleted::Deleted() | ||
36 | : Toplevel() | 38 | : Toplevel() | ||
37 | , delete_refcount(1) | 39 | , delete_refcount(1) | ||
38 | , m_frame(XCB_WINDOW_NONE) | 40 | , m_frame(XCB_WINDOW_NONE) | ||
39 | , no_border(true) | 41 | , no_border(true) | ||
40 | , m_layer(UnknownLayer) | 42 | , m_layer(UnknownLayer) | ||
41 | , m_minimized(false) | 43 | , m_minimized(false) | ||
42 | , m_modal(false) | 44 | , m_modal(false) | ||
43 | , m_wasClient(false) | 45 | , m_wasClient(false) | ||
44 | , m_wasCurrentTab(true) | 46 | , m_wasCurrentTab(true) | ||
45 | , m_decorationRenderer(nullptr) | 47 | , m_decorationRenderer(nullptr) | ||
46 | , m_fullscreen(false) | 48 | , m_fullscreen(false) | ||
47 | , m_keepAbove(false) | 49 | , m_keepAbove(false) | ||
48 | , m_keepBelow(false) | 50 | , m_keepBelow(false) | ||
51 | , m_wasActive(false) | ||||
52 | , m_wasX11Client(false) | ||||
53 | , m_wasWaylandClient(false) | ||||
54 | , m_wasGroupTransient(false) | ||||
49 | { | 55 | { | ||
50 | } | 56 | } | ||
51 | 57 | | |||
52 | Deleted::~Deleted() | 58 | Deleted::~Deleted() | ||
53 | { | 59 | { | ||
54 | if (delete_refcount != 0) | 60 | if (delete_refcount != 0) | ||
55 | qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")"; | 61 | qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")"; | ||
56 | assert(delete_refcount == 0); | 62 | assert(delete_refcount == 0); | ||
57 | if (workspace()) { | 63 | if (workspace()) { | ||
58 | workspace()->removeDeleted(this); | 64 | workspace()->removeDeleted(this); | ||
59 | } | 65 | } | ||
66 | for (Toplevel *toplevel : qAsConst(m_transientFor)) { | ||||
67 | if (auto *deleted = qobject_cast<Deleted *>(toplevel)) { | ||||
68 | deleted->removeTransient(this); | ||||
69 | } | ||||
70 | } | ||||
71 | for (Deleted *transient : qAsConst(m_transients)) { | ||||
72 | transient->removeTransientFor(this); | ||||
73 | } | ||||
60 | deleteEffectWindow(); | 74 | deleteEffectWindow(); | ||
61 | } | 75 | } | ||
62 | 76 | | |||
63 | Deleted* Deleted::create(Toplevel* c) | 77 | Deleted* Deleted::create(Toplevel* c) | ||
64 | { | 78 | { | ||
65 | Deleted* d = new Deleted(); | 79 | Deleted* d = new Deleted(); | ||
66 | d->copyToDeleted(c); | 80 | d->copyToDeleted(c); | ||
67 | workspace()->addDeleted(d, c); | 81 | workspace()->addDeleted(d, c); | ||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 108 | if (AbstractClient *client = dynamic_cast<AbstractClient*>(c)) { | |||
112 | foreach (AbstractClient *c, m_mainClients) { | 126 | foreach (AbstractClient *c, m_mainClients) { | ||
113 | connect(c, &AbstractClient::windowClosed, this, &Deleted::mainClientClosed); | 127 | connect(c, &AbstractClient::windowClosed, this, &Deleted::mainClientClosed); | ||
114 | } | 128 | } | ||
115 | m_fullscreen = client->isFullScreen(); | 129 | m_fullscreen = client->isFullScreen(); | ||
116 | m_wasCurrentTab = client->isCurrentTab(); | 130 | m_wasCurrentTab = client->isCurrentTab(); | ||
117 | m_keepAbove = client->keepAbove(); | 131 | m_keepAbove = client->keepAbove(); | ||
118 | m_keepBelow = client->keepBelow(); | 132 | m_keepBelow = client->keepBelow(); | ||
119 | m_caption = client->caption(); | 133 | m_caption = client->caption(); | ||
134 | | ||||
135 | m_wasActive = client->isActive(); | ||||
136 | | ||||
137 | const auto *x11Client = qobject_cast<Client *>(client); | ||||
138 | m_wasGroupTransient = x11Client && x11Client->groupTransient(); | ||||
139 | | ||||
140 | if (m_wasGroupTransient) { | ||||
141 | const auto members = x11Client->group()->members(); | ||||
142 | for (Client *member : members) { | ||||
143 | if (member != client) { | ||||
144 | addTransientFor(member); | ||||
145 | } | ||||
146 | } | ||||
147 | } else { | ||||
148 | AbstractClient *transientFor = client->transientFor(); | ||||
149 | if (transientFor != nullptr) { | ||||
150 | addTransientFor(transientFor); | ||||
120 | } | 151 | } | ||
121 | } | 152 | } | ||
153 | } | ||||
154 | | ||||
155 | m_wasWaylandClient = qobject_cast<ShellClient *>(c) != nullptr; | ||||
davidedmundson: I'd expect to see that in Javascript, but it's weird in C++ | |||||
156 | m_wasX11Client = !m_wasWaylandClient; | ||||
157 | } | ||||
122 | 158 | | |||
123 | void Deleted::unrefWindow() | 159 | void Deleted::unrefWindow() | ||
124 | { | 160 | { | ||
125 | if (--delete_refcount > 0) | 161 | if (--delete_refcount > 0) | ||
126 | return; | 162 | return; | ||
127 | // needs to be delayed | 163 | // needs to be delayed | ||
128 | // a) when calling from effects, otherwise it'd be rather complicated to handle the case of the | 164 | // a) when calling from effects, otherwise it'd be rather complicated to handle the case of the | ||
129 | // window going away during a painting pass | 165 | // window going away during a painting pass | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | |||||
187 | } | 223 | } | ||
188 | 224 | | |||
189 | void Deleted::mainClientClosed(Toplevel *client) | 225 | void Deleted::mainClientClosed(Toplevel *client) | ||
190 | { | 226 | { | ||
191 | if (AbstractClient *c = dynamic_cast<AbstractClient*>(client)) | 227 | if (AbstractClient *c = dynamic_cast<AbstractClient*>(client)) | ||
192 | m_mainClients.removeAll(c); | 228 | m_mainClients.removeAll(c); | ||
193 | } | 229 | } | ||
194 | 230 | | |||
231 | void Deleted::transientForClosed(Toplevel *toplevel, Deleted *deleted) | ||||
232 | { | ||||
233 | if (deleted == nullptr) { | ||||
234 | m_transientFor.removeAll(toplevel); | ||||
235 | return; | ||||
236 | } | ||||
237 | | ||||
238 | const int index = m_transientFor.indexOf(toplevel); | ||||
239 | if (index == -1) { | ||||
240 | return; | ||||
241 | } | ||||
242 | | ||||
243 | m_transientFor[index] = deleted; | ||||
244 | deleted->addTransient(this); | ||||
245 | } | ||||
246 | | ||||
195 | xcb_window_t Deleted::frameId() const | 247 | xcb_window_t Deleted::frameId() const | ||
196 | { | 248 | { | ||
197 | return m_frame; | 249 | return m_frame; | ||
198 | } | 250 | } | ||
199 | 251 | | |||
200 | double Deleted::opacity() const | 252 | double Deleted::opacity() const | ||
201 | { | 253 | { | ||
202 | return m_opacity; | 254 | return m_opacity; | ||
203 | } | 255 | } | ||
204 | 256 | | |||
205 | QByteArray Deleted::windowRole() const | 257 | QByteArray Deleted::windowRole() const | ||
206 | { | 258 | { | ||
207 | return m_windowRole; | 259 | return m_windowRole; | ||
208 | } | 260 | } | ||
209 | 261 | | |||
262 | void Deleted::addTransient(Deleted *transient) | ||||
263 | { | ||||
264 | m_transients.append(transient); | ||||
265 | } | ||||
266 | | ||||
267 | void Deleted::removeTransient(Deleted *transient) | ||||
268 | { | ||||
269 | m_transients.removeAll(transient); | ||||
270 | } | ||||
271 | | ||||
272 | void Deleted::addTransientFor(AbstractClient *parent) | ||||
273 | { | ||||
274 | m_transientFor.append(parent); | ||||
275 | connect(parent, &AbstractClient::windowClosed, this, &Deleted::transientForClosed); | ||||
276 | } | ||||
277 | | ||||
278 | void Deleted::removeTransientFor(Deleted *parent) | ||||
279 | { | ||||
280 | m_transientFor.removeAll(parent); | ||||
281 | } | ||||
282 | | ||||
210 | } // namespace | 283 | } // namespace | ||
211 | 284 | |
I'd expect to see that in Javascript, but it's weird in C++