mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 03:45:59 +01:00
xwayland: support HiDPI scale
This supports the xorg-xwayland patch at https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/733
Ported from 5a7c65cab1
This commit is contained in:
parent
8237d7e1a4
commit
5f12989a85
4 changed files with 48 additions and 8 deletions
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -250,6 +253,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);
|
||||
|
@ -283,8 +297,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);
|
||||
|
@ -1169,6 +1195,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;
|
||||
|
|
|
@ -122,12 +122,16 @@ class CXWM {
|
|||
std::string getAtomName(uint32_t atom);
|
||||
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;
|
||||
|
||||
|
|
|
@ -126,4 +126,5 @@ inline std::unordered_map<std::string, uint32_t> HYPRATOMS = {
|
|||
HYPRATOM("DELETE"),
|
||||
HYPRATOM("TEXT"),
|
||||
HYPRATOM("INCR"),
|
||||
HYPRATOM("_XWAYLAND_GLOBAL_OUTPUT_SCALE"),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue