mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-05 14:42:01 -07:00
xwayland: Fix crash when copying from wayland to xwayland (#10786)
This commit is contained in:
@@ -298,6 +298,7 @@ void CPrimarySelectionProtocol::setSelection(SP<IDataSource> source) {
|
|||||||
|
|
||||||
if (!DESTDEVICE) {
|
if (!DESTDEVICE) {
|
||||||
LOGM(LOG, "CWLDataDeviceProtocol::setSelection: cannot send selection to a client without a data_device");
|
LOGM(LOG, "CWLDataDeviceProtocol::setSelection: cannot send selection to a client without a data_device");
|
||||||
|
g_pSeatManager->m_selection.currentPrimarySelection.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,9 +309,10 @@ void CPrimarySelectionProtocol::updateSelection() {
|
|||||||
if (!g_pSeatManager->m_state.pointerFocusResource)
|
if (!g_pSeatManager->m_state.pointerFocusResource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto selection = g_pSeatManager->m_selection.currentPrimarySelection.lock();
|
||||||
auto DESTDEVICE = dataDeviceForClient(g_pSeatManager->m_state.pointerFocusResource->client());
|
auto DESTDEVICE = dataDeviceForClient(g_pSeatManager->m_state.pointerFocusResource->client());
|
||||||
|
|
||||||
if (!DESTDEVICE) {
|
if (!selection || !DESTDEVICE) {
|
||||||
LOGM(LOG, "CPrimarySelectionProtocol::updateSelection: cannot send selection to a client without a data_device");
|
LOGM(LOG, "CPrimarySelectionProtocol::updateSelection: cannot send selection to a client without a data_device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -35,16 +35,16 @@ void CX11DataDevice::sendDndEvent(xcb_window_t targetWindow, xcb_atom_t type, xc
|
|||||||
.type = type,
|
.type = type,
|
||||||
.data = data,
|
.data = data,
|
||||||
};
|
};
|
||||||
|
xcb_connection_t* conn = (g_pXWayland->m_wm->getConnection());
|
||||||
xcb_send_event(g_pXWayland->m_wm->m_connection, 0, targetWindow, XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
|
xcb_send_event(conn, 0, targetWindow, XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t CX11DataDevice::getProxyWindow(xcb_window_t window) {
|
xcb_window_t CX11DataDevice::getProxyWindow(xcb_window_t window) {
|
||||||
xcb_window_t targetWindow = window;
|
xcb_window_t targetWindow = window;
|
||||||
xcb_get_property_cookie_t proxyCookie =
|
xcb_get_property_cookie_t proxyCookie =
|
||||||
xcb_get_property(g_pXWayland->m_wm->m_connection, PROPERTY_OFFSET, window, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
xcb_get_property((g_pXWayland->m_wm->getConnection()), PROPERTY_OFFSET, window, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||||
xcb_get_property_reply_t* proxyReply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, proxyCookie, nullptr);
|
xcb_get_property_reply_t* proxyReply = xcb_get_property_reply(g_pXWayland->m_wm->getConnection(), proxyCookie, nullptr);
|
||||||
|
|
||||||
const auto isValidPropertyReply = [](xcb_get_property_reply_t* reply) {
|
const auto isValidPropertyReply = [](xcb_get_property_reply_t* reply) {
|
||||||
return reply && reply->type == XCB_ATOM_WINDOW && reply->format == PROPERTY_FORMAT_32BIT && xcb_get_property_value_length(reply) == sizeof(xcb_window_t);
|
return reply && reply->type == XCB_ATOM_WINDOW && reply->format == PROPERTY_FORMAT_32BIT && xcb_get_property_value_length(reply) == sizeof(xcb_window_t);
|
||||||
@@ -54,8 +54,8 @@ xcb_window_t CX11DataDevice::getProxyWindow(xcb_window_t window) {
|
|||||||
xcb_window_t proxyWindow = *(xcb_window_t*)xcb_get_property_value(proxyReply);
|
xcb_window_t proxyWindow = *(xcb_window_t*)xcb_get_property_value(proxyReply);
|
||||||
|
|
||||||
xcb_get_property_cookie_t proxyVerifyCookie =
|
xcb_get_property_cookie_t proxyVerifyCookie =
|
||||||
xcb_get_property(g_pXWayland->m_wm->m_connection, PROPERTY_OFFSET, proxyWindow, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
xcb_get_property(g_pXWayland->m_wm->getConnection(), PROPERTY_OFFSET, proxyWindow, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||||
xcb_get_property_reply_t* proxyVerifyReply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, proxyVerifyCookie, nullptr);
|
xcb_get_property_reply_t* proxyVerifyReply = xcb_get_property_reply(g_pXWayland->m_wm->getConnection(), proxyVerifyCookie, nullptr);
|
||||||
|
|
||||||
if (isValidPropertyReply(proxyVerifyReply)) {
|
if (isValidPropertyReply(proxyVerifyReply)) {
|
||||||
xcb_window_t verifyWindow = *(xcb_window_t*)xcb_get_property_value(proxyVerifyReply);
|
xcb_window_t verifyWindow = *(xcb_window_t*)xcb_get_property_value(proxyVerifyReply);
|
||||||
@@ -121,11 +121,11 @@ void CX11DataDevice::sendEnter(uint32_t serial, SP<CWLSurfaceResource> surf, con
|
|||||||
targets.push_back(g_pXWayland->m_wm->mimeToAtom(m));
|
targets.push_back(g_pXWayland->m_wm->mimeToAtom(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_change_property(g_pXWayland->m_wm->m_connection, XCB_PROP_MODE_REPLACE, g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndTypeList"], XCB_ATOM_ATOM, 32,
|
xcb_change_property(g_pXWayland->m_wm->getConnection(), XCB_PROP_MODE_REPLACE, g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndTypeList"], XCB_ATOM_ATOM, 32,
|
||||||
targets.size(), targets.data());
|
targets.size(), targets.data());
|
||||||
|
|
||||||
xcb_set_selection_owner(g_pXWayland->m_wm->m_connection, g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
xcb_set_selection_owner(g_pXWayland->m_wm->getConnection(), g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(g_pXWayland->m_wm->getConnection());
|
||||||
|
|
||||||
xcb_window_t targetWindow = getProxyWindow(XSURF->m_xID);
|
xcb_window_t targetWindow = getProxyWindow(XSURF->m_xID);
|
||||||
|
|
||||||
@@ -291,8 +291,8 @@ void CX11DataDevice::forceCleanupDnd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_set_selection_owner(g_pXWayland->m_wm->m_connection, XCB_ATOM_NONE, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
xcb_set_selection_owner(g_pXWayland->m_wm->getConnection(), XCB_ATOM_NONE, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(g_pXWayland->m_wm->getConnection());
|
||||||
|
|
||||||
cleanupState();
|
cleanupState();
|
||||||
|
|
||||||
|
@@ -8,11 +8,11 @@
|
|||||||
using namespace Hyprutils::OS;
|
using namespace Hyprutils::OS;
|
||||||
|
|
||||||
CXDataSource::CXDataSource(SXSelection& sel_) : m_selection(sel_) {
|
CXDataSource::CXDataSource(SXSelection& sel_) : m_selection(sel_) {
|
||||||
xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->m_wm->m_connection,
|
xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->m_wm->getConnection(),
|
||||||
1, // delete
|
1, // delete
|
||||||
m_selection.window, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 4096);
|
m_selection.window, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 4096);
|
||||||
|
|
||||||
xcb_get_property_reply_t* reply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, cookie, nullptr);
|
xcb_get_property_reply_t* reply = xcb_get_property_reply(g_pXWayland->m_wm->getConnection(), cookie, nullptr);
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -72,9 +72,9 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
|
|||||||
Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get());
|
Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get());
|
||||||
|
|
||||||
auto transfer = makeUnique<SXTransfer>(m_selection);
|
auto transfer = makeUnique<SXTransfer>(m_selection);
|
||||||
transfer->incomingWindow = xcb_generate_id(g_pXWayland->m_wm->m_connection);
|
transfer->incomingWindow = xcb_generate_id(g_pXWayland->m_wm->getConnection());
|
||||||
const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
xcb_create_window(g_pXWayland->m_wm->m_connection, XCB_COPY_FROM_PARENT, transfer->incomingWindow, g_pXWayland->m_wm->m_screen->root, 0, 0, 10, 10, 0,
|
xcb_create_window(g_pXWayland->m_wm->getConnection(), XCB_COPY_FROM_PARENT, transfer->incomingWindow, g_pXWayland->m_wm->m_screen->root, 0, 0, 10, 10, 0,
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, g_pXWayland->m_wm->m_screen->root_visual, XCB_CW_EVENT_MASK, &MASK);
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, g_pXWayland->m_wm->m_screen->root_visual, XCB_CW_EVENT_MASK, &MASK);
|
||||||
|
|
||||||
xcb_atom_t selection_atom = HYPRATOMS["CLIPBOARD"];
|
xcb_atom_t selection_atom = HYPRATOMS["CLIPBOARD"];
|
||||||
@@ -83,9 +83,9 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
|
|||||||
else if (&m_selection == &g_pXWayland->m_wm->m_dndSelection)
|
else if (&m_selection == &g_pXWayland->m_wm->m_dndSelection)
|
||||||
selection_atom = HYPRATOMS["XdndSelection"];
|
selection_atom = HYPRATOMS["XdndSelection"];
|
||||||
|
|
||||||
xcb_convert_selection(g_pXWayland->m_wm->m_connection, transfer->incomingWindow, selection_atom, mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME);
|
xcb_convert_selection(g_pXWayland->m_wm->getConnection(), transfer->incomingWindow, selection_atom, mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME);
|
||||||
|
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(g_pXWayland->m_wm->getConnection());
|
||||||
|
|
||||||
//TODO: make CFileDescriptor setflags take SETFL aswell
|
//TODO: make CFileDescriptor setflags take SETFL aswell
|
||||||
fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK);
|
fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK);
|
||||||
|
@@ -13,15 +13,15 @@ CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : m_x
|
|||||||
xcb_res_query_client_ids_cookie_t client_id_cookie = {0};
|
xcb_res_query_client_ids_cookie_t client_id_cookie = {0};
|
||||||
if (g_pXWayland->m_wm->m_xres) {
|
if (g_pXWayland->m_wm->m_xres) {
|
||||||
xcb_res_client_id_spec_t spec = {.client = m_xID, .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID};
|
xcb_res_client_id_spec_t spec = {.client = m_xID, .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID};
|
||||||
client_id_cookie = xcb_res_query_client_ids(g_pXWayland->m_wm->m_connection, 1, &spec);
|
client_id_cookie = xcb_res_query_client_ids(g_pXWayland->m_wm->getConnection(), 1, &spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t values[1];
|
uint32_t values[1];
|
||||||
values[0] = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
values[0] = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
xcb_change_window_attributes(g_pXWayland->m_wm->m_connection, m_xID, XCB_CW_EVENT_MASK, values);
|
xcb_change_window_attributes(g_pXWayland->m_wm->getConnection(), m_xID, XCB_CW_EVENT_MASK, values);
|
||||||
|
|
||||||
if (g_pXWayland->m_wm->m_xres) {
|
if (g_pXWayland->m_wm->m_xres) {
|
||||||
xcb_res_query_client_ids_reply_t* reply = xcb_res_query_client_ids_reply(g_pXWayland->m_wm->m_connection, client_id_cookie, nullptr);
|
xcb_res_query_client_ids_reply_t* reply = xcb_res_query_client_ids_reply(g_pXWayland->m_wm->getConnection(), client_id_cookie, nullptr);
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ void CXWaylandSurface::configure(const CBox& 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 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[] = {box.x, box.y, box.width, box.height, 0};
|
||||||
xcb_configure_window(g_pXWayland->m_wm->m_connection, m_xID, mask, values);
|
xcb_configure_window(g_pXWayland->m_wm->getConnection(), m_xID, mask, values);
|
||||||
|
|
||||||
if (m_geometry.width == box.width && m_geometry.height == box.height) {
|
if (m_geometry.width == box.width && m_geometry.height == box.height) {
|
||||||
// ICCCM requires a synthetic event when window size is not changed
|
// ICCCM requires a synthetic event when window size is not changed
|
||||||
@@ -184,12 +184,12 @@ void CXWaylandSurface::configure(const CBox& box) {
|
|||||||
e.border_width = 0;
|
e.border_width = 0;
|
||||||
e.above_sibling = XCB_NONE;
|
e.above_sibling = XCB_NONE;
|
||||||
e.override_redirect = m_overrideRedirect;
|
e.override_redirect = m_overrideRedirect;
|
||||||
xcb_send_event(g_pXWayland->m_wm->m_connection, false, m_xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e);
|
xcb_send_event(g_pXWayland->m_wm->getConnection(), false, m_xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pXWayland->m_wm->updateClientList();
|
g_pXWayland->m_wm->updateClientList();
|
||||||
|
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(g_pXWayland->m_wm->getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWaylandSurface::activate(bool activate) {
|
void CXWaylandSurface::activate(bool activate) {
|
||||||
@@ -211,7 +211,7 @@ void CXWaylandSurface::setMinimized(bool mz) {
|
|||||||
void CXWaylandSurface::restackToTop() {
|
void CXWaylandSurface::restackToTop() {
|
||||||
uint32_t values[1] = {XCB_STACK_MODE_ABOVE};
|
uint32_t values[1] = {XCB_STACK_MODE_ABOVE};
|
||||||
|
|
||||||
xcb_configure_window(g_pXWayland->m_wm->m_connection, m_xID, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
xcb_configure_window(g_pXWayland->m_wm->getConnection(), m_xID, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||||
|
|
||||||
auto& stack = g_pXWayland->m_wm->m_mappedSurfacesStacking;
|
auto& stack = g_pXWayland->m_wm->m_mappedSurfacesStacking;
|
||||||
auto it = std::ranges::find(stack, m_self);
|
auto it = std::ranges::find(stack, m_self);
|
||||||
@@ -221,7 +221,7 @@ void CXWaylandSurface::restackToTop() {
|
|||||||
|
|
||||||
g_pXWayland->m_wm->updateClientList();
|
g_pXWayland->m_wm->updateClientList();
|
||||||
|
|
||||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
xcb_flush(g_pXWayland->m_wm->getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWaylandSurface::close() {
|
void CXWaylandSurface::close() {
|
||||||
@@ -242,7 +242,7 @@ void CXWaylandSurface::setWithdrawn(bool withdrawn_) {
|
|||||||
else
|
else
|
||||||
props[0] = XCB_ICCCM_WM_STATE_NORMAL;
|
props[0] = XCB_ICCCM_WM_STATE_NORMAL;
|
||||||
|
|
||||||
xcb_change_property(g_pXWayland->m_wm->m_connection, XCB_PROP_MODE_REPLACE, m_xID, HYPRATOMS["WM_STATE"], HYPRATOMS["WM_STATE"], 32, props.size(), props.data());
|
xcb_change_property(g_pXWayland->m_wm->getConnection(), XCB_PROP_MODE_REPLACE, m_xID, HYPRATOMS["WM_STATE"], HYPRATOMS["WM_STATE"], 32, props.size(), props.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWaylandSurface::ping() {
|
void CXWaylandSurface::ping() {
|
||||||
|
@@ -109,7 +109,7 @@ void CXWM::handleMapRequest(xcb_map_request_event_t* e) {
|
|||||||
if (!XSURF)
|
if (!XSURF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xcb_map_window(m_connection, e->window);
|
xcb_map_window(getConnection(), e->window);
|
||||||
|
|
||||||
XSURF->restackToTop();
|
XSURF->restackToTop();
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ void CXWM::handleMapNotify(xcb_map_notify_event_t* e) {
|
|||||||
|
|
||||||
XSURF->setWithdrawn(false);
|
XSURF->setWithdrawn(false);
|
||||||
sendState(XSURF);
|
sendState(XSURF);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
|
|
||||||
XSURF->considerMap();
|
XSURF->considerMap();
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ void CXWM::handleUnmapNotify(xcb_unmap_notify_event_t* e) {
|
|||||||
|
|
||||||
XSURF->setWithdrawn(true);
|
XSURF->setWithdrawn(true);
|
||||||
sendState(XSURF);
|
sendState(XSURF);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lookupParentExists(SP<CXWaylandSurface> XSURF, SP<CXWaylandSurface> prospectiveChild) {
|
static bool lookupParentExists(SP<CXWaylandSurface> XSURF, SP<CXWaylandSurface> prospectiveChild) {
|
||||||
@@ -193,8 +193,8 @@ std::string CXWM::getAtomName(uint32_t atom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the name of the atom
|
// Get the name of the atom
|
||||||
const auto cookie = xcb_get_atom_name(m_connection, atom);
|
const auto cookie = xcb_get_atom_name(getConnection(), atom);
|
||||||
XCBReplyPtr<xcb_get_atom_name_reply_t> reply(xcb_get_atom_name_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_get_atom_name_reply_t> reply(xcb_get_atom_name_reply(getConnection(), cookie, nullptr));
|
||||||
|
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
@@ -342,8 +342,8 @@ void CXWM::handlePropertyNotify(xcb_property_notify_event_t* e) {
|
|||||||
if (!XSURF)
|
if (!XSURF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xcb_get_property_cookie_t cookie = xcb_get_property(m_connection, 0, XSURF->m_xID, e->atom, XCB_ATOM_ANY, 0, 2048);
|
xcb_get_property_cookie_t cookie = xcb_get_property(getConnection(), 0, XSURF->m_xID, e->atom, XCB_ATOM_ANY, 0, 2048);
|
||||||
XCBReplyPtr<xcb_get_property_reply_t> reply(xcb_get_property_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_get_property_reply_t> reply(xcb_get_property_reply(getConnection(), cookie, nullptr));
|
||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
Debug::log(ERR, "[xwm] Failed to read property notify cookie");
|
Debug::log(ERR, "[xwm] Failed to read property notify cookie");
|
||||||
@@ -500,8 +500,8 @@ void CXWM::sendWMMessage(SP<CXWaylandSurface> surf, xcb_client_message_data_t* d
|
|||||||
.data = *data,
|
.data = *data,
|
||||||
};
|
};
|
||||||
|
|
||||||
xcb_send_event(m_connection, 0, surf->m_xID, mask, (const char*)&event);
|
xcb_send_event(getConnection(), 0, surf->m_xID, mask, (const char*)&event);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::focusWindow(SP<CXWaylandSurface> surf) {
|
void CXWM::focusWindow(SP<CXWaylandSurface> surf) {
|
||||||
@@ -520,7 +520,7 @@ void CXWM::focusWindow(SP<CXWaylandSurface> surf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!surf) {
|
if (!surf) {
|
||||||
xcb_set_input_focus_checked(m_connection, XCB_INPUT_FOCUS_POINTER_ROOT, XCB_NONE, XCB_CURRENT_TIME);
|
xcb_set_input_focus_checked(getConnection(), XCB_INPUT_FOCUS_POINTER_ROOT, XCB_NONE, XCB_CURRENT_TIME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@ void CXWM::focusWindow(SP<CXWaylandSurface> surf) {
|
|||||||
else {
|
else {
|
||||||
sendWMMessage(surf, &msg, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT);
|
sendWMMessage(surf, &msg, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT);
|
||||||
|
|
||||||
xcb_void_cookie_t cookie = xcb_set_input_focus(m_connection, XCB_INPUT_FOCUS_POINTER_ROOT, surf->m_xID, XCB_CURRENT_TIME);
|
xcb_void_cookie_t cookie = xcb_set_input_focus(getConnection(), XCB_INPUT_FOCUS_POINTER_ROOT, surf->m_xID, XCB_CURRENT_TIME);
|
||||||
m_lastFocusSeq = cookie.sequence;
|
m_lastFocusSeq = cookie.sequence;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,8 +572,8 @@ void CXWM::selectionSendNotify(xcb_selection_request_event_t* e, bool success) {
|
|||||||
.property = success ? e->property : (uint32_t)XCB_ATOM_NONE,
|
.property = success ? e->property : (uint32_t)XCB_ATOM_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
xcb_send_event(m_connection, 0, e->requestor, XCB_EVENT_MASK_NO_EVENT, (const char*)&selection_notify);
|
xcb_send_event(getConnection(), 0, e->requestor, XCB_EVENT_MASK_NO_EVENT, (const char*)&selection_notify);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_atom_t CXWM::mimeToAtom(const std::string& mime) {
|
xcb_atom_t CXWM::mimeToAtom(const std::string& mime) {
|
||||||
@@ -582,8 +582,8 @@ xcb_atom_t CXWM::mimeToAtom(const std::string& mime) {
|
|||||||
if (mime == "text/plain")
|
if (mime == "text/plain")
|
||||||
return HYPRATOMS["TEXT"];
|
return HYPRATOMS["TEXT"];
|
||||||
|
|
||||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connection, 0, mime.length(), mime.c_str());
|
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(getConnection(), 0, mime.length(), mime.c_str());
|
||||||
XCBReplyPtr<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(getConnection(), cookie, nullptr));
|
||||||
if (!reply.get())
|
if (!reply.get())
|
||||||
return XCB_ATOM_NONE;
|
return XCB_ATOM_NONE;
|
||||||
xcb_atom_t atom = reply->atom;
|
xcb_atom_t atom = reply->atom;
|
||||||
@@ -597,8 +597,8 @@ std::string CXWM::mimeFromAtom(xcb_atom_t atom) {
|
|||||||
if (atom == HYPRATOMS["TEXT"])
|
if (atom == HYPRATOMS["TEXT"])
|
||||||
return "text/plain";
|
return "text/plain";
|
||||||
|
|
||||||
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(m_connection, atom);
|
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(getConnection(), atom);
|
||||||
XCBReplyPtr<xcb_get_atom_name_reply_t> reply(xcb_get_atom_name_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_get_atom_name_reply_t> reply(xcb_get_atom_name_reply(getConnection(), cookie, nullptr));
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return "INVALID";
|
return "INVALID";
|
||||||
size_t len = xcb_get_atom_name_name_length(reply.get());
|
size_t len = xcb_get_atom_name_name_length(reply.get());
|
||||||
@@ -709,10 +709,10 @@ void CXWM::handleSelectionRequest(xcb_selection_request_event_t* e) {
|
|||||||
atoms.push_back(mimeToAtom(m));
|
atoms.push_back(mimeToAtom(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, e->requestor, e->property, XCB_ATOM_ATOM, 32, atoms.size(), atoms.data());
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, e->requestor, e->property, XCB_ATOM_ATOM, 32, atoms.size(), atoms.data());
|
||||||
selectionSendNotify(e, true);
|
selectionSendNotify(e, true);
|
||||||
} else if (e->target == HYPRATOMS["TIMESTAMP"]) {
|
} else if (e->target == HYPRATOMS["TIMESTAMP"]) {
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, e->requestor, e->property, XCB_ATOM_INTEGER, 32, 1, &sel->timestamp);
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, e->requestor, e->property, XCB_ATOM_INTEGER, 32, 1, &sel->timestamp);
|
||||||
selectionSendNotify(e, true);
|
selectionSendNotify(e, true);
|
||||||
} else if (e->target == HYPRATOMS["DELETE"]) {
|
} else if (e->target == HYPRATOMS["DELETE"]) {
|
||||||
selectionSendNotify(e, true);
|
selectionSendNotify(e, true);
|
||||||
@@ -762,10 +762,10 @@ bool CXWM::handleSelectionXFixesNotify(xcb_xfixes_selection_notify_event_t* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sel == &m_clipboard)
|
if (sel == &m_clipboard)
|
||||||
xcb_convert_selection(m_connection, sel->window, HYPRATOMS["CLIPBOARD"], HYPRATOMS["TARGETS"], HYPRATOMS["_WL_SELECTION"], e->timestamp);
|
xcb_convert_selection(getConnection(), sel->window, HYPRATOMS["CLIPBOARD"], HYPRATOMS["TARGETS"], HYPRATOMS["_WL_SELECTION"], e->timestamp);
|
||||||
else if (sel == &m_primarySelection)
|
else if (sel == &m_primarySelection)
|
||||||
xcb_convert_selection(m_connection, sel->window, HYPRATOMS["PRIMARY"], HYPRATOMS["TARGETS"], HYPRATOMS["_WL_SELECTION"], e->timestamp);
|
xcb_convert_selection(getConnection(), sel->window, HYPRATOMS["PRIMARY"], HYPRATOMS["TARGETS"], HYPRATOMS["_WL_SELECTION"], e->timestamp);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -796,17 +796,19 @@ int CXWM::onEvent(int fd, uint32_t mask) {
|
|||||||
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
||||||
Debug::log(ERR, "XWayland has yeeten the xwm off?!");
|
Debug::log(ERR, "XWayland has yeeten the xwm off?!");
|
||||||
Debug::log(CRIT, "XWayland has yeeten the xwm off?!");
|
Debug::log(CRIT, "XWayland has yeeten the xwm off?!");
|
||||||
|
// Attempt to create fresh instance
|
||||||
|
g_pEventLoopManager->doLater([]() {
|
||||||
g_pXWayland->m_wm.reset();
|
g_pXWayland->m_wm.reset();
|
||||||
g_pXWayland->m_server.reset();
|
g_pXWayland->m_server.reset();
|
||||||
// Attempt to create fresh instance
|
g_pXWayland = makeUnique<CXWayland>(true);
|
||||||
g_pEventLoopManager->doLater([]() { g_pXWayland = makeUnique<CXWayland>(true); });
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int processedEventCount = 0;
|
int processedEventCount = 0;
|
||||||
using XCBEventPtr = std::unique_ptr<xcb_generic_event_t, decltype(&free)>;
|
using XCBEventPtr = std::unique_ptr<xcb_generic_event_t, decltype(&free)>;
|
||||||
while (true) {
|
while (true) {
|
||||||
XCBEventPtr event(xcb_poll_for_event(m_connection), &free);
|
XCBEventPtr event(xcb_poll_for_event(getConnection()), &free);
|
||||||
if (!event)
|
if (!event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -835,19 +837,19 @@ int CXWM::onEvent(int fd, uint32_t mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (processedEventCount)
|
if (processedEventCount)
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
|
|
||||||
return processedEventCount;
|
return processedEventCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::gatherResources() {
|
void CXWM::gatherResources() {
|
||||||
xcb_prefetch_extension_data(m_connection, &xcb_xfixes_id);
|
xcb_prefetch_extension_data(getConnection(), &xcb_xfixes_id);
|
||||||
xcb_prefetch_extension_data(m_connection, &xcb_composite_id);
|
xcb_prefetch_extension_data(getConnection(), &xcb_composite_id);
|
||||||
xcb_prefetch_extension_data(m_connection, &xcb_res_id);
|
xcb_prefetch_extension_data(getConnection(), &xcb_res_id);
|
||||||
|
|
||||||
for (auto& ATOM : HYPRATOMS) {
|
for (auto& ATOM : HYPRATOMS) {
|
||||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connection, 0, ATOM.first.length(), ATOM.first.c_str());
|
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(getConnection(), 0, ATOM.first.length(), ATOM.first.c_str());
|
||||||
XCBReplyPtr<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(getConnection(), cookie, nullptr));
|
||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
Debug::log(ERR, "[xwm] Atom failed: {}", ATOM.first);
|
Debug::log(ERR, "[xwm] Atom failed: {}", ATOM.first);
|
||||||
@@ -857,25 +859,25 @@ void CXWM::gatherResources() {
|
|||||||
ATOM.second = reply->atom;
|
ATOM.second = reply->atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_xfixes = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
|
m_xfixes = xcb_get_extension_data(getConnection(), &xcb_xfixes_id);
|
||||||
|
|
||||||
if (!m_xfixes || !m_xfixes->present)
|
if (!m_xfixes || !m_xfixes->present)
|
||||||
Debug::log(WARN, "XFixes not available");
|
Debug::log(WARN, "XFixes not available");
|
||||||
|
|
||||||
auto xfixes_cookie = xcb_xfixes_query_version(m_connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
|
auto xfixes_cookie = xcb_xfixes_query_version(getConnection(), XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
|
||||||
XCBReplyPtr<xcb_xfixes_query_version_reply_t> xfixes_reply(xcb_xfixes_query_version_reply(m_connection, xfixes_cookie, nullptr));
|
XCBReplyPtr<xcb_xfixes_query_version_reply_t> xfixes_reply(xcb_xfixes_query_version_reply(getConnection(), xfixes_cookie, nullptr));
|
||||||
|
|
||||||
if (xfixes_reply) {
|
if (xfixes_reply) {
|
||||||
Debug::log(LOG, "xfixes version: {}.{}", xfixes_reply->major_version, xfixes_reply->minor_version);
|
Debug::log(LOG, "xfixes version: {}.{}", xfixes_reply->major_version, xfixes_reply->minor_version);
|
||||||
m_xfixesMajor = xfixes_reply->major_version;
|
m_xfixesMajor = xfixes_reply->major_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* xresReply1 = xcb_get_extension_data(m_connection, &xcb_res_id);
|
const auto* xresReply1 = xcb_get_extension_data(getConnection(), &xcb_res_id);
|
||||||
if (!xresReply1 || !xresReply1->present)
|
if (!xresReply1 || !xresReply1->present)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto xres_cookie = xcb_res_query_version(m_connection, XCB_RES_MAJOR_VERSION, XCB_RES_MINOR_VERSION);
|
auto xres_cookie = xcb_res_query_version(getConnection(), XCB_RES_MAJOR_VERSION, XCB_RES_MINOR_VERSION);
|
||||||
XCBReplyPtr<xcb_res_query_version_reply_t> xres_reply(xcb_res_query_version_reply(m_connection, xres_cookie, nullptr));
|
XCBReplyPtr<xcb_res_query_version_reply_t> xres_reply(xcb_res_query_version_reply(getConnection(), xres_cookie, nullptr));
|
||||||
if (!xres_reply)
|
if (!xres_reply)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -908,13 +910,13 @@ void CXWM::getVisual() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_visualID = visualtype->visual_id;
|
m_visualID = visualtype->visual_id;
|
||||||
m_colormap = xcb_generate_id(m_connection);
|
m_colormap = xcb_generate_id(getConnection());
|
||||||
xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, m_colormap, m_screen->root, m_visualID);
|
xcb_create_colormap(getConnection(), XCB_COLORMAP_ALLOC_NONE, m_colormap, m_screen->root, m_visualID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::getRenderFormat() {
|
void CXWM::getRenderFormat() {
|
||||||
auto cookie = xcb_render_query_pict_formats(m_connection);
|
auto cookie = xcb_render_query_pict_formats(getConnection());
|
||||||
XCBReplyPtr<xcb_render_query_pict_formats_reply_t> reply(xcb_render_query_pict_formats_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_render_query_pict_formats_reply_t> reply(xcb_render_query_pict_formats_reply(getConnection(), cookie, nullptr));
|
||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
Debug::log(LOG, "xwm: No xcb_render_query_pict_formats_reply_t reply");
|
Debug::log(LOG, "xwm: No xcb_render_query_pict_formats_reply_t reply");
|
||||||
@@ -940,14 +942,14 @@ void CXWM::getRenderFormat() {
|
|||||||
m_renderFormatID = format->id;
|
m_renderFormatID = format->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXWM::CXWM() : m_connection(g_pXWayland->m_server->m_xwmFDs[0].get()) {
|
CXWM::CXWM() : m_connection(makeUnique<CXCBConnection>(g_pXWayland->m_server->m_xwmFDs[0].get())) {
|
||||||
|
|
||||||
if (m_connection.hasError()) {
|
if (m_connection->hasError()) {
|
||||||
Debug::log(ERR, "[xwm] Couldn't start, error {}", m_connection.hasError());
|
Debug::log(ERR, "[xwm] Couldn't start, error {}", m_connection->hasError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXCBErrorContext xcbErrCtx(m_connection);
|
CXCBErrorContext xcbErrCtx(getConnection());
|
||||||
if (!xcbErrCtx.isValid()) {
|
if (!xcbErrCtx.isValid()) {
|
||||||
Debug::log(ERR, "[xwm] Couldn't allocate errors context");
|
Debug::log(ERR, "[xwm] Couldn't allocate errors context");
|
||||||
return;
|
return;
|
||||||
@@ -955,7 +957,7 @@ CXWM::CXWM() : m_connection(g_pXWayland->m_server->m_xwmFDs[0].get()) {
|
|||||||
|
|
||||||
m_dndDataDevice->m_self = m_dndDataDevice;
|
m_dndDataDevice->m_self = m_dndDataDevice;
|
||||||
|
|
||||||
xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(m_connection));
|
xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(getConnection()));
|
||||||
m_screen = screen_iterator.data;
|
m_screen = screen_iterator.data;
|
||||||
|
|
||||||
m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, g_pXWayland->m_server->m_xwmFDs[0].get(), WL_EVENT_READABLE, ::onX11Event, nullptr);
|
m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, g_pXWayland->m_server->m_xwmFDs[0].get(), WL_EVENT_READABLE, ::onX11Event, nullptr);
|
||||||
@@ -968,16 +970,16 @@ CXWM::CXWM() : m_connection(g_pXWayland->m_server->m_xwmFDs[0].get()) {
|
|||||||
uint32_t values[] = {
|
uint32_t values[] = {
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_PROPERTY_CHANGE,
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_PROPERTY_CHANGE,
|
||||||
};
|
};
|
||||||
xcb_change_window_attributes(m_connection, m_screen->root, XCB_CW_EVENT_MASK, values);
|
xcb_change_window_attributes(getConnection(), m_screen->root, XCB_CW_EVENT_MASK, values);
|
||||||
|
|
||||||
xcb_composite_redirect_subwindows(m_connection, m_screen->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
xcb_composite_redirect_subwindows(getConnection(), m_screen->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
||||||
|
|
||||||
xcb_atom_t supported[] = {
|
xcb_atom_t supported[] = {
|
||||||
HYPRATOMS["_NET_WM_STATE"], HYPRATOMS["_NET_ACTIVE_WINDOW"], HYPRATOMS["_NET_WM_MOVERESIZE"], HYPRATOMS["_NET_WM_STATE_FOCUSED"],
|
HYPRATOMS["_NET_WM_STATE"], HYPRATOMS["_NET_ACTIVE_WINDOW"], HYPRATOMS["_NET_WM_MOVERESIZE"], HYPRATOMS["_NET_WM_STATE_FOCUSED"],
|
||||||
HYPRATOMS["_NET_WM_STATE_MODAL"], HYPRATOMS["_NET_WM_STATE_FULLSCREEN"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_VERT"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_HORZ"],
|
HYPRATOMS["_NET_WM_STATE_MODAL"], HYPRATOMS["_NET_WM_STATE_FULLSCREEN"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_VERT"], HYPRATOMS["_NET_WM_STATE_MAXIMIZED_HORZ"],
|
||||||
HYPRATOMS["_NET_WM_STATE_HIDDEN"], HYPRATOMS["_NET_CLIENT_LIST"], HYPRATOMS["_NET_CLIENT_LIST_STACKING"],
|
HYPRATOMS["_NET_WM_STATE_HIDDEN"], HYPRATOMS["_NET_CLIENT_LIST"], HYPRATOMS["_NET_CLIENT_LIST_STACKING"],
|
||||||
};
|
};
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_SUPPORTED"], XCB_ATOM_ATOM, 32, sizeof(supported) / sizeof(*supported), supported);
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_SUPPORTED"], XCB_ATOM_ATOM, 32, sizeof(supported) / sizeof(*supported), supported);
|
||||||
|
|
||||||
setActiveWindow(XCB_WINDOW_NONE);
|
setActiveWindow(XCB_WINDOW_NONE);
|
||||||
initSelection();
|
initSelection();
|
||||||
@@ -988,7 +990,7 @@ CXWM::CXWM() : m_connection(g_pXWayland->m_server->m_xwmFDs[0].get()) {
|
|||||||
|
|
||||||
createWMWindow();
|
createWMWindow();
|
||||||
|
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
CXWM::~CXWM() {
|
CXWM::~CXWM() {
|
||||||
@@ -1002,24 +1004,24 @@ CXWM::~CXWM() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::setActiveWindow(xcb_window_t window) {
|
void CXWM::setActiveWindow(xcb_window_t window) {
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_ACTIVE_WINDOW"], HYPRATOMS["WINDOW"], 32, 1, &window);
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_ACTIVE_WINDOW"], HYPRATOMS["WINDOW"], 32, 1, &window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::createWMWindow() {
|
void CXWM::createWMWindow() {
|
||||||
constexpr const char* wmName = "Hyprland :D";
|
constexpr const char* wmName = "Hyprland :D";
|
||||||
m_wmWindow = xcb_generate_id(m_connection);
|
m_wmWindow = xcb_generate_id(getConnection());
|
||||||
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, m_wmWindow, m_screen->root, 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, 0, nullptr);
|
xcb_create_window(getConnection(), XCB_COPY_FROM_PARENT, m_wmWindow, m_screen->root, 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, 0, nullptr);
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_wmWindow, HYPRATOMS["_NET_WM_NAME"], HYPRATOMS["UTF8_STRING"],
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_wmWindow, HYPRATOMS["_NET_WM_NAME"], HYPRATOMS["UTF8_STRING"],
|
||||||
8, // format
|
8, // format
|
||||||
strlen(wmName), wmName);
|
strlen(wmName), wmName);
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_SUPPORTING_WM_CHECK"], XCB_ATOM_WINDOW,
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_SUPPORTING_WM_CHECK"], XCB_ATOM_WINDOW,
|
||||||
32, // format
|
32, // format
|
||||||
1, &m_wmWindow);
|
1, &m_wmWindow);
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_wmWindow, HYPRATOMS["_NET_SUPPORTING_WM_CHECK"], XCB_ATOM_WINDOW,
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_wmWindow, HYPRATOMS["_NET_SUPPORTING_WM_CHECK"], XCB_ATOM_WINDOW,
|
||||||
32, // format
|
32, // format
|
||||||
1, &m_wmWindow);
|
1, &m_wmWindow);
|
||||||
xcb_set_selection_owner(m_connection, m_wmWindow, HYPRATOMS["WM_S0"], XCB_CURRENT_TIME);
|
xcb_set_selection_owner(getConnection(), m_wmWindow, HYPRATOMS["WM_S0"], XCB_CURRENT_TIME);
|
||||||
xcb_set_selection_owner(m_connection, m_wmWindow, HYPRATOMS["_NET_WM_CM_S0"], XCB_CURRENT_TIME);
|
xcb_set_selection_owner(getConnection(), m_wmWindow, HYPRATOMS["_NET_WM_CM_S0"], XCB_CURRENT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::activateSurface(SP<CXWaylandSurface> surf, bool activate) {
|
void CXWM::activateSurface(SP<CXWaylandSurface> surf, bool activate) {
|
||||||
@@ -1034,7 +1036,7 @@ void CXWM::activateSurface(SP<CXWaylandSurface> surf, bool activate) {
|
|||||||
focusWindow(surf);
|
focusWindow(surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::sendState(SP<CXWaylandSurface> surf) {
|
void CXWM::sendState(SP<CXWaylandSurface> surf) {
|
||||||
@@ -1044,7 +1046,7 @@ void CXWM::sendState(SP<CXWaylandSurface> surf) {
|
|||||||
surf->setWithdrawn(false); // resend normal state
|
surf->setWithdrawn(false); // resend normal state
|
||||||
|
|
||||||
if (surf->m_withdrawn) {
|
if (surf->m_withdrawn) {
|
||||||
xcb_delete_property(m_connection, surf->m_xID, HYPRATOMS["_NET_WM_STATE"]);
|
xcb_delete_property(getConnection(), surf->m_xID, HYPRATOMS["_NET_WM_STATE"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1064,7 +1066,7 @@ void CXWM::sendState(SP<CXWaylandSurface> surf) {
|
|||||||
if (surf == m_focusedSurface)
|
if (surf == m_focusedSurface)
|
||||||
props.push_back(HYPRATOMS["_NET_WM_STATE_FOCUSED"]);
|
props.push_back(HYPRATOMS["_NET_WM_STATE_FOCUSED"]);
|
||||||
|
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, surf->m_xID, HYPRATOMS["_NET_WM_STATE"], XCB_ATOM_ATOM, 32, props.size(), props.data());
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, surf->m_xID, HYPRATOMS["_NET_WM_STATE"], XCB_ATOM_ATOM, 32, props.size(), props.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::onNewSurface(SP<CWLSurfaceResource> surf) {
|
void CXWM::onNewSurface(SP<CWLSurfaceResource> surf) {
|
||||||
@@ -1109,8 +1111,8 @@ void CXWM::readWindowData(SP<CXWaylandSurface> surf) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < interestingProps.size(); i++) {
|
for (size_t i = 0; i < interestingProps.size(); i++) {
|
||||||
xcb_get_property_cookie_t cookie = xcb_get_property(m_connection, 0, surf->m_xID, interestingProps[i], XCB_ATOM_ANY, 0, 2048);
|
xcb_get_property_cookie_t cookie = xcb_get_property(getConnection(), 0, surf->m_xID, interestingProps[i], XCB_ATOM_ANY, 0, 2048);
|
||||||
XCBReplyPtr<xcb_get_property_reply_t> reply(xcb_get_property_reply(m_connection, cookie, nullptr));
|
XCBReplyPtr<xcb_get_property_reply_t> reply(xcb_get_property_reply(getConnection(), cookie, nullptr));
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
Debug::log(ERR, "[xwm] Failed to get window property");
|
Debug::log(ERR, "[xwm] Failed to get window property");
|
||||||
continue;
|
continue;
|
||||||
@@ -1169,7 +1171,7 @@ void CXWM::updateClientList() {
|
|||||||
windows.push_back(surf->m_xID);
|
windows.push_back(surf->m_xID);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_CLIENT_LIST"], XCB_ATOM_WINDOW, 32, windows.size(), windows.data());
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_CLIENT_LIST"], XCB_ATOM_WINDOW, 32, windows.size(), windows.data());
|
||||||
|
|
||||||
windows.clear();
|
windows.clear();
|
||||||
windows.reserve(m_mappedSurfacesStacking.size());
|
windows.reserve(m_mappedSurfacesStacking.size());
|
||||||
@@ -1179,7 +1181,7 @@ void CXWM::updateClientList() {
|
|||||||
windows.push_back(surf->m_xID);
|
windows.push_back(surf->m_xID);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_CLIENT_LIST_STACKING"], XCB_ATOM_WINDOW, 32, windows.size(), windows.data());
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_screen->root, HYPRATOMS["_NET_CLIENT_LIST_STACKING"], XCB_ATOM_WINDOW, 32, windows.size(), windows.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CXWM::isWMWindow(xcb_window_t w) {
|
bool CXWM::isWMWindow(xcb_window_t w) {
|
||||||
@@ -1199,16 +1201,16 @@ void CXWM::initSelection() {
|
|||||||
XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
|
XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
|
||||||
|
|
||||||
auto createSelectionWindow = [&](xcb_window_t& window, const std::string& atomName, bool inputOnly = false) {
|
auto createSelectionWindow = [&](xcb_window_t& window, const std::string& atomName, bool inputOnly = false) {
|
||||||
window = xcb_generate_id(m_connection);
|
window = xcb_generate_id(getConnection());
|
||||||
const uint16_t width = inputOnly ? 8192 : 10;
|
const uint16_t width = inputOnly ? 8192 : 10;
|
||||||
const uint16_t height = inputOnly ? 8192 : 10;
|
const uint16_t height = inputOnly ? 8192 : 10;
|
||||||
|
|
||||||
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, window, m_screen->root, 0, 0, width, height, 0,
|
xcb_create_window(getConnection(), XCB_COPY_FROM_PARENT, window, m_screen->root, 0, 0, width, height, 0,
|
||||||
inputOnly ? XCB_WINDOW_CLASS_INPUT_ONLY : XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, XCB_CW_EVENT_MASK, &windowMask);
|
inputOnly ? XCB_WINDOW_CLASS_INPUT_ONLY : XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, XCB_CW_EVENT_MASK, &windowMask);
|
||||||
|
|
||||||
if (!inputOnly) {
|
if (!inputOnly) {
|
||||||
xcb_set_selection_owner(m_connection, window, HYPRATOMS[atomName], XCB_TIME_CURRENT_TIME);
|
xcb_set_selection_owner(getConnection(), window, HYPRATOMS[atomName], XCB_TIME_CURRENT_TIME);
|
||||||
xcb_xfixes_select_selection_input(m_connection, window, HYPRATOMS[atomName], xfixesMask);
|
xcb_xfixes_select_selection_input(getConnection(), window, HYPRATOMS[atomName], xfixesMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
@@ -1225,7 +1227,7 @@ void CXWM::initSelection() {
|
|||||||
|
|
||||||
createSelectionWindow(m_dndSelection.window, "XdndAware", true);
|
createSelectionWindow(m_dndSelection.window, "XdndAware", true);
|
||||||
const uint32_t xdndVersion = XDND_VERSION;
|
const uint32_t xdndVersion = XDND_VERSION;
|
||||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_dndSelection.window, HYPRATOMS["XdndAware"], XCB_ATOM_ATOM, 32, 1, &xdndVersion);
|
xcb_change_property(getConnection(), XCB_PROP_MODE_REPLACE, m_dndSelection.window, HYPRATOMS["XdndAware"], XCB_ATOM_ATOM, 32, 1, &xdndVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXWM::setClipboardToWayland(SXSelection& sel) {
|
void CXWM::setClipboardToWayland(SXSelection& sel) {
|
||||||
@@ -1309,30 +1311,30 @@ void CXWM::setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& si
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_cursorXID)
|
if (m_cursorXID)
|
||||||
xcb_free_cursor(m_connection, m_cursorXID);
|
xcb_free_cursor(getConnection(), m_cursorXID);
|
||||||
|
|
||||||
constexpr int CURSOR_DEPTH = 32;
|
constexpr int CURSOR_DEPTH = 32;
|
||||||
|
|
||||||
xcb_pixmap_t pix = xcb_generate_id(m_connection);
|
xcb_pixmap_t pix = xcb_generate_id(getConnection());
|
||||||
xcb_create_pixmap(m_connection, CURSOR_DEPTH, pix, m_screen->root, size.x, size.y);
|
xcb_create_pixmap(getConnection(), CURSOR_DEPTH, pix, m_screen->root, size.x, size.y);
|
||||||
|
|
||||||
xcb_render_picture_t pic = xcb_generate_id(m_connection);
|
xcb_render_picture_t pic = xcb_generate_id(getConnection());
|
||||||
xcb_render_create_picture(m_connection, pic, pix, m_renderFormatID, 0, nullptr);
|
xcb_render_create_picture(getConnection(), pic, pix, m_renderFormatID, 0, nullptr);
|
||||||
|
|
||||||
xcb_gcontext_t gc = xcb_generate_id(m_connection);
|
xcb_gcontext_t gc = xcb_generate_id(getConnection());
|
||||||
xcb_create_gc(m_connection, gc, pix, 0, nullptr);
|
xcb_create_gc(getConnection(), gc, pix, 0, nullptr);
|
||||||
|
|
||||||
xcb_put_image(m_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, size.x, size.y, 0, 0, 0, CURSOR_DEPTH, stride * size.y * sizeof(uint8_t), pixData);
|
xcb_put_image(getConnection(), XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, size.x, size.y, 0, 0, 0, CURSOR_DEPTH, stride * size.y * sizeof(uint8_t), pixData);
|
||||||
xcb_free_gc(m_connection, gc);
|
xcb_free_gc(getConnection(), gc);
|
||||||
|
|
||||||
m_cursorXID = xcb_generate_id(m_connection);
|
m_cursorXID = xcb_generate_id(getConnection());
|
||||||
xcb_render_create_cursor(m_connection, m_cursorXID, pic, hotspot.x, hotspot.y);
|
xcb_render_create_cursor(getConnection(), m_cursorXID, pic, hotspot.x, hotspot.y);
|
||||||
xcb_free_pixmap(m_connection, pix);
|
xcb_free_pixmap(getConnection(), pix);
|
||||||
xcb_render_free_picture(m_connection, pic);
|
xcb_render_free_picture(getConnection(), pic);
|
||||||
|
|
||||||
uint32_t values[] = {m_cursorXID};
|
uint32_t values[] = {m_cursorXID};
|
||||||
xcb_change_window_attributes(m_connection, m_screen->root, XCB_CW_CURSOR, values);
|
xcb_change_window_attributes(getConnection(), m_screen->root, XCB_CW_CURSOR, values);
|
||||||
xcb_flush(m_connection);
|
xcb_flush(getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<CX11DataDevice> CXWM::getDataDevice() {
|
SP<CX11DataDevice> CXWM::getDataDevice() {
|
||||||
@@ -1371,7 +1373,7 @@ void SXSelection::onSelection() {
|
|||||||
if (isX11Clipboard || isX11Primary)
|
if (isX11Clipboard || isX11Primary)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xcb_connection_t* conn = g_pXWayland->m_wm->m_connection;
|
auto conn = g_pXWayland->m_wm->getConnection();
|
||||||
|
|
||||||
if (isClipboard && currentSel) {
|
if (isClipboard && currentSel) {
|
||||||
xcb_set_selection_owner(conn, g_pXWayland->m_wm->m_clipboard.window, HYPRATOMS["CLIPBOARD"], XCB_TIME_CURRENT_TIME);
|
xcb_set_selection_owner(conn, g_pXWayland->m_wm->m_clipboard.window, HYPRATOMS["CLIPBOARD"], XCB_TIME_CURRENT_TIME);
|
||||||
@@ -1421,8 +1423,15 @@ int SXSelection::onRead(int fd, uint32_t mask) {
|
|||||||
transfer->data.resize(oldSize + bytesRead);
|
transfer->data.resize(oldSize + bytesRead);
|
||||||
|
|
||||||
if (bytesRead == 0) {
|
if (bytesRead == 0) {
|
||||||
|
if (transfer->data.empty()) {
|
||||||
|
Debug::log(WARN, "[xwm] Transfer ended with zero bytes — rejecting");
|
||||||
|
g_pXWayland->m_wm->selectionSendNotify(&transfer->request, false);
|
||||||
|
transfers.erase(it);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "[xwm] Transfer complete, total size: {}", transfer->data.size());
|
Debug::log(LOG, "[xwm] Transfer complete, total size: {}", transfer->data.size());
|
||||||
auto conn = g_pXWayland->m_wm->m_connection;
|
auto conn = g_pXWayland->m_wm->getConnection();
|
||||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, transfer->request.requestor, transfer->request.property, transfer->request.target, 8, transfer->data.size(),
|
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, transfer->request.requestor, transfer->request.property, transfer->request.target, 8, transfer->data.size(),
|
||||||
transfer->data.data());
|
transfer->data.data());
|
||||||
|
|
||||||
@@ -1452,16 +1461,20 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
|
|||||||
else if (!g_pXWayland->m_wm->m_dndDataOffers.empty())
|
else if (!g_pXWayland->m_wm->m_dndDataOffers.empty())
|
||||||
selection = g_pXWayland->m_wm->m_dndDataOffers.at(0)->getSource();
|
selection = g_pXWayland->m_wm->m_dndDataOffers.at(0)->getSource();
|
||||||
|
|
||||||
if (!selection)
|
if (!selection) {
|
||||||
|
Debug::log(ERR, "[xwm] sendData: no selection source available");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const auto MIMES = selection->mimes();
|
const auto MIMES = selection->mimes();
|
||||||
|
|
||||||
if (MIMES.empty())
|
if (MIMES.empty()) {
|
||||||
|
Debug::log(ERR, "[xwm] sendData: selection source has no mimes");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::ranges::find(MIMES, mime) == MIMES.end()) {
|
if (std::ranges::find(MIMES, mime) == MIMES.end()) {
|
||||||
Debug::log(ERR, "[xwm] X Client asked for an invalid MIME, sending the first advertised. THIS SHIT MAY BREAK!");
|
Debug::log(ERR, "[xwm] X client asked for unknown MIME '{}', falling back to '{}'", mime, *MIMES.begin());
|
||||||
mime = *MIMES.begin();
|
mime = *MIMES.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1470,15 +1483,14 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
|
|||||||
|
|
||||||
int p[2];
|
int p[2];
|
||||||
if (pipe(p) == -1) {
|
if (pipe(p) == -1) {
|
||||||
Debug::log(ERR, "[xwm] selection: pipe() failed");
|
Debug::log(ERR, "[xwm] sendData: pipe() failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(p[0], F_SETFD, FD_CLOEXEC);
|
fcntl(p[0], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(p[0], F_SETFL, O_NONBLOCK);
|
fcntl(p[0], F_SETFL, O_NONBLOCK);
|
||||||
fcntl(p[1], F_SETFD, FD_CLOEXEC);
|
fcntl(p[1], F_SETFD, FD_CLOEXEC);
|
||||||
// the wayland client might not expect a non-blocking fd
|
// Do NOT set O_NONBLOCK on p[1] (wayland clients may block)
|
||||||
// fcntl(p[1], F_SETFL, O_NONBLOCK);
|
|
||||||
|
|
||||||
transfer->wlFD = CFileDescriptor{p[0]};
|
transfer->wlFD = CFileDescriptor{p[0]};
|
||||||
|
|
||||||
@@ -1487,8 +1499,8 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
|
|||||||
selection->send(mime, CFileDescriptor{p[1]});
|
selection->send(mime, CFileDescriptor{p[1]});
|
||||||
|
|
||||||
transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this);
|
transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this);
|
||||||
transfers.emplace_back(std::move(transfer));
|
|
||||||
|
|
||||||
|
transfers.emplace_back(std::move(transfer));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1533,17 +1545,17 @@ SXTransfer::~SXTransfer() {
|
|||||||
if (eventSource)
|
if (eventSource)
|
||||||
wl_event_source_remove(eventSource);
|
wl_event_source_remove(eventSource);
|
||||||
if (incomingWindow)
|
if (incomingWindow)
|
||||||
xcb_destroy_window(g_pXWayland->m_wm->m_connection, incomingWindow);
|
xcb_destroy_window(*g_pXWayland->m_wm->m_connection, incomingWindow);
|
||||||
if (propertyReply)
|
if (propertyReply)
|
||||||
free(propertyReply);
|
free(propertyReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SXTransfer::getIncomingSelectionProp(bool erase) {
|
bool SXTransfer::getIncomingSelectionProp(bool erase) {
|
||||||
xcb_get_property_cookie_t cookie =
|
xcb_get_property_cookie_t cookie =
|
||||||
xcb_get_property(g_pXWayland->m_wm->m_connection, erase, incomingWindow, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 0x1fffffff);
|
xcb_get_property(*g_pXWayland->m_wm->m_connection, erase, incomingWindow, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 0x1fffffff);
|
||||||
|
|
||||||
propertyStart = 0;
|
propertyStart = 0;
|
||||||
propertyReply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, cookie, nullptr);
|
propertyReply = xcb_get_property_reply(*g_pXWayland->m_wm->m_connection, cookie, nullptr);
|
||||||
|
|
||||||
if (!propertyReply) {
|
if (!propertyReply) {
|
||||||
Debug::log(ERR, "[SXTransfer] couldn't get a prop reply");
|
Debug::log(ERR, "[SXTransfer] couldn't get a prop reply");
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
#include <xcb/xcb_errors.h>
|
#include <xcb/xcb_errors.h>
|
||||||
#include <hyprutils/os/FileDescriptor.hpp>
|
#include <hyprutils/os/FileDescriptor.hpp>
|
||||||
|
#include <cinttypes> // for PRIxPTR
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
struct wl_event_source;
|
struct wl_event_source;
|
||||||
class CXWaylandSurfaceResource;
|
class CXWaylandSurfaceResource;
|
||||||
@@ -68,8 +70,12 @@ class CXCBConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~CXCBConnection() {
|
~CXCBConnection() {
|
||||||
if (m_connection)
|
if (m_connection) {
|
||||||
|
Debug::log(LOG, "Disconnecting XCB connection {:x}", (uintptr_t)m_connection);
|
||||||
xcb_disconnect(m_connection);
|
xcb_disconnect(m_connection);
|
||||||
|
m_connection = nullptr;
|
||||||
|
} else
|
||||||
|
Debug::log(ERR, "Double xcb_disconnect attempt");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasError() const {
|
bool hasError() const {
|
||||||
@@ -174,7 +180,7 @@ class CXWM {
|
|||||||
SXSelection* getSelection(xcb_atom_t atom);
|
SXSelection* getSelection(xcb_atom_t atom);
|
||||||
|
|
||||||
//
|
//
|
||||||
CXCBConnection m_connection;
|
UP<CXCBConnection> m_connection;
|
||||||
xcb_errors_context_t* m_errors = nullptr;
|
xcb_errors_context_t* m_errors = nullptr;
|
||||||
xcb_screen_t* m_screen = nullptr;
|
xcb_screen_t* m_screen = nullptr;
|
||||||
|
|
||||||
@@ -206,6 +212,9 @@ class CXWM {
|
|||||||
SP<CX11DataDevice> m_dndDataDevice = makeShared<CX11DataDevice>();
|
SP<CX11DataDevice> m_dndDataDevice = makeShared<CX11DataDevice>();
|
||||||
std::vector<SP<CX11DataOffer>> m_dndDataOffers;
|
std::vector<SP<CX11DataOffer>> m_dndDataOffers;
|
||||||
|
|
||||||
|
inline xcb_connection_t* getConnection() {
|
||||||
|
return m_connection ? *m_connection : nullptr;
|
||||||
|
}
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener newWLSurface;
|
CHyprSignalListener newWLSurface;
|
||||||
CHyprSignalListener newXShellSurface;
|
CHyprSignalListener newXShellSurface;
|
||||||
|
Reference in New Issue
Block a user