void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) { if (connection()->hasXRandr()) { xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(xcb_connection(), xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp), NULL); if (crtc) { m_geometry = QRect(crtc->x, crtc->y, crtc->width, crtc->height); m_availableGeometry = m_geometry; free(crtc); } } xcb_get_property_reply_t * workArea = xcb_get_property_reply(xcb_connection(), xcb_get_property_unchecked(xcb_connection(), false, screen()->root, atom(QXcbAtom::_NET_WORKAREA), XCB_ATOM_CARDINAL, 0, 1024), NULL); if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) { // If workArea->value_len > 4, the remaining ones seem to be for virtual desktops. // But QScreen doesn't know about that concept. In reality there could be a // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop. // But for now just assume the first 4 values give us the geometry of the // "work area", AKA "available geometry" uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea); QRect virtualAvailableGeometry(geom[0], geom[1], geom[2], geom[3]); // Take the intersection of the desktop's available geometry with this screen's geometry // to get the part of the available geometry which belongs to this screen. m_availableGeometry = m_geometry & virtualAvailableGeometry; } free(workArea); }
bool randr(void) { if (!xcb_get_extension_data(cfg.conn, &xcb_randr_id)->present) { warn("randr is not present\n"); return false; } const xcb_randr_get_screen_resources_cookie_t cookie = xcb_randr_get_screen_resources_unchecked(cfg.conn, cfg.screen->root); xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(cfg.conn, cookie, (void *)0); if (!reply) return false; const xcb_randr_crtc_t *info = xcb_randr_get_screen_resources_crtcs(reply); PRINTF("randr num crtcs: %u\n", reply->num_crtcs); xcb_randr_get_crtc_info_cookie_t cookies[reply->num_crtcs]; for (uint16_t crtc = 0; crtc < reply->num_crtcs; crtc++) cookies[crtc] = xcb_randr_get_crtc_info_unchecked(cfg.conn, info[crtc], XCB_CURRENT_TIME); for (uint16_t crtc = 0; crtc < reply->num_crtcs; crtc++) { xcb_randr_get_crtc_info_reply_t *reply = xcb_randr_get_crtc_info_reply(cfg.conn, cookies[crtc], (void *)0); if (!reply) continue; PRINTF("adding crtc: %u\n", crtc); monitor_add(reply->x, reply->y, reply->width, reply->height); free(reply); } free(reply); return true; }