Changeset View
Changeset View
Standalone View
Standalone View
x11client.cpp
Show First 20 Lines • Show All 2702 Lines • ▼ Show 20 Line(s) | 2696 | { | |||
---|---|---|---|---|---|
2703 | } else { | 2703 | } else { | ||
2704 | width -= m_clientFrameExtents.left() + m_clientFrameExtents.right(); | 2704 | width -= m_clientFrameExtents.left() + m_clientFrameExtents.right(); | ||
2705 | height -= m_clientFrameExtents.top() + m_clientFrameExtents.bottom(); | 2705 | height -= m_clientFrameExtents.top() + m_clientFrameExtents.bottom(); | ||
2706 | } | 2706 | } | ||
2707 | 2707 | | |||
2708 | return QSize(width, height); | 2708 | return QSize(width, height); | ||
2709 | } | 2709 | } | ||
2710 | 2710 | | |||
2711 | QRect X11Client::frameRectToBufferRect(const QRect &rect) const | ||||
2712 | { | ||||
2713 | if (isDecorated()) { | ||||
2714 | return rect; | ||||
2715 | } | ||||
2716 | return frameRectToClientRect(rect); | ||||
2717 | } | ||||
2718 | | ||||
2711 | Xcb::Property X11Client::fetchShowOnScreenEdge() const | 2719 | Xcb::Property X11Client::fetchShowOnScreenEdge() const | ||
2712 | { | 2720 | { | ||
2713 | return Xcb::Property(false, window(), atoms->kde_screen_edge_show, XCB_ATOM_CARDINAL, 0, 1); | 2721 | return Xcb::Property(false, window(), atoms->kde_screen_edge_show, XCB_ATOM_CARDINAL, 0, 1); | ||
2714 | } | 2722 | } | ||
2715 | 2723 | | |||
2716 | void X11Client::readShowOnScreenEdge(Xcb::Property &property) | 2724 | void X11Client::readShowOnScreenEdge(Xcb::Property &property) | ||
2717 | { | 2725 | { | ||
2718 | //value comes in two parts, edge in the lower byte | 2726 | //value comes in two parts, edge in the lower byte | ||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Line(s) | 2864 | { | |||
2860 | if (m_syncRequest.failsafeTimeout) { | 2868 | if (m_syncRequest.failsafeTimeout) { | ||
2861 | m_syncRequest.failsafeTimeout->stop(); | 2869 | m_syncRequest.failsafeTimeout->stop(); | ||
2862 | } | 2870 | } | ||
2863 | if (isResize()) { | 2871 | if (isResize()) { | ||
2864 | if (m_syncRequest.timeout) { | 2872 | if (m_syncRequest.timeout) { | ||
2865 | m_syncRequest.timeout->stop(); | 2873 | m_syncRequest.timeout->stop(); | ||
2866 | } | 2874 | } | ||
2867 | performMoveResize(); | 2875 | performMoveResize(); | ||
2876 | updateWindowPixmap(); | ||||
2868 | } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended | 2877 | } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended | ||
2869 | addRepaintFull(); | 2878 | addRepaintFull(); | ||
2870 | } | 2879 | } | ||
2871 | 2880 | | |||
2872 | void X11Client::move(int x, int y, ForceGeometry_t force) | 2881 | void X11Client::move(int x, int y, ForceGeometry_t force) | ||
2873 | { | 2882 | { | ||
2874 | const QPoint framePosition(x, y); | 2883 | const QPoint framePosition(x, y); | ||
2875 | m_clientGeometry.moveTopLeft(framePosToClientPos(framePosition)); | 2884 | m_clientGeometry.moveTopLeft(framePosToClientPos(framePosition)); | ||
▲ Show 20 Lines • Show All 1275 Lines • ▼ Show 20 Line(s) | 4154 | { | |||
4151 | // the geometry is used only for client_size, since that one is not used when | 4160 | // the geometry is used only for client_size, since that one is not used when | ||
4152 | // shading. Then the frame geometry is adjusted for the shaded geometry. | 4161 | // shading. Then the frame geometry is adjusted for the shaded geometry. | ||
4153 | // This gets more complicated in the case the code does only something like | 4162 | // This gets more complicated in the case the code does only something like | ||
4154 | // setGeometry( geometry()) - geometry() will return the shaded frame geometry. | 4163 | // setGeometry( geometry()) - geometry() will return the shaded frame geometry. | ||
4155 | // Such code is wrong and should be changed to handle the case when the window is shaded, | 4164 | // Such code is wrong and should be changed to handle the case when the window is shaded, | ||
4156 | // for example using X11Client::clientSize() | 4165 | // for example using X11Client::clientSize() | ||
4157 | 4166 | | |||
4158 | QRect frameGeometry(x, y, w, h); | 4167 | QRect frameGeometry(x, y, w, h); | ||
4159 | QRect bufferGeometry; | | |||
4160 | 4168 | | |||
4161 | if (shade_geometry_change) | 4169 | if (shade_geometry_change) | ||
4162 | ; // nothing | 4170 | ; // nothing | ||
4163 | else if (isShade()) { | 4171 | else if (isShade()) { | ||
4164 | if (frameGeometry.height() == borderTop() + borderBottom()) { | 4172 | if (frameGeometry.height() == borderTop() + borderBottom()) { | ||
4165 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | 4173 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | ||
4166 | } else { | 4174 | } else { | ||
4167 | m_clientGeometry = frameRectToClientRect(frameGeometry); | 4175 | m_clientGeometry = frameRectToClientRect(frameGeometry); | ||
4168 | frameGeometry.setHeight(borderTop() + borderBottom()); | 4176 | frameGeometry.setHeight(borderTop() + borderBottom()); | ||
4169 | } | 4177 | } | ||
4170 | } else { | 4178 | } else { | ||
4171 | m_clientGeometry = frameRectToClientRect(frameGeometry); | 4179 | m_clientGeometry = frameRectToClientRect(frameGeometry); | ||
4172 | } | 4180 | } | ||
4173 | if (isDecorated()) { | 4181 | const QRect bufferGeometry = frameRectToBufferRect(frameGeometry); | ||
4174 | bufferGeometry = frameGeometry; | | |||
4175 | } else { | | |||
4176 | bufferGeometry = m_clientGeometry; | | |||
4177 | } | | |||
4178 | if (!areGeometryUpdatesBlocked() && frameGeometry != rules()->checkGeometry(frameGeometry)) { | 4182 | if (!areGeometryUpdatesBlocked() && frameGeometry != rules()->checkGeometry(frameGeometry)) { | ||
4179 | qCDebug(KWIN_CORE) << "forced geometry fail:" << frameGeometry << ":" << rules()->checkGeometry(frameGeometry); | 4183 | qCDebug(KWIN_CORE) << "forced geometry fail:" << frameGeometry << ":" << rules()->checkGeometry(frameGeometry); | ||
4180 | } | 4184 | } | ||
4181 | m_frameGeometry = frameGeometry; | 4185 | m_frameGeometry = frameGeometry; | ||
4182 | if (force == NormalGeometrySet && m_bufferGeometry == bufferGeometry && pendingGeometryUpdate() == PendingGeometryNone) { | 4186 | if (force == NormalGeometrySet && m_bufferGeometry == bufferGeometry && pendingGeometryUpdate() == PendingGeometryNone) { | ||
4183 | return; | 4187 | return; | ||
4184 | } | 4188 | } | ||
4185 | m_bufferGeometry = bufferGeometry; | 4189 | m_bufferGeometry = bufferGeometry; | ||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | 4219 | { | |||
4264 | addRepaintDuringGeometryUpdates(); | 4268 | addRepaintDuringGeometryUpdates(); | ||
4265 | updateGeometryBeforeUpdateBlocking(); | 4269 | updateGeometryBeforeUpdateBlocking(); | ||
4266 | // TODO: this signal is emitted too often | 4270 | // TODO: this signal is emitted too often | ||
4267 | emit geometryChanged(); | 4271 | emit geometryChanged(); | ||
4268 | } | 4272 | } | ||
4269 | 4273 | | |||
4270 | void X11Client::updateServerGeometry() | 4274 | void X11Client::updateServerGeometry() | ||
4271 | { | 4275 | { | ||
4272 | if (m_frame.geometry().size() != m_bufferGeometry.size() || pendingGeometryUpdate() == PendingGeometryForced) { | 4276 | const QRect oldBufferGeometry = bufferGeometryBeforeUpdateBlocking(); | ||
4277 | | ||||
4278 | if (oldBufferGeometry.size() != m_bufferGeometry.size() || pendingGeometryUpdate() == PendingGeometryForced) { | ||||
4273 | resizeDecoration(); | 4279 | resizeDecoration(); | ||
4280 | // If the client is being interactively resized, then the frame window, the wrapper window, | ||||
4281 | // and the client window have correct geometry at this point, so we don't have to configure | ||||
4282 | // them again. If the client doesn't support frame counters, always update geometry. | ||||
4283 | const bool needsGeometryUpdate = !isResize() || m_syncRequest.counter == XCB_NONE; | ||||
4284 | if (needsGeometryUpdate) { | ||||
4274 | m_frame.setGeometry(m_bufferGeometry); | 4285 | m_frame.setGeometry(m_bufferGeometry); | ||
4286 | } | ||||
4275 | if (!isShade()) { | 4287 | if (!isShade()) { | ||
4276 | QSize cs = clientSize(); | 4288 | if (needsGeometryUpdate) { | ||
4277 | m_wrapper.setGeometry(QRect(clientPos(), cs)); | 4289 | m_wrapper.setGeometry(QRect(clientPos(), clientSize())); | ||
4278 | if (!isResize() || m_syncRequest.counter == XCB_NONE) { | 4290 | m_client.resize(clientSize()); | ||
4279 | m_client.setGeometry(0, 0, cs.width(), cs.height()); | | |||
4280 | } | 4291 | } | ||
4281 | // SELI - won't this be too expensive? | 4292 | // SELI - won't this be too expensive? | ||
4282 | // THOMAS - yes, but gtk+ clients will not resize without ... | 4293 | // THOMAS - yes, but gtk+ clients will not resize without ... | ||
4283 | sendSyntheticConfigureNotify(); | 4294 | sendSyntheticConfigureNotify(); | ||
4284 | } | 4295 | } | ||
4285 | updateShape(); | 4296 | updateShape(); | ||
4286 | } else { | 4297 | } else { | ||
4287 | if (isMoveResize()) { | 4298 | if (isMoveResize()) { | ||
▲ Show 20 Lines • Show All 464 Lines • ▼ Show 20 Line(s) | 4757 | { | |||
4752 | if (m_syncRequest.counter != XCB_NONE) { | 4763 | if (m_syncRequest.counter != XCB_NONE) { | ||
4753 | m_syncRequest.timeout->start(250); | 4764 | m_syncRequest.timeout->start(250); | ||
4754 | sendSyncRequest(); | 4765 | sendSyncRequest(); | ||
4755 | } else { // for clients not supporting the XSYNC protocol, we | 4766 | } else { // for clients not supporting the XSYNC protocol, we | ||
4756 | m_syncRequest.isPending = true; // limit the resizes to 30Hz to take pointless load from X11 | 4767 | m_syncRequest.isPending = true; // limit the resizes to 30Hz to take pointless load from X11 | ||
4757 | m_syncRequest.timeout->start(33); // and the client, the mouse is still moved at full speed | 4768 | m_syncRequest.timeout->start(33); // and the client, the mouse is still moved at full speed | ||
4758 | } // and no human can control faster resizes anyway | 4769 | } // and no human can control faster resizes anyway | ||
4759 | const QRect moveResizeClientGeometry = frameRectToClientRect(moveResizeGeometry()); | 4770 | const QRect moveResizeClientGeometry = frameRectToClientRect(moveResizeGeometry()); | ||
4760 | m_client.setGeometry(0, 0, moveResizeClientGeometry.width(), moveResizeClientGeometry.height()); | 4771 | const QRect moveResizeBufferGeometry = frameRectToBufferRect(moveResizeGeometry()); | ||
4772 | | ||||
4773 | // According to the Composite extension spec, a window will get a new pixmap allocated each time | ||||
4774 | // it is mapped or resized. Given that we redirect frame windows and not client windows, we have | ||||
4775 | // to resize the frame window in order to forcefully reallocate offscreen storage. If we don't do | ||||
4776 | // this, then we might render partially updated client window. I know, it sucks. | ||||
4777 | m_frame.setGeometry(moveResizeBufferGeometry); | ||||
4778 | m_wrapper.setGeometry(QRect(clientPos(), moveResizeClientGeometry.size())); | ||||
4779 | m_client.resize(moveResizeClientGeometry.size()); | ||||
4761 | } | 4780 | } | ||
4762 | 4781 | | |||
4763 | void X11Client::doPerformMoveResize() | 4782 | void X11Client::doPerformMoveResize() | ||
4764 | { | 4783 | { | ||
4765 | if (m_syncRequest.counter == XCB_NONE) { // client w/o XSYNC support. allow the next resize event | 4784 | if (m_syncRequest.counter == XCB_NONE) { // client w/o XSYNC support. allow the next resize event | ||
4766 | m_syncRequest.isPending = false; // NEVER do this for clients with a valid counter | 4785 | m_syncRequest.isPending = false; // NEVER do this for clients with a valid counter | ||
4767 | } // (leads to sync request races in some clients) | 4786 | } // (leads to sync request races in some clients) | ||
4768 | } | 4787 | } | ||
▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Line(s) | 4985 | if (m_syncRequest.counter == XCB_NONE) { // cannot detect complete redraw, consider done now | |||
4967 | setReadyForPainting(); | 4986 | setReadyForPainting(); | ||
4968 | setupWindowManagementInterface(); | 4987 | setupWindowManagementInterface(); | ||
4969 | } | 4988 | } | ||
4970 | } | 4989 | } | ||
4971 | 4990 | | |||
4972 | AbstractClient::damageNotifyEvent(); | 4991 | AbstractClient::damageNotifyEvent(); | ||
4973 | } | 4992 | } | ||
4974 | 4993 | | |||
4994 | void X11Client::updateWindowPixmap() | ||||
4995 | { | ||||
4996 | if (effectWindow() && effectWindow()->sceneWindow()) { | ||||
4997 | effectWindow()->sceneWindow()->updatePixmap(); | ||||
4998 | } | ||||
4999 | } | ||||
5000 | | ||||
4975 | } // namespace | 5001 | } // namespace |