Changeset View
Changeset View
Standalone View
Standalone View
x11client.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) 1999, 2000 Matthias Ettrich <ettrich@kde.org> | 5 | Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org> | ||
6 | Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> | 6 | Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> | ||
7 | Copyright (C) 2019 Vlad Zahorodnii <vladzzag@gmail.com> | ||||
7 | 8 | | |||
8 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | 11 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | 12 | (at your option) any later version. | ||
12 | 13 | | |||
13 | This program is distributed in the hope that it will be useful, | 14 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Line(s) | 249 | if (!on_shutdown) { | |||
250 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | 251 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | ||
251 | info->setDesktop(0); | 252 | info->setDesktop(0); | ||
252 | info->setState(NET::States(), info->state()); // Reset all state flags | 253 | info->setState(NET::States(), info->state()); // Reset all state flags | ||
253 | } | 254 | } | ||
254 | xcb_connection_t *c = connection(); | 255 | xcb_connection_t *c = connection(); | ||
255 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | 256 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | ||
256 | m_client.deleteProperty(atoms->net_frame_extents); | 257 | m_client.deleteProperty(atoms->net_frame_extents); | ||
257 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | 258 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | ||
258 | m_client.reparent(rootWindow(), m_bufferGeometry.x(), m_bufferGeometry.y()); | 259 | m_client.reparent(rootWindow(), m_serverGeometry.x(), m_serverGeometry.y()); | ||
259 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | 260 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | ||
260 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | 261 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | ||
261 | if (on_shutdown) | 262 | if (on_shutdown) | ||
262 | // Map the window, so it can be found after another WM is started | 263 | // Map the window, so it can be found after another WM is started | ||
263 | m_client.map(); | 264 | m_client.map(); | ||
264 | // TODO: Preserve minimized, shaded etc. state? | 265 | // TODO: Preserve minimized, shaded etc. state? | ||
265 | else // Make sure it's not mapped if the app unmapped it (#65279). The app | 266 | else // Make sure it's not mapped if the app unmapped it (#65279). The app | ||
266 | // may do map+unmap before we initially map the window by calling rawShow() from manage(). | 267 | // may do map+unmap before we initially map the window by calling rawShow() from manage(). | ||
▲ Show 20 Lines • Show All 1713 Lines • ▼ Show 20 Line(s) | |||||
1980 | 1981 | | |||
1981 | xcb_window_t X11Client::frameId() const | 1982 | xcb_window_t X11Client::frameId() const | ||
1982 | { | 1983 | { | ||
1983 | return m_frame; | 1984 | return m_frame; | ||
1984 | } | 1985 | } | ||
1985 | 1986 | | |||
1986 | QRect X11Client::bufferGeometry() const | 1987 | QRect X11Client::bufferGeometry() const | ||
1987 | { | 1988 | { | ||
1988 | return m_bufferGeometry; | 1989 | return m_clientGeometry; | ||
1989 | } | | |||
1990 | | ||||
1991 | QMargins X11Client::bufferMargins() const | | |||
1992 | { | | |||
1993 | return QMargins(borderLeft(), borderTop(), borderRight(), borderBottom()); | | |||
1994 | } | 1990 | } | ||
1995 | 1991 | | |||
1996 | QPoint X11Client::framePosToClientPos(const QPoint &point) const | 1992 | QPoint X11Client::framePosToClientPos(const QPoint &point) const | ||
1997 | { | 1993 | { | ||
1998 | int x = point.x(); | 1994 | int x = point.x(); | ||
1999 | int y = point.y(); | 1995 | int y = point.y(); | ||
2000 | 1996 | | |||
2001 | if (isDecorated()) { | 1997 | if (isDecorated()) { | ||
▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Line(s) | 2201 | { | |||
2211 | if (isResize()) { | 2207 | if (isResize()) { | ||
2212 | if (syncRequest.timeout) | 2208 | if (syncRequest.timeout) | ||
2213 | syncRequest.timeout->stop(); | 2209 | syncRequest.timeout->stop(); | ||
2214 | performMoveResize(); | 2210 | performMoveResize(); | ||
2215 | } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended | 2211 | } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended | ||
2216 | addRepaintFull(); | 2212 | addRepaintFull(); | ||
2217 | } | 2213 | } | ||
2218 | 2214 | | |||
2219 | bool X11Client::canUpdatePosition(const QPoint &frame, const QPoint &buffer, ForceGeometry_t force) const | | |||
2220 | { | | |||
2221 | // Obey forced geometry updates. | | |||
2222 | if (force != NormalGeometrySet) { | | |||
2223 | return true; | | |||
2224 | } | | |||
2225 | // Server-side geometry and our geometry are out of sync. | | |||
2226 | if (bufferGeometry().topLeft() != buffer) { | | |||
2227 | return true; | | |||
2228 | } | | |||
2229 | if (frameGeometry().topLeft() != frame) { | | |||
2230 | return true; | | |||
2231 | } | | |||
2232 | return false; | | |||
2233 | } | | |||
2234 | | ||||
2235 | bool X11Client::canUpdateSize(const QSize &frame, const QSize &buffer, ForceGeometry_t force) const | | |||
2236 | { | | |||
2237 | // Obey forced geometry updates. | | |||
2238 | if (force != NormalGeometrySet) { | | |||
2239 | return true; | | |||
2240 | } | | |||
2241 | // Server-side geometry and our geometry are out of sync. | | |||
2242 | if (bufferGeometry().size() != buffer) { | | |||
2243 | return true; | | |||
2244 | } | | |||
2245 | if (frameGeometry().size() != frame) { | | |||
2246 | return true; | | |||
2247 | } | | |||
2248 | return false; | | |||
2249 | } | | |||
2250 | | ||||
2251 | bool X11Client::canUpdateGeometry(const QRect &frame, const QRect &buffer, ForceGeometry_t force) const | | |||
2252 | { | | |||
2253 | if (canUpdatePosition(frame.topLeft(), buffer.topLeft(), force)) { | | |||
2254 | return true; | | |||
2255 | } | | |||
2256 | if (canUpdateSize(frame.size(), buffer.size(), force)) { | | |||
2257 | return true; | | |||
2258 | } | | |||
2259 | return pendingGeometryUpdate() != PendingGeometryNone; | | |||
2260 | } | | |||
2261 | | ||||
2262 | void X11Client::move(int x, int y, ForceGeometry_t force) | 2215 | void X11Client::move(int x, int y, ForceGeometry_t force) | ||
2263 | { | 2216 | { | ||
2264 | const QPoint framePosition(x, y); | 2217 | const QPoint framePosition(x, y); | ||
2265 | m_clientGeometry.moveTopLeft(framePosToClientPos(framePosition)); | 2218 | m_clientGeometry.moveTopLeft(framePosToClientPos(framePosition)); | ||
2266 | const QPoint bufferPosition = isDecorated() ? framePosition : m_clientGeometry.topLeft(); | 2219 | const QPoint serverPosition = isDecorated() ? framePosition : m_clientGeometry.topLeft(); | ||
2267 | // resuming geometry updates is handled only in setGeometry() | 2220 | // resuming geometry updates is handled only in setGeometry() | ||
2268 | Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked()); | 2221 | Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked()); | ||
2269 | if (!areGeometryUpdatesBlocked() && framePosition != rules()->checkPosition(framePosition)) { | 2222 | if (!areGeometryUpdatesBlocked() && framePosition != rules()->checkPosition(framePosition)) { | ||
2270 | qCDebug(KWIN_CORE) << "forced position fail:" << framePosition << ":" << rules()->checkPosition(framePosition); | 2223 | qCDebug(KWIN_CORE) << "forced position fail:" << framePosition << ":" << rules()->checkPosition(framePosition); | ||
2271 | } | 2224 | } | ||
2272 | if (!canUpdatePosition(framePosition, bufferPosition, force)) { | 2225 | if (force == NormalGeometrySet && m_serverGeometry.topLeft() == serverPosition) { | ||
2273 | return; | 2226 | return; | ||
2274 | } | 2227 | } | ||
2275 | m_bufferGeometry.moveTopLeft(bufferPosition); | 2228 | m_serverGeometry.moveTopLeft(serverPosition); | ||
2276 | geom.moveTopLeft(framePosition); | 2229 | geom.moveTopLeft(framePosition); | ||
2277 | if (areGeometryUpdatesBlocked()) { | 2230 | if (areGeometryUpdatesBlocked()) { | ||
2278 | if (pendingGeometryUpdate() == PendingGeometryForced) { | 2231 | if (pendingGeometryUpdate() == PendingGeometryForced) { | ||
2279 | // Maximum, nothing needed. | 2232 | // Maximum, nothing needed. | ||
2280 | } else if (force == ForceGeometrySet) { | 2233 | } else if (force == ForceGeometrySet) { | ||
2281 | setPendingGeometryUpdate(PendingGeometryForced); | 2234 | setPendingGeometryUpdate(PendingGeometryForced); | ||
2282 | } else { | 2235 | } else { | ||
2283 | setPendingGeometryUpdate(PendingGeometryNormal); | 2236 | setPendingGeometryUpdate(PendingGeometryNormal); | ||
2284 | } | 2237 | } | ||
2285 | return; | 2238 | return; | ||
2286 | } | 2239 | } | ||
2287 | m_frame.move(m_bufferGeometry.topLeft()); | 2240 | m_frame.move(m_serverGeometry.topLeft()); | ||
2288 | sendSyntheticConfigureNotify(); | 2241 | sendSyntheticConfigureNotify(); | ||
2289 | updateWindowRules(Rules::Position); | 2242 | updateWindowRules(Rules::Position); | ||
2290 | screens()->setCurrent(this); | 2243 | screens()->setCurrent(this); | ||
2291 | workspace()->updateStackingOrder(); | 2244 | workspace()->updateStackingOrder(); | ||
2292 | // client itself is not damaged | 2245 | // client itself is not damaged | ||
2293 | addRepaintDuringGeometryUpdates(); | 2246 | addRepaintDuringGeometryUpdates(); | ||
2294 | updateGeometryBeforeUpdateBlocking(); | 2247 | updateGeometryBeforeUpdateBlocking(); | ||
2295 | emit geometryChanged(); | 2248 | emit geometryChanged(); | ||
2296 | } | 2249 | } | ||
2297 | 2250 | | |||
2298 | } // namespace | 2251 | } // namespace | ||
2299 | 2252 | |