窗口消失时清理对应的 client
This commit is contained in:
@@ -58,6 +58,7 @@ typedef struct map_request_event_t {
|
|||||||
|
|
||||||
typedef struct unmap_notify_event_t {
|
typedef struct unmap_notify_event_t {
|
||||||
event_type_t type;
|
event_type_t type;
|
||||||
|
xcb_window_t window;
|
||||||
} unmap_notify_event_t;
|
} unmap_notify_event_t;
|
||||||
|
|
||||||
typedef struct destroy_notify_event_t {
|
typedef struct destroy_notify_event_t {
|
||||||
|
|||||||
47
src/main.c
47
src/main.c
@@ -37,10 +37,15 @@ static void xcb_event_handler(generic_event_t *event, void *user_data);
|
|||||||
static void key_press(key_press_event_t *event);
|
static void key_press(key_press_event_t *event);
|
||||||
static void configure_request(configure_request_event_t *event);
|
static void configure_request(configure_request_event_t *event);
|
||||||
static void map_request(map_request_event_t *event);
|
static void map_request(map_request_event_t *event);
|
||||||
|
static void unmap_notify(unmap_notify_event_t *event);
|
||||||
static void manage_window(xcb_window_t window);
|
static void manage_window(xcb_window_t window);
|
||||||
|
static void unmanage_client(client_t *client);
|
||||||
static void update_client_name(client_t *client);
|
static void update_client_name(client_t *client);
|
||||||
static void apply_rules(client_t *client);
|
static void apply_rules(client_t *client);
|
||||||
static void attach_client(client_t *client);
|
static void attach_client(client_t *client);
|
||||||
|
static void detach_client(client_t *client);
|
||||||
|
static void attach_stack_client(client_t *client);
|
||||||
|
static void detach_stack_client(client_t *client);
|
||||||
static void show_hide_client(client_t *client);
|
static void show_hide_client(client_t *client);
|
||||||
static void apply_monitor_layout(monitor_t *monitor);
|
static void apply_monitor_layout(monitor_t *monitor);
|
||||||
static client_t *get_client_of_window(xcb_window_t window);
|
static client_t *get_client_of_window(xcb_window_t window);
|
||||||
@@ -419,6 +424,7 @@ void xcb_event_handler(generic_event_t *event, void *user_data) {
|
|||||||
EVENT(EVENT_TYPE_KEY_PRESS, key_press);
|
EVENT(EVENT_TYPE_KEY_PRESS, key_press);
|
||||||
EVENT(EVENT_TYPE_CONFIGURE_REQUEST, configure_request);
|
EVENT(EVENT_TYPE_CONFIGURE_REQUEST, configure_request);
|
||||||
EVENT(EVENT_TYPE_MAP_REQUEST, map_request);
|
EVENT(EVENT_TYPE_MAP_REQUEST, map_request);
|
||||||
|
EVENT(EVENT_TYPE_UNMAP_NOTIFY, unmap_notify);
|
||||||
|
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
|
|
||||||
@@ -460,6 +466,13 @@ void map_request(map_request_event_t *event) {
|
|||||||
manage_window(event->window);
|
manage_window(event->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unmap_notify(unmap_notify_event_t *event) {
|
||||||
|
client_t *c = get_client_of_window(event->window);
|
||||||
|
if (c) {
|
||||||
|
unmanage_client(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void manage_window(xcb_window_t window) {
|
void manage_window(xcb_window_t window) {
|
||||||
window_geometry_t *geometry = get_window_geometry(window);
|
window_geometry_t *geometry = get_window_geometry(window);
|
||||||
client_t *c = ecalloc(1, sizeof(client_t));
|
client_t *c = ecalloc(1, sizeof(client_t));
|
||||||
@@ -487,6 +500,7 @@ void manage_window(xcb_window_t window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attach_client(c);
|
attach_client(c);
|
||||||
|
attach_stack_client(c);
|
||||||
apply_monitor_layout(c->monitor);
|
apply_monitor_layout(c->monitor);
|
||||||
init_window_event_mask(window);
|
init_window_event_mask(window);
|
||||||
change_window_border_color(window, color_set->border_color.argb);
|
change_window_border_color(window, color_set->border_color.argb);
|
||||||
@@ -497,6 +511,16 @@ void manage_window(xcb_window_t window) {
|
|||||||
update_bars();
|
update_bars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unmanage_client(client_t *client) {
|
||||||
|
monitor_t *monitor = client->monitor;
|
||||||
|
|
||||||
|
detach_client(client);
|
||||||
|
detach_stack_client(client);
|
||||||
|
free(client);
|
||||||
|
apply_monitor_layout(monitor);
|
||||||
|
flush_xcb_connection();
|
||||||
|
}
|
||||||
|
|
||||||
void update_client_name(client_t *client) {
|
void update_client_name(client_t *client) {
|
||||||
char *name = get_window_name(client->window);
|
char *name = get_window_name(client->window);
|
||||||
strncpy(client->name, name, sizeof(client->name) - 1);
|
strncpy(client->name, name, sizeof(client->name) - 1);
|
||||||
@@ -555,6 +579,29 @@ void attach_client(client_t *client) {
|
|||||||
client->monitor->clients = client;
|
client->monitor->clients = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void detach_client(client_t *client) {
|
||||||
|
client_t **c = &client->monitor->clients;
|
||||||
|
for (; *c && *c != client; c = &(*c)->next);
|
||||||
|
*c = client->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach_stack_client(client_t *client) {
|
||||||
|
client->stack_next = client->monitor->clients_stack;
|
||||||
|
client->monitor->clients_stack = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach_stack_client(client_t *client) {
|
||||||
|
client_t **tc = &client->monitor->clients_stack;
|
||||||
|
for (; *tc && *tc != client; tc = &(*tc)->stack_next);
|
||||||
|
*tc = client->stack_next;
|
||||||
|
|
||||||
|
if (client == client->monitor->selected_client) {
|
||||||
|
client_t *t = client->monitor->clients_stack;
|
||||||
|
for (; t && !CLIENT_VISIBLE(t); t = t->stack_next);
|
||||||
|
client->monitor->selected_client = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void show_hide_client(client_t *client) {
|
void show_hide_client(client_t *client) {
|
||||||
if (!client || CLIENT_VISIBLE(client)) return;
|
if (!client || CLIENT_VISIBLE(client)) return;
|
||||||
client->x = client->monitor->monitor_x;
|
client->x = client->monitor->monitor_x;
|
||||||
|
|||||||
@@ -62,9 +62,11 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
|||||||
event->map_request.parent = ev->parent;
|
event->map_request.parent = ev->parent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_UNMAP_NOTIFY:
|
case XCB_UNMAP_NOTIFY: {
|
||||||
event->type = EVENT_TYPE_UNMAP_NOTIFY;
|
xcb_unmap_notify_event_t *ev = (xcb_unmap_notify_event_t *)xcb_event;
|
||||||
break;
|
event->unmap_notify.type = EVENT_TYPE_UNMAP_NOTIFY;
|
||||||
|
event->unmap_notify.window = ev->window;
|
||||||
|
} break;
|
||||||
case XCB_DESTROY_NOTIFY:
|
case XCB_DESTROY_NOTIFY:
|
||||||
event->type = EVENT_TYPE_DESTROY_NOTIFY;
|
event->type = EVENT_TYPE_DESTROY_NOTIFY;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -248,19 +248,19 @@ void map_window(xcb_window_t window) {
|
|||||||
char *get_window_name(xcb_window_t window) {
|
char *get_window_name(xcb_window_t window) {
|
||||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(ewmh, window);
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(ewmh, window);
|
||||||
xcb_ewmh_get_utf8_strings_reply_t reply;
|
xcb_ewmh_get_utf8_strings_reply_t reply;
|
||||||
xcb_ewmh_get_wm_name_reply(ewmh, cookie, &reply, NULL);
|
if (xcb_ewmh_get_wm_name_reply(ewmh, cookie, &reply, NULL)) {
|
||||||
if (reply.strings_len) {
|
|
||||||
char *name = ecalloc(reply.strings_len + 1, sizeof(char));
|
char *name = ecalloc(reply.strings_len + 1, sizeof(char));
|
||||||
strncpy(name, reply.strings, reply.strings_len);
|
strncpy(name, reply.strings, reply.strings_len);
|
||||||
|
xcb_ewmh_get_utf8_strings_reply_wipe(&reply);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = xcb_icccm_get_wm_name(conn, window);
|
cookie = xcb_icccm_get_wm_name(conn, window);
|
||||||
xcb_icccm_get_text_property_reply_t prop;
|
xcb_icccm_get_text_property_reply_t prop;
|
||||||
xcb_icccm_get_wm_name_reply(conn, cookie, &prop, NULL);
|
if (xcb_icccm_get_wm_name_reply(conn, cookie, &prop, NULL)) {
|
||||||
if (prop.name_len) {
|
|
||||||
char *name = ecalloc(prop.name_len + 1, sizeof(char));
|
char *name = ecalloc(prop.name_len + 1, sizeof(char));
|
||||||
strncpy(name, prop.name, prop.name_len);
|
strncpy(name, prop.name, prop.name_len);
|
||||||
|
xcb_icccm_get_text_property_reply_wipe(&prop);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user