-
Notifications
You must be signed in to change notification settings - Fork 0
/
libxcb-hack-focal.diff
77 lines (75 loc) · 2.09 KB
/
libxcb-hack-focal.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
--- a/src/xcb_out.c
+++ b/src/xcb_out.c
@@ -218,6 +218,52 @@
close_fds(fds, num_fds);
}
+static inline xcb_window_t find_top_window(xcb_connection_t *conn, xcb_window_t wnd)
+{
+ xcb_query_tree_reply_t* treeReply = NULL;
+
+ if (!wnd)
+ return 0;
+
+ do {
+ treeReply = xcb_query_tree_reply(conn, xcb_query_tree(conn, wnd), NULL);
+
+ if (!treeReply || treeReply->root == wnd) {
+ wnd = 0;
+ break;
+ }
+ if (treeReply->root == treeReply->parent) {
+ break;
+ }
+
+ wnd = treeReply->parent;
+ free(treeReply);
+ } while(1);
+
+ free(treeReply);
+ return wnd;
+}
+
+static inline int check_grab(xcb_connection_t *conn, struct iovec *vector)
+{
+ xcb_get_input_focus_reply_t* focusReply = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
+
+ // TRICK: grab_window at offset 0x04 for all grab ops
+ xcb_window_t req_wnd = *(xcb_window_t *)((uint8_t *)vector[0].iov_base + 4);
+ xcb_window_t focus_wnd = focusReply->focus;
+
+ free(focusReply);
+
+ // fprintf(stderr, "%s-raw\treq %X, focus %X\n", __func__, req_wnd, focus_wnd);
+
+ req_wnd = find_top_window(conn, req_wnd);
+ focus_wnd = find_top_window(conn, focus_wnd);
+
+ // fprintf(stderr, "%s-top\treq %X, focus %X\n", __func__, req_wnd, focus_wnd);
+
+ return (focus_wnd && focus_wnd == req_wnd);
+}
+
uint64_t xcb_send_request_with_fds64(xcb_connection_t *c, int flags, struct iovec *vector,
const xcb_protocol_request_t *req, unsigned int num_fds, int *fds)
{
@@ -234,6 +280,21 @@
assert(c != 0);
assert(vector != 0);
assert(req->count > 0);
+
+ if (req->ext == NULL) {
+ switch (req->opcode) {
+ case XCB_GRAB_POINTER:
+ case XCB_GRAB_BUTTON:
+ case XCB_GRAB_KEYBOARD:
+ case XCB_GRAB_KEY:
+ if (check_grab(c, vector))
+ break;
+ // else fall through;
+ case XCB_SET_INPUT_FOCUS:
+ close_fds(fds, num_fds);
+ return 0;
+ }
+ }
if(!(flags & XCB_REQUEST_RAW))
{