处理窗口销毁事件

This commit is contained in:
2025-08-24 11:35:52 +08:00
parent bac73368e3
commit 0039cd2c43
7 changed files with 80 additions and 32 deletions

View File

@@ -39,11 +39,13 @@ static void key_press(key_press_event_t *event);
static void configure_request(configure_request_event_t *event);
static void map_request(map_request_event_t *event);
static void unmap_notify(unmap_notify_event_t *event);
static void destroy_notify(destroy_notify_event_t *event);
static void motion_notify(motion_notify_event_t *event);
static void enter_notify(enter_notify_event_t *event);
static void focus_in(focus_in_event_t *event);
static void manage_window(xcb_window_t window);
static void unmanage_client(client_t *client);
static void unmanage_client(client_t *client, bool destroyed);
static void update_client_list(void);
static void update_client_name(client_t *client);
static void apply_rules(client_t *client);
static uint32_t get_tags_mask_of_monitor(monitor_t *monitor);
@@ -465,6 +467,7 @@ void xcb_event_handler(generic_event_t *event, void *user_data) {
EVENT(EVENT_TYPE_CONFIGURE_REQUEST, configure_request);
EVENT(EVENT_TYPE_MAP_REQUEST, map_request);
EVENT(EVENT_TYPE_UNMAP_NOTIFY, unmap_notify);
EVENT(EVENT_TYPE_DESTROY_NOTIFY, destroy_notify);
EVENT(EVENT_TYPE_MOTION_NOTIFY, motion_notify);
EVENT(EVENT_TYPE_ENTER_NOTIFY, enter_notify);
EVENT(EVENT_TYPE_FOCUS_IN, focus_in);
@@ -512,10 +515,19 @@ void map_request(map_request_event_t *event) {
void unmap_notify(unmap_notify_event_t *event) {
client_t *c = get_client_of_window(event->window);
if (c) {
unmanage_client(c);
if (event->send_event) {
set_window_state(event->window, wm_state_withdrawn);
} else {
unmanage_client(c, false);
}
}
}
void destroy_notify(destroy_notify_event_t *event) {
client_t *c = get_client_of_window(event->window);
if (c) unmanage_client(c, true);
}
void motion_notify(motion_notify_event_t *event) {
logger("motion: window: 0x%x, root: 0x%x\n", event->window, event->root);
logger("x: %d, y: %d, root_x: %d, root_y: %d\n", event->x, event->y,
@@ -586,7 +598,7 @@ void manage_window(xcb_window_t window) {
attach_client(c);
attach_stack_client(c);
init_window_event_mask(window);
set_window_event_mask(window, false);
change_window_border_color(window, color_set->border_color.argb);
if (c->monitor == current_monitor) {
unfocus(current_monitor->selected_client, false);
@@ -596,14 +608,41 @@ void manage_window(xcb_window_t window) {
focus(NULL);
}
void unmanage_client(client_t *client) {
void unmanage_client(client_t *client, bool destroyed) {
monitor_t *monitor = client->monitor;
detach_client(client);
detach_stack_client(client);
if (!destroyed) {
set_window_event_mask(client->window, true);
configure_window(client->window, client->x, client->y, client->width,
client->height, client->old_border_width);
set_window_state(client->window, wm_state_withdrawn);
flush_xcb_connection();
}
free(client);
focus(NULL);
update_client_list();
arrange(monitor);
flush_xcb_connection();
}
void update_client_list(void) {
uint32_t length = 0;
for (monitor_t *m = monitors; m; m = m->next) {
for (client_t *c = m->clients; c; c = c->next) length++;
}
if (!length) {
set_window_list(NULL, length);
return;
}
xcb_window_t *list = ecalloc(length, sizeof(xcb_window_t));
uint32_t i = 0;
for (monitor_t *m = monitors; m; m = m->next) {
for (client_t *c = m->clients; c; c = c->next) list[i++] = c->window;
}
set_window_list(list, length);
free(list);
}
void update_client_name(client_t *client) {
@@ -842,7 +881,7 @@ void cleanup(void) {
while (m) {
while (c) {
client_t *tc = c->next;
free(c);
unmanage_client(c, false);
c = tc;
}
monitor_t *next_monitor = m->next;