Changeset View
Changeset View
Standalone View
Standalone View
abstract_client.cpp
Show All 22 Lines | |||||
23 | #include "decorations/decoratedclient.h" | 23 | #include "decorations/decoratedclient.h" | ||
24 | #include "decorations/decorationpalette.h" | 24 | #include "decorations/decorationpalette.h" | ||
25 | #include "decorations/decorationbridge.h" | 25 | #include "decorations/decorationbridge.h" | ||
26 | #include "cursor.h" | 26 | #include "cursor.h" | ||
27 | #include "effects.h" | 27 | #include "effects.h" | ||
28 | #include "focuschain.h" | 28 | #include "focuschain.h" | ||
29 | #include "outline.h" | 29 | #include "outline.h" | ||
30 | #include "screens.h" | 30 | #include "screens.h" | ||
31 | #ifdef KWIN_BUILD_TABBOX | 31 | #ifdef KWIN_BUILD_TABBOX | ||
32 | #include "tabbox.h" | 32 | #include "tabbox.h" | ||
33 | #endif | 33 | #endif | ||
zzag: Add it back. | |||||
gladhorn: Yes, together with it's use below... thanks :) | |||||
34 | #include "screenedge.h" | 34 | #include "screenedge.h" | ||
35 | #include "tabgroup.h" | | |||
36 | #include "useractions.h" | 35 | #include "useractions.h" | ||
37 | #include "workspace.h" | 36 | #include "workspace.h" | ||
38 | 37 | | |||
39 | #include "wayland_server.h" | 38 | #include "wayland_server.h" | ||
40 | #include <KWayland/Server/plasmawindowmanagement_interface.h> | 39 | #include <KWayland/Server/plasmawindowmanagement_interface.h> | ||
41 | 40 | | |||
42 | #include <KDecoration2/Decoration> | 41 | #include <KDecoration2/Decoration> | ||
43 | 42 | | |||
44 | #include <KDesktopFile> | 43 | #include <KDesktopFile> | ||
45 | 44 | | |||
46 | #include <QMouseEvent> | 45 | #include <QMouseEvent> | ||
47 | #include <QStyleHints> | 46 | #include <QStyleHints> | ||
48 | 47 | | |||
49 | namespace KWin | 48 | namespace KWin | ||
50 | { | 49 | { | ||
51 | 50 | | |||
52 | QHash<QString, std::weak_ptr<Decoration::DecorationPalette>> AbstractClient::s_palettes; | 51 | QHash<QString, std::weak_ptr<Decoration::DecorationPalette>> AbstractClient::s_palettes; | ||
53 | std::shared_ptr<Decoration::DecorationPalette> AbstractClient::s_defaultPalette; | 52 | std::shared_ptr<Decoration::DecorationPalette> AbstractClient::s_defaultPalette; | ||
54 | 53 | | |||
55 | AbstractClient::AbstractClient() | 54 | AbstractClient::AbstractClient() | ||
56 | : Toplevel() | 55 | : Toplevel() | ||
57 | #ifdef KWIN_BUILD_TABBOX | 56 | #ifdef KWIN_BUILD_TABBOX | ||
gladhorn: This comes back as well. | |||||
58 | , m_tabBoxClient(QSharedPointer<TabBox::TabBoxClientImpl>(new TabBox::TabBoxClientImpl(this))) | 57 | , m_tabBoxClient(QSharedPointer<TabBox::TabBoxClientImpl>(new TabBox::TabBoxClientImpl(this))) | ||
59 | #endif | 58 | #endif | ||
60 | , m_colorScheme(QStringLiteral("kdeglobals")) | 59 | , m_colorScheme(QStringLiteral("kdeglobals")) | ||
61 | { | 60 | { | ||
62 | connect(this, &AbstractClient::geometryShapeChanged, this, &AbstractClient::geometryChanged); | 61 | connect(this, &AbstractClient::geometryShapeChanged, this, &AbstractClient::geometryChanged); | ||
63 | auto signalMaximizeChanged = static_cast<void (AbstractClient::*)(KWin::AbstractClient*, MaximizeMode)>(&AbstractClient::clientMaximizedStateChanged); | 62 | auto signalMaximizeChanged = static_cast<void (AbstractClient::*)(KWin::AbstractClient*, MaximizeMode)>(&AbstractClient::clientMaximizedStateChanged); | ||
64 | connect(this, signalMaximizeChanged, this, &AbstractClient::geometryChanged); | 63 | connect(this, signalMaximizeChanged, this, &AbstractClient::geometryChanged); | ||
65 | connect(this, &AbstractClient::clientStepUserMovedResized, this, &AbstractClient::geometryChanged); | 64 | connect(this, &AbstractClient::clientStepUserMovedResized, this, &AbstractClient::geometryChanged); | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 118 | { | |||
120 | return c1->belongsToSameApplication(c2, checks); | 119 | return c1->belongsToSameApplication(c2, checks); | ||
121 | } | 120 | } | ||
122 | 121 | | |||
123 | bool AbstractClient::isTransient() const | 122 | bool AbstractClient::isTransient() const | ||
124 | { | 123 | { | ||
125 | return false; | 124 | return false; | ||
126 | } | 125 | } | ||
127 | 126 | | |||
128 | void AbstractClient::setTabGroup(TabGroup* group) | | |||
129 | { | | |||
130 | tab_group = group; | | |||
131 | emit tabGroupChanged(); | | |||
132 | } | | |||
133 | | ||||
134 | void AbstractClient::setClientShown(bool shown) | 127 | void AbstractClient::setClientShown(bool shown) | ||
135 | { | 128 | { | ||
136 | Q_UNUSED(shown) | 129 | Q_UNUSED(shown) | ||
137 | } | 130 | } | ||
138 | 131 | | |||
139 | bool AbstractClient::untab(const QRect &toGeometry, bool clientRemoved) | | |||
140 | { | | |||
141 | TabGroup *group = tab_group; | | |||
142 | if (group && group->remove(this)) { // remove sets the tabgroup to "0", therefore the pointer is cached | | |||
143 | if (group->isEmpty()) { | | |||
144 | delete group; | | |||
145 | } | | |||
146 | if (clientRemoved) | | |||
147 | return true; // there's been a broadcast signal that this client is now removed - don't touch it | | |||
148 | setClientShown(!(isMinimized() || isShade())); | | |||
149 | bool keepSize = toGeometry.size() == size(); | | |||
150 | bool changedSize = false; | | |||
151 | if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) { | | |||
152 | changedSize = true; | | |||
153 | setQuickTileMode(QuickTileFlag::None); // if we leave a quicktiled group, assume that the user wants to untile | | |||
154 | } | | |||
155 | if (toGeometry.isValid()) { | | |||
156 | if (maximizeMode() != MaximizeRestore) { | | |||
157 | changedSize = true; | | |||
158 | maximize(MaximizeRestore); // explicitly calling for a geometry -> unmaximize | | |||
159 | } | | |||
160 | if (keepSize && changedSize) { | | |||
161 | setGeometryRestore(geometry()); // checkWorkspacePosition() invokes it | | |||
162 | QPoint cpoint = Cursor::pos(); | | |||
163 | QPoint point = cpoint; | | |||
164 | point.setX((point.x() - toGeometry.x()) * geometryRestore().width() / toGeometry.width()); | | |||
165 | point.setY((point.y() - toGeometry.y()) * geometryRestore().height() / toGeometry.height()); | | |||
166 | auto geometry_restore = geometryRestore(); | | |||
167 | geometry_restore.moveTo(cpoint-point); | | |||
168 | setGeometryRestore(geometry_restore); | | |||
169 | } else { | | |||
170 | setGeometryRestore(toGeometry); // checkWorkspacePosition() invokes it | | |||
171 | } | | |||
172 | setGeometry(geometryRestore()); | | |||
173 | checkWorkspacePosition(); | | |||
174 | } | | |||
175 | return true; | | |||
176 | } | | |||
177 | return false; | | |||
178 | } | | |||
179 | | ||||
180 | bool AbstractClient::tabTo(AbstractClient *other, bool behind, bool activate) | | |||
181 | { | | |||
182 | Q_ASSERT(other && other != this); | | |||
183 | | ||||
184 | if (tab_group && tab_group == other->tabGroup()) { // special case: move inside group | | |||
185 | tab_group->move(this, other, behind); | | |||
186 | return true; | | |||
187 | } | | |||
188 | | ||||
189 | GeometryUpdatesBlocker blocker(this); | | |||
190 | const bool wasBlocking = signalsBlocked(); | | |||
191 | blockSignals(true); // prevent client emitting "retabbed to nowhere" cause it's about to be entabbed the next moment | | |||
192 | untab(); | | |||
193 | blockSignals(wasBlocking); | | |||
194 | | ||||
195 | TabGroup *newGroup = other->tabGroup() ? other->tabGroup() : new TabGroup(other); | | |||
196 | | ||||
197 | if (!newGroup->add(this, other, behind, activate)) { | | |||
198 | if (newGroup->count() < 2) { // adding "c" to "to" failed for whatever reason | | |||
199 | newGroup->remove(other); | | |||
200 | delete newGroup; | | |||
201 | } | | |||
202 | return false; | | |||
203 | } | | |||
204 | return true; | | |||
205 | } | | |||
206 | | ||||
207 | void AbstractClient::syncTabGroupFor(QString property, bool fromThisClient) | | |||
208 | { | | |||
209 | if (tab_group) | | |||
210 | tab_group->sync(property.toLatin1().data(), fromThisClient ? this : tab_group->current()); | | |||
211 | } | | |||
212 | | ||||
213 | bool AbstractClient::isCurrentTab() const | | |||
214 | { | | |||
215 | return !tab_group || tab_group->current() == this; | | |||
216 | } | | |||
217 | | ||||
218 | MaximizeMode AbstractClient::requestedMaximizeMode() const | 132 | MaximizeMode AbstractClient::requestedMaximizeMode() const | ||
219 | { | 133 | { | ||
220 | return maximizeMode(); | 134 | return maximizeMode(); | ||
221 | } | 135 | } | ||
222 | 136 | | |||
223 | xcb_timestamp_t AbstractClient::userTime() const | 137 | xcb_timestamp_t AbstractClient::userTime() const | ||
224 | { | 138 | { | ||
225 | return XCB_TIME_CURRENT_TIME; | 139 | return XCB_TIME_CURRENT_TIME; | ||
▲ Show 20 Lines • Show All 964 Lines • ▼ Show 20 Line(s) | 1008 | { | |||
1190 | case Options::MouseOpacityMore: | 1104 | case Options::MouseOpacityMore: | ||
1191 | if (!isDesktop()) // No point in changing the opacity of the desktop | 1105 | if (!isDesktop()) // No point in changing the opacity of the desktop | ||
1192 | setOpacity(qMin(opacity() + 0.1, 1.0)); | 1106 | setOpacity(qMin(opacity() + 0.1, 1.0)); | ||
1193 | break; | 1107 | break; | ||
1194 | case Options::MouseOpacityLess: | 1108 | case Options::MouseOpacityLess: | ||
1195 | if (!isDesktop()) // No point in changing the opacity of the desktop | 1109 | if (!isDesktop()) // No point in changing the opacity of the desktop | ||
1196 | setOpacity(qMax(opacity() - 0.1, 0.1)); | 1110 | setOpacity(qMax(opacity() - 0.1, 0.1)); | ||
1197 | break; | 1111 | break; | ||
1198 | case Options::MousePreviousTab: | | |||
1199 | if (tabGroup()) | | |||
1200 | tabGroup()->activatePrev(); | | |||
1201 | break; | | |||
1202 | case Options::MouseNextTab: | | |||
1203 | if (tabGroup()) | | |||
1204 | tabGroup()->activateNext(); | | |||
1205 | break; | | |||
1206 | case Options::MouseClose: | 1112 | case Options::MouseClose: | ||
1207 | closeWindow(); | 1113 | closeWindow(); | ||
1208 | break; | 1114 | break; | ||
1209 | case Options::MouseActivateRaiseAndMove: | 1115 | case Options::MouseActivateRaiseAndMove: | ||
1210 | case Options::MouseActivateRaiseAndUnrestrictedMove: | 1116 | case Options::MouseActivateRaiseAndUnrestrictedMove: | ||
1211 | workspace()->raiseClient(this); | 1117 | workspace()->raiseClient(this); | ||
1212 | workspace()->requestFocus(this); | 1118 | workspace()->requestFocus(this); | ||
1213 | screens()->setCurrent(globalPos); | 1119 | screens()->setCurrent(globalPos); | ||
Show All 39 Lines | 1139 | case Options::MouseUnrestrictedResize: { | |||
1253 | setMoveResizePointerMode(mode); | 1159 | setMoveResizePointerMode(mode); | ||
1254 | setInvertedMoveOffset(rect().bottomRight() - moveOffset); | 1160 | setInvertedMoveOffset(rect().bottomRight() - moveOffset); | ||
1255 | setUnrestrictedMoveResize((cmd == Options::MouseUnrestrictedResize)); | 1161 | setUnrestrictedMoveResize((cmd == Options::MouseUnrestrictedResize)); | ||
1256 | if (!startMoveResize()) | 1162 | if (!startMoveResize()) | ||
1257 | setMoveResizePointerButtonDown(false); | 1163 | setMoveResizePointerButtonDown(false); | ||
1258 | updateCursor(); | 1164 | updateCursor(); | ||
1259 | break; | 1165 | break; | ||
1260 | } | 1166 | } | ||
1261 | case Options::MouseDragTab: | | |||
1262 | case Options::MouseNothing: | 1167 | case Options::MouseNothing: | ||
1263 | default: | 1168 | default: | ||
1264 | replay = true; | 1169 | replay = true; | ||
1265 | break; | 1170 | break; | ||
1266 | } | 1171 | } | ||
1267 | return replay; | 1172 | return replay; | ||
1268 | } | 1173 | } | ||
1269 | 1174 | | |||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Line(s) | 1301 | { | |||
1400 | m_visibleRectBeforeGeometryUpdate = deco_rect; | 1305 | m_visibleRectBeforeGeometryUpdate = deco_rect; | ||
1401 | } | 1306 | } | ||
1402 | 1307 | | |||
1403 | void AbstractClient::updateGeometryBeforeUpdateBlocking() | 1308 | void AbstractClient::updateGeometryBeforeUpdateBlocking() | ||
1404 | { | 1309 | { | ||
1405 | m_geometryBeforeUpdateBlocking = geometry(); | 1310 | m_geometryBeforeUpdateBlocking = geometry(); | ||
1406 | } | 1311 | } | ||
1407 | 1312 | | |||
1408 | void AbstractClient::updateTabGroupStates(TabGroup::States) | | |||
1409 | { | | |||
1410 | } | | |||
1411 | | ||||
1412 | void AbstractClient::doMove(int, int) | 1313 | void AbstractClient::doMove(int, int) | ||
1413 | { | 1314 | { | ||
1414 | } | 1315 | } | ||
1415 | 1316 | | |||
1416 | void AbstractClient::updateInitialMoveResizeGeometry() | 1317 | void AbstractClient::updateInitialMoveResizeGeometry() | ||
1417 | { | 1318 | { | ||
1418 | m_moveResize.initialGeometry = geometry(); | 1319 | m_moveResize.initialGeometry = geometry(); | ||
1419 | m_moveResize.geometry = m_moveResize.initialGeometry; | 1320 | m_moveResize.geometry = m_moveResize.initialGeometry; | ||
▲ Show 20 Lines • Show All 317 Lines • ▼ Show 20 Line(s) | 1614 | { | |||
1737 | if (event->button() == Qt::LeftButton) | 1638 | if (event->button() == Qt::LeftButton) | ||
1738 | com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1(); | 1639 | com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1(); | ||
1739 | else if (event->button() == Qt::MidButton) | 1640 | else if (event->button() == Qt::MidButton) | ||
1740 | com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2(); | 1641 | com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2(); | ||
1741 | else if (event->button() == Qt::RightButton) | 1642 | else if (event->button() == Qt::RightButton) | ||
1742 | com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3(); | 1643 | com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3(); | ||
1743 | if (event->button() == Qt::LeftButton | 1644 | if (event->button() == Qt::LeftButton | ||
1744 | && com != Options::MouseOperationsMenu // actions where it's not possible to get the matching | 1645 | && com != Options::MouseOperationsMenu // actions where it's not possible to get the matching | ||
1745 | && com != Options::MouseMinimize // mouse release event | 1646 | && com != Options::MouseMinimize) // mouse release event | ||
1746 | && com != Options::MouseDragTab) { | 1647 | { | ||
1747 | setMoveResizePointerMode(mousePosition()); | 1648 | setMoveResizePointerMode(mousePosition()); | ||
1748 | setMoveResizePointerButtonDown(true); | 1649 | setMoveResizePointerButtonDown(true); | ||
1749 | setMoveOffset(event->pos()); | 1650 | setMoveOffset(event->pos()); | ||
1750 | setInvertedMoveOffset(rect().bottomRight() - moveOffset()); | 1651 | setInvertedMoveOffset(rect().bottomRight() - moveOffset()); | ||
1751 | setUnrestrictedMoveResize(false); | 1652 | setUnrestrictedMoveResize(false); | ||
1752 | startDelayedMoveResize(); | 1653 | startDelayedMoveResize(); | ||
1753 | updateCursor(); | 1654 | updateCursor(); | ||
1754 | } | 1655 | } | ||
1755 | // In the new API the decoration may process the menu action to display an inactive tab's menu. | 1656 | // In the new API the decoration may process the menu action to display an inactive tab's menu. | ||
1756 | // If the event is unhandled then the core will create one for the active window in the group. | 1657 | // If the event is unhandled then the core will create one for the active window in the group. | ||
1757 | if (!ignoreMenu || com != Options::MouseOperationsMenu) | 1658 | if (!ignoreMenu || com != Options::MouseOperationsMenu) | ||
1758 | performMouseCommand(com, event->globalPos()); | 1659 | performMouseCommand(com, event->globalPos()); | ||
1759 | return !( // Return events that should be passed to the decoration in the new API | 1660 | return !( // Return events that should be passed to the decoration in the new API | ||
1760 | com == Options::MouseRaise || | 1661 | com == Options::MouseRaise || | ||
1761 | com == Options::MouseOperationsMenu || | 1662 | com == Options::MouseOperationsMenu || | ||
1762 | com == Options::MouseActivateAndRaise || | 1663 | com == Options::MouseActivateAndRaise || | ||
1763 | com == Options::MouseActivate || | 1664 | com == Options::MouseActivate || | ||
1764 | com == Options::MouseActivateRaiseAndPassClick || | 1665 | com == Options::MouseActivateRaiseAndPassClick || | ||
1765 | com == Options::MouseActivateAndPassClick || | 1666 | com == Options::MouseActivateAndPassClick || | ||
1766 | com == Options::MouseDragTab || | | |||
1767 | com == Options::MouseNothing); | 1667 | com == Options::MouseNothing); | ||
1768 | } | 1668 | } | ||
1769 | 1669 | | |||
1770 | void AbstractClient::processDecorationButtonRelease(QMouseEvent *event) | 1670 | void AbstractClient::processDecorationButtonRelease(QMouseEvent *event) | ||
1771 | { | 1671 | { | ||
1772 | if (isDecorated()) { | 1672 | if (isDecorated()) { | ||
1773 | if (event->isAccepted() || !titlebarPositionUnderMouse()) { | 1673 | if (event->isAccepted() || !titlebarPositionUnderMouse()) { | ||
1774 | invalidateDecorationDoubleClickTimer(); // click was for the deco and shall not init a doubleclick | 1674 | invalidateDecorationDoubleClickTimer(); // click was for the deco and shall not init a doubleclick | ||
▲ Show 20 Lines • Show All 321 Lines • Show Last 20 Lines |
Add it back.