window only gets events when in focus - Xwindows

This is a discussion on window only gets events when in focus - Xwindows ; Hi, In my program, I open an X11 window in a thread, then draw on it from another using Cairo. The window is updated using the XDamage extension. My problem is that the window only gets DamageNotify and even DestroyNotify ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: window only gets events when in focus

  1. window only gets events when in focus

    Hi,

    In my program, I open an X11 window in a thread, then draw on it from
    another using Cairo. The window is updated using the XDamage
    extension.

    My problem is that the window only gets DamageNotify and even
    DestroyNotify (so this is not something specific to the XDamage
    extension) events when in focus. For example, I send the window a
    destroy event, but it is not destroyed until I select it with Alt-Tab
    in my window manager.

    I would appreciate advice on what I should do. The program is as
    follows:

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define TRUE 1
    #define FALSE 0

    #define DEBUG

    #define ERROR_OUTOFMEMORY 1
    #define ERROR_OPENDISPLAY 2
    #define ERROR_XDAMAGEMISSING 3

    #define RETURN_ERROR(err) { free(xc); return (err); }

    typedef struct {
    unsigned int width;
    unsigned int height;
    Display *display;
    int screen;
    Window window;
    Pixmap pixmap;
    GC gc;
    } xlib_context_data;

    int
    create_xlib_context(char *display_name,
    unsigned int width,
    unsigned int height,
    xlib_context_data **xc_pointer,
    cairo_t **context_pointer)
    {
    Window root; /* root window */
    Visual *visual; /* visual */
    int depth; /* depth */
    XEvent ev; /* event */
    cairo_surface_t *surface; /* surface */
    Atom prots[1];
    int damage_event, damage_error; /* for querying extension */
    Damage damage; /* damage notification handler */
    XDamageNotifyEvent *dev;
    cairo_t *context;
    XSizeHints *hints;

    xlib_context_data *xc = (void *)NULL;
    /* initialize pointer with NULL */
    *xc_pointer = NULL;
    /* allocate xlib_context */
    xc = malloc( sizeof(xlib_context_data) );
    if (!xc)
    RETURN_ERROR(ERROR_OUTOFMEMORY);
    /* save width and height */
    xc->width = width;
    xc->height = height;
    /* open display, get screen, root, visual, and depth */
    xc->display = XOpenDisplay(display_name);
    if (!xc->display)
    RETURN_ERROR( ERROR_OPENDISPLAY );
    xc->screen = DefaultScreen(xc->display);
    root = RootWindow(xc->display, xc->screen);
    visual = DefaultVisual(xc->display, xc->screen);
    depth = DefaultDepth(xc->display, xc->screen);
    /* check X damage extension */
    if (!XDamageQueryExtension( xc->display, &damage_event,
    &damage_error ))
    RETURN_ERROR( ERROR_XDAMAGEMISSING );
    /* create window and pixmap */
    xc->window = XCreateSimpleWindow(xc->display, root, 0, 0, xc-
    >width, xc->height, 0, 0,

    WhitePixel (xc->display, xc->screen));
    xc->pixmap = XCreatePixmap(xc->display, xc->window, xc->width, xc-
    >height, depth);

    /* size hints */
    hints = XAllocSizeHints();
    hints->min_width = width;
    hints->min_height = height;
    hints->max_width = width;
    hints->max_height = height;
    hints->flags = PMinSize | PMaxSize;
    XSetWMNormalHints(xc->display, xc->window, hints);
    XFree(hints);
    /* graphics context */
    xc->gc = XCreateGC(xc->display, xc->pixmap, 0, 0);
    /* setup damage notification */
    damage = XDamageCreate( xc->display, xc->pixmap,
    XDamageReportNonEmpty );
    /* select events, map window */
    XSelectInput( xc->display, xc->window,
    ExposureMask | StructureNotifyMask | KeyPressMask |
    KeyReleaseMask );
    /* handle window closing */
    prots[0] = XInternAtom(xc->display, "WM_DELETE_WINDOW", FALSE);
    XSetWMProtocols(xc->display, xc->window, prots, 1);
    /* map window */
    XMapWindow(xc->display, xc->window);
    /* allocate structure, create cairo surface */
    surface = cairo_xlib_surface_create( xc->display, xc->pixmap,
    visual,
    width, height );
    context = cairo_create(surface);
    cairo_surface_destroy(surface);
    /* set pointers before we start loop */
    #ifdef DEBUG
    FILE *debug = fopen("/tmp/debug","w");
    fprintf(debug, "before setting: xc_pointer=%p *xc_pointer=%p
    context_pointer=%p *context_pointer=%p\n", xc_pointer, *xc_pointer,
    context_pointer, *context_pointer);
    #endif /* DEBUG */
    *xc_pointer = xc;
    *context_pointer = context;
    #ifdef DEBUG
    fprintf(debug, "xc=%p=%p context=%p=%p\n", xc, *xc_pointer,
    context, *context_pointer);
    fprintf(debug, "damage_event=%d, XDamageNotify=%d\n",
    damage_event, XDamageNotify);
    fflush(debug);
    #endif /* DEBUG */
    /* main loop */
    for (; {
    XNextEvent(xc->display, &ev);
    #ifdef DEBUG
    fprintf(debug, "event of type %d\n", ev.type);
    fflush(debug);
    #endif /* DEBUG */
    if (ev.type == (damage_event + XDamageNotify)) {
    dev = (XDamageNotifyEvent *) &ev;
    #ifdef DEBUG
    fprintf(debug, "damage event received\n");
    fflush(debug);
    #endif /* DEBUG */
    /* !!!! should only update the rectangle */
    XCopyArea(xc->display, xc->pixmap, xc->window, xc->gc, 0, 0,
    xc->width, xc->height, 0, 0);
    XDamageSubtract( xc->display, dev->damage, None, None );
    } else {
    switch (ev.type) {
    case Expose:
    #ifdef DEBUG
    fprintf(debug, "expose event received\n");
    fflush(debug);
    #endif /* DEBUG */
    if (ev.xexpose.count > 0)
    break;
    /* !!!! should only update the rectangle */
    XCopyArea(xc->display, xc->pixmap, xc->window, xc->gc, 0, 0,
    xc->width, xc->height, 0, 0);
    break;
    case DestroyNotify:
    case ClientMessage:
    /* cleanup & close */
    XDamageDestroy( xc->display, damage );
    XDestroyWindow( xc->display, xc->window );
    XCloseDisplay( xc->display );
    #ifdef DEBUG
    fclose(debug);
    #endif /* DEBUG */
    return(0);
    default:
    break;
    }
    }
    }
    }

    void close_xlib_context(xlib_context_data *xc)
    {
    XEvent ev;
    ev.type = DestroyNotify;
    XSendEvent(xc->display, xc->window, FALSE, 0, &ev);
    }

    Thanks,

    Tamas


  2. Re: window only gets events when in focus


    "Tamas" wrote in message
    news:1181657669.529656.94760@i13g2000prf.googlegro ups.com...
    > Hi,
    >
    > In my program, I open an X11 window in a thread, then draw on it from
    > another using Cairo. The window is updated using the XDamage
    > extension.
    >
    > My problem is that the window only gets DamageNotify and even
    > DestroyNotify (so this is not something specific to the XDamage
    > extension) events when in focus. For example, I send the window a
    > destroy event, but it is not destroyed until I select it with Alt-Tab
    > in my window manager.
    >
    > I would appreciate advice on what I should do. The program is as
    > follows:
    > (snip)
    >
    > XSelectInput( xc->display, xc->window,
    > ExposureMask | StructureNotifyMask | KeyPressMask |
    > KeyReleaseMask );
    >
    > (snip)


    Try adding SubstructureNotifyMask to get DestroyNotify events.
    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Aero Stability and Controls Computing



  3. Re: window only gets events when in focus

    On Jun 12, 8:17 pm, "Fred Kleinschmidt"
    wrote:
    > "Tamas" wrote in message
    >
    > news:1181657669.529656.94760@i13g2000prf.googlegro ups.com...
    >
    >
    >
    > > Hi,

    >
    > > In my program, I open an X11 window in a thread, then draw on it from
    > > another using Cairo. The window is updated using the XDamage
    > > extension.

    >
    > > My problem is that the window only gets DamageNotify and even
    > > DestroyNotify (so this is not something specific to the XDamage
    > > extension) events when in focus. For example, I send the window a
    > > destroy event, but it is not destroyed until I select it with Alt-Tab
    > > in my window manager.

    >
    > > I would appreciate advice on what I should do. The program is as
    > > follows:
    > > (snip)

    >
    > > XSelectInput( xc->display, xc->window,
    > > ExposureMask | StructureNotifyMask | KeyPressMask |
    > > KeyReleaseMask );

    >
    > > (snip)

    >
    > Try adding SubstructureNotifyMask to get DestroyNotify events.
    > --
    > Fred L. Kleinschmidt
    > Boeing Associate Technical Fellow
    > Aero Stability and Controls Computing


    Thanks, but it didn't help. I realize my previous example was too
    complicated for people to look at it, so I simplified. But it still
    doesn't work: I start create_window in a thread, then issue
    close_window, which only takes effect after I focus and click on the
    window title bar (merely making the window active doesn't work). I am
    using SBCL's threads.

    #include
    #include
    #include
    #include
    #include

    typedef struct {
    Display *display;
    Window window;
    } window_data;

    /
    ************************************************** *************************
    * create_window -- create window, save it in wd_pointer, start event
    loop *

    ************************************************** *************************/
    int
    create_window(char *display_name,
    window_data **wd_pointer)
    {
    Window root; /* root window */
    Visual *visual; /* visual */
    int depth; /* depth */
    XEvent ev; /* event */
    int screen; /* screen */
    GC gc;
    Atom prots[1];

    window_data *wd = malloc( sizeof(window_data) ); /* allocate
    window_data */
    /* open display, get screen, root, visual, and depth */
    wd->display = XOpenDisplay(display_name);
    screen = DefaultScreen(wd->display);
    root = RootWindow(wd->display, screen);
    visual = DefaultVisual(wd->display, screen);
    depth = DefaultDepth(wd->display, screen);
    wd->window = XCreateSimpleWindow(wd->display, root, 0, 0, 100,
    100, 0, 0,
    WhitePixel (wd->display, screen));
    /* graphics context */
    gc = XCreateGC(wd->display, wd->window, 0, 0);
    /* select events, map window */
    XSelectInput( wd->display, wd->window,
    ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask
    |
    SubstructureNotifyMask );
    /* handle window closing */
    prots[0] = XInternAtom(wd->display, "WM_DELETE_WINDOW", 0);
    XSetWMProtocols(wd->display, wd->window, prots, 1);
    XMapWindow(wd->display, wd->window); /* map window */
    *wd_pointer = wd; /* set pointers before we start loop */
    /* main loop */
    for (; {
    XNextEvent(wd->display, &ev);
    switch (ev.type) {
    case Expose:
    if (ev.xexpose.count > 0)
    break;
    /* do nothing */
    break;
    case DestroyNotify:
    case ClientMessage:
    /* cleanup & close */
    XDestroyWindow( wd->display, wd->window );
    XCloseDisplay( wd->display );
    return(0);
    default:
    break;
    }
    }
    }

    void close_window(window_data *wd)
    {
    XEvent ev;
    ev.type = DestroyNotify;
    XSendEvent(wd->display, wd->window, 0, 0, &ev);
    }


  4. Re: window only gets events when in focus

    On Jun 13, 10:24 am, Tamas wrote:

    > Thanks, but it didn't help. I realize my previous example was too
    > complicated for people to look at it, so I simplified. But it still
    > doesn't work: I start create_window in a thread, then issue
    > close_window, which only takes effect after I focus and click on the
    > window title bar (merely making the window active doesn't work). I am
    > using SBCL's threads.


    I think I am on my way to a solution. The events are received when I
    call XSync or XFlush. I understand the need to call XFlush after
    using XSendEvent, but when I am drawing onto the pixmap, I thought
    that the XDamage extension wouldn't only generate the events but flush
    them out too. How can I make it do that?

    Thanks,

    Tamas


+ Reply to Thread