Skip to content

Commit 897ee27

Browse files
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
1 parent 94a3088 commit 897ee27

File tree

5 files changed

+91
-53
lines changed

5 files changed

+91
-53
lines changed

src/desktop/Window.cpp

+76-44
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,15 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
9595
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
9696
m_pWLSurface = CWLSurface::create();
9797

98-
listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
99-
listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
100-
listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
101-
listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
102-
listeners.configure = m_pXWaylandSurface->events.configure.registerListener([this](std::any d) { onX11Configure(std::any_cast<CBox>(d)); });
103-
listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
104-
listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
105-
listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
106-
listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
98+
listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
99+
listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
100+
listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
101+
listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
102+
listeners.configureRequest = m_pXWaylandSurface->events.configureRequest.registerListener([this](std::any d) { onX11ConfigureRequest(std::any_cast<CBox>(d)); });
103+
listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
104+
listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
105+
listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
106+
listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
107107

108108
if (m_pXWaylandSurface->overrideRedirect)
109109
listeners.setGeometry = m_pXWaylandSurface->events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); });
@@ -1530,14 +1530,14 @@ void CWindow::onResourceChangeX11() {
15301530
Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface->resource().get());
15311531
}
15321532

1533-
void CWindow::onX11Configure(CBox box) {
1533+
void CWindow::onX11ConfigureRequest(CBox box) {
15341534

15351535
if (!m_pXWaylandSurface->surface || !m_pXWaylandSurface->mapped || !m_bIsMapped) {
15361536
m_pXWaylandSurface->configure(box);
15371537
m_vPendingReportedSize = box.size();
15381538
m_vReportedSize = box.size();
1539-
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
1540-
m_fX11SurfaceScaledBy = PMONITOR->scale;
1539+
m_vReportedPosition = box.pos();
1540+
updateX11SurfaceScale();
15411541
return;
15421542
}
15431543

@@ -1555,25 +1555,20 @@ void CWindow::onX11Configure(CBox box) {
15551555
else
15561556
setHidden(true);
15571557

1558-
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos());
1559-
1560-
m_vRealPosition->setValueAndWarp(LOGICALPOS);
1561-
m_vRealSize->setValueAndWarp(box.size());
1562-
1563-
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
1564-
if (*PXWLFORCESCALEZERO) {
1565-
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) {
1566-
m_vRealSize->setValueAndWarp(m_vRealSize->goal() / PMONITOR->scale);
1567-
m_fX11SurfaceScaledBy = PMONITOR->scale;
1568-
}
1569-
}
1558+
m_vRealPosition->setValueAndWarp(xwaylandPositionToReal(box.pos()));
1559+
m_vRealSize->setValueAndWarp(xwaylandSizeToReal(box.size()));
15701560

15711561
m_vPosition = m_vRealPosition->goal();
15721562
m_vSize = m_vRealSize->goal();
15731563

1574-
m_vPendingReportedSize = box.size();
1575-
m_vReportedSize = box.size();
1564+
if (m_vPendingReportedSize != box.size() || m_vReportedPosition != box.pos()) {
1565+
m_pXWaylandSurface->configure(box);
1566+
m_vReportedSize = box.size();
1567+
m_vPendingReportedSize = box.size();
1568+
m_vReportedPosition = box.pos();
1569+
}
15761570

1571+
updateX11SurfaceScale();
15771572
updateWindowDecos();
15781573

15791574
if (!m_pWorkspace || !m_pWorkspace->isVisible())
@@ -1700,37 +1695,74 @@ Vector2D CWindow::requestedMaxSize() {
17001695
return maxSize;
17011696
}
17021697

1703-
void CWindow::sendWindowSize(bool force) {
1698+
Vector2D CWindow::realToReportSize() {
1699+
if (!m_bIsX11)
1700+
return m_vRealSize->goal().clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
1701+
1702+
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
1703+
1704+
const auto REPORTSIZE = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
1705+
const auto PMONITOR = m_pMonitor.lock();
1706+
1707+
if (*PXWLFORCESCALEZERO && PMONITOR)
1708+
return REPORTSIZE * PMONITOR->scale;
1709+
1710+
return REPORTSIZE;
1711+
}
1712+
1713+
Vector2D CWindow::realToReportPosition() {
1714+
if (!m_bIsX11)
1715+
return m_vRealPosition->goal();
1716+
1717+
return g_pXWaylandManager->waylandToXWaylandCoords(m_vRealPosition->goal());
1718+
}
1719+
1720+
Vector2D CWindow::xwaylandSizeToReal(Vector2D size) {
1721+
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
1722+
1723+
const auto PMONITOR = m_pMonitor.lock();
1724+
const auto SIZE = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
1725+
const auto SCALE = *PXWLFORCESCALEZERO ? PMONITOR->scale : 1.0f;
1726+
1727+
return SIZE / SCALE;
1728+
}
1729+
1730+
Vector2D CWindow::xwaylandPositionToReal(Vector2D pos) {
1731+
return g_pXWaylandManager->xwaylandToWaylandCoords(pos);
1732+
}
1733+
1734+
void CWindow::updateX11SurfaceScale() {
17041735
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
1705-
const auto PMONITOR = m_pMonitor.lock();
1736+
1737+
m_fX11SurfaceScaledBy = 1.0f;
1738+
if (m_bIsX11 && *PXWLFORCESCALEZERO) {
1739+
if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR)
1740+
m_fX11SurfaceScaledBy = PMONITOR->scale;
1741+
}
1742+
}
1743+
1744+
void CWindow::sendWindowSize(bool force) {
1745+
const auto PMONITOR = m_pMonitor.lock();
17061746

17071747
Debug::log(TRACE, "sendWindowSize: window:{:x},title:{} with real pos {}, real size {} (force: {})", (uintptr_t)this, this->m_szTitle, m_vRealPosition->goal(),
17081748
m_vRealSize->goal(), force);
17091749

17101750
// TODO: this should be decoupled from setWindowSize IMO
1711-
Vector2D windowPos = m_vRealPosition->goal();
1712-
Vector2D size = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
1751+
const auto REPORTPOS = realToReportPosition();
17131752

1714-
if (m_bIsX11 && PMONITOR) {
1715-
windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos);
1716-
if (*PXWLFORCESCALEZERO)
1717-
size *= PMONITOR->scale;
1718-
}
1753+
const auto REPORTSIZE = realToReportSize();
17191754

1720-
if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11))
1755+
if (!force && m_vPendingReportedSize == REPORTSIZE && (m_vReportedPosition == REPORTPOS || !m_bIsX11))
17211756
return;
17221757

1723-
m_vReportedPosition = windowPos;
1724-
m_vPendingReportedSize = size;
1725-
m_fX11SurfaceScaledBy = 1.0f;
1726-
1727-
if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR)
1728-
m_fX11SurfaceScaledBy = PMONITOR->scale;
1758+
m_vReportedPosition = REPORTPOS;
1759+
m_vPendingReportedSize = REPORTSIZE;
1760+
updateX11SurfaceScale();
17291761

17301762
if (m_bIsX11 && m_pXWaylandSurface)
1731-
m_pXWaylandSurface->configure({windowPos, size});
1763+
m_pXWaylandSurface->configure({REPORTPOS, REPORTSIZE});
17321764
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
1733-
m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor());
1765+
m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(REPORTSIZE), REPORTPOS.floor());
17341766
}
17351767

17361768
NContentType::eContentType CWindow::getContentType() {

src/desktop/Window.hpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ class CWindow {
460460
void onFocusAnimUpdate();
461461
void onUpdateState();
462462
void onUpdateMeta();
463-
void onX11Configure(CBox box);
463+
void onX11ConfigureRequest(CBox box);
464464
void onResourceChangeX11();
465465
std::string fetchTitle();
466466
std::string fetchClass();
@@ -471,6 +471,11 @@ class CWindow {
471471
bool isModal();
472472
Vector2D requestedMinSize();
473473
Vector2D requestedMaxSize();
474+
Vector2D realToReportSize();
475+
Vector2D realToReportPosition();
476+
Vector2D xwaylandSizeToReal(Vector2D size);
477+
Vector2D xwaylandPositionToReal(Vector2D size);
478+
void updateX11SurfaceScale();
474479
void sendWindowSize(bool force = false);
475480
NContentType::eContentType getContentType();
476481
void setContentType(NContentType::eContentType contentType);
@@ -497,7 +502,7 @@ class CWindow {
497502
CHyprSignalListener commit;
498503
CHyprSignalListener destroy;
499504
CHyprSignalListener activate;
500-
CHyprSignalListener configure;
505+
CHyprSignalListener configureRequest;
501506
CHyprSignalListener setGeometry;
502507
CHyprSignalListener updateState;
503508
CHyprSignalListener updateMetadata;

src/xwayland/XSurface.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class CXWaylandSurface {
5050
CSignal resourceChange; // associated / dissociated
5151

5252
CSignal setGeometry;
53-
CSignal configure; // CBox
53+
CSignal configureRequest; // CBox
5454

5555
CSignal map;
5656
CSignal unmap;
@@ -116,4 +116,4 @@ class CXWaylandSurface {
116116
} listeners;
117117

118118
friend class CXWM;
119-
};
119+
};

src/xwayland/XWM.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void CXWM::handleDestroy(xcb_destroy_notify_event_t* e) {
5959
std::erase_if(surfaces, [XSURF](const auto& other) { return XSURF == other; });
6060
}
6161

62-
void CXWM::handleConfigure(xcb_configure_request_event_t* e) {
62+
void CXWM::handleConfigureRequest(xcb_configure_request_event_t* e) {
6363
const auto XSURF = windowForXID(e->window);
6464

6565
if (!XSURF)
@@ -70,8 +70,9 @@ void CXWM::handleConfigure(xcb_configure_request_event_t* e) {
7070
if (!(MASK & GEOMETRY))
7171
return;
7272

73-
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,
74-
MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width, MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height});
73+
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,
74+
MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width,
75+
MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height});
7576
}
7677

7778
void CXWM::handleConfigureNotify(xcb_configure_notify_event_t* e) {
@@ -758,7 +759,7 @@ int CXWM::onEvent(int fd, uint32_t mask) {
758759
switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
759760
case XCB_CREATE_NOTIFY: handleCreate((xcb_create_notify_event_t*)event); break;
760761
case XCB_DESTROY_NOTIFY: handleDestroy((xcb_destroy_notify_event_t*)event); break;
761-
case XCB_CONFIGURE_REQUEST: handleConfigure((xcb_configure_request_event_t*)event); break;
762+
case XCB_CONFIGURE_REQUEST: handleConfigureRequest((xcb_configure_request_event_t*)event); break;
762763
case XCB_CONFIGURE_NOTIFY: handleConfigureNotify((xcb_configure_notify_event_t*)event); break;
763764
case XCB_MAP_REQUEST: handleMapRequest((xcb_map_request_event_t*)event); break;
764765
case XCB_MAP_NOTIFY: handleMapNotify((xcb_map_notify_event_t*)event); break;

src/xwayland/XWM.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class CXWM {
148148
// event handlers
149149
void handleCreate(xcb_create_notify_event_t* e);
150150
void handleDestroy(xcb_destroy_notify_event_t* e);
151-
void handleConfigure(xcb_configure_request_event_t* e);
151+
void handleConfigureRequest(xcb_configure_request_event_t* e);
152152
void handleConfigureNotify(xcb_configure_notify_event_t* e);
153153
void handleMapRequest(xcb_map_request_event_t* e);
154154
void handleMapNotify(xcb_map_notify_event_t* e);

0 commit comments

Comments
 (0)