Compare commits

...

2 Commits

Author SHA1 Message Date
f822c400e5 replace old client linked list code 2023-07-06 14:54:33 +02:00
4b1a638633 fix memory leaks 2023-07-06 14:41:54 +02:00
3 changed files with 70 additions and 45 deletions

View File

@ -42,14 +42,20 @@ XWindowChanges wm_client_to_xwchanges(Client *c)
Client* wm_client_find(Wm *wm, Window w)
{
Client *c;
PtrArray clients = wm_treenode_find_client_nodes_ptr(&wm->smon->workspaces[wm->smon->selws].tree);
Client *ret = NULL;
for (c = wm->smon->clients; c; c = c->next) {
if (c->window == w)
return c;
for (size_t i = 0; i < clients.size; i++) {
Client *c = ((TreeNode*)clients.ptrs[i])->client;
if (c->window == w) {
ret = c;
goto ret;
}
}
return NULL;
ret:
wm_ptrarray_free(&clients);
return ret;
}
Client* wm_client_create(Wm *wm, Window w)
@ -70,6 +76,7 @@ Client* wm_client_create(Wm *wm, Window w)
c->ws = &wm->smon->workspaces[wm->smon->selws];
c->hidden = true;
c->is_floating = false;
c->name = NULL;
if (xtp.value) {
strln = strlen((char*)xtp.value);
@ -114,19 +121,17 @@ void wm_client_handle_window_types(Wm *wm, Client *c, XMapRequestEvent e)
}
for (size_t i = 0; i < nitems_ret; i++) {
char *atom_name = XGetAtomName(wm->display, ((Atom*)prop_ret)[i]);
DEBUG_PRINT("ConfigureRequest handler: window %d has property %s\n",
(int)e.window, XGetAtomName(wm->display, ((Atom*)prop_ret)[i]));
if (strcmp(XGetAtomName(wm->display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
(int)e.window, atom_name);
if (strcmp(atom_name,"_NET_WM_WINDOW_TYPE_NORMAL") == 0) {
is_normal = true;
} else if (strcmp(XGetAtomName(wm->display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_DOCK") == 0) {
} else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DOCK") == 0) {
// wm->dock = e.window;
fprintf(stderr, "client should not have _NET_WM_WINDOW_TYPE_DOCK type\n");
// todo function to exit
exit(1);
} else if (strcmp(XGetAtomName(wm->display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
} else if (strcmp(atom_name, "_NET_WM_WINDOW_TYPE_DIALOG") == 0) {
c->is_floating = true;
}
}
@ -137,6 +142,8 @@ void wm_client_handle_window_types(Wm *wm, Client *c, XMapRequestEvent e)
// wm_client_kill(wm, c);
return;
}
XFree(prop_ret);
}
void wm_client_hide(Wm *wm, Client *c)
@ -208,19 +215,10 @@ void wm_client_free(Wm *wm, Client *c)
DEBUG_PRINT("%s\n", __func__);
RETURN_IF_NULL(c);
if (c == wm->smon->clients) {
if (c->next)
wm->smon->clients = c->next;
else
wm->smon->clients = NULL;
} else {
if (!c->next)
c->prev->next = NULL;
else {
c->prev->next = c->next;
c->next->prev = c->prev;
}
}
if (c->name)
free(c->name);
free(c);
}
void wm_client_kill(Wm *wm, Client *c)
@ -247,6 +245,7 @@ void wm_client_kill(Wm *wm, Client *c)
TreeNode* parent = wm_treenode_remove_client(wm, &c->ws->tree, c);
wm_client_free(wm, c);
wm->focused_client = NULL;
wm_layout(wm, m);
@ -299,8 +298,9 @@ Atom wm_client_get_atom(Wm *wm, Client *c, const char *name, unsigned char **ato
DEBUG_PRINT("actual number of items return: %ld\n", *nitems_ret)
DEBUG_PRINT("bytes remaining: %ld\n", *nitems_ret)
for (int i = 0; i < *nitems_ret; i++) {
printf("property return str: %s\n",
XGetAtomName(wm->display, ((Atom*)*atom_ret)[i]));
char *atom_name = XGetAtomName(wm->display, ((Atom*)*atom_ret)[i]);
printf("property return str: %s\n", atom_name);
XFree(atom_name);
}
return type_ret;
@ -448,15 +448,18 @@ void wm_monitor_clients_border(Wm *wm, Monitor *m)
{
DEBUG_PRINT("%s\n", __func__)
RETURN_IF_NULL(m);
Client *c;
PtrArray clients = wm_treenode_find_client_nodes_ptr(&m->workspaces[m->selws].tree);
if (clients.size == 0)
return;
for (c = wm->smon->clients; c; c = c->next) {
if (c->window != wm->root.window) {
DEBUG_PRINT("monitor border c: %p\n", c)
DEBUG_PRINT("monitor border c window: %ld\n", c->window)
wm_client_border(wm, c);
}
for (size_t i = 0; i < clients.size; i++) {
Client *client = ((TreeNode*)clients.ptrs[i])->client;
DEBUG_PRINT("monitor border c: %p\n", client)
DEBUG_PRINT("monitor border c window: %ld\n", client->window)
wm_client_border(wm, client);
}
wm_ptrarray_free(&clients);
}
bool wm_client_is_focused(Wm *wm, Client *c)

View File

@ -187,6 +187,7 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client)
if (client_node->parent == NULL) {
client_node->client = NULL;
wm_nodearray_clear(&client_node->children);
wm_nodearray_free(&client_node->children);
return NULL;
}
@ -198,6 +199,8 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client)
node->type = NODE_CLIENT;
node->client = node->children.nodes[i].client;
wm_nodearray_free(&client_node->children);
wm_nodearray_free(&node->children.nodes[i].children);
wm_nodearray_clear(&node->children);
return node;
}

View File

@ -57,7 +57,8 @@ void wm_monitors_open_all(Wm *wm, Display *d)
printf("wm: Could not open display. Exiting.\n");
exit(1);
}
wm->wm_mc = count;
wm->monitors = malloc(count * sizeof(Monitor));
for (int i = 0; i < count; i++) {
@ -84,6 +85,7 @@ void wm_monitors_open_all(Wm *wm, Display *d)
wm->smon = &wm->monitors[0];
// wm->smon->clients = &wm->root;
DEBUG_PRINT("smon width: %d\n", wm->smon->info.width);
XFree(xsi);
}
Display* wm_connect_display()
@ -149,16 +151,19 @@ bool wm_window_is_dock(Wm *wm, Window w)
DEBUG_PRINT("bytes remaining: %ld\n", nitems_ret)
//DEBUG_PRINT("property return dec: %d\n", prop_ret)
for (size_t i = 0; i < nitems_ret; i++) {
printf("property return str: %s\n",
XGetAtomName(wm->display, ((Atom*)prop_ret)[i]));
if (strcmp(XGetAtomName(wm->display, ((Atom*)prop_ret)[i]),
"_NET_WM_WINDOW_TYPE_DOCK") == 0) {
char *ret_str = XGetAtomName(wm->display, ((Atom*)prop_ret)[i]);
printf("property return str: %s\n", ret_str);
if (strcmp(ret_str, "_NET_WM_WINDOW_TYPE_DOCK") == 0) {
DEBUG_PRINT("%s", __func__)
DEBUG_PRINT("returning true\n")
XFree(ret_str);
return true;
}
XFree(ret_str);
}
XFree(prop_ret);
return false;
}
@ -596,20 +601,34 @@ void wm_init(Wm *wm)
void wm_exit(Wm *wm)
{
DEBUG_PRINT("%s\n", __func__);
Client *c;
XUngrabKey(wm->display, AnyKey, AnyModifier, wm->root.window);
PtrArray all_clients = wm_ptrarray_new();
// todo add clients to root client linked list
for (c = wm->smon->clients; c; c = c->next) {
XKillClient(wm->display, c->window);
// TODO: perhaps add created clients to a PtrArray field in workspace.
// would reduce number of calls to wm_treenode_find_client_nodes_ptr
for (size_t i = 0; i < wm->wm_mc; i++) {
for (size_t j = 0; j < wm->monitors[i].wscount; j++) {
PtrArray clients = wm_treenode_find_client_nodes_ptr(
&wm->monitors[i].workspaces[j].tree);
for (size_t k = 0; k < clients.size; k++) {
wm_ptrarray_push(&all_clients, clients.ptrs[i]);
}
wm_ptrarray_free(&clients);
}
}
for (c = wm->smon->clients; c; c = c->next) {
for (size_t i = 0; i < all_clients.size; i++) {
Client *c = ((TreeNode*)all_clients.ptrs[i])->client;
XKillClient(wm->display, c->window);
wm_client_free(wm, c);
}
DEBUG_PRINT("%s1\n", __func__);
XCloseDisplay(wm->display);
wm_ptrarray_free(&all_clients);
exit(EXIT_SUCCESS);
}