封装窗口焦点控制函数

This commit is contained in:
2025-11-25 06:10:42 +08:00
parent 2ccf2a3f53
commit b99b8368aa
4 changed files with 52 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ pkg_check_modules(deps REQUIRED
xcb xcb
xcb-aux xcb-aux
xcb-cursor xcb-cursor
xcb-icccm
xcb-keysyms xcb-keysyms
xcb-randr xcb-randr
xcb-xfixes xcb-xfixes

View File

@@ -1 +1,6 @@
_XKB_RULES_NAMES _XKB_RULES_NAMES
WM_PROTOCOLS
WM_TAKE_FOCUS
_NET_ACTIVE_WINDOW

View File

@@ -1,11 +1,14 @@
#include "xwindow.h" #include "xwindow.h"
#include <stdint.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_aux.h> #include <xcb/xcb_aux.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h> #include <xcb/xcb_keysyms.h>
#include <xcb/xproto.h> #include <xcb/xproto.h>
#include "action.h" #include "action.h"
#include "atoms-extern.h"
#include "utils.h" #include "utils.h"
#include "wm.h" #include "wm.h"
#include "xcursor.h" #include "xcursor.h"
@@ -127,3 +130,44 @@ void xwindow_grab_keys(xcb_window_t window, const keyboard_t *keys,
} }
} }
} }
bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom) {
bool exist = false;
xcb_get_property_cookie_t cookie =
xcb_icccm_get_wm_protocols(wm.xcb_conn, window, atom);
xcb_icccm_get_wm_protocols_reply_t reply;
if (xcb_icccm_get_wm_protocols_reply(wm.xcb_conn, cookie, &reply, nullptr)) {
for (uint32_t i = 0; !exist && i < reply.atoms_len; i++) {
exist = reply.atoms[i] == atom;
}
xcb_icccm_get_wm_protocols_reply_wipe(&reply);
}
if (exist) {
xcb_client_message_event_t ev;
p_clear(&ev, 1);
ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 32;
ev.window = window;
ev.type = WM_PROTOCOLS;
ev.data.data32[0] = atom;
ev.data.data32[1] = XCB_CURRENT_TIME;
}
return exist;
}
void xwindow_focus(xcb_window_t window) {
if (window == XCB_WINDOW_NONE || window == wm.screen->root) {
xcb_set_input_focus(wm.xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT,
wm.screen->root, XCB_CURRENT_TIME);
xcb_delete_property(wm.xcb_conn, wm.screen->root, _NET_ACTIVE_WINDOW);
} else {
xcb_set_input_focus(wm.xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, window,
XCB_CURRENT_TIME);
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, wm.screen->root,
_NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 32, 1, &window);
xwindow_send_event(window, WM_TAKE_FOCUS);
}
}

View File

@@ -15,3 +15,5 @@ visual_t *xwindow_get_xcb_visual(bool prefer_alpha);
void xwindow_change_cursor(xcb_window_t window, cursor_t cursor); void xwindow_change_cursor(xcb_window_t window, cursor_t cursor);
void xwindow_grab_keys(xcb_window_t window, const keyboard_t *keys, void xwindow_grab_keys(xcb_window_t window, const keyboard_t *keys,
int keys_length); int keys_length);
bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom);
void xwindow_focus(xcb_window_t window);