diff options
-rw-r--r-- | .Xdefaults | 5 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | config.h | 30 | ||||
-rwxr-xr-x | st-copyout | 4 | ||||
-rw-r--r-- | x.c | 169 |
5 files changed, 172 insertions, 45 deletions
@@ -7,6 +7,11 @@ st.font: Monospace-11; ! st.termname: st-256color ! st.borderpx: 2 +!! Set the background, foreground and cursor colors as below: +*.background: #282828 +*.foreground: white +*.cursorColor: white + /* !! gruvbox: */ /* *.color0: #1d2021 */ /* *.color1: #cc241d */ @@ -20,12 +20,13 @@ The [suckless terminal (st)](https://st.suckless.org/) with some additional feat + Compatibility with `Xresources` and `pywal` for dynamic colors. The `Xdefaults` file shows a usage example. + Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise. + Transparency/alpha, which is also adjustable from your `Xresources`. -+ Default font is system "mono" at 16pt, meaning the font will match your system font. ++ Default font is system "mono" at 14pt, meaning the font will match your system font. ## Other st patches + Vertcenter + Scrollback ++ font2 + updated to latest version 0.8.2 ## Installation for newbs @@ -69,6 +70,12 @@ To be clear about the color settings: Note that when you run `wal`, it will negate the transparency of existing windows, but new windows will continue with the previously defined transparency. +## Notes on Emojis and Special Characters + +If st crashes when viewing emojis, install [libxft-bgra](https://aur.archlinux.org/packages/libxft-bgra/) from the AUR. + +Note that some special characters may appear truncated if too wide. You might want to manually set your prefered emoji/special character font to a lower size in the `config.h` file to avoid this. By default, JoyPixels is used at a smaller size than the usual text. + ## Contact - Luke Smith <luke@lukesmith.xyz> @@ -5,7 +5,8 @@ * * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ -static char *font = "mono:pixelsize=16:antialias=true:autohint=true"; +static char *font = "mono:pixelsize=14:antialias=true:autohint=true"; +static char *font2[] = { "JoyPixels:pixelsize=10:antialias=true:autohint=true" }; static int borderpx = 2; /* @@ -112,9 +113,10 @@ static const char *colorname[] = { "#ebdbb2", [255] = 0, /* more colors can be added after 255 to use with DefaultXX */ - "#282828", /* 256 -> bg */ - "#ebdbb2", /* 257 -> fg */ - "#add8e6", /* 258 -> cursor */ + "#add8e6", /* 256 -> cursor */ + "#555555", /* 257 -> rev cursor*/ + "#282828", /* 258 -> bg */ + "#ebdbb2", /* 259 -> fg */ }; @@ -122,10 +124,10 @@ static const char *colorname[] = { * Default colors (colorname index) * foreground, background, cursor, reverse cursor */ -unsigned int defaultfg = 257; -unsigned int defaultbg = 256; -static unsigned int defaultcs = 258; -static unsigned int defaultrcs = 0; +unsigned int defaultfg = 259; +unsigned int defaultbg = 258; +static unsigned int defaultcs = 256; +static unsigned int defaultrcs = 257; /* * Default shape of cursor @@ -161,6 +163,7 @@ static unsigned int defaultattr = 11; */ ResourcePref resources[] = { { "font", STRING, &font }, + { "fontalt0", STRING, &font2[0] }, { "color0", STRING, &colorname[0] }, { "color1", STRING, &colorname[1] }, { "color2", STRING, &colorname[2] }, @@ -177,9 +180,9 @@ ResourcePref resources[] = { { "color13", STRING, &colorname[13] }, { "color14", STRING, &colorname[14] }, { "color15", STRING, &colorname[15] }, - { "background", STRING, &colorname[256] }, - { "foreground", STRING, &colorname[257] }, - { "cursorColor", STRING, &colorname[258] }, + { "background", STRING, &colorname[258] }, + { "foreground", STRING, &colorname[259] }, + { "cursorColor", STRING, &colorname[256] }, { "termname", STRING, &termname }, { "shell", STRING, &shell }, { "xfps", INTEGER, &xfps }, @@ -219,11 +222,11 @@ MouseKey mkeys[] = { }; static char *openurlcmd[] = { "/bin/sh", "-c", - "sed 's/.*│//g' | tr -d '\n' | grep -aEo '((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?=_-]*' | uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -p 'Follow which url?' -l 10 | xargs -r xdg-open", + "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)'| uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Follow which url?' -l 10 | xargs -r xdg-open", "externalpipe", NULL }; static char *copyurlcmd[] = { "/bin/sh", "-c", - "sed 's/.*│//g' | tr -d '\n' | grep -aEo '((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?=_-]*' | uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard", + "sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)' | uniq | sed 's/^www./http:\\/\\/www\\./g' | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard", "externalpipe", NULL }; static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL }; @@ -241,6 +244,7 @@ static Shortcut shortcuts[] = { { MODKEY, XK_c, clipcopy, {.i = 0} }, { MODKEY, XK_v, clippaste, {.i = 0} }, { MODKEY, XK_p, selpaste, {.i = 0} }, + { XK_ANY_MOD, Button2, selpaste, {.i = 0} }, { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, { MODKEY, XK_Control_L, iso14755, {.i = 0} }, { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, @@ -6,7 +6,7 @@ tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX) trap 'rm "$tmpfile"' 0 1 15 sed -n "w $tmpfile" -ps1="$(grep "\S" "$tmpfile" | tail -n 1 | cut -d' ' -f1)" +ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)" chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')" eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')" -awk "/^$chosen$/{p=1;print;next} p&&/^$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard +awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard @@ -92,6 +92,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; typedef struct { int tw, th; /* tty width and height */ int w, h; /* window width and height */ + int hborderpx, vborderpx; int ch; /* char height */ int cw; /* char width */ int cyo; /* char y offset */ @@ -165,6 +166,8 @@ static void xhints(void); static int xloadcolor(int, const char *, Color *); static int xloadfont(Font *, FcPattern *); static void xloadfonts(char *, double); +static int xloadsparefont(FcPattern *, int); +static void xloadsparefonts(void); static void xunloadfont(Font *); static void xunloadfonts(void); static void xsetenv(void); @@ -313,6 +316,7 @@ zoomabs(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, arg->f); + xloadsparefonts(); cresize(0, 0); redraw(); xhints(); @@ -332,7 +336,7 @@ zoomreset(const Arg *arg) int evcol(XEvent *e) { - int x = e->xbutton.x - borderpx; + int x = e->xbutton.x - win.hborderpx; LIMIT(x, 0, win.tw - 1); return x / win.cw; } @@ -340,7 +344,7 @@ evcol(XEvent *e) int evrow(XEvent *e) { - int y = e->xbutton.y - borderpx; + int y = e->xbutton.y - win.vborderpx; LIMIT(y, 0, win.th - 1); return y / win.ch; } @@ -707,6 +711,9 @@ cresize(int width, int height) col = MAX(1, col); row = MAX(1, row); + win.hborderpx = (win.w - col * win.cw) / 2; + win.vborderpx = (win.h - row * win.ch) / 2; + tresize(col, row); xresize(col, row); ttyresize(win.tw, win.th); @@ -784,9 +791,15 @@ xloadcols(void) /* set alpha value of bg color */ if (opt_alpha) alpha = strtof(opt_alpha, NULL); - dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); - dc.col[defaultbg].pixel &= 0x00FFFFFF; - dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); + dc.col[defaultbg].color.red = + ((unsigned short)(dc.col[defaultbg].color.red * alpha)) & 0xff00; + dc.col[defaultbg].color.green = + ((unsigned short)(dc.col[defaultbg].color.green * alpha)) & 0xff00; + dc.col[defaultbg].color.blue = + ((unsigned short)(dc.col[defaultbg].color.blue * alpha)) & 0xff00; + dc.col[defaultbg].pixel &= 0x00FFFFFF; + dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; loaded = 1; } @@ -831,8 +844,8 @@ xhints(void) sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; sizeh->height = win.h; sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; + sizeh->height_inc = 1; + sizeh->width_inc = 1; sizeh->base_height = 2 * borderpx; sizeh->base_width = 2 * borderpx; sizeh->min_height = win.ch + 2 * borderpx; @@ -1013,6 +1026,101 @@ xloadfonts(char *fontstr, double fontsize) FcPatternDestroy(pattern); } +int +xloadsparefont(FcPattern *pattern, int flags) +{ + FcPattern *match; + FcResult result; + + match = FcFontMatch(NULL, pattern, &result); + if (!match) { + return 1; + } + + if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { + FcPatternDestroy(match); + return 1; + } + + frc[frclen].flags = flags; + /* Believe U+0000 glyph will present in each default font */ + frc[frclen].unicodep = 0; + frclen++; + + return 0; +} + +void +xloadsparefonts(void) +{ + FcPattern *pattern; + double sizeshift, fontval; + int fc; + char **fp; + + if (frclen != 0) + die("can't embed spare fonts. cache isn't empty"); + + /* Calculate count of spare fonts */ + fc = sizeof(font2) / sizeof(*font2); + if (fc == 0) + return; + + /* Allocate memory for cache entries. */ + if (frccap < 4 * fc) { + frccap += 4 * fc - frccap; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } + + for (fp = font2; fp - font2 < fc; ++fp) { + + if (**fp == '-') + pattern = XftXlfdParse(*fp, False, False); + else + pattern = FcNameParse((FcChar8 *)*fp); + + if (!pattern) + die("can't open spare font %s\n", *fp); + + if (defaultfontsize > 0) { + sizeshift = usedfontsize - defaultfontsize; + if (sizeshift != 0 && + FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == + FcResultMatch) { + fontval += sizeshift; + FcPatternDel(pattern, FC_PIXEL_SIZE); + FcPatternDel(pattern, FC_SIZE); + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); + } + } + + FcPatternAddBool(pattern, FC_SCALABLE, 1); + + FcConfigSubstitute(NULL, pattern, FcMatchPattern); + XftDefaultSubstitute(xw.dpy, xw.scr, pattern); + + if (xloadsparefont(pattern, FRC_NORMAL)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + if (xloadsparefont(pattern, FRC_ITALIC)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_WEIGHT); + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (xloadsparefont(pattern, FRC_ITALICBOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDel(pattern, FC_SLANT); + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); + if (xloadsparefont(pattern, FRC_BOLD)) + die("can't open spare font %s\n", *fp); + + FcPatternDestroy(pattern); + } +} + void xunloadfont(Font *f) { @@ -1103,13 +1211,16 @@ xinit(int cols, int rows) usedfont = (opt_font == NULL)? font : opt_font; xloadfonts(usedfont, 0); + /* spare fonts */ + xloadsparefonts(); + /* colors */ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); xloadcols(); /* adjust fixed window geometry */ - win.w = 2 * borderpx + cols * win.cw; - win.h = 2 * borderpx + rows * win.ch; + win.w = 2 * win.hborderpx + cols * win.cw; + win.h = 2 * win.vborderpx + rows * win.ch; if (xw.gm & XNegative) xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; if (xw.gm & YNegative) @@ -1190,7 +1301,7 @@ xinit(int cols, int rows) int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { - float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; + float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; ushort mode, prevmode = USHRT_MAX; Font *font = &dc.font; int frcflags = FRC_NORMAL; @@ -1323,7 +1434,7 @@ void xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) { int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, width = charlen * win.cw; Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; XRenderColor colfg, colbg; @@ -1409,17 +1520,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i /* Intelligent cleaning up of the borders. */ if (x == 0) { - xclear(0, (y == 0)? 0 : winy, borderpx, + xclear(0, (y == 0)? 0 : winy, win.vborderpx, winy + win.ch + - ((winy + win.ch >= borderpx + win.th)? win.h : 0)); + ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); } - if (winx + width >= borderpx + win.tw) { + if (winx + width >= win.hborderpx + win.tw) { xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); + ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); } if (y == 0) - xclear(winx, 0, winx + width, borderpx); - if (winy + win.ch >= borderpx + win.th) + xclear(winx, 0, winx + width, win.hborderpx); + if (winy + win.ch >= win.vborderpx + win.th) xclear(winx, winy + win.ch, winx + width, win.h); /* Clean up the region we want to draw to. */ @@ -1512,35 +1623,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) case 3: /* Blinking Underline */ case 4: /* Steady Underline */ XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - \ cursorthickness, win.cw, cursorthickness); break; case 5: /* Blinking bar */ case 6: /* Steady bar */ XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, cursorthickness, win.ch); break; } } else { XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, win.cw - 1, 1); XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, + win.hborderpx + cx * win.cw, + win.vborderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, + win.hborderpx + (cx + 1) * win.cw - 1, + win.vborderpx + cy * win.ch, 1, win.ch - 1); XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, + win.hborderpx + cx * win.cw, + win.vborderpx + (cy + 1) * win.ch - 1, win.cw, 1); } } |