xcbOrg/Window: Destroy connections when no longer in use
This commit is contained in:
@@ -73,6 +73,18 @@ size_t ConnectionManager::getConnectionCount()
|
||||
return connections.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a specific connection from the manager
|
||||
* @param id Connection identifier to remove
|
||||
*/
|
||||
void ConnectionManager::removeConnection(const ConnectionIdentifier& id)
|
||||
{
|
||||
auto it = connections.find(id);
|
||||
if (it != connections.end()) {
|
||||
connections.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
namespace window_search {
|
||||
|
||||
struct XcbReplyDeleter {
|
||||
@@ -83,14 +95,14 @@ struct XcbReplyDeleter {
|
||||
xcb_window_t findById(
|
||||
xcb_connection_t* conn, xcb_window_t root, uint32_t targetId)
|
||||
{
|
||||
if (root == targetId) return root;
|
||||
|
||||
xcb_query_tree_cookie_t cookie = xcb_query_tree(conn, root);
|
||||
std::unique_ptr<xcb_query_tree_reply_t, XcbReplyDeleter> reply(
|
||||
xcb_query_tree_reply(conn, cookie, nullptr));
|
||||
|
||||
if (!reply) return 0;
|
||||
|
||||
if (root == targetId) return root;
|
||||
|
||||
xcb_window_t* children = xcb_query_tree_children(reply.get());
|
||||
int num_children = xcb_query_tree_children_length(reply.get());
|
||||
|
||||
@@ -262,3 +274,19 @@ xcb_window_t xcb_xorg_find_window_by_name(void* conn, xcb_window_t root,
|
||||
connection->getConnection(), root, targetName, outWindowName,
|
||||
matchType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dereference a connection (decrements ref count and closes if zero)
|
||||
* @param conn Shared pointer to the connection to dereference
|
||||
*/
|
||||
extern "C" dereference_connection_fn xcb_xorg_dereference_connection;
|
||||
void xcb_xorg_dereference_connection(std::shared_ptr<xcb_xorg::XcbConnection> conn)
|
||||
{
|
||||
if (!conn) return;
|
||||
|
||||
int newRefCount = conn->decrementRefCount();
|
||||
// Remove from connection manager if ref count reaches zero
|
||||
if (newRefCount <= 0) {
|
||||
xcb_xorg::ConnectionManager::removeConnection(conn->getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,12 @@ public:
|
||||
*/
|
||||
static size_t getConnectionCount();
|
||||
|
||||
/**
|
||||
* @brief Remove a specific connection from the manager
|
||||
* @param id Connection identifier to remove
|
||||
*/
|
||||
static void removeConnection(const ConnectionIdentifier& id);
|
||||
|
||||
private:
|
||||
static std::map<ConnectionIdentifier, std::shared_ptr<XcbConnection>> connections;
|
||||
};
|
||||
@@ -167,6 +173,8 @@ xcb_window_t findByName(xcb_connection_t* conn, xcb_window_t root,
|
||||
typedef std::shared_ptr<xcb_xorg::XcbConnection> get_or_create_connection_fn(
|
||||
int display, int screen);
|
||||
typedef void cleanup_connections_fn();
|
||||
typedef void dereference_connection_fn(
|
||||
std::shared_ptr<xcb_xorg::XcbConnection> conn);
|
||||
typedef xcb_window_t find_window_by_id_fn(
|
||||
void* conn, xcb_window_t root, uint32_t targetId);
|
||||
typedef xcb_window_t find_window_by_name_fn(void* conn, xcb_window_t root,
|
||||
|
||||
Reference in New Issue
Block a user