How to Hide the Mouse Pointer Under Linux/X11

How do you hide the mouse pointer under Linux/X11?

You can create and set an invisible cursor theme. This trick is used by maemo, because it's rather pointless to have a cursor on a touchscreen device.

Sadly, the ability to change the global cursor theme at runtime is not uniform across X11 applications and toolkits. You can change the server resource Xcursor.theme, and nobody will notice (generally it's only queried at startup); you can inform xsettings which only seems to affect Gtk+ programs; KDE uses some sort of communication through properties on the root window; etc.

At least changing the cursor for your own application is as easy as XDefineCursor, and if you do that on the root window, some applications might follow along.

How to hide the mouse cursor in X11/Xorg

Yes I can confirm that is code definitely works

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xfixes.h>
#include <string>
#include <iostream>

Window window;
void show(Display *dispy);

int main()
{
Display *display;
XEvent e;
std::string msg = "Hello, World!";
int screen;

display = XOpenDisplay(nullptr);
if (display == nullptr)
{
std::cerr << "Cannot open display\n";
throw;
}

screen = XDefaultScreen(display);
window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 500, 500, 1,
BlackPixel(display, screen), WhitePixel(display, screen));
XStoreName(display, window, "Silly Window");
XSelectInput(display, window, ExposureMask | KeyPressMask );
XMapWindow(display, window);

while (true)
{
XNextEvent(display, &e);
if (e.type == Expose)
{
std::cout << "Window Exposed!\n";
XExposeEvent ev = e.xexpose;
if (ev.window != window) continue;
XFillRectangle(display, window, DefaultGC(display, screen), 50, 50, 400, 50);
XDrawString(display, window, DefaultGC(display, screen), 220, 150, msg.c_str(), msg.length());
XDrawString(display, window, DefaultGC(display, screen), 220, 220, msg.c_str(), msg.length());
XDrawString(display, window, DefaultGC(display, screen), 220, 300, msg.c_str(), msg.length());
XFillRectangle(display, window, DefaultGC(display, screen), 50, 400, 400, 50);
}
else if (e.type == KeyPress)
{
char buf[128] = {0};
KeySym keysym;
XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL);
if (keysym == XK_Escape)
{
break;
}
else if (keysym == XK_space)
{
show(display);
XAllowEvents(display, SyncBoth, CurrentTime);
}
}

}

XDestroyWindow(display, window);
XCloseDisplay(display);
return 0;
}

bool toggle = true;
void show(Display *dpy)
{
if (toggle)
{
std::cout << "toggle On->Off\n";
XFixesHideCursor(dpy, window);
XFlush(dpy);
}
else
{
std::cout << "toggle Off->On\n";
XFixesShowCursor(dpy, window);
XFlush(dpy);
}
toggle = !toggle;
}

X11 restrict mouse to visible area

Okay, I have found the relevant code.

This behavior is hardcoded in Xorg X server, in RandR extension, including visible area continuity check.

Definitely nothing configurable. Well, unless you agree with creator of dwm on what the word "configuration" means :)

I do agree. Right now relevant code locations are randr/rrpointer.c and
randr/rrcrtc.c:332,1685.

Would be nice though if someone created a proper X srver extension for that.

how to hide cursor in XCB?


Actually, it gives me this error:

{
"error_code": 1,
"major_code": 138,
"minor_code": 29,
"sequence:": 2,
"full_sequence": 2
}

Error 1 is BadRequest / XCB_REQUEST. You get a BadRequest error, because you did not initialise the XFIXES extension (= informed the X11 server about your supported version).

Relevant code in the server that checks if the request is valid for the version that the client provided:
https://codesearch.debian.net/show?file=xorg-server_2%3A1.20.4-1%2Fxfixes%2Fxfixes.c&line=150#L150

From the protocol specification (https://codesearch.debian.net/show?file=xorg-server_2%3A1.20.4-1%2Fxfixes%2Fxfixes.c&line=150#L150):

4. Extension initialization

The client must negotiate the version of the extension before executing
extension requests. Behavior of the server is undefined otherwise.

QueryVersion
[...]

Thus, to answer your question: You need to do xcb_xfixes_query_version(c, 4, 0) before you can do HideCursor requests.

To answer your first follow-up question: Version 4.0 is the version that introduced HideCursor. This can be seen in the protocol specification, because HideCursor is documented under "XFIXES VERSION 4 OR BETTER".

To answer your second follow-up question: XFixesHideCursor automatically queries the version for you: https://codesearch.debian.net/show?file=libxfixes_1%3A5.0.3-1%2Fsrc%2FCursor.c&line=255#L250

This code ends up calling XFixesHideCursor -> XFixesFindDisplay -> XFixesExtAddDisplay and this function queries the version: https://codesearch.debian.net/show?file=libxfixes_1%3A5.0.3-1%2Fsrc%2FXfixes.c&line=79#L79

How to set the mouse position under X11 (linux desktop)?

Sounds like you're using X, so what you probably want is XWarpPointer. To give an absolute position on the whole screen, use the Root Window as dest window.

(You can get a quick and dirty list of X functions using ls /usr/share/man/man3/ | grep '^X')

I want to hide the cursor movements everywhere

I found that post before, but apparently I didn't try the code. So after trying it, it worked out fine.



Related Topics



Leave a reply



Submit