如何在X11下隐藏鼠标指针?我想使用内置库来完成这个功能,而不是像SDL(SDL_ShowCursor(0))或glut(glutSetCursor(GLUT_CURSOR_NONE))那样的东西。另外,无论指针位置在哪里,鼠标指针都应该被隐藏,而不仅仅是在它自己的窗口中。
以下是 描述 如何实现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/某处永久禁用鼠标模块。请查看您的发行版手册。
我最终使用了ephemient提到的XDefineCursor。控制应用程序更改了默认根窗口光标,而其他应用程序(在我的控制下)则继承了它。
代码具体细节如下:
// 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的左手光标(因为它是根窗口,我不希望它保持不可见状态)。 我不确定,但我可能也可以使用
要恢复 X 的左手光标(因为它是根窗口,我不希望它保持不可见状态)。我不确定,但我可能还可以使用
XUndefineCursor(display, window);
XDefineCursor
和XUndefineCursor
之后需要调用XSync(display, False)
才能使其正常工作。如果你的光标没有正确地消失/重新出现,你也可以尝试一下这个方法。 - Pythagoras of Samos你可以创建并设置一个不可见的光标主题。这种技巧被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 };
那么,
To hide the mouse pointer cursor,
$ xsetroot -cursor blnk_ptr.xbm blnk_ptr.xbm
To show the mouse pointer cursor again,
$ xsetroot -cursor_name left_ptr
You can use a mouse pointer cursor other than "left_ptr", but this one seems to be widely available across *nix systems.
顺便说一下,我还不知道如何使用xsetroot获取系统当前使用的指针名称。 我猜我会去查找这个问题的答案(像往常一样),但如果有知道怎么做的人给我答案,那就太好了;)
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
,它也无法在虚拟设备(例如无线鼠标和键盘)上工作,并且它会完全禁用鼠标 - 就我所理解的问题是关于仅隐藏指针。 - cprnxinput $1 $(xinput | grep -oP "Mouse.*id=\K[0-9]+")
。 - Ipor Sircer源代码,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);
}
Depends on Xfixes. On Debian/Ubuntu,
apt install libxfixes-dev
Compile it and execute it in the background,
cc xtoggle.c -lX11 -lXfixes -o xtoggle
./xtoggle &
Toggle cursor visibility by sending it a USR1 signal,
pkill -USR1 -x xtoggle
Possibly useful exercise: Use XWarpPointer to move the invisible mouse pointer out of the way when hidden.