Support an alternative harcoded scale for X

Anything in xcb_ structs are always in X local, all member variables
aside from buffers are in kwin local space.

This patch ignores a few paths that are not relevant on wayland.
This commit is contained in:
David Edmundson 2022-02-02 04:35:13 +01:00
parent d70bd2435b
commit 419c0b81fd
16 changed files with 201 additions and 68 deletions

View file

@ -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

View file

@ -0,0 +1,30 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2022 Aleix Pol Gonzalez <aleixpol@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <utils/xcbutils.h>
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;
}
}

View file

@ -441,9 +441,15 @@ bool X11Window::windowEvent(xcb_generic_event_t *e)
}
case XCB_MOTION_NOTIFY: {
const auto *event = reinterpret_cast<xcb_motion_notify_event_t *>(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<xcb_leave_notify_event_t *>(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<EffectsHandlerImpl *>(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;

View file

@ -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;

View file

@ -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()

View file

@ -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();

View file

@ -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));
}
}

View file

@ -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();

View file

@ -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

View file

@ -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<uint32_t>(geometry.x()),
static_cast<uint32_t>(geometry.y()),
static_cast<uint32_t>(geometry.width()),
static_cast<uint32_t>(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;
}

View file

@ -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(&current);
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);

View file

@ -114,6 +114,7 @@ public:
bool mapped = false;
bool hasCacheState = false;
qreal scaleOverride = 1.;
qreal pendingScaleOverride = 1.;
QVector<OutputInterface *> outputs;

View file

@ -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;
}

View file

@ -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());

View file

@ -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);
}
}

View file

@ -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();