Compare commits

..

10 Commits

Author SHA1 Message Date
Bert Münnich
1d28627868 Stable version 26 2020-01-16 14:30:49 +01:00
Bert Münnich
8494b43635 Document dependencies
Fixes issues #378 and #374.
2020-01-16 12:36:26 +01:00
Bert Münnich
d9e60cb4c0 Fix memory leak in win_res()
Fixes issue #372.
2020-01-16 12:36:04 +01:00
Bert Münnich
55777ba9f4 Fix indentation 2020-01-16 10:31:41 +01:00
Bert Münnich
07300da7df Do not keep track of fullscreen state
There is no more need for this after the removal of the special color handling
for fullscreen mode in commit 2886876.
2019-07-16 19:26:04 +02:00
Bert Münnich
28868767e6 Use normal win colors in fullscreen mode
Fixes issues #361 and #367
2019-07-16 19:18:13 +02:00
Bert Münnich
6511d681ac Hint to xrdb for changing X resources 2019-04-19 16:13:05 +02:00
Bert Münnich
18d63dba28 Mention supported X resources in man page 2019-04-19 15:52:44 +02:00
Bert Münnich
7bde7e618a Change colors and font only via X resources 2019-04-19 15:25:06 +02:00
vxid
4407a3de54 Add Xresources font support 2019-04-19 15:03:03 +02:00
9 changed files with 76 additions and 114 deletions

View File

@ -1,4 +1,4 @@
version = 25+ version = 26
srcdir = . srcdir = .
VPATH = $(srcdir) VPATH = $(srcdir)

View File

@ -32,9 +32,27 @@ Screenshots
![Thumb](http://muennich.github.com/sxiv/img/thumb.png "Thumb mode") ![Thumb](http://muennich.github.com/sxiv/img/thumb.png "Thumb mode")
Installation Dependencies
------------ ------------
sxiv requires the following software to be installed:
* Imlib2
* X11
* Xft
* freetype2
* fontconfig
* giflib (optional, disabled with `HAVE_GIFLIB=0`)
* libexif (optional, disabled with `HAVE_LIBEXIF=0`)
Please make sure to install the corresponding development packages in case that
you want to build sxiv on a distribution with separate runtime and development
packages (e.g. *-dev on Debian).
Building
--------
sxiv is built using the commands: sxiv is built using the commands:
$ make $ make
@ -74,6 +92,11 @@ on GitHub or get a copy using git with the following command:
**Stable releases** **Stable releases**
**[v26](https://github.com/muennich/sxiv/archive/v26.tar.gz)**
*(January 16, 2020)*
* Maintenance release
**[v25](https://github.com/muennich/sxiv/archive/v25.tar.gz)** **[v25](https://github.com/muennich/sxiv/archive/v25.tar.gz)**
*(January 26, 2019)* *(January 26, 2019)*

View File

@ -6,17 +6,10 @@ enum {
WIN_HEIGHT = 600 WIN_HEIGHT = 600
}; };
/* bar font: /* colors and font are configured with 'background', 'foreground' and
* (see fonts-conf(5) subsection "FONT NAMES" for valid values) * 'font' X resource properties.
* See X(7) section Resources and xrdb(1) for more information.
*/ */
static const char * const BAR_FONT = "monospace:size=8";
/* colors:
* overwritten by 'background' and 'foreground' X resource properties.
* (see X(7) section "COLOR NAMES" for valid values)
*/
static const char * const BG_COLOR = "#ffffea";
static const char * const FG_COLOR = "#555555";
#endif #endif
#ifdef _IMAGE_CONFIG #ifdef _IMAGE_CONFIG

View File

@ -497,7 +497,7 @@ void img_render(img_t *img)
} }
imlib_image_put_back_data(data); imlib_image_put_back_data(data);
} else { } else {
c = win->fullscreen ? win->black.pixel : win->bg.pixel; c = win->bg.pixel;
imlib_context_set_color(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF, 0xFF); imlib_context_set_color(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF, 0xFF);
imlib_image_fill_rectangle(0, 0, dw, dh); imlib_image_fill_rectangle(0, 0, dw, dh);
} }

2
main.c
View File

@ -774,7 +774,7 @@ void run(void)
} else { } else {
tns.dirty = true; tns.dirty = true;
} }
if (!resized || win.fullscreen) { if (!resized) {
redraw(); redraw();
set_timeout(clear_resize, TO_REDRAW_RESIZE, false); set_timeout(clear_resize, TO_REDRAW_RESIZE, false);
resized = true; resized = true;

17
sxiv.1
View File

@ -375,6 +375,19 @@ Zoom in.
.TP .TP
.B ScrollDown .B ScrollDown
Zoom out. Zoom out.
.SH CONFIGURATION
The following X resources are supported:
.TP
.B background
Color of the window background and bar foreground
.TP
.B foreground
Color of the window foreground and bar background
.TP
.B font
Name of Xft bar font
.TP
Please see xrdb(1) on how to change them.
.SH STATUS BAR .SH STATUS BAR
The information displayed on the left side of the status bar can be replaced The information displayed on the left side of the status bar can be replaced
with the output of a user-provided script, which is called by sxiv whenever an with the output of a user-provided script, which is called by sxiv whenever an
@ -431,5 +444,5 @@ Max Voit <mvdev at with-eyes.net>
https://github.com/muennich/sxiv https://github.com/muennich/sxiv
.EE .EE
.SH SEE ALSO .SH SEE ALSO
.BR feh (1), .BR X (7),
.BR qiv (1) .BR xrdb (1)

5
sxiv.h
View File

@ -385,7 +385,6 @@ enum {
ATOM__NET_WM_ICON, ATOM__NET_WM_ICON,
ATOM__NET_WM_STATE, ATOM__NET_WM_STATE,
ATOM__NET_WM_STATE_FULLSCREEN, ATOM__NET_WM_STATE_FULLSCREEN,
ATOM__NET_SUPPORTED,
ATOM_COUNT ATOM_COUNT
}; };
@ -408,10 +407,8 @@ struct win {
Window xwin; Window xwin;
win_env_t env; win_env_t env;
bool light; /* bg is lighter than fg */
XftColor bg; XftColor bg;
XftColor fg; XftColor fg;
XftColor black;
int x; int x;
int y; int y;
@ -419,8 +416,6 @@ struct win {
unsigned int h; /* = win height - bar height */ unsigned int h; /* = win height - bar height */
unsigned int bw; unsigned int bw;
bool fullscreen;
struct { struct {
int w; int w;
int h; int h;

View File

@ -469,14 +469,14 @@ void tns_mark(tns_t *tns, int n, bool mark)
if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) { if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) {
win_t *win = tns->win; win_t *win = tns->win;
thumb_t *t = &tns->thumbs[n]; thumb_t *t = &tns->thumbs[n];
unsigned long col = win->fullscreen ? win->black.pixel : win->bg.pixel; unsigned long col = win->bg.pixel;
int x = t->x + t->w, y = t->y + t->h; int x = t->x + t->w, y = t->y + t->h;
win_draw_rect(win, x - 1, y + 1, 1, tns->bw, true, 1, col); win_draw_rect(win, x - 1, y + 1, 1, tns->bw, true, 1, col);
win_draw_rect(win, x + 1, y - 1, tns->bw, 1, true, 1, col); win_draw_rect(win, x + 1, y - 1, tns->bw, 1, true, 1, col);
if (mark) if (mark)
col = win->fullscreen && win->light ? win->bg.pixel : win->fg.pixel; col = win->fg.pixel;
win_draw_rect(win, x, y, tns->bw + 2, tns->bw + 2, true, 1, col); win_draw_rect(win, x, y, tns->bw + 2, tns->bw + 2, true, 1, col);
@ -490,14 +490,9 @@ void tns_highlight(tns_t *tns, int n, bool hl)
if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) { if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) {
win_t *win = tns->win; win_t *win = tns->win;
thumb_t *t = &tns->thumbs[n]; thumb_t *t = &tns->thumbs[n];
unsigned long col; unsigned long col = hl ? win->fg.pixel : win->bg.pixel;
int oxy = (tns->bw + 1) / 2 + 1, owh = tns->bw + 2; int oxy = (tns->bw + 1) / 2 + 1, owh = tns->bw + 2;
if (hl)
col = win->fullscreen && win->light ? win->bg.pixel : win->fg.pixel;
else
col = win->fullscreen ? win->black.pixel : win->bg.pixel;
win_draw_rect(win, t->x - oxy, t->y - oxy, t->w + owh, t->h + owh, win_draw_rect(win, t->x - oxy, t->y - oxy, t->w + owh, t->h + owh,
false, tns->bw, col); false, tns->bw, col);

105
window.c
View File

@ -53,9 +53,6 @@ static int barheight;
Atom atoms[ATOM_COUNT]; Atom atoms[ATOM_COUNT];
static Bool fs_support;
static Bool fs_warned;
void win_init_font(const win_env_t *e, const char *fontstr) void win_init_font(const win_env_t *e, const char *fontstr)
{ {
if ((font = XftFontOpenName(e->dpy, e->scr, fontstr)) == NULL) if ((font = XftFontOpenName(e->dpy, e->scr, fontstr)) == NULL)
@ -74,48 +71,14 @@ void win_alloc_color(const win_env_t *e, const char *name, XftColor *col)
} }
} }
void win_check_wm_support(Display *dpy, Window root) const char* win_res(XrmDatabase db, const char *name, const char *def)
{
int format;
long offset = 0, length = 16;
Atom *data, type;
unsigned long i, nitems, bytes_left;
Bool found = False;
while (!found && length > 0) {
if (XGetWindowProperty(dpy, root, atoms[ATOM__NET_SUPPORTED],
offset, length, False, XA_ATOM, &type, &format,
&nitems, &bytes_left, (unsigned char**) &data))
{
break;
}
if (type == XA_ATOM && format == 32) {
for (i = 0; i < nitems; i++) {
if (data[i] == atoms[ATOM__NET_WM_STATE_FULLSCREEN]) {
found = True;
fs_support = True;
break;
}
}
}
XFree(data);
offset += nitems;
length = MIN(length, bytes_left / 4);
}
}
const char* win_res(Display *dpy, const char *name, const char *def)
{ {
char *type; char *type;
XrmValue ret; XrmValue ret;
XrmDatabase db;
char *res_man;
XrmInitialize(); if (db != None &&
XrmGetResource(db, name, name, &type, &ret) &&
if ((res_man = XResourceManagerString(dpy)) != NULL && STREQ(type, "String"))
(db = XrmGetStringDatabase(res_man)) != NULL &&
XrmGetResource(db, name, name, &type, &ret) && STREQ(type, "String"))
{ {
return ret.addr; return ret.addr;
} else { } else {
@ -123,18 +86,15 @@ const char* win_res(Display *dpy, const char *name, const char *def)
} }
} }
unsigned int win_luminance(const XftColor *col)
{
return (col->color.red + col->color.green + col->color.blue) / 3;
}
#define INIT_ATOM_(atom) \ #define INIT_ATOM_(atom) \
atoms[ATOM_##atom] = XInternAtom(e->dpy, #atom, False); atoms[ATOM_##atom] = XInternAtom(e->dpy, #atom, False);
void win_init(win_t *win) void win_init(win_t *win)
{ {
win_env_t *e; win_env_t *e;
const char *bg, *fg; const char *bg, *fg, *f;
char *res_man;
XrmDatabase db;
memset(win, 0, sizeof(win_t)); memset(win, 0, sizeof(win_t));
@ -152,14 +112,17 @@ void win_init(win_t *win)
if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0) if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0)
error(0, 0, "No locale support"); error(0, 0, "No locale support");
win_init_font(e, BAR_FONT); XrmInitialize();
res_man = XResourceManagerString(e->dpy);
db = res_man != NULL ? XrmGetStringDatabase(res_man) : None;
bg = win_res(e->dpy, RES_CLASS ".background", BG_COLOR); f = win_res(db, RES_CLASS ".font", "monospace-8");
fg = win_res(e->dpy, RES_CLASS ".foreground", FG_COLOR); win_init_font(e, f);
bg = win_res(db, RES_CLASS ".background", "white");
fg = win_res(db, RES_CLASS ".foreground", "black");
win_alloc_color(e, bg, &win->bg); win_alloc_color(e, bg, &win->bg);
win_alloc_color(e, fg, &win->fg); win_alloc_color(e, fg, &win->fg);
win_alloc_color(e, "black", &win->black);
win->light = win_luminance(&win->bg) > win_luminance(&win->fg);
win->bar.l.size = BAR_L_LEN; win->bar.l.size = BAR_L_LEN;
win->bar.r.size = BAR_R_LEN; win->bar.r.size = BAR_R_LEN;
@ -176,9 +139,6 @@ void win_init(win_t *win)
INIT_ATOM_(_NET_WM_ICON); INIT_ATOM_(_NET_WM_ICON);
INIT_ATOM_(_NET_WM_STATE); INIT_ATOM_(_NET_WM_STATE);
INIT_ATOM_(_NET_WM_STATE_FULLSCREEN); INIT_ATOM_(_NET_WM_STATE_FULLSCREEN);
INIT_ATOM_(_NET_SUPPORTED);
win_check_wm_support(e->dpy, RootWindow(e->dpy, e->scr));
} }
void win_open(win_t *win) void win_open(win_t *win)
@ -194,7 +154,6 @@ void win_open(win_t *win)
Pixmap none; Pixmap none;
int gmask; int gmask;
XSizeHints sizehints; XSizeHints sizehints;
Bool fullscreen = options->fullscreen && fs_support;
e = &win->env; e = &win->env;
parent = options->embed != 0 ? options->embed : RootWindow(e->dpy, e->scr); parent = options->embed != 0 ? options->embed : RootWindow(e->dpy, e->scr);
@ -299,14 +258,14 @@ void win_open(win_t *win)
win->buf.h = e->scrh; win->buf.h = e->scrh;
win->buf.pm = XCreatePixmap(e->dpy, win->xwin, win->buf.pm = XCreatePixmap(e->dpy, win->xwin,
win->buf.w, win->buf.h, e->depth); win->buf.w, win->buf.h, e->depth);
XSetForeground(e->dpy, gc, fullscreen ? win->black.pixel : win->bg.pixel); XSetForeground(e->dpy, gc, win->bg.pixel);
XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
XSetWindowBackgroundPixmap(e->dpy, win->xwin, win->buf.pm); XSetWindowBackgroundPixmap(e->dpy, win->xwin, win->buf.pm);
XMapWindow(e->dpy, win->xwin); XMapWindow(e->dpy, win->xwin);
XFlush(e->dpy); XFlush(e->dpy);
if (fullscreen) if (options->fullscreen)
win_toggle_fullscreen(win); win_toggle_fullscreen(win);
} }
@ -343,15 +302,6 @@ void win_toggle_fullscreen(win_t *win)
XEvent ev; XEvent ev;
XClientMessageEvent *cm; XClientMessageEvent *cm;
if (!fs_support) {
if (!fs_warned) {
error(0, 0, "No fullscreen support");
fs_warned = True;
}
return;
}
win->fullscreen = !win->fullscreen;
memset(&ev, 0, sizeof(ev)); memset(&ev, 0, sizeof(ev));
ev.type = ClientMessage; ev.type = ClientMessage;
@ -359,9 +309,8 @@ void win_toggle_fullscreen(win_t *win)
cm->window = win->xwin; cm->window = win->xwin;
cm->message_type = atoms[ATOM__NET_WM_STATE]; cm->message_type = atoms[ATOM__NET_WM_STATE];
cm->format = 32; cm->format = 32;
cm->data.l[0] = win->fullscreen; cm->data.l[0] = 2; // toggle
cm->data.l[1] = atoms[ATOM__NET_WM_STATE_FULLSCREEN]; cm->data.l[1] = atoms[ATOM__NET_WM_STATE_FULLSCREEN];
cm->data.l[2] = cm->data.l[3] = 0;
XSendEvent(win->env.dpy, DefaultRootWindow(win->env.dpy), False, XSendEvent(win->env.dpy, DefaultRootWindow(win->env.dpy), False,
SubstructureNotifyMask | SubstructureRedirectMask, &ev); SubstructureNotifyMask | SubstructureRedirectMask, &ev);
@ -391,7 +340,7 @@ void win_clear(win_t *win)
win->buf.pm = XCreatePixmap(e->dpy, win->xwin, win->buf.pm = XCreatePixmap(e->dpy, win->xwin,
win->buf.w, win->buf.h, e->depth); win->buf.w, win->buf.h, e->depth);
} }
XSetForeground(e->dpy, gc, win->fullscreen ? win->black.pixel : win->bg.pixel); XSetForeground(e->dpy, gc, win->bg.pixel);
XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
} }
@ -438,7 +387,6 @@ void win_draw_bar(win_t *win)
win_env_t *e; win_env_t *e;
win_bar_t *l, *r; win_bar_t *l, *r;
XftDraw *d; XftDraw *d;
const XftColor *bg, *fg;
if ((l = &win->bar.l)->buf == NULL || (r = &win->bar.r)->buf == NULL) if ((l = &win->bar.l)->buf == NULL || (r = &win->bar.r)->buf == NULL)
return; return;
@ -449,28 +397,23 @@ void win_draw_bar(win_t *win)
d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr), d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr),
DefaultColormap(e->dpy, e->scr)); DefaultColormap(e->dpy, e->scr));
if (win->fullscreen && !win->light) XSetForeground(e->dpy, gc, win->fg.pixel);
bg = &win->bg, fg = &win->fg;
else
bg = &win->fg, fg = &win->bg;
XSetForeground(e->dpy, gc, bg->pixel);
XFillRectangle(e->dpy, win->buf.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, fg->pixel); XSetForeground(e->dpy, gc, win->bg.pixel);
XSetBackground(e->dpy, gc, bg->pixel); XSetBackground(e->dpy, gc, win->fg.pixel);
if ((len = strlen(r->buf)) > 0) { if ((len = strlen(r->buf)) > 0) {
if ((tw = TEXTWIDTH(win, r->buf, len)) > w) if ((tw = TEXTWIDTH(win, r->buf, len)) > w)
return; return;
x = win->w - tw - H_TEXT_PAD; x = win->w - tw - H_TEXT_PAD;
w -= tw; w -= tw;
win_draw_text(win, d, fg, x, y, r->buf, len, tw); win_draw_text(win, d, &win->bg, x, y, r->buf, len, tw);
} }
if ((len = strlen(l->buf)) > 0) { if ((len = strlen(l->buf)) > 0) {
x = H_TEXT_PAD; x = H_TEXT_PAD;
w -= 2 * H_TEXT_PAD; /* gap between left and right parts */ w -= 2 * H_TEXT_PAD; /* gap between left and right parts */
win_draw_text(win, d, fg, x, y, l->buf, len, w); win_draw_text(win, d, &win->bg, x, y, l->buf, len, w);
} }
XftDrawDestroy(d); XftDrawDestroy(d);
} }