首页 文章

如何在X11 / Xorg中隐藏鼠标光标

提问于
浏览
1

为什么以下X11 / Xorg代码不能在Ubuntu 18.04下隐藏鼠标光标?如果不是这样做的话是什么?是否有一些缺少依赖/ library / .dev包?

我的直觉说这可能是Ubuntu(或Debian)X11 / Xorg包中的一个错误或者其他一些错误 . 这就是HaXe / Kha如何隐藏鼠标以便跨平台兼容 .

#include <iostream>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

#include <string>
#include <iostream>

Window window;
void show();

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, 220, 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;
            int len = XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL);
            if (keysym == XK_Escape)
            {
                break;
            }
            else if (keysym == XK_space)
            {
                show();
                XAllowEvents(display, SyncBoth, CurrentTime);
            }
        }

    }

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

bool toggle = false;
void show()
{
    Display* dpy = XOpenDisplay(0);
    if (toggle)
    {
        std::cout << "toggle On\n";
        XUndefineCursor(dpy, window);
    }
    else
    {
        std::cout << "toggle Off\n";
        XColor col;
        char data[1] = {0X00};
        Pixmap blank = XCreateBitmapFromData(dpy, window, data, 1, 1);
        Cursor cursor = XCreatePixmapCursor(dpy, blank, blank, &col, &col, 0, 0);
        XDefineCursor(dpy, window, cursor);
        // XSetWindowAttributes wa;
        // XChangeWindowAttributes(dpy, window, CWCursor, &wa);
        // wa.cursor = cursor;
        XFreePixmap(dpy, blank);
    }
    toggle = !toggle;
}

1 回答

  • 1

    是的我可以确认代码肯定有效

    #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;
    }
    

相关问题