Changeset View
Standalone View
src/windowsystem/waylandintegration.cpp
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Line(s) | |||||
57 | void WaylandIntegration::setupKWaylandIntegration() | 57 | void WaylandIntegration::setupKWaylandIntegration() | ||
58 | { | 58 | { | ||
59 | using namespace KWayland::Client; | 59 | using namespace KWayland::Client; | ||
60 | m_waylandConnection = ConnectionThread::fromApplication(this); | 60 | m_waylandConnection = ConnectionThread::fromApplication(this); | ||
61 | if (!m_waylandConnection) { | 61 | if (!m_waylandConnection) { | ||
62 | qCWarning(KWAYLAND_KWS) << "Failed getting Wayland connection from QPA"; | 62 | qCWarning(KWAYLAND_KWS) << "Failed getting Wayland connection from QPA"; | ||
63 | return; | 63 | return; | ||
64 | } | 64 | } | ||
65 | m_registry = new Registry(this); | 65 | m_registry = new Registry(qApp); | ||
66 | m_registry->create(m_waylandConnection); | 66 | m_registry->create(m_waylandConnection); | ||
67 | m_waylandCompositor = Compositor::fromApplication(this); | 67 | m_waylandCompositor = Compositor::fromApplication(this); | ||
68 | 68 | | |||
69 | //when the Qt QPA closes it deletes the wl_display | | |||
70 | //closing wl_display deletes the wl_registry | | |||
71 | //when we destroy the kwayland wrapper we double delete | | |||
72 | //as we're a singleton we're not deleted till after qApp | | |||
73 | //we want to release our wayland parts first | | |||
74 | connect(qApp, &QCoreApplication::aboutToQuit, this, [=]() { | | |||
75 | if (m_waylandBlurManager) { | | |||
76 | m_waylandBlurManager->release(); | | |||
77 | } | | |||
78 | if (m_waylandContrastManager) { | | |||
79 | m_waylandContrastManager->release(); | | |||
80 | } | | |||
81 | if (m_waylandSlideManager) { | | |||
82 | m_waylandSlideManager->release(); | | |||
83 | } | | |||
84 | if (m_waylandCompositor) { | | |||
85 | m_waylandCompositor->release(); | | |||
86 | } | | |||
87 | if (m_wm) { | | |||
88 | m_wm->release(); | | |||
89 | } | | |||
90 | if (m_waylandPlasmaShell) { | | |||
91 | m_waylandPlasmaShell->release(); | | |||
92 | } | | |||
93 | m_registry->release(); | | |||
94 | }); | | |||
95 | | ||||
96 | m_registry->setup(); | 69 | m_registry->setup(); | ||
97 | m_waylandConnection->roundtrip(); | 70 | m_waylandConnection->roundtrip(); | ||
98 | } | 71 | } | ||
99 | 72 | | |||
100 | WaylandIntegration *WaylandIntegration::self() | 73 | WaylandIntegration *WaylandIntegration::self() | ||
101 | { | 74 | { | ||
102 | return &privateWaylandIntegrationSelf()->self; | 75 | return &privateWaylandIntegrationSelf()->self; | ||
103 | } | 76 | } | ||
104 | 77 | | |||
105 | 78 | | |||
106 | KWayland::Client::ConnectionThread *WaylandIntegration::waylandConnection() const | 79 | KWayland::Client::ConnectionThread *WaylandIntegration::waylandConnection() const | ||
107 | { | 80 | { | ||
108 | return m_waylandConnection; | 81 | return m_waylandConnection; | ||
109 | } | 82 | } | ||
110 | 83 | | |||
111 | KWayland::Client::BlurManager *WaylandIntegration::waylandBlurManager() | 84 | KWayland::Client::BlurManager *WaylandIntegration::waylandBlurManager() | ||
112 | { | 85 | { | ||
113 | if (!m_waylandBlurManager) { | 86 | if (!m_waylandBlurManager && m_registry) { | ||
114 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Blur); | 87 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Blur); | ||
115 | 88 | | |||
116 | if (wmInterface.name == 0) { | 89 | if (wmInterface.name == 0) { | ||
117 | return nullptr; | 90 | return nullptr; | ||
118 | } | 91 | } | ||
119 | 92 | | |||
120 | m_waylandBlurManager = m_registry->createBlurManager(wmInterface.name, wmInterface.version, this); | 93 | m_waylandBlurManager = m_registry->createBlurManager(wmInterface.name, wmInterface.version, qApp); | ||
121 | 94 | | |||
122 | connect(m_waylandBlurManager, &KWayland::Client::BlurManager::removed, this, | 95 | connect(m_waylandBlurManager, &KWayland::Client::BlurManager::removed, this, | ||
123 | [this] () { | 96 | [this] () { | ||
124 | m_waylandBlurManager->deleteLater(); | 97 | m_waylandBlurManager->deleteLater(); | ||
125 | m_waylandBlurManager = nullptr; | | |||
zzag: Is it safe to drop this line? What was the reasoning behind this change? | |||||
apol: Yes, note it's a QPointer now. | |||||
Is it okay to access waylandBlurManager() right after it's been deleted (or rather scheduled for removal)? zzag: Is it okay to access waylandBlurManager() right after it's been deleted (or rather scheduled… | |||||
There's two questions here. I'll answer both. Is it safe to call a method on BlurManager after the registry removes it? It should be. Typically protocols works as follows:
(it should then stops listening for events on that interface) and the registry removes it
That way we're race free. Not all wayland globals behave quite the same, because that would be far too convenient! If someone uses it after the QApp destruction could the QPA have got deleted in the meantime (and hit the original bug) For any normal signal, maybe. But QApp is special QCoreApplication::execCleanup happens before QGuiApp destructor which removes the davidedmundson:
There's two questions here. I'll answer both.
---
Is it safe to call a method on… | |||||
126 | } | 98 | } | ||
127 | ); | 99 | ); | ||
Since qApp is the parent are they needed? When destroyed qApp will call delete on m_waylandBlurManager, no? anthonyfieroni: Since qApp is the parent are they needed? When destroyed qApp will call delete on… | |||||
anthonyfieroni: Or that's when removed during the normal execution? | |||||
davidedmundson: Yeah, exactly that. | |||||
128 | } | 100 | } | ||
129 | 101 | | |||
130 | return m_waylandBlurManager; | 102 | return m_waylandBlurManager; | ||
131 | } | 103 | } | ||
132 | 104 | | |||
133 | KWayland::Client::ContrastManager *WaylandIntegration::waylandContrastManager() | 105 | KWayland::Client::ContrastManager *WaylandIntegration::waylandContrastManager() | ||
134 | { | 106 | { | ||
135 | if (!m_waylandContrastManager) { | 107 | if (!m_waylandContrastManager && m_registry) { | ||
136 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Contrast); | 108 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Contrast); | ||
137 | 109 | | |||
138 | if (wmInterface.name == 0) { | 110 | if (wmInterface.name == 0) { | ||
139 | return nullptr; | 111 | return nullptr; | ||
140 | } | 112 | } | ||
141 | 113 | | |||
142 | m_waylandContrastManager = m_registry->createContrastManager(wmInterface.name, wmInterface.version, this); | 114 | m_waylandContrastManager = m_registry->createContrastManager(wmInterface.name, wmInterface.version, qApp); | ||
143 | 115 | | |||
144 | connect(m_waylandContrastManager, &KWayland::Client::ContrastManager::removed, this, | 116 | connect(m_waylandContrastManager, &KWayland::Client::ContrastManager::removed, this, | ||
145 | [this] () { | 117 | [this] () { | ||
146 | m_waylandContrastManager->deleteLater(); | 118 | m_waylandContrastManager->deleteLater(); | ||
147 | m_waylandContrastManager = nullptr; | | |||
148 | } | 119 | } | ||
149 | ); | 120 | ); | ||
150 | } | 121 | } | ||
151 | | ||||
152 | return m_waylandContrastManager; | 122 | return m_waylandContrastManager; | ||
153 | } | 123 | } | ||
154 | 124 | | |||
155 | KWayland::Client::SlideManager *WaylandIntegration::waylandSlideManager() | 125 | KWayland::Client::SlideManager *WaylandIntegration::waylandSlideManager() | ||
156 | { | 126 | { | ||
157 | if (!m_waylandSlideManager) { | 127 | if (!m_waylandSlideManager && m_registry) { | ||
158 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Slide); | 128 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::Slide); | ||
159 | 129 | | |||
160 | if (wmInterface.name == 0) { | 130 | if (wmInterface.name == 0) { | ||
161 | return nullptr; | 131 | return nullptr; | ||
162 | } | 132 | } | ||
163 | 133 | | |||
164 | m_waylandSlideManager = m_registry->createSlideManager(wmInterface.name, wmInterface.version, this); | 134 | m_waylandSlideManager = m_registry->createSlideManager(wmInterface.name, wmInterface.version, qApp); | ||
165 | 135 | | |||
166 | connect(m_waylandSlideManager, &KWayland::Client::SlideManager::removed, this, | 136 | connect(m_waylandSlideManager, &KWayland::Client::SlideManager::removed, this, | ||
167 | [this] () { | 137 | [this] () { | ||
168 | m_waylandSlideManager->deleteLater(); | 138 | m_waylandSlideManager->deleteLater(); | ||
169 | m_waylandSlideManager = nullptr; | | |||
170 | } | 139 | } | ||
171 | ); | 140 | ); | ||
172 | } | 141 | } | ||
173 | 142 | | |||
174 | return m_waylandSlideManager; | 143 | return m_waylandSlideManager; | ||
175 | } | 144 | } | ||
176 | 145 | | |||
177 | KWayland::Client::Compositor *WaylandIntegration::waylandCompositor() const | 146 | KWayland::Client::Compositor *WaylandIntegration::waylandCompositor() const | ||
178 | { | 147 | { | ||
179 | return m_waylandCompositor; | 148 | return m_waylandCompositor; | ||
180 | } | 149 | } | ||
181 | 150 | | |||
182 | KWayland::Client::PlasmaWindowManagement *WaylandIntegration::plasmaWindowManagement() | 151 | KWayland::Client::PlasmaWindowManagement *WaylandIntegration::plasmaWindowManagement() | ||
183 | { | 152 | { | ||
184 | using namespace KWayland::Client; | 153 | using namespace KWayland::Client; | ||
185 | 154 | | |||
186 | if (!m_wm) { | 155 | if (!m_wm && m_registry) { | ||
187 | const Registry::AnnouncedInterface wmInterface = m_registry->interface(Registry::Interface::PlasmaWindowManagement); | 156 | const Registry::AnnouncedInterface wmInterface = m_registry->interface(Registry::Interface::PlasmaWindowManagement); | ||
188 | 157 | | |||
189 | if (wmInterface.name == 0) { | 158 | if (wmInterface.name == 0) { | ||
190 | qCWarning(KWAYLAND_KWS) << "This compositor does not support the Plasma Window Management interface"; | 159 | qCWarning(KWAYLAND_KWS) << "This compositor does not support the Plasma Window Management interface"; | ||
191 | return nullptr; | 160 | return nullptr; | ||
192 | } | 161 | } | ||
193 | 162 | | |||
194 | m_wm = m_registry->createPlasmaWindowManagement(wmInterface.name, wmInterface.version, this); | 163 | m_wm = m_registry->createPlasmaWindowManagement(wmInterface.name, wmInterface.version, qApp); | ||
195 | connect(m_wm, &PlasmaWindowManagement::windowCreated, this, | 164 | connect(m_wm, &PlasmaWindowManagement::windowCreated, this, | ||
196 | [this] (PlasmaWindow *w) { | 165 | [this] (PlasmaWindow *w) { | ||
197 | emit KWindowSystem::self()->windowAdded(w->internalId()); | 166 | emit KWindowSystem::self()->windowAdded(w->internalId()); | ||
198 | emit KWindowSystem::self()->stackingOrderChanged(); | 167 | emit KWindowSystem::self()->stackingOrderChanged(); | ||
199 | connect(w, &PlasmaWindow::unmapped, this, | 168 | connect(w, &PlasmaWindow::unmapped, this, | ||
200 | [w] { | 169 | [w] { | ||
201 | emit KWindowSystem::self()->windowRemoved(w->internalId()); | 170 | emit KWindowSystem::self()->windowRemoved(w->internalId()); | ||
202 | emit KWindowSystem::self()->stackingOrderChanged(); | 171 | emit KWindowSystem::self()->stackingOrderChanged(); | ||
203 | } | 172 | } | ||
204 | ); | 173 | ); | ||
205 | } | 174 | } | ||
206 | ); | 175 | ); | ||
207 | connect(m_wm, &PlasmaWindowManagement::activeWindowChanged, this, | 176 | connect(m_wm, &PlasmaWindowManagement::activeWindowChanged, this, | ||
208 | [this] { | 177 | [this] { | ||
209 | if (PlasmaWindow *w = m_wm->activeWindow()) { | 178 | if (PlasmaWindow *w = m_wm->activeWindow()) { | ||
210 | emit KWindowSystem::self()->activeWindowChanged(w->internalId()); | 179 | emit KWindowSystem::self()->activeWindowChanged(w->internalId()); | ||
211 | } else { | 180 | } else { | ||
212 | emit KWindowSystem::self()->activeWindowChanged(0); | 181 | emit KWindowSystem::self()->activeWindowChanged(0); | ||
213 | } | 182 | } | ||
214 | } | 183 | } | ||
215 | ); | 184 | ); | ||
216 | connect(m_wm, &PlasmaWindowManagement::showingDesktopChanged, KWindowSystem::self(), &KWindowSystem::showingDesktopChanged); | 185 | connect(m_wm, &PlasmaWindowManagement::showingDesktopChanged, KWindowSystem::self(), &KWindowSystem::showingDesktopChanged); | ||
217 | qCDebug(KWAYLAND_KWS) << "Plasma Window Management interface bound"; | 186 | qCDebug(KWAYLAND_KWS) << "Plasma Window Management interface bound"; | ||
187 | | ||||
188 | connect(m_wm, &KWayland::Client::PlasmaWindowManagement::removed, this, | ||||
189 | [this] () { | ||||
190 | m_wm->deleteLater(); | ||||
191 | } | ||||
192 | ); | ||||
218 | } | 193 | } | ||
219 | 194 | | |||
220 | return m_wm; | 195 | return m_wm; | ||
221 | } | 196 | } | ||
222 | 197 | | |||
223 | KWayland::Client::PlasmaShell *WaylandIntegration::waylandPlasmaShell() | 198 | KWayland::Client::PlasmaShell *WaylandIntegration::waylandPlasmaShell() | ||
224 | { | 199 | { | ||
225 | if (!m_waylandPlasmaShell) { | 200 | if (!m_waylandPlasmaShell && m_registry) { | ||
226 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); | 201 | const KWayland::Client::Registry::AnnouncedInterface wmInterface = m_registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); | ||
227 | 202 | | |||
228 | if (wmInterface.name == 0) { | 203 | if (wmInterface.name == 0) { | ||
229 | return nullptr; | 204 | return nullptr; | ||
230 | } | 205 | } | ||
231 | 206 | | |||
232 | m_waylandPlasmaShell = m_registry->createPlasmaShell(wmInterface.name, wmInterface.version, this); | 207 | m_waylandPlasmaShell = m_registry->createPlasmaShell(wmInterface.name, wmInterface.version, qApp); | ||
233 | } | 208 | } | ||
234 | return m_waylandPlasmaShell; | 209 | return m_waylandPlasmaShell; | ||
235 | } | 210 | } |
Is it safe to drop this line? What was the reasoning behind this change?