summaryrefslogtreecommitdiffstats
path: root/window.c
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2014-07-28 20:36:32 +0200
committerBert Münnich <ber.t@posteo.de>2014-07-28 20:36:32 +0200
commitbb6721549b30c33b0080975aa19a0b02a916c7e5 (patch)
tree5836842e5120d9dcdeee1e0efaf94c34d35a04e2 /window.c
parent5e481912ec983be89f10cbbb21561ed7cc898027 (diff)
downloadnsxiv-bb6721549b30c33b0080975aa19a0b02a916c7e5.tar.zst
Overhauled window drawing, yet again; fixes issue #155
- Buffer for window content is bigger than the window, minimizes artifacts when window is resized - Back to using XSetWindowBackgroundPixmap() instead of XCopyArea(), no need to handle exposure events; X server can show gray background directly after resize event before sxiv redraws the window contents
Diffstat (limited to 'window.c')
-rw-r--r--window.c83
1 files changed, 31 insertions, 52 deletions
diff --git a/window.c b/window.c
index a0a8d80..5387564 100644
--- a/window.c
+++ b/window.c
@@ -186,14 +186,13 @@ void win_open(win_t *win)
int c, i, j, n;
win_env_t *e;
XClassHint classhint;
- XSetWindowAttributes attr;
- unsigned long attr_mask;
unsigned long *icon_data;
XColor col;
char none_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
Pixmap none;
int gmask;
XSizeHints sizehints;
+ Bool fullscreen = options->fullscreen && fs_support;
if (win == NULL)
return;
@@ -237,18 +236,15 @@ void win_open(win_t *win)
win->y = 0;
}
- attr.background_pixel = win->bgcol;
- attr_mask = CWBackPixel;
-
win->xwin = XCreateWindow(e->dpy, RootWindow(e->dpy, e->scr),
win->x, win->y, win->w, win->h, 0,
- e->depth, InputOutput, e->vis, attr_mask, &attr);
+ e->depth, InputOutput, e->vis, 0, NULL);
if (win->xwin == None)
die("could not create window");
XSelectInput(e->dpy, win->xwin,
- ExposureMask | ButtonReleaseMask | ButtonPressMask |
- KeyPressMask | PointerMotionMask | StructureNotifyMask);
+ ButtonReleaseMask | ButtonPressMask | KeyPressMask |
+ PointerMotionMask | StructureNotifyMask);
carrow = XCreateFontCursor(e->dpy, XC_left_ptr);
chand = XCreateFontCursor(e->dpy, XC_fleur);
@@ -299,10 +295,18 @@ void win_open(win_t *win)
win->h -= win->bar.h;
+ win->buf.w = e->scrw;
+ win->buf.h = e->scrh;
+ win->buf.pm = XCreatePixmap(e->dpy, win->xwin,
+ win->buf.w, win->buf.h, e->depth);
+ XSetForeground(e->dpy, gc, fullscreen ? win->fscol : win->bgcol);
+ XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
+ XSetWindowBackgroundPixmap(e->dpy, win->xwin, win->buf.pm);
+
XMapWindow(e->dpy, win->xwin);
XFlush(e->dpy);
- if (options->fullscreen)
+ if (fullscreen)
win_toggle_fullscreen(win);
}
@@ -329,12 +333,7 @@ bool win_configure(win_t *win, XConfigureEvent *c)
if (win == NULL || c == NULL)
return false;
- if ((changed = win->w != c->width || win->h + win->bar.h != c->height)) {
- if (win->pm != None) {
- XFreePixmap(win->env.dpy, win->pm);
- win->pm = None;
- }
- }
+ changed = win->w != c->width || win->h + win->bar.h != c->height;
win->x = c->x;
win->y = c->y;
@@ -345,15 +344,6 @@ bool win_configure(win_t *win, XConfigureEvent *c)
return changed;
}
-void win_expose(win_t *win, XExposeEvent *e)
-{
- if (win == NULL || win->xwin == None || win->pm == None || e == NULL)
- return;
-
- XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
- e->x, e->y, e->width, e->height, e->x, e->y);
-}
-
void win_toggle_fullscreen(win_t *win)
{
XEvent ev;
@@ -402,20 +392,22 @@ 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->bar.h;
e = &win->env;
- if (win->pm == None)
- win->pm = XCreatePixmap(e->dpy, win->xwin, win->w, h, e->depth);
-
+ if (win->w > win->buf.w || win->h + win->bar.h > win->buf.h) {
+ XFreePixmap(e->dpy, win->buf.pm);
+ win->buf.w = MAX(win->buf.w, win->w);
+ win->buf.h = MAX(win->buf.h, win->h + win->bar.h);
+ win->buf.pm = XCreatePixmap(e->dpy, win->xwin,
+ win->buf.w, win->buf.h, e->depth);
+ }
XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol);
- XFillRectangle(e->dpy, win->pm, gc, 0, 0, win->w, h);
+ XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
}
void win_draw_bar(win_t *win)
@@ -425,7 +417,7 @@ void win_draw_bar(win_t *win)
const char *dots = "...";
win_env_t *e;
- if (win == NULL || win->xwin == None || win->pm == None)
+ if (win == NULL || win->xwin == None)
return;
e = &win->env;
@@ -433,7 +425,7 @@ void win_draw_bar(win_t *win)
w = win->w;
XSetForeground(e->dpy, gc, win->bar.bgcol);
- XFillRectangle(e->dpy, win->pm, gc, 0, win->h, win->w, win->bar.h);
+ XFillRectangle(e->dpy, win->buf.pm, gc, 0, win->h, win->w, win->bar.h);
XSetForeground(e->dpy, gc, win->bar.fgcol);
XSetBackground(e->dpy, gc, win->bar.bgcol);
@@ -444,9 +436,9 @@ void win_draw_bar(win_t *win)
x = win->w - tw + H_TEXT_PAD;
w -= tw;
if (font.set)
- XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, win->bar.r, len);
+ XmbDrawString(e->dpy, win->buf.pm, font.set, gc, x, y, win->bar.r, len);
else
- XDrawString(e->dpy, win->pm, gc, x, y, win->bar.r, len);
+ XDrawString(e->dpy, win->buf.pm, gc, x, y, win->bar.r, len);
}
if ((len = strlen(win->bar.l)) > 0) {
olen = len;
@@ -462,9 +454,9 @@ void win_draw_bar(win_t *win)
}
x = H_TEXT_PAD;
if (font.set)
- XmbDrawString(e->dpy, win->pm, font.set, gc, x, y, win->bar.l, len);
+ XmbDrawString(e->dpy, win->buf.pm, font.set, gc, x, y, win->bar.l, len);
else
- XDrawString(e->dpy, win->pm, gc, x, y, win->bar.l, len);
+ XDrawString(e->dpy, win->buf.pm, gc, x, y, win->bar.l, len);
if (len != olen)
memcpy(win->bar.l + len - w, rest, w);
}
@@ -473,14 +465,14 @@ void win_draw_bar(win_t *win)
void win_draw(win_t *win)
{
- if (win == NULL || win->xwin == None || win->pm == None)
+ if (win == NULL || win->xwin == None)
return;
if (win->bar.h > 0)
win_draw_bar(win);
- XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
- 0, 0, win->w, win->h + win->bar.h, 0, 0);
+ XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->buf.pm);
+ XClearWindow(win->env.dpy, win->xwin);
XFlush(win->env.dpy);
}
@@ -502,19 +494,6 @@ void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h,
XDrawRectangle(win->env.dpy, pm, gc, x, y, w, h);
}
-void win_update_bar(win_t *win)
-{
- if (win == NULL || win->xwin == None || win->pm == None)
- return;
-
- if (win->bar.h > 0) {
- win_draw_bar(win);
- XCopyArea(win->env.dpy, win->pm, win->xwin, gc,
- 0, win->h, win->w, win->bar.h, 0, win->h);
- XFlush(win->env.dpy);
- }
-}
-
int win_textwidth(const char *text, unsigned int len, bool with_padding)
{
XRectangle r;