Skip to content

Commit

Permalink
xwayland: support HiDPI scale
Browse files Browse the repository at this point in the history
  • Loading branch information
moetayuko committed Aug 31, 2024
1 parent c5fd577 commit 713df39
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/xwayland/XSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ void CXWaylandSurface::configure(const CBox& box) {
geometry = box;

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[] = {box.x, box.y, box.width, box.height, 0};
uint32_t values[] = {g_pXWayland->pWM->applyScale(box.x), g_pXWayland->pWM->applyScale(box.y), g_pXWayland->pWM->applyScale(box.width),
g_pXWayland->pWM->applyScale(box.height), 0};
xcb_configure_window(g_pXWayland->pWM->connection, xID, mask, values);

g_pXWayland->pWM->updateClientList();
Expand Down
48 changes: 41 additions & 7 deletions src/xwayland/XWM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ void CXWM::handleCreate(xcb_create_notify_event_t* e) {
if (isWMWindow(e->window))
return;

const auto XSURF = surfaces.emplace_back(SP<CXWaylandSurface>(new CXWaylandSurface(e->window, CBox{e->x, e->y, e->width, e->height}, e->override_redirect)));
XSURF->self = XSURF;
const auto XSURF = surfaces.emplace_back(
SP<CXWaylandSurface>(new CXWaylandSurface(e->window, CBox{applyUnScale(e->x), applyUnScale(e->y), applyUnScale(e->width), applyUnScale(e->height)}, e->override_redirect)));
XSURF->self = XSURF;
Debug::log(LOG, "[xwm] New XSurface at {:x} with xid of {}", (uintptr_t)XSURF.get(), e->window);

const auto WINDOW = CWindow::create(XSURF);
Expand Down Expand Up @@ -67,8 +68,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.configure.emit(CBox{MASK & XCB_CONFIG_WINDOW_X ? applyUnScale(e->x) : XSURF->geometry.x, MASK & XCB_CONFIG_WINDOW_Y ? applyUnScale(e->y) : XSURF->geometry.y,
MASK & XCB_CONFIG_WINDOW_WIDTH ? applyUnScale(e->width) : XSURF->geometry.width,
MASK & XCB_CONFIG_WINDOW_HEIGHT ? applyUnScale(e->height) : XSURF->geometry.height});
}

void CXWM::handleConfigureNotify(xcb_configure_notify_event_t* e) {
Expand All @@ -77,10 +79,11 @@ void CXWM::handleConfigureNotify(xcb_configure_notify_event_t* e) {
if (!XSURF)
return;

if (XSURF->geometry == CBox{e->x, e->y, e->width, e->height})
const CBox geom = {applyUnScale(e->x), applyUnScale(e->y), applyUnScale(e->width), applyUnScale(e->height)};
if (XSURF->geometry == geom)
return;

XSURF->geometry = {e->x, e->y, e->width, e->height};
XSURF->geometry = geom;
updateOverrideRedirect(XSURF, e->override_redirect);
XSURF->events.setGeometry.emit();
}
Expand Down Expand Up @@ -236,6 +239,17 @@ void CXWM::readProp(SP<CXWaylandSurface> XSURF, uint32_t atom, xcb_get_property_

xcb_icccm_get_wm_size_hints_from_reply(XSURF->sizeHints.get(), reply);

XSURF->sizeHints->x = applyUnScale(XSURF->sizeHints->x);
XSURF->sizeHints->y = applyUnScale(XSURF->sizeHints->y);
XSURF->sizeHints->width = applyUnScale(XSURF->sizeHints->width);
XSURF->sizeHints->height = applyUnScale(XSURF->sizeHints->height);
XSURF->sizeHints->min_width = applyUnScale(XSURF->sizeHints->min_width);
XSURF->sizeHints->min_height = applyUnScale(XSURF->sizeHints->min_height);
XSURF->sizeHints->max_width = applyUnScale(XSURF->sizeHints->max_width);
XSURF->sizeHints->max_height = applyUnScale(XSURF->sizeHints->max_height);
XSURF->sizeHints->base_width = applyUnScale(XSURF->sizeHints->base_width);
XSURF->sizeHints->base_height = applyUnScale(XSURF->sizeHints->base_height);

const int32_t FLAGS = XSURF->sizeHints->flags;
const bool HASMIN = (FLAGS & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE);
const bool HASBASE = (FLAGS & XCB_ICCCM_SIZE_HINT_BASE_SIZE);
Expand Down Expand Up @@ -269,8 +283,20 @@ void CXWM::readProp(SP<CXWaylandSurface> XSURF, uint32_t atom, xcb_get_property_
void CXWM::handlePropertyNotify(xcb_property_notify_event_t* e) {
const auto XSURF = windowForXID(e->window);

if (!XSURF)
if (!XSURF) {
if (e->atom == HYPRATOMS["_XWAYLAND_GLOBAL_OUTPUT_SCALE"]) {
xcb_get_property_cookie_t cookie = xcb_get_property(connection, 0, e->window, e->atom, XCB_ATOM_ANY, 0, 2048);
xcb_get_property_reply_t* reply = xcb_get_property_reply(connection, cookie, nullptr);
if (!reply) {
return;
}
if (reply->type == XCB_ATOM_CARDINAL) {
scale = *(uint32_t*)xcb_get_property_value(reply);
}
free(reply);
}
return;
}

xcb_get_property_cookie_t cookie = xcb_get_property(connection, 0, XSURF->xID, e->atom, XCB_ATOM_ANY, 0, 2048);
xcb_get_property_reply_t* reply = xcb_get_property_reply(connection, cookie, nullptr);
Expand Down Expand Up @@ -1151,6 +1177,14 @@ void CXWM::setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& si
xcb_flush(connection);
}

double CXWM::applyScale(double val) {
return std::floor(val * scale);
}

double CXWM::applyUnScale(double val) {
return std::ceil(val / scale);
}

void SXSelection::onSelection() {
if (g_pSeatManager->selection.currentSelection && g_pSeatManager->selection.currentSelection->type() == DATA_SOURCE_TYPE_X11)
return;
Expand Down
4 changes: 4 additions & 0 deletions src/xwayland/XWM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,16 @@ class CXWM {
void getTransferData(SXSelection& sel);
void readProp(SP<CXWaylandSurface> XSURF, uint32_t atom, xcb_get_property_reply_t* reply);

double applyScale(double val);
double applyUnScale(double val);

//
xcb_connection_t* connection = nullptr;
xcb_errors_context_t* errors = nullptr;
xcb_screen_t* screen = nullptr;

xcb_window_t wmWindow;
double scale = 1.0;

wl_event_source* eventSource = nullptr;

Expand Down
3 changes: 2 additions & 1 deletion src/xwayland/XWayland.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,5 @@ inline std::unordered_map<std::string, uint32_t> HYPRATOMS = {
HYPRATOM("DELETE"),
HYPRATOM("TEXT"),
HYPRATOM("INCR"),
};
HYPRATOM("_XWAYLAND_GLOBAL_OUTPUT_SCALE"),
};

0 comments on commit 713df39

Please sign in to comment.