summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com>2025-02-16 00:20:42 +0000
committerGitHub <noreply@github.com>2025-02-16 01:20:42 +0100
commit897ee276dc0a8a6b11a8102b225a9e969faac0bf (patch)
tree4285cd2e7c1840ae7b80d6730af6250246c5d878 /src
parent94a30889a78fa7c7f87fe8134c18357855824c35 (diff)
xwayland: configure on a configure request and cleanup geometry conversion (#9375)
* xwayland: configure the window on a configure request * xwayland: move coordinate conversion handling to their own functions * xwayland: rename configure to configureRequest
Diffstat (limited to 'src')
-rw-r--r--src/desktop/Window.cpp120
-rw-r--r--src/desktop/Window.hpp9
-rw-r--r--src/xwayland/XSurface.hpp4
-rw-r--r--src/xwayland/XWM.cpp9
-rw-r--r--src/xwayland/XWM.hpp2
5 files changed, 91 insertions, 53 deletions
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp
index 7c0cb741..7b7f954d 100644
--- a/src/desktop/Window.cpp
+++ b/src/desktop/Window.cpp
@@ -95,15 +95,15 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
m_pWLSurface = CWLSurface::create();
- listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
- listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
- listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
- listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
- listeners.configure = m_pXWaylandSurface->events.configure.registerListener([this](std::any d) { onX11Configure(std::any_cast<CBox>(d)); });
- listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
- listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
- listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
- listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
+ listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
+ listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
+ listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
+ listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
+ listeners.configureRequest = m_pXWaylandSurface->events.configureRequest.registerListener([this](std::any d) { onX11ConfigureRequest(std::any_cast<CBox>(d)); });
+ listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
+ listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
+ listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
+ listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
if (m_pXWaylandSurface->overrideRedirect)
listeners.setGeometry = m_pXWaylandSurface->events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); });
@@ -1530,14 +1530,14 @@ void CWindow::onResourceChangeX11() {
Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface->resource().get());
}
-void CWindow::onX11Configure(CBox box) {
+void CWindow::onX11ConfigureRequest(CBox box) {
if (!m_pXWaylandSurface->surface || !m_pXWaylandSurface->mapped || !m_bIsMapped) {
m_pXWaylandSurface->configure(box);
m_vPendingReportedSize = box.size();
m_vReportedSize = box.size();
- if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
- m_fX11SurfaceScaledBy = PMONITOR->scale;
+ m_vReportedPosition = box.pos();
+ updateX11SurfaceScale();
return;
}
@@ -1555,25 +1555,20 @@ void CWindow::onX11Configure(CBox box) {
else
setHidden(true);
- const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos());
-
- m_vRealPosition->setValueAndWarp(LOGICALPOS);
- m_vRealSize->setValueAndWarp(box.size());
-
- static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
- if (*PXWLFORCESCALEZERO) {
- if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) {
- m_vRealSize->setValueAndWarp(m_vRealSize->goal() / PMONITOR->scale);
- m_fX11SurfaceScaledBy = PMONITOR->scale;
- }
- }
+ m_vRealPosition->setValueAndWarp(xwaylandPositionToReal(box.pos()));
+ m_vRealSize->setValueAndWarp(xwaylandSizeToReal(box.size()));
m_vPosition = m_vRealPosition->goal();
m_vSize = m_vRealSize->goal();
- m_vPendingReportedSize = box.size();
- m_vReportedSize = box.size();
+ if (m_vPendingReportedSize != box.size() || m_vReportedPosition != box.pos()) {
+ m_pXWaylandSurface->configure(box);
+ m_vReportedSize = box.size();
+ m_vPendingReportedSize = box.size();
+ m_vReportedPosition = box.pos();
+ }
+ updateX11SurfaceScale();
updateWindowDecos();
if (!m_pWorkspace || !m_pWorkspace->isVisible())
@@ -1700,37 +1695,74 @@ Vector2D CWindow::requestedMaxSize() {
return maxSize;
}
-void CWindow::sendWindowSize(bool force) {
+Vector2D CWindow::realToReportSize() {
+ if (!m_bIsX11)
+ return m_vRealSize->goal().clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
+
+ static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
+
+ const auto REPORTSIZE = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
+ const auto PMONITOR = m_pMonitor.lock();
+
+ if (*PXWLFORCESCALEZERO && PMONITOR)
+ return REPORTSIZE * PMONITOR->scale;
+
+ return REPORTSIZE;
+}
+
+Vector2D CWindow::realToReportPosition() {
+ if (!m_bIsX11)
+ return m_vRealPosition->goal();
+
+ return g_pXWaylandManager->waylandToXWaylandCoords(m_vRealPosition->goal());
+}
+
+Vector2D CWindow::xwaylandSizeToReal(Vector2D size) {
+ static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
+
+ const auto PMONITOR = m_pMonitor.lock();
+ const auto SIZE = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
+ const auto SCALE = *PXWLFORCESCALEZERO ? PMONITOR->scale : 1.0f;
+
+ return SIZE / SCALE;
+}
+
+Vector2D CWindow::xwaylandPositionToReal(Vector2D pos) {
+ return g_pXWaylandManager->xwaylandToWaylandCoords(pos);
+}
+
+void CWindow::updateX11SurfaceScale() {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
- const auto PMONITOR = m_pMonitor.lock();
+
+ m_fX11SurfaceScaledBy = 1.0f;
+ if (m_bIsX11 && *PXWLFORCESCALEZERO) {
+ if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
+ m_fX11SurfaceScaledBy = PMONITOR->scale;
+ }
+}
+
+void CWindow::sendWindowSize(bool force) {
+ const auto PMONITOR = m_pMonitor.lock();
Debug::log(TRACE, "sendWindowSize: window:{:x},title:{} with real pos {}, real size {} (force: {})", (uintptr_t)this, this->m_szTitle, m_vRealPosition->goal(),
m_vRealSize->goal(), force);
// TODO: this should be decoupled from setWindowSize IMO
- Vector2D windowPos = m_vRealPosition->goal();
- Vector2D size = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
+ const auto REPORTPOS = realToReportPosition();
- if (m_bIsX11 && PMONITOR) {
- windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos);
- if (*PXWLFORCESCALEZERO)
- size *= PMONITOR->scale;
- }
+ const auto REPORTSIZE = realToReportSize();
- if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11))
+ if (!force && m_vPendingReportedSize == REPORTSIZE && (m_vReportedPosition == REPORTPOS || !m_bIsX11))
return;
- m_vReportedPosition = windowPos;
- m_vPendingReportedSize = size;
- m_fX11SurfaceScaledBy = 1.0f;
-
- if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR)
- m_fX11SurfaceScaledBy = PMONITOR->scale;
+ m_vReportedPosition = REPORTPOS;
+ m_vPendingReportedSize = REPORTSIZE;
+ updateX11SurfaceScale();
if (m_bIsX11 && m_pXWaylandSurface)
- m_pXWaylandSurface->configure({windowPos, size});
+ m_pXWaylandSurface->configure({REPORTPOS, REPORTSIZE});
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
- m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor());
+ m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(REPORTSIZE), REPORTPOS.floor());
}
NContentType::eContentType CWindow::getContentType() {
diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp
index 171a15f4..bc32bab4 100644
--- a/src/desktop/Window.hpp
+++ b/src/desktop/Window.hpp
@@ -460,7 +460,7 @@ class CWindow {
void onFocusAnimUpdate();
void onUpdateState();
void onUpdateMeta();
- void onX11Configure(CBox box);
+ void onX11ConfigureRequest(CBox box);
void onResourceChangeX11();
std::string fetchTitle();
std::string fetchClass();
@@ -471,6 +471,11 @@ class CWindow {
bool isModal();
Vector2D requestedMinSize();
Vector2D requestedMaxSize();
+ Vector2D realToReportSize();
+ Vector2D realToReportPosition();
+ Vector2D xwaylandSizeToReal(Vector2D size);
+ Vector2D xwaylandPositionToReal(Vector2D size);
+ void updateX11SurfaceScale();
void sendWindowSize(bool force = false);
NContentType::eContentType getContentType();
void setContentType(NContentType::eContentType contentType);
@@ -497,7 +502,7 @@ class CWindow {
CHyprSignalListener commit;
CHyprSignalListener destroy;
CHyprSignalListener activate;
- CHyprSignalListener configure;
+ CHyprSignalListener configureRequest;
CHyprSignalListener setGeometry;
CHyprSignalListener updateState;
CHyprSignalListener updateMetadata;
diff --git a/src/xwayland/XSurface.hpp b/src/xwayland/XSurface.hpp
index 7584354e..55e96078 100644
--- a/src/xwayland/XSurface.hpp
+++ b/src/xwayland/XSurface.hpp
@@ -50,7 +50,7 @@ class CXWaylandSurface {
CSignal resourceChange; // associated / dissociated
CSignal setGeometry;
- CSignal configure; // CBox
+ CSignal configureRequest; // CBox
CSignal map;
CSignal unmap;
@@ -116,4 +116,4 @@ class CXWaylandSurface {
} listeners;
friend class CXWM;
-}; \ No newline at end of file
+};
diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp
index f2a9b794..a4e3289b 100644
--- a/src/xwayland/XWM.cpp
+++ b/src/xwayland/XWM.cpp
@@ -59,7 +59,7 @@ void CXWM::handleDestroy(xcb_destroy_notify_event_t* e) {
std::erase_if(surfaces, [XSURF](const auto& other) { return XSURF == other; });
}
-void CXWM::handleConfigure(xcb_configure_request_event_t* e) {
+void CXWM::handleConfigureRequest(xcb_configure_request_event_t* e) {
const auto XSURF = windowForXID(e->window);
if (!XSURF)
@@ -70,8 +70,9 @@ void CXWM::handleConfigure(xcb_configure_request_event_t* e) {
if (!(MASK & GEOMETRY))
return;
- XSURF->events.configure.emit(CBox{MASK & XCB_CONFIG_WINDOW_X ? e->x : XSURF->geometry.x, MASK & XCB_CONFIG_WINDOW_Y ? e->y : XSURF->geometry.y,
- MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width, MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height});
+ XSURF->events.configureRequest.emit(CBox{MASK & XCB_CONFIG_WINDOW_X ? e->x : XSURF->geometry.x, MASK & XCB_CONFIG_WINDOW_Y ? e->y : XSURF->geometry.y,
+ MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width,
+ MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height});
}
void CXWM::handleConfigureNotify(xcb_configure_notify_event_t* e) {
@@ -758,7 +759,7 @@ int CXWM::onEvent(int fd, uint32_t mask) {
switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
case XCB_CREATE_NOTIFY: handleCreate((xcb_create_notify_event_t*)event); break;
case XCB_DESTROY_NOTIFY: handleDestroy((xcb_destroy_notify_event_t*)event); break;
- case XCB_CONFIGURE_REQUEST: handleConfigure((xcb_configure_request_event_t*)event); break;
+ case XCB_CONFIGURE_REQUEST: handleConfigureRequest((xcb_configure_request_event_t*)event); break;
case XCB_CONFIGURE_NOTIFY: handleConfigureNotify((xcb_configure_notify_event_t*)event); break;
case XCB_MAP_REQUEST: handleMapRequest((xcb_map_request_event_t*)event); break;
case XCB_MAP_NOTIFY: handleMapNotify((xcb_map_notify_event_t*)event); break;
diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp
index f6dcee54..4326c77b 100644
--- a/src/xwayland/XWM.hpp
+++ b/src/xwayland/XWM.hpp
@@ -148,7 +148,7 @@ class CXWM {
// event handlers
void handleCreate(xcb_create_notify_event_t* e);
void handleDestroy(xcb_destroy_notify_event_t* e);
- void handleConfigure(xcb_configure_request_event_t* e);
+ void handleConfigureRequest(xcb_configure_request_event_t* e);
void handleConfigureNotify(xcb_configure_notify_event_t* e);
void handleMapRequest(xcb_map_request_event_t* e);
void handleMapNotify(xcb_map_notify_event_t* e);