From 0de69fbb4df1bcfb6e9d7a5ea309e03618e066c6 Mon Sep 17 00:00:00 2001 From: rewine Date: Tue, 5 Nov 2024 16:00:23 +0800 Subject: [PATCH] Support only configure position or size for x11 --- src/server/protocols/wxwaylandsurface.cpp | 106 ++++++++++++++++++++ src/server/protocols/wxwaylandsurface.h | 3 + src/server/qtquick/wxwaylandsurfaceitem.cpp | 23 +++-- 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/server/protocols/wxwaylandsurface.cpp b/src/server/protocols/wxwaylandsurface.cpp index 95364a87..5b227e36 100644 --- a/src/server/protocols/wxwaylandsurface.cpp +++ b/src/server/protocols/wxwaylandsurface.cpp @@ -45,6 +45,8 @@ class Q_DECL_HIDDEN WXWaylandSurfacePrivate : public WToplevelSurfacePrivate void updateChildren(); void updateParent(); void updateWindowTypes(); + void doConfigureSize(uint16_t width, uint16_t height); + void doConfigurePosition(int16_t x, int16_t y); W_DECLARE_PUBLIC(WXWaylandSurface) @@ -241,6 +243,98 @@ void WXWaylandSurfacePrivate::updateWindowTypes() Q_EMIT q_func()->windowTypesChanged(); } +void WXWaylandSurfacePrivate::doConfigureSize(uint16_t width, uint16_t height) { + // auto xsurface = nativeHandle(); + // xsurface->width = width; + // xsurface->height = height; + + // uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + // uint32_t values[] = { width, height }; + // qDebug() << Q_FUNC_INFO << " " << width << " " << height; + // xcb_configure_window(xwayland->xcbConnection(), xsurface->window_id, mask, values); + + // xcb_flush(xwayland->xcbConnection()); + + auto xsurface = handle()->handle(); + int old_w = xsurface->width; + int old_h = xsurface->height; + + xsurface->x = 100; + xsurface->y = 100; + xsurface->width = width; + xsurface->height = height; + + struct wlr_xwm *xwm = xsurface->xwm; + uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | + XCB_CONFIG_WINDOW_BORDER_WIDTH; + uint32_t values[] = {100, 100, width, height, 0}; + xcb_configure_window(xwayland->xcbConnection(), xsurface->window_id, mask, values); + + // If the window size did not change, then we cannot rely on + // the X server to generate a ConfigureNotify event. Instead, + // we are supposed to send a synthetic event. See ICCCM part + // 4.1.5. But we ignore override-redirect windows as ICCCM does + // not apply to them. + if (width == old_w && height == old_h && !xsurface->override_redirect) { + xcb_configure_notify_event_t configure_notify = { + .response_type = XCB_CONFIGURE_NOTIFY, + .event = xsurface->window_id, + .window = xsurface->window_id, + .x = 100, + .y = 100, + .width = width, + .height = height, + }; + + xcb_send_event(xwayland->xcbConnection(), 0, xsurface->window_id, + XCB_EVENT_MASK_STRUCTURE_NOTIFY, + (const char *)&configure_notify); + } + + xcb_flush(xwayland->xcbConnection()); + + + //wlr_xwayland_surface_configure(q_func()->handle()->handle(),100,100,width,height); +} + +void WXWaylandSurfacePrivate::doConfigurePosition(int16_t x, int16_t y) +{ + return; + auto xsurface = nativeHandle(); + + xsurface->x = x; + xsurface->y = y; + + uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + uint32_t values[] = { (uint32_t)x, (uint32_t)y }; + xcb_configure_window(xwayland->xcbConnection(), xsurface->window_id, mask, values); + + // If the window size did not change, then we cannot rely on + // the X server to generate a ConfigureNotify event. Instead, + // we are supposed to send a synthetic event. See ICCCM part + // 4.1.5. But we ignore override-redirect windows as ICCCM does + // not apply to them. + if (!xsurface->override_redirect) { + xcb_configure_notify_event_t configure_notify = { + .response_type = XCB_CONFIGURE_NOTIFY, + .event = xsurface->window_id, + .window = xsurface->window_id, + .x = x, + .y = y, + .width = xsurface->width, + .height = xsurface->height, + }; + + xcb_send_event(xwayland->xcbConnection(), 0, xsurface->window_id, + XCB_EVENT_MASK_STRUCTURE_NOTIFY, + (const char *)&configure_notify); + } + + xcb_flush(xwayland->xcbConnection()); +} + + WXWaylandSurface::WXWaylandSurface(qw_xwayland_surface *handle, WXWayland *xwayland, QObject *parent) : WToplevelSurface(*new WXWaylandSurfacePrivate(this, handle, xwayland), parent) { @@ -461,6 +555,18 @@ WXWaylandSurface::DecorationsType WXWaylandSurface::decorationsType() const return static_cast(d->nativeHandle()->decorations); } +void WXWaylandSurface::configureSize(uint16_t width, uint16_t height) +{ + W_D(WXWaylandSurface); + d->doConfigureSize(width, height); +} + +void WXWaylandSurface::configurePosition(int16_t x, int16_t y) +{ + W_D(WXWaylandSurface); + d->doConfigurePosition(x, y); +} + bool WXWaylandSurface::checkNewSize(const QSize &size) { const QSize minSize = this->minSize(); diff --git a/src/server/protocols/wxwaylandsurface.h b/src/server/protocols/wxwaylandsurface.h index d1308720..c032358b 100644 --- a/src/server/protocols/wxwaylandsurface.h +++ b/src/server/protocols/wxwaylandsurface.h @@ -113,6 +113,9 @@ class WAYLIB_SERVER_EXPORT WXWaylandSurface : public WToplevelSurface WindowTypes windowTypes() const; DecorationsType decorationsType() const; + void configureSize(uint16_t width, uint16_t height); + void configurePosition(int16_t x, int16_t y); + public Q_SLOTS: bool checkNewSize(const QSize &size) override; void resize(const QSize &size) override; diff --git a/src/server/qtquick/wxwaylandsurfaceitem.cpp b/src/server/qtquick/wxwaylandsurfaceitem.cpp index c53a3e57..a17b747b 100644 --- a/src/server/qtquick/wxwaylandsurfaceitem.cpp +++ b/src/server/qtquick/wxwaylandsurfaceitem.cpp @@ -13,7 +13,8 @@ class Q_DECL_HIDDEN WXWaylandSurfaceItemPrivate : public WSurfaceItemPrivate { Q_DECLARE_PUBLIC(WXWaylandSurfaceItem) public: - void configureSurface(const QRect &newGeometry); + void configureSurfaceSize(const QSize &newSize); + void configureSurfacePosition(const QPoint &newPosition); QSize expectSurfaceSize() const; QPoint explicitSurfacePosition() const; static inline WXWaylandSurfaceItemPrivate *get(WXWaylandSurfaceItem *qq) { @@ -27,15 +28,25 @@ class Q_DECL_HIDDEN WXWaylandSurfaceItemPrivate : public WSurfaceItemPrivate QSize maximumSize; }; -void WXWaylandSurfaceItemPrivate::configureSurface(const QRect &newGeometry) +void WXWaylandSurfaceItemPrivate::configureSurfaceSize(const QSize &newSize) { Q_Q(WXWaylandSurfaceItem); if (!q->isVisible()) return; - q->xwaylandSurface()->configure(newGeometry); + q->xwaylandSurface()->configureSize(newSize.width(), newSize.height()); q->updateSurfaceState(); } +void WXWaylandSurfaceItemPrivate::configureSurfacePosition(const QPoint &newPosition) +{ + Q_Q(WXWaylandSurfaceItem); + if (!q->isVisible()) + return; + q->xwaylandSurface()->configurePosition(newPosition.x(), newPosition.y()); + q->updateSurfaceState(); +} + + QSize WXWaylandSurfaceItemPrivate::expectSurfaceSize() const { const Q_Q(WXWaylandSurfaceItem); @@ -234,7 +245,8 @@ void WXWaylandSurfaceItem::initSurface() bool WXWaylandSurfaceItem::doResizeSurface(const QSize &newSize) { Q_D(WXWaylandSurfaceItem); - d->configureSurface(QRect(d->surfacePosition.toPoint(), newSize)); + + d->configureSurfaceSize(newSize); return true; } @@ -251,8 +263,7 @@ QSizeF WXWaylandSurfaceItem::getContentSize() const void WXWaylandSurfaceItem::updatePosition() { Q_D(WXWaylandSurfaceItem); - d->configureSurface(QRect(d->explicitSurfacePosition(), - d->expectSurfaceSize())); + d->configureSurfacePosition(d->explicitSurfacePosition()); } WAYLIB_SERVER_END_NAMESPACE