Changeset View
Changeset View
Standalone View
Standalone View
shell_client.cpp
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Line(s) | 72 | ShellClient::ShellClient(ShellSurfaceInterface *surface) | |||
---|---|---|---|---|---|
73 | : AbstractClient() | 73 | : AbstractClient() | ||
74 | , m_shellSurface(surface) | 74 | , m_shellSurface(surface) | ||
75 | , m_xdgShellSurface(nullptr) | 75 | , m_xdgShellSurface(nullptr) | ||
76 | , m_xdgShellPopup(nullptr) | 76 | , m_xdgShellPopup(nullptr) | ||
77 | , m_internal(surface->client() == waylandServer()->internalConnection()) | 77 | , m_internal(surface->client() == waylandServer()->internalConnection()) | ||
78 | { | 78 | { | ||
79 | setSurface(surface->surface()); | 79 | setSurface(surface->surface()); | ||
80 | init(); | 80 | init(); | ||
81 | m_initialized = true; | ||||
81 | } | 82 | } | ||
82 | 83 | | |||
83 | ShellClient::ShellClient(XdgShellSurfaceInterface *surface) | 84 | ShellClient::ShellClient(XdgShellSurfaceInterface *surface) | ||
84 | : AbstractClient() | 85 | : AbstractClient() | ||
85 | , m_shellSurface(nullptr) | 86 | , m_shellSurface(nullptr) | ||
86 | , m_xdgShellSurface(surface) | 87 | , m_xdgShellSurface(surface) | ||
87 | , m_xdgShellPopup(nullptr) | 88 | , m_xdgShellPopup(nullptr) | ||
88 | , m_internal(surface->client() == waylandServer()->internalConnection()) | 89 | , m_internal(surface->client() == waylandServer()->internalConnection()) | ||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Line(s) | 114 | { | |||
137 | // determine the resource name, this is inspired from ICCCM 4.1.2.5 | 138 | // determine the resource name, this is inspired from ICCCM 4.1.2.5 | ||
138 | // the binary name of the invoked client | 139 | // the binary name of the invoked client | ||
139 | QFileInfo info{shellSurface->client()->executablePath()}; | 140 | QFileInfo info{shellSurface->client()->executablePath()}; | ||
140 | QByteArray resourceName; | 141 | QByteArray resourceName; | ||
141 | if (info.exists()) { | 142 | if (info.exists()) { | ||
142 | resourceName = info.fileName().toUtf8(); | 143 | resourceName = info.fileName().toUtf8(); | ||
143 | } | 144 | } | ||
144 | setResourceClass(resourceName, shellSurface->windowClass()); | 145 | setResourceClass(resourceName, shellSurface->windowClass()); | ||
146 | setDesktopFileName(shellSurface->windowClass()); | ||||
145 | connect(shellSurface, &T::windowClassChanged, this, | 147 | connect(shellSurface, &T::windowClassChanged, this, | ||
146 | [this, resourceName] (const QByteArray &windowClass) { | 148 | [this, resourceName] (const QByteArray &windowClass) { | ||
147 | setResourceClass(resourceName, windowClass); | 149 | setResourceClass(resourceName, windowClass); | ||
148 | if (!m_internal) { | 150 | if (m_initialized && supportsWindowRules()) { | ||
149 | setupWindowRules(true); | 151 | setupWindowRules(true); | ||
150 | applyWindowRules(); | 152 | applyWindowRules(); | ||
151 | } | 153 | } | ||
152 | setDesktopFileName(windowClass); | 154 | setDesktopFileName(windowClass); | ||
153 | } | 155 | } | ||
154 | ); | 156 | ); | ||
155 | connect(shellSurface, &T::resizeRequested, this, | 157 | connect(shellSurface, &T::resizeRequested, this, | ||
156 | [this] (SeatInterface *seat, quint32 serial, Qt::Edges edges) { | 158 | [this] (SeatInterface *seat, quint32 serial, Qt::Edges edges) { | ||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | |||||
198 | ); | 200 | ); | ||
199 | // TODO: consider output! | 201 | // TODO: consider output! | ||
200 | connect(shellSurface, &T::fullscreenChanged, this, &ShellClient::clientFullScreenChanged); | 202 | connect(shellSurface, &T::fullscreenChanged, this, &ShellClient::clientFullScreenChanged); | ||
201 | 203 | | |||
202 | connect(shellSurface, &T::transientForChanged, this, &ShellClient::setTransient); | 204 | connect(shellSurface, &T::transientForChanged, this, &ShellClient::setTransient); | ||
203 | 205 | | |||
204 | connect(this, &ShellClient::geometryChanged, this, &ShellClient::updateClientOutputs); | 206 | connect(this, &ShellClient::geometryChanged, this, &ShellClient::updateClientOutputs); | ||
205 | connect(screens(), &Screens::changed, this, &ShellClient::updateClientOutputs); | 207 | connect(screens(), &Screens::changed, this, &ShellClient::updateClientOutputs); | ||
206 | | ||||
207 | if (!m_internal) { | | |||
208 | setupWindowRules(false); | | |||
209 | } | | |||
210 | setDesktopFileName(rules()->checkDesktopFile(shellSurface->windowClass(), true).toUtf8()); | | |||
211 | } | 208 | } | ||
212 | 209 | | |||
213 | void ShellClient::init() | 210 | void ShellClient::init() | ||
214 | { | 211 | { | ||
215 | connect(this, &ShellClient::desktopFileNameChanged, this, &ShellClient::updateIcon); | 212 | connect(this, &ShellClient::desktopFileNameChanged, this, &ShellClient::updateIcon); | ||
216 | createWindowId(); | 213 | createWindowId(); | ||
217 | setupCompositing(); | 214 | setupCompositing(); | ||
218 | updateIcon(); | 215 | updateIcon(); | ||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Line(s) | 321 | } else if (m_xdgShellPopup) { | |||
332 | connect(m_xdgShellPopup, &XdgShellPopupInterface::configureAcknowledged, this, [this](int serial) { | 329 | connect(m_xdgShellPopup, &XdgShellPopupInterface::configureAcknowledged, this, [this](int serial) { | ||
333 | m_lastAckedConfigureRequest = serial; | 330 | m_lastAckedConfigureRequest = serial; | ||
334 | }); | 331 | }); | ||
335 | 332 | | |||
336 | connect(m_xdgShellPopup, &XdgShellPopupInterface::destroyed, this, &ShellClient::destroyClient); | 333 | connect(m_xdgShellPopup, &XdgShellPopupInterface::destroyed, this, &ShellClient::destroyClient); | ||
337 | } | 334 | } | ||
338 | 335 | | |||
339 | // set initial desktop | 336 | // set initial desktop | ||
340 | setDesktop(rules()->checkDesktop(m_internal ? int(NET::OnAllDesktops) : VirtualDesktopManager::self()->current(), true)); | 337 | setDesktop(m_internal ? int(NET::OnAllDesktops) : VirtualDesktopManager::self()->current()); | ||
341 | // TODO: merge in checks from Client::manage? | | |||
342 | if (rules()->checkMinimize(false, true)) { | | |||
343 | minimize(true); // No animation | | |||
344 | } | | |||
345 | setSkipTaskbar(rules()->checkSkipTaskbar(m_plasmaShellSurface ? m_plasmaShellSurface->skipTaskbar() : false, true)); | | |||
346 | setSkipPager(rules()->checkSkipPager(false, true)); | | |||
347 | setSkipSwitcher(rules()->checkSkipSwitcher(false, true)); | | |||
348 | setKeepAbove(rules()->checkKeepAbove(false, true)); | | |||
349 | setKeepBelow(rules()->checkKeepBelow(false, true)); | | |||
350 | setShortcut(rules()->checkShortcut(QString(), true)); | | |||
351 | 338 | | |||
352 | // setup shadow integration | 339 | // setup shadow integration | ||
353 | getShadow(); | 340 | getShadow(); | ||
354 | connect(s, &SurfaceInterface::shadowChanged, this, &Toplevel::getShadow); | 341 | connect(s, &SurfaceInterface::shadowChanged, this, &Toplevel::getShadow); | ||
355 | 342 | | |||
356 | connect(waylandServer(), &WaylandServer::foreignTransientChanged, this, [this](KWayland::Server::SurfaceInterface *child) { | 343 | connect(waylandServer(), &WaylandServer::foreignTransientChanged, this, [this](KWayland::Server::SurfaceInterface *child) { | ||
357 | if (child == surface()) { | 344 | if (child == surface()) { | ||
358 | setTransient(); | 345 | setTransient(); | ||
359 | } | 346 | } | ||
360 | }); | 347 | }); | ||
361 | setTransient(); | 348 | setTransient(); | ||
362 | 349 | | |||
363 | AbstractClient::updateColorScheme(QString()); | 350 | AbstractClient::updateColorScheme(QString()); | ||
364 | | ||||
365 | if (!m_internal) { | | |||
366 | discardTemporaryRules(); | | |||
367 | applyWindowRules(); // Just in case | | |||
368 | RuleBook::self()->discardUsed(this, false); // Remove ApplyNow rules | | |||
369 | updateWindowRules(Rules::All); // Was blocked while !isManaged() | | |||
370 | } | | |||
371 | } | 351 | } | ||
372 | 352 | | |||
373 | void ShellClient::finishInit() { | 353 | void ShellClient::finishInit() { | ||
374 | SurfaceInterface *s = surface(); | 354 | SurfaceInterface *s = surface(); | ||
375 | disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit); | 355 | disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit); | ||
376 | 356 | | |||
357 | if (supportsWindowRules()) { | ||||
358 | setupWindowRules(false); | ||||
359 | | ||||
360 | setDesktop(rules()->checkDesktop(desktop(), true)); | ||||
361 | setDesktopFileName(rules()->checkDesktopFile(desktopFileName(), true).toUtf8()); | ||||
362 | if (rules()->checkMinimize(isMinimized(), true)) { | ||||
363 | minimize(true); // No animation. | ||||
364 | } | ||||
365 | setSkipTaskbar(rules()->checkSkipTaskbar(skipTaskbar(), true)); | ||||
366 | setSkipPager(rules()->checkSkipPager(skipPager(), true)); | ||||
367 | setSkipSwitcher(rules()->checkSkipSwitcher(skipSwitcher(), true)); | ||||
368 | setKeepAbove(rules()->checkKeepAbove(keepAbove(), true)); | ||||
369 | setKeepBelow(rules()->checkKeepBelow(keepBelow(), true)); | ||||
370 | setShortcut(rules()->checkShortcut(shortcut().toString(), true)); | ||||
371 | updateColorScheme(); | ||||
372 | | ||||
373 | discardTemporaryRules(); | ||||
374 | RuleBook::self()->discardUsed(this, false); // Remove Apply Now rules. | ||||
375 | updateWindowRules(Rules::All); | ||||
376 | } | ||||
377 | | ||||
377 | if (m_xdgShellPopup) { | 378 | if (m_xdgShellPopup) { | ||
378 | QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); | 379 | QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); | ||
379 | placeIn(area); | 380 | placeIn(area); | ||
380 | } | 381 | } | ||
381 | 382 | | |||
382 | m_requestGeometryBlockCounter--; | 383 | m_requestGeometryBlockCounter--; | ||
383 | if (m_requestGeometryBlockCounter == 0) { | 384 | if (m_requestGeometryBlockCounter == 0) { | ||
384 | requestGeometry(m_blockedRequestGeometry); | 385 | requestGeometry(m_blockedRequestGeometry); | ||
385 | } | 386 | } | ||
387 | | ||||
388 | m_initialized = true; | ||||
386 | } | 389 | } | ||
387 | 390 | | |||
388 | void ShellClient::destroyClient() | 391 | void ShellClient::destroyClient() | ||
389 | { | 392 | { | ||
390 | m_closing = true; | 393 | m_closing = true; | ||
391 | Deleted *del = nullptr; | 394 | Deleted *del = nullptr; | ||
392 | if (workspace()) { | 395 | if (workspace()) { | ||
393 | del = Deleted::create(this); | 396 | del = Deleted::create(this); | ||
▲ Show 20 Lines • Show All 1473 Lines • ▼ Show 20 Line(s) | 1860 | { | |||
1867 | return false; | 1870 | return false; | ||
1868 | } | 1871 | } | ||
1869 | 1872 | | |||
1870 | QWindow *ShellClient::internalWindow() const | 1873 | QWindow *ShellClient::internalWindow() const | ||
1871 | { | 1874 | { | ||
1872 | return nullptr; | 1875 | return nullptr; | ||
1873 | } | 1876 | } | ||
1874 | 1877 | | |||
1878 | bool ShellClient::supportsWindowRules() const | ||||
1879 | { | ||||
1880 | return m_xdgShellSurface; | ||||
davidedmundson: Maybe we want to exclude anything with m_plasmaShellSurface.
Even if it works well in kwin it… | |||||
1881 | } | ||||
1882 | | ||||
1875 | } | 1883 | } |
Maybe we want to exclude anything with m_plasmaShellSurface.
Even if it works well in kwin it has potential to allow us to mess up plasma.