封装窗口焦点控制函数
This commit is contained in:
@@ -48,6 +48,7 @@ pkg_check_modules(deps REQUIRED
|
||||
xcb
|
||||
xcb-aux
|
||||
xcb-cursor
|
||||
xcb-icccm
|
||||
xcb-keysyms
|
||||
xcb-randr
|
||||
xcb-xfixes
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
_XKB_RULES_NAMES
|
||||
|
||||
WM_PROTOCOLS
|
||||
WM_TAKE_FOCUS
|
||||
|
||||
_NET_ACTIVE_WINDOW
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "xwindow.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "action.h"
|
||||
#include "atoms-extern.h"
|
||||
#include "utils.h"
|
||||
#include "wm.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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_grab_keys(xcb_window_t window, const keyboard_t *keys,
|
||||
int keys_length);
|
||||
bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom);
|
||||
void xwindow_focus(xcb_window_t window);
|
||||
|
||||
Reference in New Issue
Block a user