使用 _NET_WM_DESKTOP 保存和恢复 client 所在 tag

This commit is contained in:
2026-01-28 09:50:36 +08:00
parent d1fa848632
commit 99d2e33a46
4 changed files with 40 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ COMPOUND_TEXT
_NET_ACTIVE_WINDOW _NET_ACTIVE_WINDOW
_NET_CLIENT_LIST _NET_CLIENT_LIST
_NET_WM_DESKTOP
_NET_WM_NAME _NET_WM_NAME
_NET_WM_ICON_NAME _NET_WM_ICON_NAME
_NET_SUPPORTING_WM_CHECK _NET_SUPPORTING_WM_CHECK

View File

@@ -77,6 +77,8 @@ task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag) {
static void client_add_to_tag(client_t *client, tag_t *tag) { static void client_add_to_tag(client_t *client, tag_t *tag) {
if (client_get_task_in_tag(client, tag)) return; if (client_get_task_in_tag(client, tag)) return;
xwindow_set_wm_desktop(client->window, tag->index);
task_in_tag_t *task = p_new(task_in_tag_t, 1); task_in_tag_t *task = p_new(task_in_tag_t, 1);
task->client = client; task->client = client;
task->next = tag->task_list; task->next = tag->task_list;
@@ -145,6 +147,20 @@ static inline void client_init_geometry(client_t *c) {
client_change_border_width(c, wm.border_width); client_change_border_width(c, wm.border_width);
} }
static void client_init_tag_by_wm_desktop(client_t *client) {
uint32_t tag_index = 0;
if (!xwindow_get_wm_desktop(client->window, &tag_index)) return;
for (monitor_t *m = wm.monitor_list; m; m = m->next) {
for (tag_t *tag = m->tag_list; tag; tag = tag->next) {
if (tag->index == tag_index) {
client->monitor = m;
client->tags = tag->mask;
return;
}
}
}
}
void client_manage(xcb_window_t window, void client_manage(xcb_window_t window,
xcb_get_geometry_reply_t *geometry_reply) { xcb_get_geometry_reply_t *geometry_reply) {
client_t *c = p_new(client_t, 1); client_t *c = p_new(client_t, 1);
@@ -198,6 +214,7 @@ void client_manage(xcb_window_t window,
} }
client_init_geometry(c); client_init_geometry(c);
client_init_tag_by_wm_desktop(c);
client_tags_apply(c); client_tags_apply(c);
} }

View File

@@ -206,6 +206,25 @@ void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property,
p_delete(&reply); p_delete(&reply);
} }
void xwindow_set_wm_desktop(xcb_window_t window, uint32_t desktop) {
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, window,
_NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &desktop);
}
bool xwindow_get_wm_desktop(xcb_window_t window, uint32_t *desktop) {
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(
wm.xcb_conn, false, window, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 0, 1);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(wm.xcb_conn, cookie, nullptr);
if (!reply) return false;
bool success = reply->type == XCB_ATOM_CARDINAL && reply->format == 32;
if (success) *desktop = *(uint32_t *)xcb_get_property_value(reply);
p_delete(&reply);
return success;
}
xcb_window_t xwindow_get_transient_for(xcb_window_t window) { xcb_window_t xwindow_get_transient_for(xcb_window_t window) {
xcb_connection_t *conn = wm.xcb_conn; xcb_connection_t *conn = wm.xcb_conn;
xcb_window_t t_window = XCB_WINDOW_NONE; xcb_window_t t_window = XCB_WINDOW_NONE;

View File

@@ -20,6 +20,9 @@ bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom);
void xwindow_focus(xcb_window_t window); void xwindow_focus(xcb_window_t window);
void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property, void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property,
char **out); char **out);
void xwindow_set_wm_desktop(xcb_window_t window, uint32_t desktop);
bool xwindow_get_wm_desktop(xcb_window_t window, uint32_t *desktop);
xcb_window_t xwindow_get_transient_for(xcb_window_t window); xcb_window_t xwindow_get_transient_for(xcb_window_t window);
int32_t xwindow_get_state(xcb_window_t window); int32_t xwindow_get_state(xcb_window_t window);
xcb_get_geometry_reply_t *xwindow_get_geometry_reply(xcb_window_t window); xcb_get_geometry_reply_t *xwindow_get_geometry_reply(xcb_window_t window);