diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 6735ea79af..ac7ae7a5b0 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -52,6 +52,7 @@ ecm_mark_as_test(testVirtualDesktops) set(testClientMachine_SRCS ../src/client_machine.cpp test_client_machine.cpp + xcb_scaling_mock.cpp ) add_executable(testClientMachine ${testClientMachine_SRCS}) set_target_properties(testClientMachine PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") @@ -80,10 +81,7 @@ ecm_mark_as_test(testClientMachine) ######################################################## # Test XcbWrapper ######################################################## -set(testXcbWrapper_SRCS - test_xcb_wrapper.cpp -) -add_executable(testXcbWrapper ${testXcbWrapper_SRCS}) +add_executable(testXcbWrapper test_xcb_wrapper.cpp xcb_scaling_mock.cpp) target_link_libraries(testXcbWrapper Qt::Test @@ -103,7 +101,7 @@ add_test(NAME kwin-testXcbWrapper COMMAND testXcbWrapper) ecm_mark_as_test(testXcbWrapper) if (XCB_ICCCM_FOUND) - add_executable(testXcbSizeHints test_xcb_size_hints.cpp) + add_executable(testXcbSizeHints test_xcb_size_hints.cpp xcb_scaling_mock.cpp) set_target_properties(testXcbSizeHints PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") target_link_libraries(testXcbSizeHints Qt::Test @@ -127,10 +125,7 @@ endif() ######################################################## # Test XcbWindow ######################################################## -set(testXcbWindow_SRCS - test_xcb_window.cpp -) -add_executable(testXcbWindow ${testXcbWindow_SRCS}) +add_executable(testXcbWindow test_xcb_window.cpp xcb_scaling_mock.cpp) target_link_libraries(testXcbWindow Qt::Test diff --git a/autotests/xcb_scaling_mock.cpp b/autotests/xcb_scaling_mock.cpp new file mode 100644 index 0000000000..33a20c9159 --- /dev/null +++ b/autotests/xcb_scaling_mock.cpp @@ -0,0 +1,30 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2022 Aleix Pol Gonzalez + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include + +namespace KWin +{ + +uint32_t Xcb::toXNative(uint value) +{ + return value; +} + +uint32_t Xcb::fromXNative(uint value) +{ + return value; +} + +QSize Xcb::fromXNative(const QSize &value) +{ + return value; +} + +} diff --git a/src/events.cpp b/src/events.cpp index a22017056e..7caacbfce0 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -441,9 +441,15 @@ bool X11Window::windowEvent(xcb_generic_event_t *e) } case XCB_MOTION_NOTIFY: { const auto *event = reinterpret_cast(e); + + int x = Xcb::fromXNative(event->event_x); + int y = Xcb::fromXNative(event->event_y); + int root_x = Xcb::fromXNative(event->root_x); + int root_y = Xcb::fromXNative(event->root_y); + motionNotifyEvent(event->event, event->state, - event->event_x, event->event_y, event->root_x, event->root_y); - workspace()->updateFocusMousePosition(QPoint(event->root_x, event->root_y)); + x, y, root_x, root_y); + workspace()->updateFocusMousePosition(QPoint(root_x, root_y)); break; } case XCB_ENTER_NOTIFY: { @@ -454,15 +460,25 @@ bool X11Window::windowEvent(xcb_generic_event_t *e) // starts or only ends there, Enter/LeaveNotify are generated. // Fake a MotionEvent in such cases to make handle of mouse // events simpler (Qt does that too). + int x = Xcb::fromXNative(event->event_x); + int y = Xcb::fromXNative(event->event_y); + int root_x = Xcb::fromXNative(event->root_x); + int root_y = Xcb::fromXNative(event->root_y); + motionNotifyEvent(event->event, event->state, - event->event_x, event->event_y, event->root_x, event->root_y); - workspace()->updateFocusMousePosition(QPoint(event->root_x, event->root_y)); + x, y, root_x, root_y); + workspace()->updateFocusMousePosition(QPoint(root_x, root_y)); break; } case XCB_LEAVE_NOTIFY: { auto *event = reinterpret_cast(e); + + int x = Xcb::fromXNative(event->event_x); + int y = Xcb::fromXNative(event->event_y); + int root_x = Xcb::fromXNative(event->root_x); + int root_y = Xcb::fromXNative(event->root_y); motionNotifyEvent(event->event, event->state, - event->event_x, event->event_y, event->root_x, event->root_y); + x, y, root_x, root_y); leaveNotifyEvent(event); // not here, it'd break following enter notify handling // workspace()->updateFocusMousePosition( QPoint( e->xcrossing.x_root, e->xcrossing.y_root )); @@ -625,9 +641,9 @@ void X11Window::configureRequestEvent(xcb_configure_request_event_t *e) } if (e->value_mask & (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_WIDTH)) { - configureRequest(e->value_mask, e->x, e->y, e->width, e->height, 0, false); + configureRequest(e->value_mask, Xcb::fromXNative(e->x), + Xcb::fromXNative(e->y), Xcb::fromXNative(e->width), Xcb::fromXNative(e->height), 0, false); } - if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { restackWindow(e->sibling, e->stack_mode, NET::FromApplication, userTime(), false); } @@ -1295,7 +1311,7 @@ void Unmanaged::configureNotifyEvent(xcb_configure_notify_event_t *e) if (effects) { static_cast(effects)->checkInputWindowStacking(); // keep them on top } - QRect newgeom(e->x, e->y, e->width, e->height); + QRect newgeom(Xcb::fromXNative(e->x), Xcb::fromXNative(e->y), Xcb::fromXNative(e->width), Xcb::fromXNative(e->height)); if (newgeom != m_frameGeometry) { QRect old = m_frameGeometry; m_clientGeometry = newgeom; diff --git a/src/main.cpp b/src/main.cpp index f4ddab66ed..5e6126f1c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -378,6 +378,14 @@ static X11EventFilterContainer *takeEventFilter(X11EventFilter *eventFilter, return nullptr; } +void Application::setXwaylandScale(qreal scale) +{ + if (scale != m_xwaylandScale) { + m_xwaylandScale = scale; + Q_EMIT xwaylandScaleChanged(); + } +} + void Application::unregisterEventFilter(X11EventFilter *filter) { X11EventFilterContainer *container = nullptr; diff --git a/src/main.h b/src/main.h index 87b4b5f35f..aaef36320f 100644 --- a/src/main.h +++ b/src/main.h @@ -82,6 +82,7 @@ public: */ OperationModeXwayland }; + Q_ENUM(OperationMode) ~Application() override; void setConfigLock(bool lock); @@ -190,6 +191,21 @@ public: return m_defaultScreen; } + qreal xwaylandScale() const + { + return m_xwaylandScale; + } + + void setXwaylandScale(qreal scale); + + /** + * Returns @c true if we're in the middle of destroying the X11 connection. + */ + bool isClosingX11Connection() const + { + return m_isClosingX11Connection; + } + #if KWIN_BUILD_ACTIVITIES bool usesKActivities() const { @@ -220,6 +236,7 @@ public: Q_SIGNALS: void x11ConnectionChanged(); void x11ConnectionAboutToBeDestroyed(); + void xwaylandScaleChanged(); void workspaceCreated(); void screensCreated(); void platformCreated(); @@ -299,6 +316,8 @@ private: #endif Platform *m_platform = nullptr; bool m_terminating = false; + bool m_isClosingX11Connection = false; + qreal m_xwaylandScale = 1; }; inline static Application *kwinApp() diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index 1720e14e7f..694b21a893 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -132,6 +132,7 @@ void ApplicationWayland::performStartup() { if (m_startXWayland) { setOperationMode(OperationModeXwayland); + setXwaylandScale(config()->group("Xwayland").readEntry("Scale", 1.0)); } // first load options - done internally by a different thread createOptions(); diff --git a/src/netinfo.cpp b/src/netinfo.cpp index 09d8392f42..14cfbab23a 100644 --- a/src/netinfo.cpp +++ b/src/netinfo.cpp @@ -204,7 +204,7 @@ void RootInfo::moveResize(xcb_window_t w, int x_root, int y_root, unsigned long X11Window *c = Workspace::self()->findClient(Predicate::WindowMatch, w); if (c) { updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp - c->NETMoveResize(x_root, y_root, (Direction)direction); + c->NETMoveResize(Xcb::fromXNative(x_root), Xcb::fromXNative(y_root), (Direction)direction); } } @@ -212,7 +212,7 @@ void RootInfo::moveResizeWindow(xcb_window_t w, int flags, int x, int y, int wid { X11Window *c = Workspace::self()->findClient(Predicate::WindowMatch, w); if (c) { - c->NETMoveResizeWindow(flags, x, y, width, height); + c->NETMoveResizeWindow(flags, Xcb::fromXNative(x), Xcb::fromXNative(y), Xcb::fromXNative(width), Xcb::fromXNative(height)); } } diff --git a/src/unmanaged.cpp b/src/unmanaged.cpp index e5b67ade31..246f590e94 100644 --- a/src/unmanaged.cpp +++ b/src/unmanaged.cpp @@ -115,6 +115,7 @@ bool Unmanaged::track(xcb_window_t w) if (geo.isNull()) { return false; } + setWindowHandles(w); // the window is also the frame Xcb::selectInput(w, attr->your_event_mask | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE); m_bufferGeometry = geo.rect(); diff --git a/src/utils/xcbutils.cpp b/src/utils/xcbutils.cpp index 54c44069c1..b7f0a10467 100644 --- a/src/utils/xcbutils.cpp +++ b/src/utils/xcbutils.cpp @@ -611,5 +611,30 @@ bool Shm::init() return true; } +uint32_t toXNative(uint value) +{ + return kwinApp()->xwaylandScale() * value; +} + +QRect toXNative(const QRect &r) +{ + return QRect(toXNative(r.x()), toXNative(r.y()), toXNative(r.width()), toXNative(r.height())); +} + +uint32_t fromXNative(uint value) +{ + return value / kwinApp()->xwaylandScale(); +} + +QRect fromXNative(const QRect &r) +{ + return QRect(fromXNative(r.x()), fromXNative(r.y()), fromXNative(r.width()), fromXNative(r.height())); +} + +QSize fromXNative(const QSize &s) +{ + return QSize(fromXNative(s.width()), fromXNative(s.height())); +} + } // namespace Xcb } // namespace KWin diff --git a/src/utils/xcbutils.h b/src/utils/xcbutils.h index 2b7cba78b7..0d121ee8e1 100644 --- a/src/utils/xcbutils.h +++ b/src/utils/xcbutils.h @@ -36,6 +36,12 @@ namespace Xcb typedef xcb_window_t WindowId; +uint32_t KWIN_EXPORT toXNative(uint value); +QRect KWIN_EXPORT toXNative(const QRect &value); +uint KWIN_EXPORT fromXNative(uint32_t value); +QRect KWIN_EXPORT fromXNative(const QRect &value); +QSize KWIN_EXPORT fromXNative(const QSize &value); + // forward declaration of methods static void defineCursor(xcb_window_t window, xcb_cursor_t cursor); static void setInputFocus(xcb_window_t window, uint8_t revertTo = XCB_INPUT_FOCUS_POINTER_ROOT, xcb_timestamp_t time = xTime()); @@ -584,7 +590,7 @@ public: if (!geometry) { return QRect(); } - return QRect(geometry->x, geometry->y, geometry->width, geometry->height); + return QRect(Xcb::fromXNative(geometry->x), Xcb::fromXNative(geometry->y), Xcb::fromXNative(geometry->width), Xcb::fromXNative(geometry->height)); } inline QSize size() @@ -593,7 +599,7 @@ public: if (!geometry) { return QSize(); } - return QSize(geometry->width, geometry->height); + return QSize(Xcb::fromXNative(geometry->width), Xcb::fromXNative(geometry->height)); } }; @@ -991,7 +997,8 @@ public: if (!hasMaxSize()) { return QSize(INT_MAX, INT_MAX); } - return QSize(qMax(m_sizeHints->maxWidth, 1), qMax(m_sizeHints->maxHeight, 1)); + const QSize size(qMax(m_sizeHints->maxWidth, 1), qMax(m_sizeHints->maxHeight, 1)); + return fromXNative(size); } QSize minSize() const { @@ -999,7 +1006,8 @@ public: // according to ICCCM 4.1.23 base size should be used as a fallback return baseSize(); } - return QSize(m_sizeHints->minWidth, m_sizeHints->minHeight); + const QSize size(m_sizeHints->minWidth, m_sizeHints->minHeight); + return fromXNative(size); } QSize baseSize() const { @@ -1007,14 +1015,16 @@ public: if (!hasBaseSize()) { return QSize(0, 0); } - return QSize(m_sizeHints->baseWidth, m_sizeHints->baseHeight); + const QSize size(m_sizeHints->baseWidth, m_sizeHints->baseHeight); + return fromXNative(size); } QSize resizeIncrements() const { if (!hasResizeIncrements()) { return QSize(1, 1); } - return QSize(qMax(m_sizeHints->widthInc, 1), qMax(m_sizeHints->heightInc, 1)); + const QSize size(qMax(m_sizeHints->widthInc, 1), qMax(m_sizeHints->heightInc, 1)); + return fromXNative(size); } xcb_gravity_t windowGravity() const { @@ -1623,7 +1633,7 @@ inline xcb_window_t Window::doCreate(const QRect &geometry, uint16_t windowClass m_logicGeometry = geometry; xcb_window_t w = xcb_generate_id(connection()); xcb_create_window(connection(), XCB_COPY_FROM_PARENT, w, parent, - geometry.x(), geometry.y(), geometry.width(), geometry.height(), + Xcb::toXNative(geometry.x()), Xcb::toXNative(geometry.y()), Xcb::toXNative(geometry.width()), Xcb::toXNative(geometry.height()), 0, windowClass, XCB_COPY_FROM_PARENT, mask, values); return w; } @@ -1647,7 +1657,7 @@ inline void Window::setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t return; } const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - const uint32_t values[] = {x, y, width, height}; + const uint32_t values[] = {Xcb::toXNative(x), Xcb::toXNative(y), Xcb::toXNative(width), Xcb::toXNative(height)}; xcb_configure_window(connection(), m_window, mask, values); } @@ -1677,7 +1687,7 @@ inline void Window::resize(uint32_t width, uint32_t height) return; } const uint16_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - const uint32_t values[] = {width, height}; + const uint32_t values[] = {Xcb::toXNative(width), Xcb::toXNative(height)}; xcb_configure_window(connection(), m_window, mask, values); } @@ -1713,7 +1723,7 @@ inline void Window::reparent(xcb_window_t parent, int x, int y) if (!isValid()) { return; } - xcb_reparent_window(connection(), m_window, parent, x, y); + xcb_reparent_window(connection(), m_window, parent, Xcb::toXNative(x), Xcb::toXNative(y)); } inline void Window::changeProperty(xcb_atom_t property, xcb_atom_t type, uint8_t format, uint32_t length, const void *data, uint8_t mode) @@ -1737,7 +1747,8 @@ inline void Window::setBorderWidth(uint32_t width) if (!isValid()) { return; } - xcb_configure_window(connection(), m_window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &width); + uint32_t _width = Xcb::toXNative(width); + xcb_configure_window(connection(), m_window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &_width); } inline void Window::grabButton(uint8_t pointerMode, uint8_t keyboardmode, uint16_t modifiers, @@ -1800,11 +1811,8 @@ inline void Window::kill() static inline void moveResizeWindow(WindowId window, const QRect &geometry) { const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - const uint32_t values[] = { - static_cast(geometry.x()), - static_cast(geometry.y()), - static_cast(geometry.width()), - static_cast(geometry.height())}; + + const uint32_t values[] = {Xcb::toXNative(geometry.x()), Xcb::toXNative(geometry.y()), Xcb::toXNative(geometry.width()), Xcb::toXNative(geometry.height())}; xcb_configure_window(connection(), window, mask, values); } @@ -1816,7 +1824,7 @@ static inline void moveWindow(xcb_window_t window, const QPoint &pos) static inline void moveWindow(xcb_window_t window, uint32_t x, uint32_t y) { const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - const uint32_t values[] = {x, y}; + const uint32_t values[] = {Xcb::toXNative(x), Xcb::toXNative(y)}; xcb_configure_window(connection(), window, mask, values); } @@ -1881,11 +1889,12 @@ static inline int defaultDepth() static inline xcb_rectangle_t fromQt(const QRect &rect) { + const QRect nativeRect = toXNative(rect); xcb_rectangle_t rectangle; - rectangle.x = rect.x(); - rectangle.y = rect.y(); - rectangle.width = rect.width(); - rectangle.height = rect.height(); + rectangle.x = nativeRect.x(); + rectangle.y = nativeRect.y(); + rectangle.width = nativeRect.width(); + rectangle.height = nativeRect.height(); return rectangle; } diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 1ece1f7177..b4e487aff2 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -357,10 +357,10 @@ SurfaceInterface::SurfaceInterface(CompositorInterface *compositor, wl_resource d->init(resource); d->client = compositor->display()->getConnection(d->resource()->client()); - d->scaleOverride = d->client->scaleOverride(); + d->pendingScaleOverride = d->client->scaleOverride(); + d->scaleOverride = d->pendingScaleOverride; connect(d->client, &ClientConnection::scaleOverrideChanged, this, [this]() { - d->scaleOverride = d->client->scaleOverride(); - // TODO before merging we should do some applyState() with the current state + d->pendingScaleOverride = d->client->scaleOverride(); }); } @@ -561,6 +561,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) const QRegion oldInputRegion = inputRegion; next->mergeInto(¤t); + scaleOverride = pendingScaleOverride; if (lockedPointer) { auto lockedPointerPrivate = LockedPointerV1InterfacePrivate::get(lockedPointer); @@ -607,7 +608,6 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) } else { surfaceSize = implicitSurfaceSize; } - surfaceSize = implicitSurfaceSize; const QRect surfaceRect(QPoint(0, 0), surfaceSize); inputRegion = current.input & surfaceRect; @@ -618,7 +618,10 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) opaqueRegion = current.opaque & surfaceRect; } - const QMatrix4x4 scaleOverrideMatrix(QTransform::fromScale(1. / scaleOverride, 1. / scaleOverride)); + QMatrix4x4 scaleOverrideMatrix; + if (scaleOverride != 1.) { + scaleOverrideMatrix.scale(1. / scaleOverride, 1. / scaleOverride); + } opaqueRegion = map_helper(scaleOverrideMatrix, opaqueRegion); inputRegion = map_helper(scaleOverrideMatrix, inputRegion); diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index b208c35a42..f37b9bce72 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -114,6 +114,7 @@ public: bool mapped = false; bool hasCacheState = false; qreal scaleOverride = 1.; + qreal pendingScaleOverride = 1.; QVector outputs; diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 4007726aad..68a3f584d7 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -642,6 +642,12 @@ int WaylandServer::createXWaylandConnection() return -1; } m_xwaylandConnection = socket.connection; + + m_xwaylandConnection->setScaleOverride(kwinApp()->xwaylandScale()); + connect(kwinApp(), &Application::xwaylandScaleChanged, m_xwaylandConnection, [this]() { + m_xwaylandConnection->setScaleOverride(kwinApp()->xwaylandScale()); + }); + return socket.fd; } diff --git a/src/window.cpp b/src/window.cpp index 5479c81a8a..b2fe9d8540 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -485,7 +485,7 @@ void Window::getWmOpaqueRegion() const auto rects = info->opaqueRegion(); QRegion new_opaque_region; for (const auto &r : rects) { - new_opaque_region += QRect(r.pos.x, r.pos.y, r.size.width, r.size.height); + new_opaque_region += Xcb::fromXNative(QRect(r.pos.x, r.pos.y, r.size.width, r.size.height)); } opaque_region = new_opaque_region; @@ -507,7 +507,7 @@ QRegion Window::shapeRegion() const const xcb_rectangle_t *rects = xcb_shape_get_rectangles_rectangles(reply.data()); const int rectCount = xcb_shape_get_rectangles_rectangles_length(reply.data()); for (int i = 0; i < rectCount; ++i) { - m_shapeRegion += QRegion(rects[i].x, rects[i].y, rects[i].width, rects[i].height); + m_shapeRegion += Xcb::fromXNative(QRect(rects[i].x, rects[i].y, rects[i].width, rects[i].height)); } // make sure the shape is sane (X is async, maybe even XShape is broken) m_shapeRegion &= QRegion(0, 0, bufferGeometry.width(), bufferGeometry.height()); diff --git a/src/workspace.cpp b/src/workspace.cpp index 698b3dd72a..c0d3e1a83c 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -2032,8 +2032,8 @@ void Workspace::desktopResized() if (rootInfo()) { NETSize desktop_geometry; - desktop_geometry.width = m_geometry.width(); - desktop_geometry.height = m_geometry.height(); + desktop_geometry.width = Xcb::toXNative(m_geometry.width()); + desktop_geometry.height = Xcb::toXNative(m_geometry.height()); rootInfo()->setDesktopGeometry(desktop_geometry); } @@ -2219,13 +2219,9 @@ void Workspace::updateClientArea() m_restrictedAreas = restrictedAreas; if (rootInfo()) { - NETRect r; for (VirtualDesktop *desktop : desktops) { const QRect &workArea = m_workAreas[desktop]; - r.pos.x = workArea.x(); - r.pos.y = workArea.y(); - r.size.width = workArea.width(); - r.size.height = workArea.height(); + NETRect r(Xcb::toXNative(workArea)); rootInfo()->setWorkArea(desktop->x11DesktopNumber(), r); } } @@ -2822,7 +2818,7 @@ void Workspace::fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_rep // left and top needed due to narrowing conversations restrictions in C++11 const uint32_t left = frame.left; const uint32_t top = frame.top; - const uint32_t values[] = {geometry->x - left, geometry->y - top}; + const uint32_t values[] = {Xcb::toXNative(geometry->x - left), Xcb::toXNative(geometry->y - top)}; xcb_configure_window(kwinApp()->x11Connection(), w, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values); } } diff --git a/src/x11window.cpp b/src/x11window.cpp index 3c91ae3038..936f924a90 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -1242,7 +1242,10 @@ void X11Window::updateFrameExtents() void X11Window::setClientFrameExtents(const NETStrut &strut) { - const QMargins clientFrameExtents(strut.left, strut.top, strut.right, strut.bottom); + const QMargins clientFrameExtents(Xcb::fromXNative(strut.left), + Xcb::fromXNative(strut.top), + Xcb::fromXNative(strut.right), + Xcb::fromXNative(strut.bottom)); if (m_clientFrameExtents == clientFrameExtents) { return; } @@ -1345,8 +1348,14 @@ void X11Window::updateShape() updateDecoration(true); } if (!isDecorated()) { - xcb_shape_combine(kwinApp()->x11Connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, - frameId(), clientPos().x(), clientPos().y(), window()); + xcb_shape_combine(kwinApp()->x11Connection(), + XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, + XCB_SHAPE_SK_BOUNDING, + frameId(), + Xcb::toXNative(clientPos().x()), + Xcb::toXNative(clientPos().y()), + window()); } } else if (app_noborder) { xcb_shape_mask(kwinApp()->x11Connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, frameId(), 0, 0, XCB_PIXMAP_NONE); @@ -1388,14 +1397,27 @@ void X11Window::updateInputShape() if (!shape_helper_window.isValid()) { shape_helper_window.create(QRect(0, 0, 1, 1)); } - shape_helper_window.resize(m_bufferGeometry.size()); + const QSize bufferSize = m_bufferGeometry.size(); + shape_helper_window.resize(QSize(Xcb::toXNative(bufferSize.width()), Xcb::toXNative(bufferSize.height()))); xcb_connection_t *c = kwinApp()->x11Connection(); xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_BOUNDING, shape_helper_window, 0, 0, frameId()); - xcb_shape_combine(c, XCB_SHAPE_SO_SUBTRACT, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_BOUNDING, - shape_helper_window, clientPos().x(), clientPos().y(), window()); - xcb_shape_combine(c, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_INPUT, - shape_helper_window, clientPos().x(), clientPos().y(), window()); + xcb_shape_combine(c, + XCB_SHAPE_SO_SUBTRACT, + XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_BOUNDING, + shape_helper_window, + Xcb::toXNative(clientPos().x()), + Xcb::toXNative(clientPos().y()), + window()); + xcb_shape_combine(c, + XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, + shape_helper_window, + Xcb::toXNative(clientPos().x()), + Xcb::toXNative(clientPos().y()), + window()); xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_INPUT, frameId(), 0, 0, shape_helper_window); } @@ -3744,10 +3766,10 @@ void X11Window::sendSyntheticConfigureNotify() u.event.response_type = XCB_CONFIGURE_NOTIFY; u.event.event = window(); u.event.window = window(); - u.event.x = m_clientGeometry.x(); - u.event.y = m_clientGeometry.y(); - u.event.width = m_clientGeometry.width(); - u.event.height = m_clientGeometry.height(); + u.event.x = Xcb::toXNative(m_clientGeometry.x()); + u.event.y = Xcb::toXNative(m_clientGeometry.y()); + u.event.width = Xcb::toXNative(m_clientGeometry.width()); + u.event.height = Xcb::toXNative(m_clientGeometry.height()); u.event.border_width = 0; u.event.above_sibling = XCB_WINDOW_NONE; u.event.override_redirect = 0; @@ -4035,6 +4057,7 @@ void X11Window::resizeWithChecks(int w, int h, xcb_gravity_t gravity) } // _NET_MOVERESIZE_WINDOW +// note co-ordinates are kwin logical void X11Window::NETMoveResizeWindow(int flags, int x, int y, int width, int height) { int gravity = flags & 0xff; @@ -4630,7 +4653,7 @@ bool X11Window::doStartInteractiveMoveResize() // something with Enter/LeaveNotify events, looks like XFree performance problem or something *shrug* // (https://lists.kde.org/?t=107302193400001&r=1&w=2) QRect r = workspace()->clientArea(FullArea, this); - m_moveResizeGrabWindow.create(r, XCB_WINDOW_CLASS_INPUT_ONLY, 0, nullptr, kwinApp()->x11RootWindow()); + m_moveResizeGrabWindow.create(Xcb::toXNative(r), XCB_WINDOW_CLASS_INPUT_ONLY, 0, nullptr, kwinApp()->x11RootWindow()); m_moveResizeGrabWindow.map(); m_moveResizeGrabWindow.raise(); updateXTime();