diff --git a/atoms.h b/atoms.h --- a/atoms.h +++ b/atoms.h @@ -88,6 +88,7 @@ Xcb::Atom delete_atom; Xcb::Atom incr; Xcb::Atom wl_selection; + Xcb::Atom xwayland_randr_emu_monitor_rects; /** * @internal diff --git a/atoms.cpp b/atoms.cpp --- a/atoms.cpp +++ b/atoms.cpp @@ -81,6 +81,7 @@ , wl_selection(QByteArrayLiteral("WL_SELECTION")) , m_dtSmWindowInfo(QByteArrayLiteral("_DT_SM_WINDOW_INFO")) , m_motifSupport(QByteArrayLiteral("_MOTIF_WM_INFO")) + , xwayland_randr_emu_monitor_rects(QByteArrayLiteral("_XWAYLAND_RANDR_EMU_MONITOR_RECTS")) , m_helpersRetrieved(false) { } diff --git a/geometry.cpp b/geometry.cpp --- a/geometry.cpp +++ b/geometry.cpp @@ -27,6 +27,7 @@ */ +#include "atoms.h" #include "x11client.h" #include "composite.h" #include "cursor.h" @@ -1576,8 +1577,49 @@ c.window = window(); c.x = m_clientGeometry.x(); c.y = m_clientGeometry.y(); + + auto getEmulatedXWaylandSize = [this]() { + auto property = Xcb::Property(false, window(), + atoms->xwayland_randr_emu_monitor_rects, XCB_ATOM_CARDINAL, + 0, 1000); + if (!property) { + return QSize(); + } + uint32_t *rects = property.value(); + + if (property->value_len % 4) { + return QSize(); + } + + for (uint32_t i = 0; i < property->value_len / 4; i++) { + uint32_t *r = &rects[i]; + if (r[0] - m_clientGeometry.x() == 0 && r[1] - m_clientGeometry.y() == 0) { + return QSize(r[2], r[3]); + } + } + return QSize(); + }; + c.width = m_clientGeometry.width(); c.height = m_clientGeometry.height(); + + if (isFullScreen()) { + // Workaround for XWayland clients setting fullscreen + const QSize emulatedSize = getEmulatedXWaylandSize(); + if (emulatedSize.isValid()) { + c.width = emulatedSize.width(); + c.height = emulatedSize.height(); + const uint32_t values[] = { c.width, c.height }; + ScopedCPointer error(xcb_request_check(connection(), + xcb_configure_window_checked(connection(), c.window, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + values))); + if (!error.isNull()) { + qCDebug(KWIN_CORE) << "Error on emulating XWayland size: " << error->error_code; + } + } + } + c.border_width = 0; c.above_sibling = XCB_WINDOW_NONE; c.override_redirect = 0;