Overhauled window drawing

- Draw onto pixmap as before, but use the same size for the pixmap as
  for the window, allocate new pixmap after configure requests
- Use XCopyArea() instead of XSetWindowBackgroundPixmap(), which now
  requires handling of Expose events
This commit is contained in:
Bert Münnich 2012-10-29 18:25:17 +01:00
parent 65d5d44696
commit 4a5d5d26aa
3 changed files with 47 additions and 17 deletions

24
main.c
View file

@ -420,7 +420,7 @@ void run(void) {
fd_set fds; fd_set fds;
struct timeval timeout; struct timeval timeout;
XEvent ev, nextev; XEvent ev, nextev;
unsigned int qlen; bool discard;
redraw(); redraw();
@ -453,10 +453,20 @@ void run(void) {
do { do {
XNextEvent(win.env.dpy, &ev); XNextEvent(win.env.dpy, &ev);
qlen = XEventsQueued(win.env.dpy, QueuedAlready); discard = false;
if (qlen > 0) if (XEventsQueued(win.env.dpy, QueuedAlready) > 0) {
XPeekEvent(win.env.dpy, &nextev); XPeekEvent(win.env.dpy, &nextev);
} while (qlen > 0 && ev.type == nextev.type); switch (ev.type) {
case ConfigureNotify:
discard = ev.type == nextev.type;
break;
case KeyPress:
discard = (nextev.type == KeyPress || nextev.type == KeyRelease)
&& ev.xkey.keycode == nextev.xkey.keycode;
break;
}
}
} while (discard);
switch (ev.type) { switch (ev.type) {
/* handle events */ /* handle events */
@ -482,9 +492,11 @@ void run(void) {
} }
} }
break; break;
case Expose:
win_expose(&win, &ev.xexpose);
break;
case KeyPress: case KeyPress:
if (qlen == 0 || ev.xkey.keycode != nextev.xkey.keycode) on_keypress(&ev.xkey);
on_keypress(&ev.xkey);
break; break;
case MotionNotify: case MotionNotify:
if (mode == MODE_IMAGE) { if (mode == MODE_IMAGE) {

View file

@ -188,8 +188,9 @@ void win_open(win_t *win) {
if (win->xwin == None) if (win->xwin == None)
die("could not create window"); die("could not create window");
XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask | XSelectInput(e->dpy, win->xwin,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask); ExposureMask | ButtonReleaseMask | ButtonPressMask |
KeyPressMask | PointerMotionMask | StructureNotifyMask);
carrow = XCreateFontCursor(e->dpy, XC_left_ptr); carrow = XCreateFontCursor(e->dpy, XC_left_ptr);
chand = XCreateFontCursor(e->dpy, XC_fleur); chand = XCreateFontCursor(e->dpy, XC_fleur);
@ -246,10 +247,15 @@ void win_close(win_t *win) {
bool win_configure(win_t *win, XConfigureEvent *c) { bool win_configure(win_t *win, XConfigureEvent *c) {
bool changed; bool changed;
if (win == NULL) if (win == NULL || c == NULL)
return false; return false;
changed = win->w != c->width || win->h + win->barh != c->height; if ((changed = win->w != c->width || win->h + win->barh != c->height)) {
if (win->pm != None) {
XFreePixmap(win->env.dpy, win->pm);
win->pm = None;
}
}
win->x = c->x; win->x = c->x;
win->y = c->y; win->y = c->y;
@ -260,6 +266,15 @@ bool win_configure(win_t *win, XConfigureEvent *c) {
return changed; return changed;
} }
void win_expose(win_t *win, XExposeEvent *e) {
if (win == NULL || win->xwin == None || e == NULL)
return;
if (win->pm != None)
XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
e->x, e->y, e->width, e->height, e->x, e->y);
}
bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) { bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) {
if (win == NULL || win->xwin == None) if (win == NULL || win->xwin == None)
return false; return false;
@ -323,19 +338,20 @@ void win_toggle_bar(win_t *win) {
} }
void win_clear(win_t *win) { void win_clear(win_t *win) {
int h;
win_env_t *e; win_env_t *e;
if (win == NULL || win->xwin == None) if (win == NULL || win->xwin == None)
return; return;
h = win->h + win->barh;
e = &win->env; e = &win->env;
if (win->pm != None) if (win->pm == None)
XFreePixmap(e->dpy, win->pm); win->pm = XCreatePixmap(e->dpy, win->xwin, win->w, h, e->depth);
win->pm = XCreatePixmap(e->dpy, win->xwin, e->scrw, e->scrh, e->depth);
XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol); XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol);
XFillRectangle(e->dpy, win->pm, gc, 0, 0, e->scrw, e->scrh); XFillRectangle(e->dpy, win->pm, gc, 0, 0, win->w, h);
} }
void win_draw_bar(win_t *win) { void win_draw_bar(win_t *win) {
@ -397,12 +413,13 @@ void win_draw(win_t *win) {
if (win->barh > 0) if (win->barh > 0)
win_draw_bar(win); win_draw_bar(win);
XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm); XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
XClearWindow(win->env.dpy, win->xwin); 0, 0, win->w, win->h + win->barh, 0, 0);
} }
void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h, void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h,
bool fill, int lw, unsigned long col) { bool fill, int lw, unsigned long col)
{
XGCValues gcval; XGCValues gcval;
if (win == NULL || pm == None) if (win == NULL || pm == None)

View file

@ -66,6 +66,7 @@ void win_open(win_t*);
void win_close(win_t*); void win_close(win_t*);
bool win_configure(win_t*, XConfigureEvent*); bool win_configure(win_t*, XConfigureEvent*);
void win_expose(win_t*, XExposeEvent*);
bool win_moveresize(win_t*, int, int, unsigned int, unsigned int); bool win_moveresize(win_t*, int, int, unsigned int, unsigned int);
void win_toggle_fullscreen(win_t*); void win_toggle_fullscreen(win_t*);