Krolyxon
Commit 4a5d5d2

Branches

Refs →

nsxiv4a5d5d2

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
Author
Bert Münnich
Date
2012-10-29 18:25 +0100
Committer
Bert Münnich · 2012-10-29 18:36 +0100
Parent
65d5d44
Commit
4a5d5d26aa8c66ef9c4e64cc355c63888b04d4e3

+47 −17

3 files changed

  1. M main.c +18 −6
  2. M window.c +28 −11
  3. M window.h +1 −0
M main.c View
@@ -420,7 +420,7 @@ void run(void) {
420420 fd_set fds;
421421 struct timeval timeout;
422422 XEvent ev, nextev;
423− unsigned int qlen;
423+ bool discard;
424424
425425 redraw();
426426
@@ -453,10 +453,20 @@ void run(void) {
453453
454454 do {
455455 XNextEvent(win.env.dpy, &ev);
456− qlen = XEventsQueued(win.env.dpy, QueuedAlready);
457− if (qlen > 0)
456+ discard = false;
457+ if (XEventsQueued(win.env.dpy, QueuedAlready) > 0) {
458458 XPeekEvent(win.env.dpy, &nextev);
459− } while (qlen > 0 && ev.type == nextev.type);
459+ switch (ev.type) {
460+ case ConfigureNotify:
461+ discard = ev.type == nextev.type;
462+ break;
463+ case KeyPress:
464+ discard = (nextev.type == KeyPress || nextev.type == KeyRelease)
465+ && ev.xkey.keycode == nextev.xkey.keycode;
466+ break;
467+ }
468+ }
469+ } while (discard);
460470
461471 switch (ev.type) {
462472 /* handle events */
@@ -482,9 +492,11 @@ void run(void) {
482492 }
483493 }
484494 break;
495+ case Expose:
496+ win_expose(&win, &ev.xexpose);
497+ break;
485498 case KeyPress:
486− if (qlen == 0 || ev.xkey.keycode != nextev.xkey.keycode)
487− on_keypress(&ev.xkey);
499+ on_keypress(&ev.xkey);
488500 break;
489501 case MotionNotify:
490502 if (mode == MODE_IMAGE) {
M window.c View
@@ -188,8 +188,9 @@ void win_open(win_t *win) {
188188 if (win->xwin == None)
189189 die("could not create window");
190190
191− XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask |
192− ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
191+ XSelectInput(e->dpy, win->xwin,
192+ ExposureMask | ButtonReleaseMask | ButtonPressMask |
193+ KeyPressMask | PointerMotionMask | StructureNotifyMask);
193194
194195 carrow = XCreateFontCursor(e->dpy, XC_left_ptr);
195196 chand = XCreateFontCursor(e->dpy, XC_fleur);
@@ -246,10 +247,15 @@ void win_close(win_t *win) {
246247 bool win_configure(win_t *win, XConfigureEvent *c) {
247248 bool changed;
248249
249− if (win == NULL)
250+ if (win == NULL || c == NULL)
250251 return false;
251252
252− changed = win->w != c->width || win->h + win->barh != c->height;
253+ if ((changed = win->w != c->width || win->h + win->barh != c->height)) {
254+ if (win->pm != None) {
255+ XFreePixmap(win->env.dpy, win->pm);
256+ win->pm = None;
257+ }
258+ }
253259
254260 win->x = c->x;
255261 win->y = c->y;
@@ -260,6 +266,15 @@ bool win_configure(win_t *win, XConfigureEvent *c) {
260266 return changed;
261267 }
262268
269+void win_expose(win_t *win, XExposeEvent *e) {
270+ if (win == NULL || win->xwin == None || e == NULL)
271+ return;
272+
273+ if (win->pm != None)
274+ XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
275+ e->x, e->y, e->width, e->height, e->x, e->y);
276+}
277+
263278 bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) {
264279 if (win == NULL || win->xwin == None)
265280 return false;
@@ -323,19 +338,20 @@ void win_toggle_bar(win_t *win) {
323338 }
324339
325340 void win_clear(win_t *win) {
341+ int h;
326342 win_env_t *e;
327343
328344 if (win == NULL || win->xwin == None)
329345 return;
330346
347+ h = win->h + win->barh;
331348 e = &win->env;
332349
333− if (win->pm != None)
334− XFreePixmap(e->dpy, win->pm);
335− win->pm = XCreatePixmap(e->dpy, win->xwin, e->scrw, e->scrh, e->depth);
350+ if (win->pm == None)
351+ win->pm = XCreatePixmap(e->dpy, win->xwin, win->w, h, e->depth);
336352
337353 XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol);
338− XFillRectangle(e->dpy, win->pm, gc, 0, 0, e->scrw, e->scrh);
354+ XFillRectangle(e->dpy, win->pm, gc, 0, 0, win->w, h);
339355 }
340356
341357 void win_draw_bar(win_t *win) {
@@ -397,12 +413,13 @@ void win_draw(win_t *win) {
397413 if (win->barh > 0)
398414 win_draw_bar(win);
399415
400− XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm);
401− XClearWindow(win->env.dpy, win->xwin);
416+ XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
417+ 0, 0, win->w, win->h + win->barh, 0, 0);
402418 }
403419
404420 void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h,
405− bool fill, int lw, unsigned long col) {
421+ bool fill, int lw, unsigned long col)
422+{
406423 XGCValues gcval;
407424
408425 if (win == NULL || pm == None)
M window.h View
@@ -66,6 +66,7 @@ void win_open(win_t*);
6666 void win_close(win_t*);
6767
6868 bool win_configure(win_t*, XConfigureEvent*);
69+void win_expose(win_t*, XExposeEvent*);
6970 bool win_moveresize(win_t*, int, int, unsigned int, unsigned int);
7071
7172 void win_toggle_fullscreen(win_t*);