处理焦点相关事件
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "app.h"
|
||||
#include "utils.h"
|
||||
#include "window.h"
|
||||
#include "xcb-private.h"
|
||||
|
||||
xcb_connection_t *conn = NULL;
|
||||
@@ -170,58 +169,13 @@ void set_wallpaper(uint32_t *wallpaper_data) {
|
||||
xcb_flush(conn);
|
||||
}
|
||||
|
||||
xcb_ewmh_connection_t *ewmh = NULL;
|
||||
static bool ewmh_init_failed = false;
|
||||
static xcb_window_t wm_check_window = XCB_NONE;
|
||||
static void init_ewmh_extension(void) {
|
||||
if (ewmh || ewmh_init_failed) return;
|
||||
|
||||
ewmh = ecalloc(1, sizeof(xcb_ewmh_connection_t));
|
||||
xcb_intern_atom_cookie_t *cookie = xcb_ewmh_init_atoms(conn, ewmh);
|
||||
if (!xcb_ewmh_init_atoms_replies(ewmh, cookie, NULL)) {
|
||||
free(ewmh);
|
||||
ewmh = NULL;
|
||||
ewmh_init_failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
wm_check_window = xcb_generate_id(conn);
|
||||
xcb_create_window(conn, XCB_COPY_FROM_PARENT, wm_check_window, screen->root,
|
||||
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
|
||||
screen->root_visual, XCB_NONE, NULL);
|
||||
const char *class = APP_NAME "_wm_check";
|
||||
set_window_class_instance(wm_check_window, class, class);
|
||||
xcb_ewmh_set_wm_name(ewmh, wm_check_window, strlen(APP_NAME), APP_NAME);
|
||||
xcb_ewmh_set_supporting_wm_check(ewmh, screen->root, wm_check_window);
|
||||
xcb_ewmh_set_supporting_wm_check(ewmh, wm_check_window, wm_check_window);
|
||||
|
||||
uint8_t mode = XCB_PROP_MODE_REPLACE;
|
||||
xcb_atom_t atom = XCB_ATOM_ATOM;
|
||||
const xcb_atom_t state[] = {ewmh->_NET_WM_STATE_STICKY};
|
||||
const xcb_atom_t supported[] = {
|
||||
ewmh->_NET_ACTIVE_WINDOW,
|
||||
ewmh->_NET_SUPPORTED,
|
||||
ewmh->_NET_WM_NAME,
|
||||
ewmh->_NET_WM_STATE,
|
||||
ewmh->_NET_SUPPORTING_WM_CHECK,
|
||||
ewmh->_NET_WM_STATE_FULLSCREEN,
|
||||
ewmh->_NET_WM_WINDOW_TYPE,
|
||||
ewmh->_NET_WM_WINDOW_TYPE_DIALOG,
|
||||
ewmh->_NET_CLIENT_LIST,
|
||||
};
|
||||
xcb_change_property(conn, mode, wm_check_window, ewmh->_NET_WM_STATE, atom,
|
||||
32, LENGTH(state), state);
|
||||
xcb_change_property(conn, mode, screen->root, ewmh->_NET_SUPPORTED, atom, 32,
|
||||
LENGTH(supported), supported);
|
||||
xcb_delete_property(conn, screen->root, ewmh->_NET_CLIENT_LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描窗口列表
|
||||
* @returns 若无窗口,返回 NULL,否则返回窗口列表
|
||||
* @note: 返回的窗口列表数据使用完后使用 free_window_list 释放
|
||||
*/
|
||||
window_list_t *scan_window_list(void) {
|
||||
init_icccm_extension();
|
||||
init_ewmh_extension();
|
||||
|
||||
xcb_query_tree_cookie_t cookie = xcb_query_tree(conn, screen->root);
|
||||
@@ -278,21 +232,7 @@ void free_window_list(window_list_t *window_list) {
|
||||
|
||||
void clean_xcb(void) {
|
||||
clean_xcb_cursor();
|
||||
|
||||
if (wm_check_window != XCB_NONE) {
|
||||
xcb_destroy_window(conn, wm_check_window);
|
||||
wm_check_window = XCB_NONE;
|
||||
}
|
||||
|
||||
if (ewmh) {
|
||||
if (!ewmh_init_failed) {
|
||||
xcb_ewmh_connection_wipe(ewmh);
|
||||
}
|
||||
free(ewmh);
|
||||
ewmh_init_failed = false;
|
||||
ewmh = NULL;
|
||||
}
|
||||
|
||||
clean_ewmh_extension();
|
||||
xcb_disconnect(conn);
|
||||
conn = NULL;
|
||||
screen = NULL;
|
||||
@@ -322,3 +262,18 @@ void grab_keybindings(const keybinding_t *keys, const size_t length) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool get_pointer_position(int32_t *x, int32_t *y) {
|
||||
xcb_query_pointer_cookie_t cookie = xcb_query_pointer(conn, screen->root);
|
||||
xcb_query_pointer_reply_t *reply =
|
||||
xcb_query_pointer_reply(conn, cookie, NULL);
|
||||
|
||||
if (reply) {
|
||||
*x = reply->root_x;
|
||||
*y = reply->root_y;
|
||||
free(reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user