Changeset View
Changeset View
Standalone View
Standalone View
shell_client.cpp
1 | /******************************************************************** | 1 | /******************************************************************** | ||
---|---|---|---|---|---|
2 | KWin - the KDE window manager | 2 | KWin - the KDE window manager | ||
3 | This file is part of the KDE project. | 3 | This file is part of the KDE project. | ||
4 | 4 | | |||
5 | Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org> | 5 | Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org> | ||
6 | Copyright (C) 2018 David Edmundson <davidedmundson@kde.org> | ||||
6 | 7 | | |||
7 | This program is free software; you can redistribute it and/or modify | 8 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | 9 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | 10 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | 11 | (at your option) any later version. | ||
11 | 12 | | |||
12 | This program is distributed in the hope that it will be useful, | 13 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
▲ Show 20 Lines • Show All 587 Lines • ▼ Show 20 Line(s) | 589 | { | |||
601 | if (pendingGeometryUpdate() != PendingGeometryNone) { | 602 | if (pendingGeometryUpdate() != PendingGeometryNone) { | ||
602 | // reset geometry to the one before blocking, so that we can compare properly | 603 | // reset geometry to the one before blocking, so that we can compare properly | ||
603 | geom = geometryBeforeUpdateBlocking(); | 604 | geom = geometryBeforeUpdateBlocking(); | ||
604 | } | 605 | } | ||
605 | // TODO: better merge with Client's implementation | 606 | // TODO: better merge with Client's implementation | ||
606 | if (QSize(w, h) == geom.size() && !isWaitingForMoveResizeSync()) { | 607 | if (QSize(w, h) == geom.size() && !isWaitingForMoveResizeSync()) { | ||
607 | // size didn't change, update directly | 608 | // size didn't change, update directly | ||
608 | doSetGeometry(QRect(x, y, w, h)); | 609 | doSetGeometry(QRect(x, y, w, h)); | ||
610 | updateMaximizeMode(m_requestedMaximizeMode); | ||||
609 | } else { | 611 | } else { | ||
610 | // size did change, Client needs to provide a new buffer | 612 | // size did change, Client needs to provide a new buffer | ||
611 | requestGeometry(QRect(x, y, w, h)); | 613 | requestGeometry(QRect(x, y, w, h)); | ||
612 | } | 614 | } | ||
613 | } | 615 | } | ||
614 | 616 | | |||
615 | void ShellClient::doSetGeometry(const QRect &rect) | 617 | void ShellClient::doSetGeometry(const QRect &rect) | ||
616 | { | 618 | { | ||
▲ Show 20 Lines • Show All 204 Lines • ▼ Show 20 Line(s) | 818 | { | |||
821 | if (!isResizable()) { | 823 | if (!isResizable()) { | ||
822 | return; | 824 | return; | ||
823 | } | 825 | } | ||
824 | 826 | | |||
825 | const QRect clientArea = isElectricBorderMaximizing() ? | 827 | const QRect clientArea = isElectricBorderMaximizing() ? | ||
826 | workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : | 828 | workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : | ||
827 | workspace()->clientArea(MaximizeArea, this); | 829 | workspace()->clientArea(MaximizeArea, this); | ||
828 | 830 | | |||
829 | MaximizeMode oldMode = m_maximizeMode; | 831 | MaximizeMode oldMode = m_requestedMaximizeMode; | ||
830 | StackingUpdatesBlocker blocker(workspace()); | 832 | StackingUpdatesBlocker blocker(workspace()); | ||
831 | RequestGeometryBlocker geometryBlocker(this); | 833 | RequestGeometryBlocker geometryBlocker(this); | ||
832 | // 'adjust == true' means to update the size only, e.g. after changing workspace size | 834 | // 'adjust == true' means to update the size only, e.g. after changing workspace size | ||
833 | if (!adjust) { | 835 | if (!adjust) { | ||
834 | if (vertical) | 836 | if (vertical) | ||
romangg: Improve coding style when you are at it. | |||||
835 | m_maximizeMode = MaximizeMode(m_maximizeMode ^ MaximizeVertical); | 837 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeVertical); | ||
836 | if (horizontal) | 838 | if (horizontal) | ||
837 | m_maximizeMode = MaximizeMode(m_maximizeMode ^ MaximizeHorizontal); | 839 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeHorizontal); | ||
838 | } | 840 | } | ||
839 | // TODO: add more checks as in Client | 841 | // TODO: add more checks as in Client | ||
840 | 842 | | |||
841 | // call into decoration update borders | 843 | // call into decoration update borders | ||
842 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && m_maximizeMode == KWin::MaximizeFull)) { | 844 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && m_requestedMaximizeMode == KWin::MaximizeFull)) { | ||
843 | changeMaximizeRecursion = true; | 845 | changeMaximizeRecursion = true; | ||
844 | const auto c = decoration()->client().data(); | 846 | const auto c = decoration()->client().data(); | ||
845 | if ((m_maximizeMode & MaximizeVertical) != (oldMode & MaximizeVertical)) { | 847 | if ((m_requestedMaximizeMode & MaximizeVertical) != (oldMode & MaximizeVertical)) { | ||
846 | emit c->maximizedVerticallyChanged(m_maximizeMode & MaximizeVertical); | 848 | emit c->maximizedVerticallyChanged(m_requestedMaximizeMode & MaximizeVertical); | ||
847 | } | 849 | } | ||
848 | if ((m_maximizeMode & MaximizeHorizontal) != (oldMode & MaximizeHorizontal)) { | 850 | if ((m_requestedMaximizeMode & MaximizeHorizontal) != (oldMode & MaximizeHorizontal)) { | ||
849 | emit c->maximizedHorizontallyChanged(m_maximizeMode & MaximizeHorizontal); | 851 | emit c->maximizedHorizontallyChanged(m_requestedMaximizeMode & MaximizeHorizontal); | ||
850 | } | 852 | } | ||
851 | if ((m_maximizeMode == MaximizeFull) != (oldMode == MaximizeFull)) { | 853 | if ((m_requestedMaximizeMode == MaximizeFull) != (oldMode == MaximizeFull)) { | ||
852 | emit c->maximizedChanged(m_maximizeMode & MaximizeFull); | 854 | emit c->maximizedChanged(m_requestedMaximizeMode & MaximizeFull); | ||
853 | } | 855 | } | ||
854 | changeMaximizeRecursion = false; | 856 | changeMaximizeRecursion = false; | ||
855 | } | 857 | } | ||
856 | 858 | | |||
857 | if (options->borderlessMaximizedWindows()) { | 859 | if (options->borderlessMaximizedWindows()) { | ||
858 | // triggers a maximize change. | 860 | // triggers a maximize change. | ||
859 | // The next setNoBorder interation will exit since there's no change but the first recursion pullutes the restore geometry | 861 | // The next setNoBorder interation will exit since there's no change but the first recursion pullutes the restore geometry | ||
860 | changeMaximizeRecursion = true; | 862 | changeMaximizeRecursion = true; | ||
861 | setNoBorder(rules()->checkNoBorder(m_maximizeMode == MaximizeFull)); | 863 | setNoBorder(rules()->checkNoBorder(m_requestedMaximizeMode == MaximizeFull)); | ||
862 | changeMaximizeRecursion = false; | 864 | changeMaximizeRecursion = false; | ||
863 | } | 865 | } | ||
864 | 866 | | |||
865 | // Conditional quick tiling exit points | 867 | // Conditional quick tiling exit points | ||
866 | const auto oldQuickTileMode = quickTileMode(); | 868 | const auto oldQuickTileMode = quickTileMode(); | ||
867 | if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) { | 869 | if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) { | ||
868 | if (oldMode == MaximizeFull && | 870 | if (oldMode == MaximizeFull && | ||
869 | !clientArea.contains(m_geomMaximizeRestore.center())) { | 871 | !clientArea.contains(m_geomMaximizeRestore.center())) { | ||
870 | // Not restoring on the same screen | 872 | // Not restoring on the same screen | ||
871 | // TODO: The following doesn't work for some reason | 873 | // TODO: The following doesn't work for some reason | ||
872 | //quick_tile_mode = QuickTileNone; // And exit quick tile mode manually | 874 | //quick_tile_mode = QuickTileNone; // And exit quick tile mode manually | ||
873 | } else if ((oldMode == MaximizeVertical && m_maximizeMode == MaximizeRestore) || | 875 | } else if ((oldMode == MaximizeVertical && m_requestedMaximizeMode == MaximizeRestore) || | ||
874 | (oldMode == MaximizeFull && m_maximizeMode == MaximizeHorizontal)) { | 876 | (oldMode == MaximizeFull && m_requestedMaximizeMode == MaximizeHorizontal)) { | ||
875 | // Modifying geometry of a tiled window | 877 | // Modifying geometry of a tiled window | ||
876 | updateQuickTileMode(QuickTileFlag::None); // Exit quick tile mode without restoring geometry | 878 | updateQuickTileMode(QuickTileFlag::None); // Exit quick tile mode without restoring geometry | ||
877 | } | 879 | } | ||
878 | } | 880 | } | ||
879 | 881 | | |||
880 | // TODO: check rules | 882 | // TODO: check rules | ||
881 | if (m_maximizeMode == MaximizeFull) { | 883 | if (m_requestedMaximizeMode == MaximizeFull) { | ||
882 | m_geomMaximizeRestore = geometry(); | 884 | m_geomMaximizeRestore = geometry(); | ||
883 | // TODO: Client has more checks | 885 | // TODO: Client has more checks | ||
884 | if (options->electricBorderMaximize()) { | 886 | if (options->electricBorderMaximize()) { | ||
885 | updateQuickTileMode(QuickTileFlag::Maximize); | 887 | updateQuickTileMode(QuickTileFlag::Maximize); | ||
886 | } else { | 888 | } else { | ||
887 | updateQuickTileMode(QuickTileFlag::None); | 889 | updateQuickTileMode(QuickTileFlag::None); | ||
888 | } | 890 | } | ||
889 | if (quickTileMode() != oldQuickTileMode) { | 891 | if (quickTileMode() != oldQuickTileMode) { | ||
890 | emit quickTileModeChanged(); | 892 | emit quickTileModeChanged(); | ||
891 | } | 893 | } | ||
892 | setGeometry(workspace()->clientArea(MaximizeArea, this)); | 894 | setGeometry(workspace()->clientArea(MaximizeArea, this)); | ||
893 | workspace()->raiseClient(this); | 895 | workspace()->raiseClient(this); | ||
894 | } else { | 896 | } else { | ||
895 | if (m_maximizeMode == MaximizeRestore) { | 897 | if (m_requestedMaximizeMode == MaximizeRestore) { | ||
896 | updateQuickTileMode(QuickTileFlag::None); | 898 | updateQuickTileMode(QuickTileFlag::None); | ||
897 | } | 899 | } | ||
898 | if (quickTileMode() != oldQuickTileMode) { | 900 | if (quickTileMode() != oldQuickTileMode) { | ||
899 | emit quickTileModeChanged(); | 901 | emit quickTileModeChanged(); | ||
900 | } | 902 | } | ||
901 | 903 | | |||
902 | if (m_geomMaximizeRestore.isValid()) { | 904 | if (m_geomMaximizeRestore.isValid()) { | ||
903 | setGeometry(m_geomMaximizeRestore); | 905 | setGeometry(m_geomMaximizeRestore); | ||
▲ Show 20 Lines • Show All 265 Lines • ▼ Show 20 Line(s) | |||||
1169 | void ShellClient::requestGeometry(const QRect &rect) | 1171 | void ShellClient::requestGeometry(const QRect &rect) | ||
1170 | { | 1172 | { | ||
1171 | if (m_requestGeometryBlockCounter != 0) { | 1173 | if (m_requestGeometryBlockCounter != 0) { | ||
1172 | m_blockedRequestGeometry = rect; | 1174 | m_blockedRequestGeometry = rect; | ||
1173 | return; | 1175 | return; | ||
1174 | } | 1176 | } | ||
1175 | PendingConfigureRequest configureRequest; | 1177 | PendingConfigureRequest configureRequest; | ||
1176 | configureRequest.positionAfterResize = rect.topLeft(); | 1178 | configureRequest.positionAfterResize = rect.topLeft(); | ||
1179 | configureRequest.maximizeMode = m_requestedMaximizeMode; | ||||
1177 | 1180 | | |||
1178 | const QSize size = rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | 1181 | const QSize size = rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | ||
1179 | if (m_shellSurface) { | 1182 | if (m_shellSurface) { | ||
1180 | m_shellSurface->requestSize(size); | 1183 | m_shellSurface->requestSize(size); | ||
1181 | } | 1184 | } | ||
1182 | if (m_xdgShellSurface) { | 1185 | if (m_xdgShellSurface) { | ||
1183 | configureRequest.serialId = m_xdgShellSurface->configure(xdgSurfaceStates(), size); | 1186 | configureRequest.serialId = m_xdgShellSurface->configure(xdgSurfaceStates(), size); | ||
1184 | } | 1187 | } | ||
Show All 12 Lines | |||||
1197 | if (m_internal) { | 1200 | if (m_internal) { | ||
1198 | m_internalWindow->setGeometry(QRect(rect.topLeft() + QPoint(borderLeft(), borderTop()), rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | 1201 | m_internalWindow->setGeometry(QRect(rect.topLeft() + QPoint(borderLeft(), borderTop()), rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | ||
1199 | } | 1202 | } | ||
1200 | } | 1203 | } | ||
1201 | 1204 | | |||
1202 | void ShellClient::updatePendingGeometry() | 1205 | void ShellClient::updatePendingGeometry() | ||
1203 | { | 1206 | { | ||
1204 | QPoint position = geom.topLeft(); | 1207 | QPoint position = geom.topLeft(); | ||
1208 | MaximizeMode maximizeMode = m_maximizeMode; | ||||
1209 | | ||||
1205 | const QPoint oldPosition = position; | 1210 | const QPoint oldPosition = position; | ||
1211 | | ||||
1206 | while (! m_pendingConfigureRequests.isEmpty()) { | 1212 | while (! m_pendingConfigureRequests.isEmpty()) { | ||
1207 | if (m_pendingConfigureRequests.first().serialId > m_lastAckedConfigureRequest) { | 1213 | if (m_pendingConfigureRequests.first().serialId > m_lastAckedConfigureRequest) { | ||
1208 | break; | 1214 | break; | ||
1209 | } | 1215 | } | ||
1210 | auto configureRequest = m_pendingConfigureRequests.takeFirst(); | 1216 | auto configureRequest = m_pendingConfigureRequests.takeFirst(); | ||
1211 | position = configureRequest.positionAfterResize; | 1217 | position = configureRequest.positionAfterResize; | ||
1218 | maximizeMode = configureRequest.maximizeMode; | ||||
1212 | } | 1219 | } | ||
1213 | if (position != oldPosition) { | 1220 | if (position != oldPosition) { | ||
1214 | addLayerRepaint(geometry()); | 1221 | addLayerRepaint(geometry()); | ||
1215 | } | 1222 | } | ||
1216 | doSetGeometry(QRect(position, m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | 1223 | doSetGeometry(QRect(position, m_clientSize + QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); | ||
1224 | updateMaximizeMode(maximizeMode); | ||||
1217 | } | 1225 | } | ||
1218 | 1226 | | |||
1219 | void ShellClient::clientFullScreenChanged(bool fullScreen) | 1227 | void ShellClient::clientFullScreenChanged(bool fullScreen) | ||
1220 | { | 1228 | { | ||
1221 | setFullScreen(fullScreen, false); | 1229 | setFullScreen(fullScreen, false); | ||
1222 | } | 1230 | } | ||
1223 | 1231 | | |||
1224 | void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) | 1232 | void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) | ||
▲ Show 20 Lines • Show All 244 Lines • ▼ Show 20 Line(s) | |||||
1469 | { | 1477 | { | ||
1470 | if (m_paletteInterface) { | 1478 | if (m_paletteInterface) { | ||
1471 | AbstractClient::updateColorScheme(rules()->checkDecoColor(m_paletteInterface->palette())); | 1479 | AbstractClient::updateColorScheme(rules()->checkDecoColor(m_paletteInterface->palette())); | ||
1472 | } else { | 1480 | } else { | ||
1473 | AbstractClient::updateColorScheme(rules()->checkDecoColor(QString())); | 1481 | AbstractClient::updateColorScheme(rules()->checkDecoColor(QString())); | ||
1474 | } | 1482 | } | ||
1475 | } | 1483 | } | ||
1476 | 1484 | | |||
1485 | void ShellClient::updateMaximizeMode(MaximizeMode maximizeMode) | ||||
1486 | { | ||||
1487 | if (maximizeMode == m_maximizeMode) { | ||||
1488 | return; | ||||
1489 | } | ||||
1490 | | ||||
1491 | bool horizontalChanged = (maximizeMode & MaximizeHorizontal) != (m_maximizeMode & MaximizeHorizontal); | ||||
1492 | bool verticalChanged = (maximizeMode & MaximizeVertical) != (m_maximizeMode & MaximizeVertical); | ||||
1493 | m_maximizeMode = maximizeMode; | ||||
1494 | | ||||
1495 | emit clientMaximizedStateChanged(this, m_maximizeMode); | ||||
1496 | emit clientMaximizedStateChanged(this, horizontalChanged, verticalChanged); | ||||
1497 | } | ||||
1498 | | ||||
1477 | bool ShellClient::hasStrut() const | 1499 | bool ShellClient::hasStrut() const | ||
1478 | { | 1500 | { | ||
1479 | if (!isShown(true)) { | 1501 | if (!isShown(true)) { | ||
1480 | return false; | 1502 | return false; | ||
1481 | } | 1503 | } | ||
1482 | if (!m_plasmaShellSurface) { | 1504 | if (!m_plasmaShellSurface) { | ||
1483 | return false; | 1505 | return false; | ||
1484 | } | 1506 | } | ||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Line(s) | |||||
1621 | { | 1643 | { | ||
1622 | XdgShellSurfaceInterface::States states; | 1644 | XdgShellSurfaceInterface::States states; | ||
1623 | if (isActive()) { | 1645 | if (isActive()) { | ||
1624 | states |= XdgShellSurfaceInterface::State::Activated; | 1646 | states |= XdgShellSurfaceInterface::State::Activated; | ||
1625 | } | 1647 | } | ||
1626 | if (isFullScreen()) { | 1648 | if (isFullScreen()) { | ||
1627 | states |= XdgShellSurfaceInterface::State::Fullscreen; | 1649 | states |= XdgShellSurfaceInterface::State::Fullscreen; | ||
1628 | } | 1650 | } | ||
1629 | if (maximizeMode() == MaximizeMode::MaximizeFull) { | 1651 | if (m_requestedMaximizeMode == MaximizeMode::MaximizeFull) { | ||
1630 | states |= XdgShellSurfaceInterface::State::Maximized; | 1652 | states |= XdgShellSurfaceInterface::State::Maximized; | ||
1631 | } | 1653 | } | ||
1632 | if (isResize()) { | 1654 | if (isResize()) { | ||
1633 | states |= XdgShellSurfaceInterface::State::Resizing; | 1655 | states |= XdgShellSurfaceInterface::State::Resizing; | ||
1634 | } | 1656 | } | ||
1635 | return states; | 1657 | return states; | ||
1636 | } | 1658 | } | ||
1637 | 1659 | | |||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |
Improve coding style when you are at it.