1

I would like to open a "dock type" window without its title bar with x11 in C and I want to capture a key press (Ctrl-q) to close it. The actual code does not capture the key presses to the active window as they are all sent and printed in the terminal. Almost all the Ctrl key presses are somehow not detected. The only key presses that actually work on the opened window are Ctrl-c. I am aware of the _MOTIF_WM_HINTS property but it has the disadvantage to display a window icon in the panel to show a new opened window.

How can I have a "dock type" window while not losing the ability to detect key presses to the active window?

Here is the code basically copied from two other posts here and here

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

int main(int argc, char **argv) 
{
    Display *dpy = XOpenDisplay(0);

    int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

    Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 
                     200, 100, 0, blackColor, blackColor);

    //Tell X Server to send MapNotify events
    XSelectInput(dpy, w, StructureNotifyMask | KeyPressMask);
    Atom window_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
    long value = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);

    XChangeProperty(dpy, w, window_type, 4, 32,
                    PropModeReplace,
                    (unsigned char *)&value, 1);

    //Make window appear
    XMapWindow(dpy, w);
    //Graphics Context
    GC gc = XCreateGC(dpy, w, 0, 0);
    //Set white color for drawing
    XSetForeground(dpy, gc, whiteColor);

    //Wait for the MapNotify event
    for(;;) {
        XEvent e;
        XNextEvent(dpy, &e);
        if (e.type == MapNotify) {
          break;
        }
    }

    //Draw the line
    XDrawLine(dpy, w, gc, 10, 60, 180, 20);
    //Send the "DrawLine" request to the server
    XFlush(dpy);

    char text[255];
    XEvent e;
    KeySym key;
    int numKeys = 0;
    for(;;) {
        XNextEvent(dpy, &e);
        if(e.type == KeyPress) {
            if((numKeys = XLookupString(&e.xkey, text, 255, &key, 0))) {
                if(e.xkey.state == ControlMask && key == XK_q) {
                    printf("CTRL-Q\n");
                    break;
                }
            }
        }
    }
    if (dpy && gc) XFreeGC(dpy, gc);
    if (dpy && w) XDestroyWindow(dpy, w);
    if (dpy) XCloseDisplay(dpy);
    return 0;
}

Compiled with: gcc main.c -L/usr/X11R6/lib -lX11 -lm && ./a.out

I've also looked at the _NET_WM_STRUT_PARTIAL property but I haven't been succesful at implementing it.

tham mes
  • 19
  • 2

0 Answers0