封装窗口焦点控制函数
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -1 +1,6 @@
|
|||||||
_XKB_RULES_NAMES
|
_XKB_RULES_NAMES
|
||||||
|
|
||||||
|
WM_PROTOCOLS
|
||||||
|
WM_TAKE_FOCUS
|
||||||
|
|
||||||
|
_NET_ACTIVE_WINDOW
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user