调整 client 坐标配置流程

This commit is contained in:
2025-12-14 22:09:51 +08:00
parent ffc39cd2bf
commit 0c029b7bfd
4 changed files with 82 additions and 24 deletions

View File

@@ -115,8 +115,24 @@ void client_manage(xcb_window_t window,
client_t *c = p_new(client_t, 1); client_t *c = p_new(client_t, 1);
c->window = window; c->window = window;
client_attach_list(c); client_move_to(c, geometry_reply->x, geometry_reply->y);
client_attach_stack(c); client_resize(c, geometry_reply->width, geometry_reply->height);
client_change_border_width(c, geometry_reply->border_width);
{
const xcb_params_cw_t params = {
.event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE |
XCB_EVENT_MASK_PROPERTY_CHANGE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,
};
xcb_aux_change_window_attributes(wm.xcb_conn, window, XCB_CW_EVENT_MASK,
&params);
xcb_map_window(wm.xcb_conn, window);
}
client_update_names(c);
xwindow_get_text_property(c->window, WM_WINDOW_ROLE, &c->role);
client_update_wm_hints(c);
{ {
xcb_icccm_get_wm_class_reply_t prop; xcb_icccm_get_wm_class_reply_t prop;
@@ -127,7 +143,6 @@ void client_manage(xcb_window_t window,
c->instance = strdup(prop.instance_name); c->instance = strdup(prop.instance_name);
xcb_icccm_get_wm_class_reply_wipe(&prop); xcb_icccm_get_wm_class_reply_wipe(&prop);
} }
xwindow_get_text_property(c->window, WM_WINDOW_ROLE, &c->role);
} }
{ {
@@ -149,20 +164,12 @@ void client_manage(xcb_window_t window,
client_tags_apply(c); client_tags_apply(c);
} }
monitor_arrange(c->monitor); client_attach_list(c);
{ client_attach_stack(c);
const xcb_params_cw_t params = {
.event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE |
XCB_EVENT_MASK_PROPERTY_CHANGE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
};
xcb_aux_change_window_attributes(wm.xcb_conn, window, XCB_CW_EVENT_MASK,
&params);
xcb_map_window(wm.xcb_conn, window);
}
client_update_names(c); monitor_arrange(c->monitor);
monitor_draw_bar(c->monitor); monitor_draw_bar(c->monitor);
xcb_flush(wm.xcb_conn); xcb_flush(wm.xcb_conn);
} }
@@ -204,6 +211,29 @@ void client_resize(client_t *client, uint16_t width, uint16_t height) {
width, height); width, height);
} }
void client_change_border_width(client_t *client, uint16_t border_width) {
if (client->border_width == border_width) return;
uint16_t mask = XCB_CONFIG_WINDOW_BORDER_WIDTH;
const xcb_params_configure_window_t params = {.border_width = border_width};
xcb_aux_configure_window(wm.xcb_conn, client->window, mask, &params);
client->border_width = border_width;
}
void client_update_wm_hints(client_t *client) {
xcb_get_property_cookie_t cookie =
xcb_icccm_get_wm_hints(wm.xcb_conn, client->window);
xcb_icccm_wm_hints_t hints;
if (xcb_icccm_get_wm_hints_reply(wm.xcb_conn, cookie, &hints, nullptr)) {
if (client == wm.client_focused &&
(hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY)) {
hints.flags &= ~XCB_ICCCM_WM_HINT_X_URGENCY;
xcb_icccm_set_wm_hints(wm.xcb_conn, client->window, &hints);
} else {
client->urgent = hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY;
}
}
}
void client_unmanage(client_t *client) { void client_unmanage(client_t *client) {
monitor_t *m = client->monitor; monitor_t *m = client->monitor;
@@ -221,6 +251,19 @@ void client_unmanage(client_t *client) {
xcb_flush(wm.xcb_conn); xcb_flush(wm.xcb_conn);
} }
void client_apply_task_geometry(client_t *client, task_in_tag_t *task) {
if (!client || !task || client != task->client) return;
if (task->geometry.x != client->geometry.x ||
task->geometry.y != client->geometry.y) {
client_move_to(client, task->geometry.x, task->geometry.y);
}
if (task->geometry.width != client->geometry.width ||
task->geometry.height != client->geometry.height) {
client_resize(client, task->geometry.width, task->geometry.height);
}
}
bool client_is_visible(client_t *client) { bool client_is_visible(client_t *client) {
return client->tags & client->monitor->selected_tag->mask; return client->tags & client->monitor->selected_tag->mask;
} }

View File

@@ -20,6 +20,8 @@ void client_resize(client_t *client, uint16_t width, uint16_t height);
void client_change_border_color(client_t *client, color_t *color); void client_change_border_color(client_t *client, color_t *color);
void client_change_border_width(client_t *client, uint16_t border_width); void client_change_border_width(client_t *client, uint16_t border_width);
void client_update_wm_hints(client_t *client);
void client_set_floating(client_t *client, bool floating); void client_set_floating(client_t *client, bool floating);
void client_set_fullscreen(client_t *client, bool fullscreen); void client_set_fullscreen(client_t *client, bool fullscreen);
void client_set_maximize(client_t *client, bool maximize); void client_set_maximize(client_t *client, bool maximize);
@@ -43,6 +45,7 @@ void client_set_leader_window(client_t *client, xcb_window_t leader_window);
void client_kill(client_t *client); void client_kill(client_t *client);
void client_unmanage(client_t *client); void client_unmanage(client_t *client);
void client_apply_task_geometry(client_t *client, task_in_tag_t *task);
void client_focus(client_t *client); void client_focus(client_t *client);
void client_stack_raise(client_t *client); void client_stack_raise(client_t *client);

View File

@@ -55,7 +55,23 @@ static void button_press(xcb_button_press_event_t *ev) {
static void configure_request(xcb_configure_request_event_t *ev) { static void configure_request(xcb_configure_request_event_t *ev) {
client_t *client = client_get_by_window(ev->window); client_t *client = client_get_by_window(ev->window);
if (!client) { if (client) {
if (ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
client_change_border_width(client, ev->border_width);
} else {
tag_t *tag = client->monitor->selected_tag;
task_in_tag_t *task = client_get_task_in_tag(client, tag);
if (!task || !(client->floating || !tag->layout->arrange)) return;
if (ev->value_mask & XCB_CONFIG_WINDOW_X) task->geometry.x = ev->x;
if (ev->value_mask & XCB_CONFIG_WINDOW_Y) task->geometry.y = ev->y;
if (ev->value_mask & XCB_CONFIG_WINDOW_WIDTH)
task->geometry.width = ev->width;
if (ev->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
task->geometry.height = ev->height;
client_apply_task_geometry(client, task);
}
} else {
uint16_t value_mask = ev->value_mask; uint16_t value_mask = ev->value_mask;
xcb_configure_window_value_list_t value_list = { xcb_configure_window_value_list_t value_list = {
.x = ev->x, .x = ev->x,
@@ -136,6 +152,9 @@ static void property_notify(xcb_property_notify_event_t *ev) {
} else if (ev->atom == _NET_WM_ICON_NAME) { } else if (ev->atom == _NET_WM_ICON_NAME) {
xwindow_get_text_property(ev->window, ev->atom, &client->net_icon_name); xwindow_get_text_property(ev->window, ev->atom, &client->net_icon_name);
monitor_draw_bar(client->monitor); monitor_draw_bar(client->monitor);
} else if (ev->atom == XCB_ATOM_WM_HINTS) {
client_update_wm_hints(client);
monitor_draw_bar(client->monitor);
} }
} }

View File

@@ -253,14 +253,7 @@ void monitor_arrange(monitor_t *monitor) {
for (client_t *c = wm.client_list; c; c = c->next) { for (client_t *c = wm.client_list; c; c = c->next) {
task_in_tag_t *task = client_get_task_in_tag(c, tag); task_in_tag_t *task = client_get_task_in_tag(c, tag);
if (task) { if (task) {
if (task->geometry.x != c->geometry.x || client_apply_task_geometry(c, task);
task->geometry.y != c->geometry.y) {
client_move_to(c, task->geometry.x, task->geometry.y);
}
if (task->geometry.width != c->geometry.width ||
task->geometry.height != c->geometry.height) {
client_resize(c, task->geometry.width, task->geometry.height);
}
} else { } else {
int16_t x = -c->geometry.width; int16_t x = -c->geometry.width;
int16_t y = -c->geometry.height; int16_t y = -c->geometry.height;