fix a problem when removing a node that has another split as their sibling

This commit is contained in:
Akos Horvath 2023-07-02 22:40:37 +02:00
parent 463d095aa0
commit ebaa9734dc
3 changed files with 31 additions and 17 deletions

View File

@ -245,19 +245,13 @@ void wm_client_kill(Wm *wm, Client *c)
XKillClient(wm->display, c->window);
TreeNode* parent = wm_treenode_remove_client(&c->ws->tree, c);
Client *client_to_be_focused = NULL;
if (!parent || parent->type != NODE_CLIENT || !parent->client) {
PtrArray clients = wm_treenode_find_client_nodes_ptr(&c->ws->tree);
if (clients.size > 0)
client_to_be_focused = ((TreeNode*)clients.ptrs[0])->client;
}
wm_client_free(wm, c);
wm_layout(wm, m);
wm_client_focus(wm, parent->client);
if (parent && parent->type == NODE_CLIENT)
wm_client_focus(wm, parent->client);
}
void wm_client_set_atom(Wm *wm, Client *c, const char* name, const unsigned char *data,

37
util.c
View File

@ -164,6 +164,18 @@ void wm_treenode_remove_node(TreeNode *root, unsigned int node_id)
}
}
TreeNode* wm_treenode_split_get_sibling(TreeNode *node)
{
for (size_t i = 0; i < node->parent->children.size; i++) {
TreeNode *sibling_node = &node->parent->children.nodes[i];
if (sibling_node->id != node->id) {
return sibling_node;
}
}
return NULL;
}
TreeNode* wm_treenode_remove_client(TreeNode *root, Client *client)
{
DEBUG_PRINT("%s\n", __func__);
@ -178,24 +190,31 @@ TreeNode* wm_treenode_remove_client(TreeNode *root, Client *client)
}
TreeNode *node = client_node->parent;
node->type = NODE_CLIENT;
Client *other_client = NULL;
for (size_t i = 0; i < node->children.size; i++) {
if (node->children.nodes[i].type == NODE_CLIENT &&
node->children.nodes[i].client != client) {
other_client = node->children.nodes[i].client;
node->type = NODE_CLIENT;
node->client = node->children.nodes[i].client;
wm_nodearray_clear(&node->children);
return node;
}
}
if (other_client == NULL) {
DEBUG_PRINT("%s: other_client was NULL!\n", __func__);
DEBUG_PRINT("%s: other_client was NULL!\n", __func__);
// todo
}
TreeNode *sibling_node = wm_treenode_split_get_sibling(client_node);
wm_nodearray_free(&client_node->children);
node->client = other_client;
wm_nodearray_clear(&node->children);
wm_nodearray_free(&node->children);
if (node->parent == NULL) {
// parent is root node
sibling_node->parent = NULL;
client->ws->tree = *sibling_node;
} else
*node = *sibling_node;
return node;
}

1
util.h
View File

@ -90,6 +90,7 @@ void wm_ptrarray_free(PtrArray *arr);
TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root);
TreeNode* wm_treenode_ptr_find_client_node(TreeNode *root, Client *client);
PtrArray wm_treenode_find_client_nodes_ptr(TreeNode *root);
TreeNode* wm_treenode_split_get_sibling(TreeNode *node);
PtrArray wm_all_nodes_to_ptrarray(TreeNode *root);
ClientArray wm_clientarray_new();