【发布时间】:2009-03-19 00:25:25
【问题描述】:
X11下如何隐藏鼠标指针?我想使用内置库来执行此操作,而不是使用 SDL (SDL_ShowCursor(0)) 或 glut (glutSetCursor(GLUT_CURSOR_NONE)) 之类的东西。此外,无论指针位置如何,鼠标指针都应该被隐藏,而不仅仅是在它自己的窗口中。
【问题讨论】:
X11下如何隐藏鼠标指针?我想使用内置库来执行此操作,而不是使用 SDL (SDL_ShowCursor(0)) 或 glut (glutSetCursor(GLUT_CURSOR_NONE)) 之类的东西。此外,无论指针位置如何,鼠标指针都应该被隐藏,而不仅仅是在它自己的窗口中。
【问题讨论】:
这是description unclutter 实用程序如何做到的。
Unclutter 是一个在 X11 后台永久运行的程序 会议。它每隔几个检查一次 X11 指针(光标)的位置 秒,当它发现它没有移动(并且没有按钮 被鼠标按下,且光标不在根窗口中) 它创建一个小的子窗口作为光标所在窗口的子窗口。 新窗口安装大小为 1x1 的光标,但掩码为 全为 0,即一个不可见的光标。这使您可以查看所有文本 例如,一个 xterm 或 xedit。人为因素人群会同意 应该让事情不那么分散注意力。
创建后,程序等待指针离开窗口 然后摧毁它,恢复原状。 按钮事件透明地传递到父窗口。 它们通常会导致光标重新出现,因为主动抓取 将在按钮按下时由程序制作,因此指针 显然会离开窗口,即使它的 x y 位置没有改变。
【讨论】:
Xorg 1.7 及更高版本有一个-no-cursor 选项。 https://www.x.org/wiki/AdvancedTopicsFAQ/
xinit -- -nocursor 或 startx -- -nocursor 可以工作。
【讨论】:
我宁愿使用更简单的方法:
unclutter -idle 0
您几乎看不到光标,但它仍然可用。禁用鼠标:
rmmod psmouse
或者在 /etc/ 中的某处永久禁用鼠标模块。请参阅您的分发手册。
【讨论】:
Unclutter 对我不起作用,因为它不能很好地与硬件加速表面(例如在解码视频时由英特尔的 VA-API 产生的表面)配合使用。于是我找了一个程序,以一种不那么迂回的方式隐藏了鼠标指针,hhp,并用最小依赖的C语言重写了它,结果是hhpc。我这样做是为了避免需要 haskell 来编译它,因为 hhp 有时会停止隐藏鼠标指针。
hhpc,只依赖glibc和xlib,所以很容易构建,只需要make release。您可以从my repository 获取代码和说明。它非常节省内存和 CPU(因为它几乎什么都不做)。
【讨论】:
我最终使用了 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);
【讨论】:
XDefineCursor 和XUndefineCursor 之后调用XSync(display, False) 才能使其正常工作。如果您的光标没有正确消失/重新出现,您可能也想尝试一下。
您可以创建和设置不可见的光标主题。 maemo 使用了这个技巧,因为在触摸屏设备上放置光标是毫无意义的。
遗憾的是,在运行时更改全局光标主题的能力在 X11 应用程序和工具包中并不统一。可以更改服务器资源Xcursor.theme,没人会注意到(一般只在启动时查询);你可以通知xsettings 这似乎只影响 Gtk+ 程序; KDE 通过根窗口的属性使用某种通信方式;等等
至少为您自己的应用程序更改光标就像XDefineCursor 一样简单,如果您在根窗口上执行此操作,一些 应用程序可能 随之而来。
【讨论】:
【讨论】:
要隐藏鼠标光标,创建一个额外的小文件(我叫我的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
}
【讨论】:
xdotool,为什么?由于grep Mouse,它也不适用于虚拟设备(例如无线鼠标和键盘),并且它会完全禁用鼠标 - 据我了解,问题只是关于隐藏指针。
xinput $1 $(xinput | grep -oP "Mouse.*id=\K[0-9]+")
源码,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
【讨论】: