简体   繁体   中英

X11 window does not get refreshed until it gets an event

In my application ( cairo and X11 ), the user can issue a command whereby the drawing is enlarged. To be able to grab the entire drawing as a pattern, I enlarge the drawing surface to match the current scale (the drawing is just a graph, so this can be afforded as far as memory is concerned). Beginning with a certain scale though, the X11 window refuses to refresh until it gets an event (eg loss of focus, which is not even handled in my application).

I tried refreshing the window using both XFlush() and XSync() .

Does this look like a bug in the windowing system? If not, what should I do? Everything works perfectly with smaller scales.

EDIT 1 : After much work with gdb , I found that the problem is not with the window not refreshing. Rather, at a certain point a call to XNextEvent() causes the window to become all black.

EDIT2 : It looks like calls to XNextEvent() actually cause the window to be refreshed! And here is the code that caused the problem:

struct PatternLock {
    PatternLock(Graphics &g)
        : g_(g) {
        p_ = cairo_get_source(g_.cr);
        cairo_pattern_reference(p_);
    }

    ~PatternLock() {
        // The commented lines caused the problem. How come?
        // cairo_set_source_rgb(g_.cr, 0, 0, 0);
        // cairo_paint(g_.cr);
        cairo_set_source(g_.cr, p_);
        cairo_paint(g_.cr);
        cairo_pattern_destroy(p_);
    }

private:
    Graphics &g_;
    cairo_pattern_t *p_;
};

Suppose the we have this code for moving the drawing:

{
    PatternLock lock{g};
    ... // Change of transformation matrix
}

It somehow happen that the effect of the commented lines in the destructor of PatternLock becomes visible (hence the black screen), but the effect of the following lines does not. I realize that the commented code is actually unneeded. But still, how does this happen?

If my memory serves me correct, there's a limit to Drawables (eg Windows and Pixmaps) of 4096x4096 pixels. You should check the return values of your calls to XCreatePixmap() etc.

Either way, just enlarging the pixmap to draw your drawing is Bad Design (tm), and will inevitably lead to a very slow program. Learn how to deal with zoom and pan (tip: work from the center of your viewport, not the corners). Assuming your drawing is vector-based (ie lines and curves) you can optimize painting a lot at high zoom factors.

If you must grab a complete graph at a resolutions larger than 4096 pixels you must implement tiling, which isn't that hard if you have zoom and pan already.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM