summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBert Münnich <be.muennich@gmail.com>2012-10-29 18:25:17 +0100
committerBert Münnich <be.muennich@gmail.com>2012-10-29 18:36:48 +0100
commit4a5d5d26aa8c66ef9c4e64cc355c63888b04d4e3 (patch)
treeff6ef317d752c3b75e61e63a80d2e78cf21505af
parent65d5d4469610a375d9fb9a5b7b269aaad98334e0 (diff)
downloadnsxiv-4a5d5d26aa8c66ef9c4e64cc355c63888b04d4e3.tar.zst
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
-rw-r--r--main.c24
-rw-r--r--window.c39
-rw-r--r--window.h1
3 files changed, 47 insertions, 17 deletions
diff --git a/main.c b/main.c
index f6d09f5..848d1a4 100644
--- a/main.c
+++ b/main.c
@@ -420,7 +420,7 @@ void run(void) {
fd_set fds;
struct timeval timeout;
XEvent ev, nextev;
- unsigned int qlen;
+ bool discard;
redraw();
@@ -453,10 +453,20 @@ void run(void) {
do {
XNextEvent(win.env.dpy, &ev);
- qlen = XEventsQueued(win.env.dpy, QueuedAlready);
- if (qlen > 0)
+ discard = false;
+ if (XEventsQueued(win.env.dpy, QueuedAlready) > 0) {
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) {
/* handle events */
@@ -482,9 +492,11 @@ void run(void) {
}
}
break;
+ case Expose:
+ win_expose(&win, &ev.xexpose);
+ break;
case KeyPress:
- if (qlen == 0 || ev.xkey.keycode != nextev.xkey.keycode)
- on_keypress(&ev.xkey);
+ on_keypress(&ev.xkey);
break;
case MotionNotify:
if (mode == MODE_IMAGE) {
diff --git a/window.c b/window.c
index 0d86925..71a7915 100644
--- a/window.c
+++ b/window.c
@@ -188,8 +188,9 @@ void win_open(win_t *win) {
if (win->xwin == None)
die("could not create window");
- XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
+ XSelectInput(e->dpy, win->xwin,
+ ExposureMask | ButtonReleaseMask | ButtonPressMask |
+ KeyPressMask | PointerMotionMask | StructureNotifyMask);
carrow = XCreateFontCursor(e->dpy, XC_left_ptr);
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 changed;
- if (win == NULL)
+ if (win == NULL || c == NULL)
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->y = c->y;
@@ -260,6 +266,15 @@ bool win_configure(win_t *win, XConfigureEvent *c) {
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) {
if (win == NULL || win->xwin == None)
return false;
@@ -323,19 +338,20 @@ void win_toggle_bar(win_t *win) {
}
void win_clear(win_t *win) {
+ int h;
win_env_t *e;
if (win == NULL || win->xwin == None)
return;
+ h = win->h + win->barh;
e = &win->env;
- if (win->pm != None)
- XFreePixmap(e->dpy, win->pm);
- win->pm = XCreatePixmap(e->dpy, win->xwin, e->scrw, e->scrh, e->depth);
+ if (win->pm == None)
+ win->pm = XCreatePixmap(e->dpy, win->xwin, win->w, h, e->depth);
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) {
@@ -397,12 +413,13 @@ void win_draw(win_t *win) {
if (win->barh > 0)
win_draw_bar(win);
- XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm);
- XClearWindow(win->env.dpy, win->xwin);
+ XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
+ 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,
- bool fill, int lw, unsigned long col) {
+ bool fill, int lw, unsigned long col)
+{
XGCValues gcval;
if (win == NULL || pm == None)
diff --git a/window.h b/window.h
index c3948cd..5e033e3 100644
--- a/window.h
+++ b/window.h
@@ -66,6 +66,7 @@ void win_open(win_t*);
void win_close(win_t*);
bool win_configure(win_t*, XConfigureEvent*);
+void win_expose(win_t*, XExposeEvent*);
bool win_moveresize(win_t*, int, int, unsigned int, unsigned int);
void win_toggle_fullscreen(win_t*);