Changeset View
Changeset View
Standalone View
Standalone View
xdgshellclient.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | |||||
42 | #include <KWayland/Server/display.h> | 42 | #include <KWayland/Server/display.h> | ||
43 | #include <KWayland/Server/plasmashell_interface.h> | 43 | #include <KWayland/Server/plasmashell_interface.h> | ||
44 | #include <KWayland/Server/plasmawindowmanagement_interface.h> | 44 | #include <KWayland/Server/plasmawindowmanagement_interface.h> | ||
45 | #include <KWayland/Server/qtsurfaceextension_interface.h> | 45 | #include <KWayland/Server/qtsurfaceextension_interface.h> | ||
46 | #include <KWayland/Server/seat_interface.h> | 46 | #include <KWayland/Server/seat_interface.h> | ||
47 | #include <KWayland/Server/server_decoration_interface.h> | 47 | #include <KWayland/Server/server_decoration_interface.h> | ||
48 | #include <KWayland/Server/server_decoration_palette_interface.h> | 48 | #include <KWayland/Server/server_decoration_palette_interface.h> | ||
49 | #include <KWayland/Server/shadow_interface.h> | 49 | #include <KWayland/Server/shadow_interface.h> | ||
50 | #include <KWayland/Server/subcompositor_interface.h> | ||||
50 | #include <KWayland/Server/surface_interface.h> | 51 | #include <KWayland/Server/surface_interface.h> | ||
51 | #include <KWayland/Server/xdgdecoration_interface.h> | 52 | #include <KWayland/Server/xdgdecoration_interface.h> | ||
52 | 53 | | |||
53 | #include <QFileInfo> | 54 | #include <QFileInfo> | ||
54 | 55 | | |||
55 | #include <sys/types.h> | 56 | #include <sys/types.h> | ||
56 | #include <unistd.h> | 57 | #include <unistd.h> | ||
57 | 58 | | |||
Show All 29 Lines | |||||
87 | void XdgShellClient::init() | 88 | void XdgShellClient::init() | ||
88 | { | 89 | { | ||
89 | m_requestGeometryBlockCounter++; | 90 | m_requestGeometryBlockCounter++; | ||
90 | 91 | | |||
91 | connect(this, &XdgShellClient::desktopFileNameChanged, this, &XdgShellClient::updateIcon); | 92 | connect(this, &XdgShellClient::desktopFileNameChanged, this, &XdgShellClient::updateIcon); | ||
92 | createWindowId(); | 93 | createWindowId(); | ||
93 | setupCompositing(); | 94 | setupCompositing(); | ||
94 | updateIcon(); | 95 | updateIcon(); | ||
95 | doSetGeometry(QRect(QPoint(0, 0), m_clientSize)); | 96 | | ||
97 | // TODO: Initialize with null rect. | ||||
98 | geom = QRect(0, 0, -1, -1); | ||||
99 | m_windowGeometry = QRect(0, 0, -1, -1); | ||||
96 | 100 | | |||
97 | if (waylandServer()->inputMethodConnection() == surface()->client()) { | 101 | if (waylandServer()->inputMethodConnection() == surface()->client()) { | ||
98 | m_windowType = NET::OnScreenDisplay; | 102 | m_windowType = NET::OnScreenDisplay; | ||
99 | } | 103 | } | ||
100 | 104 | | |||
101 | connect(surface(), &SurfaceInterface::unmapped, this, &XdgShellClient::unmap); | 105 | connect(surface(), &SurfaceInterface::unmapped, this, &XdgShellClient::unmap); | ||
102 | connect(surface(), &SurfaceInterface::unbound, this, &XdgShellClient::destroyClient); | 106 | connect(surface(), &SurfaceInterface::unbound, this, &XdgShellClient::destroyClient); | ||
103 | connect(surface(), &SurfaceInterface::destroyed, this, &XdgShellClient::destroyClient); | 107 | connect(surface(), &SurfaceInterface::destroyed, this, &XdgShellClient::destroyClient); | ||
Show All 20 Lines | 109 | if (m_xdgShellSurface) { | |||
124 | setDesktopFileName(m_xdgShellSurface->windowClass()); | 128 | setDesktopFileName(m_xdgShellSurface->windowClass()); | ||
125 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowClassChanged, this, &XdgShellClient::handleWindowClassChanged); | 129 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowClassChanged, this, &XdgShellClient::handleWindowClassChanged); | ||
126 | 130 | | |||
127 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::minimizeRequested, this, &XdgShellClient::handleMinimizeRequested); | 131 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::minimizeRequested, this, &XdgShellClient::handleMinimizeRequested); | ||
128 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::maximizedChanged, this, &XdgShellClient::handleMaximizeRequested); | 132 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::maximizedChanged, this, &XdgShellClient::handleMaximizeRequested); | ||
129 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::fullscreenChanged, this, &XdgShellClient::handleFullScreenRequested); | 133 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::fullscreenChanged, this, &XdgShellClient::handleFullScreenRequested); | ||
130 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowMenuRequested, this, &XdgShellClient::handleWindowMenuRequested); | 134 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowMenuRequested, this, &XdgShellClient::handleWindowMenuRequested); | ||
131 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::transientForChanged, this, &XdgShellClient::handleTransientForChanged); | 135 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::transientForChanged, this, &XdgShellClient::handleTransientForChanged); | ||
136 | connect(m_xdgShellSurface, &XdgShellSurfaceInterface::windowGeometryChanged, this, &XdgShellClient::handleWindowGeometryChanged); | ||||
132 | 137 | | |||
133 | auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global()); | 138 | auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global()); | ||
134 | connect(global, &XdgShellInterface::pingDelayed, this, &XdgShellClient::handlePingDelayed); | 139 | connect(global, &XdgShellInterface::pingDelayed, this, &XdgShellClient::handlePingDelayed); | ||
135 | connect(global, &XdgShellInterface::pingTimeout, this, &XdgShellClient::handlePingTimeout); | 140 | connect(global, &XdgShellInterface::pingTimeout, this, &XdgShellClient::handlePingTimeout); | ||
136 | connect(global, &XdgShellInterface::pongReceived, this, &XdgShellClient::handlePongReceived); | 141 | connect(global, &XdgShellInterface::pongReceived, this, &XdgShellClient::handlePongReceived); | ||
137 | 142 | | |||
138 | auto configure = [this] { | 143 | auto configure = [this] { | ||
139 | if (m_closing) { | 144 | if (m_closing) { | ||
Show All 9 Lines | |||||
149 | connect(this, &AbstractClient::clientFinishUserMovedResized, this, configure); | 154 | connect(this, &AbstractClient::clientFinishUserMovedResized, this, configure); | ||
150 | 155 | | |||
151 | connect(this, &XdgShellClient::geometryChanged, this, &XdgShellClient::updateClientOutputs); | 156 | connect(this, &XdgShellClient::geometryChanged, this, &XdgShellClient::updateClientOutputs); | ||
152 | connect(screens(), &Screens::changed, this, &XdgShellClient::updateClientOutputs); | 157 | connect(screens(), &Screens::changed, this, &XdgShellClient::updateClientOutputs); | ||
153 | } else if (m_xdgShellPopup) { | 158 | } else if (m_xdgShellPopup) { | ||
154 | connect(m_xdgShellPopup, &XdgShellPopupInterface::configureAcknowledged, this, &XdgShellClient::handleConfigureAcknowledged); | 159 | connect(m_xdgShellPopup, &XdgShellPopupInterface::configureAcknowledged, this, &XdgShellClient::handleConfigureAcknowledged); | ||
155 | connect(m_xdgShellPopup, &XdgShellPopupInterface::grabRequested, this, &XdgShellClient::handleGrabRequested); | 160 | connect(m_xdgShellPopup, &XdgShellPopupInterface::grabRequested, this, &XdgShellClient::handleGrabRequested); | ||
156 | connect(m_xdgShellPopup, &XdgShellPopupInterface::destroyed, this, &XdgShellClient::destroyClient); | 161 | connect(m_xdgShellPopup, &XdgShellPopupInterface::destroyed, this, &XdgShellClient::destroyClient); | ||
162 | connect(m_xdgShellPopup, &XdgShellPopupInterface::windowGeometryChanged, this, &XdgShellClient::handleWindowGeometryChanged); | ||||
157 | } | 163 | } | ||
158 | 164 | | |||
159 | // set initial desktop | 165 | // set initial desktop | ||
160 | setDesktop(VirtualDesktopManager::self()->current()); | 166 | setDesktop(VirtualDesktopManager::self()->current()); | ||
161 | 167 | | |||
162 | // setup shadow integration | 168 | // setup shadow integration | ||
163 | updateShadow(); | 169 | updateShadow(); | ||
164 | connect(surface(), &SurfaceInterface::shadowChanged, this, &Toplevel::updateShadow); | 170 | connect(surface(), &SurfaceInterface::shadowChanged, this, &Toplevel::updateShadow); | ||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Line(s) | 252 | #endif | |||
280 | deleteClient(this); | 286 | deleteClient(this); | ||
281 | } | 287 | } | ||
282 | 288 | | |||
283 | void XdgShellClient::deleteClient(XdgShellClient *c) | 289 | void XdgShellClient::deleteClient(XdgShellClient *c) | ||
284 | { | 290 | { | ||
285 | delete c; | 291 | delete c; | ||
286 | } | 292 | } | ||
287 | 293 | | |||
288 | QSize XdgShellClient::toWindowGeometry(const QSize &size) const | 294 | QRect XdgShellClient::bufferGeometry() const | ||
289 | { | 295 | { | ||
290 | QSize adjustedSize = size - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | 296 | return m_bufferGeometry; | ||
291 | // a client going fullscreen should have the window the contents size of the screen | | |||
292 | if (!isFullScreen() && requestedMaximizeMode() != MaximizeFull) { | | |||
293 | adjustedSize -= QSize(m_windowMargins.left() + m_windowMargins.right(), m_windowMargins.top() + m_windowMargins.bottom()); | | |||
294 | } | | |||
295 | return adjustedSize; | | |||
296 | } | 297 | } | ||
297 | 298 | | |||
298 | QStringList XdgShellClient::activities() const | 299 | QStringList XdgShellClient::activities() const | ||
299 | { | 300 | { | ||
300 | // TODO: implement | 301 | // TODO: implement | ||
301 | return QStringList(); | 302 | return QStringList(); | ||
302 | } | 303 | } | ||
303 | 304 | | |||
304 | QPoint XdgShellClient::clientContentPos() const | 305 | QPoint XdgShellClient::clientContentPos() const | ||
305 | { | 306 | { | ||
306 | return -1 * clientPos(); | 307 | return -1 * clientPos(); | ||
307 | } | 308 | } | ||
308 | 309 | | |||
309 | QSize XdgShellClient::clientSize() const | 310 | QSize XdgShellClient::clientSize() const | ||
310 | { | 311 | { | ||
311 | return m_clientSize; | 312 | return m_windowGeometry.size(); | ||
312 | } | 313 | } | ||
313 | 314 | | |||
314 | void XdgShellClient::debug(QDebug &stream) const | 315 | void XdgShellClient::debug(QDebug &stream) const | ||
315 | { | 316 | { | ||
316 | stream.nospace(); | 317 | stream.nospace(); | ||
317 | stream << "\'XdgShellClient:" << surface() << ";WMCLASS:" << resourceClass() << ":" | 318 | stream << "\'XdgShellClient:" << surface() << ";WMCLASS:" << resourceClass() << ":" | ||
318 | << resourceName() << ";Caption:" << caption() << "\'"; | 319 | << resourceName() << ";Caption:" << caption() << "\'"; | ||
319 | } | 320 | } | ||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Line(s) | 422 | if (!isShade()) { | |||
422 | checkWorkspacePosition(oldGeometry); | 423 | checkWorkspacePosition(oldGeometry); | ||
423 | } | 424 | } | ||
424 | emit geometryShapeChanged(this, oldGeometry); | 425 | emit geometryShapeChanged(this, oldGeometry); | ||
425 | } | 426 | } | ||
426 | ); | 427 | ); | ||
427 | } | 428 | } | ||
428 | setDecoration(decoration); | 429 | setDecoration(decoration); | ||
429 | // TODO: ensure the new geometry still fits into the client area (e.g. maximized windows) | 430 | // TODO: ensure the new geometry still fits into the client area (e.g. maximized windows) | ||
430 | doSetGeometry(QRect(oldGeom.topLeft(), m_clientSize + (decoration ? QSize(decoration->borderLeft() + decoration->borderRight(), | 431 | doSetGeometry(QRect(oldGeom.topLeft(), m_windowGeometry.size() + QSize(borderLeft() + borderRight(), borderBottom() + borderTop()))); | ||
431 | decoration->borderBottom() + decoration->borderTop()) : QSize()))); | | |||
432 | 432 | | |||
433 | emit geometryShapeChanged(this, oldGeom); | 433 | emit geometryShapeChanged(this, oldGeom); | ||
434 | } | 434 | } | ||
435 | 435 | | |||
436 | void XdgShellClient::updateDecoration(bool check_workspace_pos, bool force) | 436 | void XdgShellClient::updateDecoration(bool check_workspace_pos, bool force) | ||
437 | { | 437 | { | ||
438 | if (!force && | 438 | if (!force && | ||
439 | ((!isDecorated() && noBorder()) || (isDecorated() && !noBorder()))) | 439 | ((!isDecorated() && noBorder()) || (isDecorated() && !noBorder()))) | ||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | 467 | { | |||
482 | } | 482 | } | ||
483 | 483 | | |||
484 | if (pendingGeometryUpdate() != PendingGeometryNone) { | 484 | if (pendingGeometryUpdate() != PendingGeometryNone) { | ||
485 | // reset geometry to the one before blocking, so that we can compare properly | 485 | // reset geometry to the one before blocking, so that we can compare properly | ||
486 | geom = geometryBeforeUpdateBlocking(); | 486 | geom = geometryBeforeUpdateBlocking(); | ||
487 | } | 487 | } | ||
488 | 488 | | |||
489 | const QSize requestedClientSize = newGeometry.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | 489 | const QSize requestedClientSize = newGeometry.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | ||
490 | const QSize requestedWindowGeometrySize = toWindowGeometry(newGeometry.size()); | | |||
491 | 490 | | |||
492 | if (requestedClientSize == m_clientSize && | 491 | if (requestedClientSize == m_windowGeometry.size() && | ||
493 | (m_requestedClientSize.isEmpty() || requestedWindowGeometrySize == m_requestedClientSize)) { | 492 | (m_requestedClientSize.isEmpty() || requestedClientSize == m_requestedClientSize)) { | ||
494 | // size didn't change, and we don't need to explicitly request a new size | 493 | // size didn't change, and we don't need to explicitly request a new size | ||
495 | doSetGeometry(newGeometry); | 494 | doSetGeometry(newGeometry); | ||
496 | updateMaximizeMode(m_requestedMaximizeMode); | 495 | updateMaximizeMode(m_requestedMaximizeMode); | ||
497 | } else { | 496 | } else { | ||
498 | // size did change, Client needs to provide a new buffer | 497 | // size did change, Client needs to provide a new buffer | ||
499 | requestGeometry(newGeometry); | 498 | requestGeometry(newGeometry); | ||
500 | } | 499 | } | ||
501 | } | 500 | } | ||
502 | 501 | | |||
502 | QRect XdgShellClient::determineBufferGeometry() const | ||||
503 | { | ||||
504 | // Offset of the main surface relative to the frame rect. | ||||
505 | const int offsetX = borderLeft() - m_windowGeometry.left(); | ||||
506 | const int offsetY = borderTop() - m_windowGeometry.top(); | ||||
507 | | ||||
508 | QRect bufferGeometry; | ||||
509 | bufferGeometry.setX(x() + offsetX); | ||||
510 | bufferGeometry.setY(y() + offsetY); | ||||
511 | bufferGeometry.setSize(surface()->size()); | ||||
512 | | ||||
513 | return bufferGeometry; | ||||
514 | } | ||||
515 | | ||||
503 | void XdgShellClient::doSetGeometry(const QRect &rect) | 516 | void XdgShellClient::doSetGeometry(const QRect &rect) | ||
504 | { | 517 | { | ||
505 | if (geom == rect && pendingGeometryUpdate() == PendingGeometryNone) { | 518 | bool frameGeometryIsChanged = false; | ||
506 | return; | 519 | bool bufferGeometryIsChanged = false; | ||
520 | | ||||
521 | if (geom != rect) { | ||||
522 | geom = rect; | ||||
523 | frameGeometryIsChanged = true; | ||||
507 | } | 524 | } | ||
508 | if (!m_unmapped) { | 525 | | ||
509 | addWorkspaceRepaint(visibleRect()); | 526 | const QRect bufferGeometry = determineBufferGeometry(); | ||
527 | if (m_bufferGeometry != bufferGeometry) { | ||||
528 | m_bufferGeometry = bufferGeometry; | ||||
529 | bufferGeometryIsChanged = true; | ||||
510 | } | 530 | } | ||
511 | 531 | | |||
512 | geom = rect; | 532 | if (!frameGeometryIsChanged && !bufferGeometryIsChanged) { | ||
513 | updateWindowRules(Rules::Position | Rules::Size); | 533 | return; | ||
534 | } | ||||
514 | 535 | | |||
515 | if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) { | 536 | if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) { | ||
516 | // use first valid geometry as restore geometry | 537 | // use first valid geometry as restore geometry | ||
517 | m_geomMaximizeRestore = geom; | 538 | m_geomMaximizeRestore = geom; | ||
518 | } | 539 | } | ||
519 | 540 | | |||
520 | if (!m_unmapped) { | 541 | if (frameGeometryIsChanged) { | ||
521 | addWorkspaceRepaint(visibleRect()); | | |||
522 | } | | |||
523 | if (hasStrut()) { | 542 | if (hasStrut()) { | ||
524 | workspace()->updateClientArea(); | 543 | workspace()->updateClientArea(); | ||
525 | } | 544 | } | ||
545 | updateWindowRules(Rules::Position | Rules::Size); | ||||
546 | } | ||||
547 | | ||||
526 | const auto old = geometryBeforeUpdateBlocking(); | 548 | const auto old = geometryBeforeUpdateBlocking(); | ||
549 | addRepaintDuringGeometryUpdates(); | ||||
davidedmundson: the
if (!m_unampped) has gone
Arguably it's a non issue as we'll just trigger a repaint that… | |||||
527 | updateGeometryBeforeUpdateBlocking(); | 550 | updateGeometryBeforeUpdateBlocking(); | ||
528 | emit geometryShapeChanged(this, old); | 551 | emit geometryShapeChanged(this, old); | ||
529 | 552 | | |||
530 | if (isResize()) { | 553 | if (isResize()) { | ||
531 | performMoveResize(); | 554 | performMoveResize(); | ||
532 | } | 555 | } | ||
533 | } | 556 | } | ||
534 | 557 | | |||
558 | void XdgShellClient::doMove(int x, int y) | ||||
559 | { | ||||
560 | Q_UNUSED(x) | ||||
561 | Q_UNUSED(y) | ||||
562 | m_bufferGeometry = determineBufferGeometry(); | ||||
563 | } | ||||
564 | | ||||
535 | QByteArray XdgShellClient::windowRole() const | 565 | QByteArray XdgShellClient::windowRole() const | ||
536 | { | 566 | { | ||
537 | return QByteArray(); | 567 | return QByteArray(); | ||
538 | } | 568 | } | ||
539 | 569 | | |||
540 | bool XdgShellClient::belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const | 570 | bool XdgShellClient::belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const | ||
541 | { | 571 | { | ||
542 | if (checks.testFlag(SameApplicationCheck::AllowCrossProcesses)) { | 572 | if (checks.testFlag(SameApplicationCheck::AllowCrossProcesses)) { | ||
▲ Show 20 Lines • Show All 470 Lines • ▼ Show 20 Line(s) | |||||
1013 | { | 1043 | { | ||
1014 | if (m_requestGeometryBlockCounter != 0) { | 1044 | if (m_requestGeometryBlockCounter != 0) { | ||
1015 | m_blockedRequestGeometry = rect; | 1045 | m_blockedRequestGeometry = rect; | ||
1016 | return; | 1046 | return; | ||
1017 | } | 1047 | } | ||
1018 | 1048 | | |||
1019 | QSize size; | 1049 | QSize size; | ||
1020 | if (rect.isValid()) { | 1050 | if (rect.isValid()) { | ||
1021 | size = toWindowGeometry(rect.size()); | 1051 | size = rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | ||
1022 | } else { | 1052 | } else { | ||
1023 | size = QSize(0, 0); | 1053 | size = QSize(0, 0); | ||
1024 | } | 1054 | } | ||
1025 | m_requestedClientSize = size; | 1055 | m_requestedClientSize = size; | ||
1026 | 1056 | | |||
1027 | quint64 serialId = 0; | 1057 | quint64 serialId = 0; | ||
1028 | 1058 | | |||
1029 | if (m_xdgShellSurface) { | 1059 | if (m_xdgShellSurface) { | ||
Show All 35 Lines | 1091 | if (it->serialId == m_lastAckedConfigureRequest) { | |||
1065 | position = it->positionAfterResize; | 1095 | position = it->positionAfterResize; | ||
1066 | maximizeMode = it->maximizeMode; | 1096 | maximizeMode = it->maximizeMode; | ||
1067 | 1097 | | |||
1068 | m_pendingConfigureRequests.erase(m_pendingConfigureRequests.begin(), ++it); | 1098 | m_pendingConfigureRequests.erase(m_pendingConfigureRequests.begin(), ++it); | ||
1069 | break; | 1099 | break; | ||
1070 | } | 1100 | } | ||
1071 | //else serialId < m_lastAckedConfigureRequest and the state is now irrelevant and can be ignored | 1101 | //else serialId < m_lastAckedConfigureRequest and the state is now irrelevant and can be ignored | ||
1072 | } | 1102 | } | ||
1073 | doSetGeometry(QRect(position, m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | 1103 | doSetGeometry(QRect(position, m_windowGeometry.size() + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | ||
1074 | updateMaximizeMode(maximizeMode); | 1104 | updateMaximizeMode(maximizeMode); | ||
1075 | } | 1105 | } | ||
1076 | 1106 | | |||
1077 | void XdgShellClient::handleConfigureAcknowledged(quint32 serial) | 1107 | void XdgShellClient::handleConfigureAcknowledged(quint32 serial) | ||
1078 | { | 1108 | { | ||
1079 | m_lastAckedConfigureRequest = serial; | 1109 | m_lastAckedConfigureRequest = serial; | ||
1080 | } | 1110 | } | ||
1081 | 1111 | | |||
Show All 30 Lines | 1141 | { | |||
1112 | setResourceClass(resourceName(), windowClass); | 1142 | setResourceClass(resourceName(), windowClass); | ||
1113 | if (m_isInitialized && supportsWindowRules()) { | 1143 | if (m_isInitialized && supportsWindowRules()) { | ||
1114 | setupWindowRules(true); | 1144 | setupWindowRules(true); | ||
1115 | applyWindowRules(); | 1145 | applyWindowRules(); | ||
1116 | } | 1146 | } | ||
1117 | setDesktopFileName(windowClass); | 1147 | setDesktopFileName(windowClass); | ||
1118 | } | 1148 | } | ||
1119 | 1149 | | |||
1150 | static QRect subSurfaceTreeRect(const SurfaceInterface *surface, const QPoint &position = QPoint()) | ||||
1151 | { | ||||
1152 | QRect rect(position, surface->size()); | ||||
1153 | | ||||
1154 | const QList<QPointer<SubSurfaceInterface>> subSurfaces = surface->childSubSurfaces(); | ||||
1155 | for (const QPointer<SubSurfaceInterface> &subSurface : subSurfaces) { | ||||
1156 | if (Q_UNLIKELY(!subSurface)) { | ||||
1157 | continue; | ||||
1158 | } | ||||
1159 | const SurfaceInterface *child = subSurface->surface(); | ||||
1160 | if (Q_UNLIKELY(!child)) { | ||||
1161 | continue; | ||||
1162 | } | ||||
1163 | rect |= subSurfaceTreeRect(child, position + subSurface->position()); | ||||
1164 | } | ||||
1165 | | ||||
1166 | return rect; | ||||
1167 | } | ||||
1168 | | ||||
1169 | void XdgShellClient::handleWindowGeometryChanged(const QRect &windowGeometry) | ||||
1170 | { | ||||
1171 | const QRect boundingRect = subSurfaceTreeRect(surface()); | ||||
1172 | m_windowGeometry = windowGeometry & boundingRect; | ||||
1173 | m_hasWindowGeometry = true; | ||||
1174 | } | ||||
1175 | | ||||
1120 | void XdgShellClient::handleWindowTitleChanged(const QString &title) | 1176 | void XdgShellClient::handleWindowTitleChanged(const QString &title) | ||
1121 | { | 1177 | { | ||
1122 | const QString oldSuffix = m_captionSuffix; | 1178 | const QString oldSuffix = m_captionSuffix; | ||
1123 | m_caption = title.simplified(); | 1179 | m_caption = title.simplified(); | ||
1124 | updateCaption(); | 1180 | updateCaption(); | ||
1125 | if (m_captionSuffix == oldSuffix) { | 1181 | if (m_captionSuffix == oldSuffix) { | ||
1126 | // Don't emit caption change twice it already got emitted by the changing suffix. | 1182 | // Don't emit caption change twice it already got emitted by the changing suffix. | ||
1127 | emit captionChanged(); | 1183 | emit captionChanged(); | ||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Line(s) | |||||
1247 | } | 1303 | } | ||
1248 | 1304 | | |||
1249 | void XdgShellClient::handleCommitted() | 1305 | void XdgShellClient::handleCommitted() | ||
1250 | { | 1306 | { | ||
1251 | if (!surface()->buffer()) { | 1307 | if (!surface()->buffer()) { | ||
1252 | return; | 1308 | return; | ||
1253 | } | 1309 | } | ||
1254 | 1310 | | |||
1255 | m_clientSize = surface()->size(); | 1311 | if (!m_hasWindowGeometry) { | ||
1312 | m_windowGeometry = subSurfaceTreeRect(surface()); | ||||
1313 | } | ||||
1256 | 1314 | | |||
1257 | updateWindowMargins(); | | |||
1258 | updatePendingGeometry(); | 1315 | updatePendingGeometry(); | ||
1259 | 1316 | | |||
1260 | setDepth((surface()->buffer()->hasAlphaChannel() && !isDesktop()) ? 32 : 24); | 1317 | setDepth((surface()->buffer()->hasAlphaChannel() && !isDesktop()) ? 32 : 24); | ||
1261 | markAsMapped(); | 1318 | markAsMapped(); | ||
1262 | } | 1319 | } | ||
1263 | 1320 | | |||
1264 | void XdgShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) | 1321 | void XdgShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) | ||
1265 | { | 1322 | { | ||
Show All 22 Lines | 1335 | { | |||
1288 | } | 1345 | } | ||
1289 | emit windowHidden(this); | 1346 | emit windowHidden(this); | ||
1290 | } | 1347 | } | ||
1291 | 1348 | | |||
1292 | void XdgShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface) | 1349 | void XdgShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface) | ||
1293 | { | 1350 | { | ||
1294 | m_plasmaShellSurface = surface; | 1351 | m_plasmaShellSurface = surface; | ||
1295 | auto updatePosition = [this, surface] { | 1352 | auto updatePosition = [this, surface] { | ||
1296 | QRect rect = QRect(surface->position(), m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom())); | 1353 | // That's a mis-use of doSetGeometry method. One should instead use move method. | ||
1354 | QRect rect = QRect(surface->position(), size()); | ||||
1297 | doSetGeometry(rect); | 1355 | doSetGeometry(rect); | ||
1298 | }; | 1356 | }; | ||
1299 | auto updateRole = [this, surface] { | 1357 | auto updateRole = [this, surface] { | ||
1300 | NET::WindowType type = NET::Unknown; | 1358 | NET::WindowType type = NET::Unknown; | ||
1301 | switch (surface->role()) { | 1359 | switch (surface->role()) { | ||
1302 | case PlasmaShellSurfaceInterface::Role::Desktop: | 1360 | case PlasmaShellSurfaceInterface::Role::Desktop: | ||
1303 | type = NET::Desktop; | 1361 | type = NET::Desktop; | ||
1304 | break; | 1362 | break; | ||
▲ Show 20 Lines • Show All 582 Lines • ▼ Show 20 Line(s) | 1944 | for (OutputInterface* output: qAsConst(outputs)) { | |||
1887 | const QRect outputGeom(output->globalPosition(), output->pixelSize() / output->scale()); | 1945 | const QRect outputGeom(output->globalPosition(), output->pixelSize() / output->scale()); | ||
1888 | if (frameGeometry().intersects(outputGeom)) { | 1946 | if (frameGeometry().intersects(outputGeom)) { | ||
1889 | clientOutputs << output; | 1947 | clientOutputs << output; | ||
1890 | } | 1948 | } | ||
1891 | } | 1949 | } | ||
1892 | surface()->setOutputs(clientOutputs); | 1950 | surface()->setOutputs(clientOutputs); | ||
1893 | } | 1951 | } | ||
1894 | 1952 | | |||
1895 | void XdgShellClient::updateWindowMargins() | | |||
1896 | { | | |||
1897 | QRect windowGeometry; | | |||
1898 | QSize clientSize = m_clientSize; | | |||
1899 | | ||||
1900 | if (m_xdgShellSurface) { | | |||
1901 | windowGeometry = m_xdgShellSurface->windowGeometry(); | | |||
1902 | } else { | | |||
1903 | windowGeometry = m_xdgShellPopup->windowGeometry(); | | |||
1904 | if (!clientSize.isValid()) { | | |||
1905 | clientSize = m_xdgShellPopup->initialSize(); | | |||
1906 | } | | |||
1907 | } | | |||
1908 | | ||||
1909 | if (windowGeometry.isEmpty() || | | |||
1910 | windowGeometry.width() > clientSize.width() || | | |||
1911 | windowGeometry.height() > clientSize.height()) { | | |||
1912 | m_windowMargins = QMargins(); | | |||
1913 | } else { | | |||
1914 | m_windowMargins = QMargins(windowGeometry.left(), | | |||
1915 | windowGeometry.top(), | | |||
1916 | clientSize.width() - (windowGeometry.right() + 1), | | |||
1917 | clientSize.height() - (windowGeometry.bottom() + 1)); | | |||
1918 | } | | |||
1919 | } | | |||
1920 | | ||||
1921 | bool XdgShellClient::isPopupWindow() const | 1953 | bool XdgShellClient::isPopupWindow() const | ||
1922 | { | 1954 | { | ||
1923 | if (Toplevel::isPopupWindow()) { | 1955 | if (Toplevel::isPopupWindow()) { | ||
1924 | return true; | 1956 | return true; | ||
1925 | } | 1957 | } | ||
1926 | if (m_xdgShellPopup != nullptr) { | 1958 | if (m_xdgShellPopup != nullptr) { | ||
1927 | return true; | 1959 | return true; | ||
1928 | } | 1960 | } | ||
Show All 12 Lines |
the
if (!m_unampped) has gone
Arguably it's a non issue as we'll just trigger a repaint that will in turn not do anything, but I'm wondering if it was there deliberately.