Skip to content

Commit

Permalink
fix: use native resolution in X11 layershell emu
Browse files Browse the repository at this point in the history
Log:
  • Loading branch information
RigoLigoRLC committed Oct 18, 2024
1 parent 2264369 commit 6329385
Showing 1 changed file with 47 additions and 14 deletions.
61 changes: 47 additions & 14 deletions frame/layershell/x11dlayershellemulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <QGuiApplication>
#include <QLoggingCategory>

#include <private/qhighdpiscaling_p.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformscreen_p.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformwindow_p.h>

Expand Down Expand Up @@ -104,42 +107,72 @@ void LayerShellEmulation::onLayerChanged()

void LayerShellEmulation::onPositionChanged()
{
// Work around QPA abstraction so we can use physical pixels, not logical pixels after Qt DPI transformation
auto platformScreen = m_window->screen()->handle();
qreal factor = QHighDpiScaling::factor(platformScreen);

// These geometries are in physical pixels
auto windowGeometry = m_window->handle()->geometry();
auto screenGeom = platformScreen->geometry();

auto anchors = m_dlayerShellWindow->anchors();
auto screen = m_window->screen();
auto screenRect = screen->geometry();
auto x = screenRect.left() + (screenRect.width() - m_window->width()) / 2;
auto y = screenRect.top() + (screenRect.height() - m_window->height()) / 2;
auto x = screenGeom.left() + (screenGeom.width() - windowGeometry.width()) / 2;
auto y = screenGeom.top() + (screenGeom.height() - windowGeometry.height()) / 2;

// Set
if (anchors & DLayerShellWindow::AnchorRight) {
// https://doc.qt.io/qt-6/qrect.html#right
x = (screen->geometry().right() + 1 - m_window->width() - m_dlayerShellWindow->rightMargin());
x = (screenGeom.right() + 1 - windowGeometry.width() - qRound(m_dlayerShellWindow->rightMargin() * factor));
}

if (anchors & DLayerShellWindow::AnchorBottom) {
// https://doc.qt.io/qt-6/qrect.html#bottom
y = (screen->geometry().bottom() + 1 - m_window->height() - m_dlayerShellWindow->bottomMargin());
y = (screenGeom.bottom() + 1 - windowGeometry.height() - qRound(m_dlayerShellWindow->bottomMargin() * factor));
}
if (anchors & DLayerShellWindow::AnchorLeft) {
x = (screen->geometry().left() + m_dlayerShellWindow->leftMargin());
x = (screenGeom.left() + qRound(m_dlayerShellWindow->leftMargin() * factor));
}
if (anchors & DLayerShellWindow::AnchorTop) {
y = (screen->geometry().top() + m_dlayerShellWindow->topMargin());
y = (screenGeom.top() + qRound(m_dlayerShellWindow->topMargin() * factor));
}

QRect rect(x, y, m_window->width(), m_window->height());
QRect rect(x, y, windowGeometry.width(), windowGeometry.height());

const bool horizontallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorLeft, DLayerShellWindow::AnchorRight});
const bool verticallyConstrained = anchors.testFlags({DLayerShellWindow::AnchorTop, DLayerShellWindow::AnchorBottom});

if (horizontallyConstrained) {
rect.setX(screen->geometry().left() + m_dlayerShellWindow->leftMargin());
rect.setWidth(screen->geometry().width() - m_dlayerShellWindow->leftMargin() - m_dlayerShellWindow->rightMargin());
rect.setX(screenGeom.left() + qRound(m_dlayerShellWindow->leftMargin() * factor));
rect.setWidth(screenGeom.width() - qRound((m_dlayerShellWindow->leftMargin() + m_dlayerShellWindow->rightMargin()) * factor));
}
if (verticallyConstrained) {
rect.setY(screen->geometry().top() + m_dlayerShellWindow->topMargin());
rect.setHeight(screen->geometry().height() - m_dlayerShellWindow->topMargin() - m_dlayerShellWindow->bottomMargin());
rect.setY(screenGeom.top() + qRound(m_dlayerShellWindow->topMargin() * factor));
rect.setHeight(screenGeom.height() - qRound((m_dlayerShellWindow->topMargin() + m_dlayerShellWindow->bottomMargin()) * factor));
}

m_window->setGeometry(rect);
// Configure window geometry via XCB interface
auto x11App = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
auto xcbConnection = x11App->connection();
auto xcbWindow = m_window->winId();
uint16_t mask = 0;
struct {
int32_t x;
int32_t y;
uint32_t width;
uint32_t height;
} targetWindowRect;

targetWindowRect.x = rect.x();
targetWindowRect.y = rect.y();
targetWindowRect.width = rect.width();
targetWindowRect.height = rect.height();
mask |= XCB_CONFIG_WINDOW_X;
mask |= XCB_CONFIG_WINDOW_Y;
mask |= XCB_CONFIG_WINDOW_WIDTH;
mask |= XCB_CONFIG_WINDOW_HEIGHT;

xcb_configure_window(xcbConnection, xcbWindow, mask, &targetWindowRect);
xcb_flush(xcbConnection);
}

/**
Expand Down

0 comments on commit 6329385

Please sign in to comment.