Linux-Mint
StructureNotifyMask 會干擾 linux Mint 上的其他視窗
我正在嘗試根據此答案中的程式碼擷取所有鍵盤輸入。實際的密鑰擷取工作正常。但是,在 Linux Mint Cinnamon 上執行程式碼會導致其他問題:
- 我無法使用滑鼠拖動或調整任何視窗的大小
- 在 xed 和 nemo(文件、視圖等)中點擊菜單欄中的選項不會彈出子菜單選項
- 點擊開始菜單會顯示應用程序列表,但焦點由其後面的視窗保留,因此我無法懸停、滾動或點擊應用程序列表中的項目。
程式碼的簡化但功能版本如下。我已將原因縮小
StructureNotifyMask
到XSelectInput
. 如果沒有該事件遮罩,則不存在上述任何問題。但這也意味著當視窗被映射時程序不會得到通知,因此擷取不起作用。在沒有上述任何問題的情況下,如何讓擷取工作?
XSelectInput
在程序被通知只有按鍵按下和釋放事件遮罩的映射後,我嘗試過包括一秒鐘。但是,這似乎並不能解決問題。#include <X11/Xlib.h> #include <X11/keysym.h> #include <stdio.h> 主函式() { 顯示*顯示; 視窗視窗,根視窗; XEvent 事件; KeySym 轉義; 顯示 = XOpenDisplay(NULL); rootwindow = DefaultRootWindow(display); 視窗 = XCreateWindow(顯示,根視窗, -99, -99, 1, 1, /* x, y, 寬度, 高度 */ 0, 0, InputOnly, /* 邊框、深度、類 */ CopyFromParent, /* 視覺 */ 0,空);/* 值遮罩和屬性 */ XSelectInput(display, window, StructureNotifyMask | KeyPressMask | KeyReleaseMask); XMapWindow(顯示, 視窗); 做 { XNextEvent(顯示, &event); } while (event.type != MapNotify); XGrabKeyboard(display, window, False, GrabModeAsync, GrabModeAsync, CurrentTime); 轉義 = XKeysymToKeycode(顯示,XK_Escape); printf("\n按 ESC 退出。\n\n"); fflush(標準輸出); 而(1){ XNextEvent(顯示, &event); if (event.type == KeyPress) { printf("KeyPress: keycode %u state %u\n", event.xkey.keycode, event.xkey.state); fflush(標準輸出); } 別的 if (event.type == KeyRelease) { printf("KeyRelease: keycode %u state %u\n", event.xkey.keycode, event.xkey.state); fflush(標準輸出); if (event.xkey.keycode == 轉義) 休息; } 別的 { printf("事件類型 %d\n", event.type); fflush(標準輸出); } } XUngrabKeyboard(display, CurrentTime); XDestroyWindow(顯示,視窗); XCloseDisplay(顯示); 返回0; }
你不能做一個永久的
XGrabKeyboard
。只要正在進行某種互動,此抓取僅用於臨時使用。如果您繼續握住抓取,則所有其他需要自己抓取的功能(例如您提到的 WM 操作)都將不起作用。