实现 _NET_ACTIVE_WINDOW 消息协议
This commit is contained in:
@@ -10,6 +10,7 @@ UTF8_STRING
|
||||
COMPOUND_TEXT
|
||||
|
||||
_NET_ACTIVE_WINDOW
|
||||
_NET_CLIENT_LIST
|
||||
_NET_WM_NAME
|
||||
_NET_WM_ICON_NAME
|
||||
_NET_SUPPORTING_WM_CHECK
|
||||
|
||||
18
src/client.c
18
src/client.c
@@ -204,6 +204,9 @@ void client_manage(xcb_window_t window,
|
||||
client_attach_list(c);
|
||||
client_attach_stack(c);
|
||||
|
||||
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_APPEND, wm.screen->root,
|
||||
_NET_CLIENT_LIST, XCB_ATOM_WINDOW, 32, 1, &window);
|
||||
|
||||
monitor_arrange(c->monitor);
|
||||
monitor_draw_bar(c->monitor);
|
||||
|
||||
@@ -284,6 +287,19 @@ void client_update_wm_hints(client_t *client) {
|
||||
}
|
||||
}
|
||||
|
||||
static void update_client_list(void) {
|
||||
xcb_connection_t *conn = wm.xcb_conn;
|
||||
xcb_window_t root = wm.screen->root;
|
||||
xcb_atom_t atom = _NET_CLIENT_LIST;
|
||||
uint8_t mode = XCB_PROP_MODE_PREPEND;
|
||||
xcb_atom_t type = XCB_ATOM_WINDOW;
|
||||
|
||||
xcb_delete_property(conn, root, atom);
|
||||
for (client_t *c = wm.client_list; c; c = c->next) {
|
||||
xcb_change_property(conn, mode, root, atom, type, 32, 1, &c->window);
|
||||
}
|
||||
}
|
||||
|
||||
void client_unmanage(client_t *client) {
|
||||
monitor_t *m = client->monitor;
|
||||
|
||||
@@ -296,6 +312,8 @@ void client_unmanage(client_t *client) {
|
||||
|
||||
client_wipe(client);
|
||||
|
||||
update_client_list();
|
||||
|
||||
wm_restack_clients();
|
||||
monitor_deal_focus(m);
|
||||
monitor_arrange(m);
|
||||
|
||||
17
src/event.c
17
src/event.c
@@ -135,6 +135,22 @@ static void map_request(xcb_map_request_event_t *ev) {
|
||||
p_delete(&wa_reply);
|
||||
}
|
||||
|
||||
static void client_message(xcb_client_message_event_t *ev) {
|
||||
client_t *c = client_get_by_window(ev->window);
|
||||
if (c == nullptr) return;
|
||||
|
||||
if (ev->type == _NET_ACTIVE_WINDOW) {
|
||||
for (tag_t *t = c->monitor->tag_list; t; t = t->next) {
|
||||
if ((t->mask & c->tags) == 0) continue;
|
||||
|
||||
wm.current_monitor = c->monitor;
|
||||
monitor_select_tag(c->monitor, t->mask);
|
||||
client_focus(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void property_notify(xcb_property_notify_event_t *ev) {
|
||||
client_t *client = client_get_by_window(ev->window);
|
||||
if (client == nullptr) return;
|
||||
@@ -185,6 +201,7 @@ static void handle_xcb_event(xcb_generic_event_t *event) {
|
||||
EVENT(XCB_KEY_RELEASE, key_press);
|
||||
EVENT(XCB_CONFIGURE_REQUEST, configure_request);
|
||||
EVENT(XCB_MAP_REQUEST, map_request);
|
||||
EVENT(XCB_CLIENT_MESSAGE, client_message);
|
||||
EVENT(XCB_PROPERTY_NOTIFY, property_notify);
|
||||
EVENT(XCB_UNMAP_NOTIFY, unmap_notify);
|
||||
EVENT(XCB_DESTROY_NOTIFY, destroy_notify);
|
||||
|
||||
Reference in New Issue
Block a user