X11下如何隐藏鼠标指针?我想使用内置库来执行此操作,而不是使用 SDL (SDL_ShowCursor(0)) 或 glut (glutSetCursor(GLUT_CURSOR_NONE)) 之类的东西。此外,无论指针位置如何,鼠标指针都应该隐藏,而不仅仅是在它自己的窗口中。
11 回答
这是实用程序如何执行此操作的描述。unclutter
Unclutter 是一个在 X11 会话的后台永久运行的程序。它每隔几秒钟检查一次 X11 指针(光标)的位置,当它发现它没有移动时(并且没有在鼠标上按下任何按钮,并且光标不在根窗口中),它会创建一个小的子窗口光标所在窗口的子窗口。新窗口安装大小为 1x1 但掩码为全 0 的光标,即不可见光标。例如,这允许您查看 xterm 或 xedit 中的所有文本。人为因素人群会同意它应该使事情不那么分散注意力。
一旦创建,程序等待指针离开窗口然后销毁它,恢复原来的情况。按钮事件透明地传递到父窗口。它们通常会导致光标重新出现,因为当按钮按下时程序会进行主动抓取,因此指针显然会离开窗口,即使它的 xy 位置没有改变。
Xorg 1.7 及更高版本有一个-no-cursor
选项。https://www.x.org/wiki/AdvancedTopicsFAQ/
xinit -- -nocursor
或者startx -- -nocursor
可以工作。
我宁愿使用更简单的方法:
unclutter -idle 0
您几乎看不到光标,但它仍然可用。要禁用鼠标:
rmmod psmouse
或者在 /etc/ 中的某处永久禁用鼠标模块。请参阅您的分发手册。
我最终使用了 XDefineCursor,就像提到的 ehemient 一样。控制应用程序更改了默认的根窗口光标,其他应用程序(在我的控制下)继承了它。
代码细节如下所示:
// Hide the cursor
if (NULL==(display=XOpenDisplay(NULL)))
{
printf("Unable to open NULL display\n");
exit(1);
}
window = DefaultRootWindow(display);
Cursor invisibleCursor;
Pixmap bitmapNoData;
XColor black;
static char noData[] = { 0,0,0,0,0,0,0,0 };
black.red = black.green = black.blue = 0;
bitmapNoData = XCreateBitmapFromData(display, window, noData, 8, 8);
invisibleCursor = XCreatePixmapCursor(display, bitmapNoData, bitmapNoData,
&black, &black, 0, 0);
XDefineCursor(display,window, invisibleCursor);
XFreeCursor(display, invisibleCursor);
XFreePixmap(display, bitmapNoData);
为了隐藏光标然后在我完成之后
// Restore the X left facing cursor
Cursor cursor;
cursor=XCreateFontCursor(display,XC_left_ptr);
XDefineCursor(display, window, cursor);
XFreeCursor(display, cursor);
恢复 X 的左手光标(因为它是根窗口,我不希望它保持不可见。我不确定,但我也可以使用
XUndefineCursor(display, window);
您可以创建和设置不可见的光标主题。maemo使用了这个技巧,因为在触摸屏设备上放置光标是毫无意义的。
遗憾的是,在运行时更改全局光标主题的能力在 X11 应用程序和工具包中并不统一。可以更改服务器资源Xcursor.theme
,没有人会注意到(一般只在启动时查询);您可以通知似乎只影响 Gtk+ 程序的xsettings ;KDE 通过根窗口的属性使用某种通信方式;等等
至少为您自己的应用程序更改光标就像XDefineCursor一样简单,如果您在根窗口上这样做,一些应用程序可能会随之而来。
要隐藏鼠标光标,请创建一个额外的小文件(我称为 mine blnk_ptr.xbm
):
#define blnk_ptr_width 1
#define blnk_ptr_height 1
#define blnk_ptr_x_hot 0
#define blnk_ptr_y_hot 0
static unsigned char blnk_ptr_bits[] = {
0x00 };
然后,
要隐藏鼠标指针光标,
$ xsetroot -cursor blnk_ptr.xbm blnk_ptr.xbm
要再次显示鼠标指针光标,
$ xsetroot -cursor_name left_ptr
您可以使用“left_ptr”以外的鼠标指针光标,但这似乎在 *nix 系统中广泛使用。
顺便说一句,我还不知道如何使用 xsetroot 获取系统当前使用的指针的名称。我想我也会[像往常一样]挖掘那个,但我很高兴有人知道如何给我答案(这很好;))
这是我的解决方案。它将光标放在你看不到的地方(在我的例子中,在左下角)——然后,它会禁用鼠标,所以你不能移动它。
注意您可以从 中解析数据xrandr
,或在登录时将该数据放入环境中,然后使用它;这样,您就不必对其进行硬编码。但是,至于我,我从不改变我的屏幕分辨率,所以 768 就可以了 :)
setmouse () {
DISPLAY=":0" xinput $1 `DISPLAY=":0" xinput | grep Mouse |
tr -d " " | tr "\t" " " |
cut -d" " -f2 | cut -d"=" -f2`
}
offmouse () {
DISPLAY=":0" xdotool mousemove 0 768 # use xrandr to find out
setmouse disable
}
onmouse () {
setmouse enable
}
源代码,xtoggle.c
:
#include <signal.h>
#include <X11/extensions/Xfixes.h>
Display *display;
volatile sig_atomic_t breakout = 0;
void toggle_cursor(int x) { breakout = x; }
int main(void) {
int hidden = 0;
struct sigaction act;
sigset_t mask;
if (!(display = XOpenDisplay(NULL))) { return(1); }
act.sa_handler = toggle_cursor;
sigaction(SIGUSR1, &act, NULL);
sigemptyset(&mask);
while (1) {
if (hidden) { XFixesShowCursor(display, DefaultRootWindow(display)); }
else { XFixesHideCursor(display, DefaultRootWindow(display)); }
XFlush(display);
hidden = !hidden;
breakout = 0;
while (!breakout) { sigsuspend(&mask); }
}
return(0);
}
取决于Xfixes。在 Debian/Ubuntu 上,
apt install libxfixes-dev
编译它并在后台执行它,
cc xtoggle.c -lX11 -lXfixes -o xtoggle ./xtoggle &
通过向其发送 USR1 信号来切换光标可见性,
pkill -USR1 -x xtoggle
可能有用的练习:使用 XWarpPointer 在隐藏时将不可见的鼠标指针移开。
有一个名为 Fixes 的 X11 扩展,它有一个可以用来隐藏光标的功能。这个函数的优点是它会向隐藏精灵的 X 服务器发送消息。没有技巧(即像素图中的不可见光标),据我所知,它适用于整个屏幕。
#include <X11/extensions/Xfixes.h>
...
XFixesHideCursor(dpy, window);
XFlush(dpy); // not required unless you want an immediate effect