Compare commits
	
		
			8 Commits
		
	
	
		
			2e7bb36b4a
			...
			39cec0d572
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 39cec0d572 | |||
| 539dfd0bac | |||
| af62c87aa8 | |||
| aa9d16a41b | |||
| 71d1f725b3 | |||
| fb7383d52f | |||
| 3a32e68b82 | |||
| a8d62fe07b | 
							
								
								
									
										55
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								config.def.h
									
									
									
									
									
								
							| @@ -56,6 +56,12 @@ int allowwindowops = 0; | ||||
| static double minlatency = 8; | ||||
| static double maxlatency = 33; | ||||
|  | ||||
| /* | ||||
|  * Synchronized-Update timeout in ms | ||||
|  * https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec | ||||
|  */ | ||||
| static uint su_timeout = 200; | ||||
|  | ||||
| /* | ||||
|  * blinking timeout (set to 0 to disable blinking) for the terminal blinking | ||||
|  * attribute. | ||||
| @@ -93,35 +99,30 @@ char *termname = "st-256color"; | ||||
|  */ | ||||
| unsigned int tabspaces = 8; | ||||
|  | ||||
| /* bg opacity */ | ||||
| float alpha = 0.8; | ||||
|  | ||||
| /* Terminal colors (16 first used in escape sequence) */ | ||||
| static const char *colorname[] = { | ||||
| 	/* 8 normal colors */ | ||||
| 	"black", | ||||
| 	"red3", | ||||
| 	"green3", | ||||
| 	"yellow3", | ||||
| 	"blue2", | ||||
| 	"magenta3", | ||||
| 	"cyan3", | ||||
| 	"gray90", | ||||
| 	[0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ | ||||
| 	[1] = "#cc241d", /* red     */ | ||||
| 	[2] = "#98971a", /* green   */ | ||||
| 	[3] = "#d79921", /* yellow  */ | ||||
| 	[4] = "#458588", /* blue    */ | ||||
| 	[5] = "#b16286", /* magenta */ | ||||
| 	[6] = "#689d6a", /* cyan    */ | ||||
| 	[7] = "#a89984", /* white   */ | ||||
|  | ||||
| 	/* 8 bright colors */ | ||||
| 	"gray50", | ||||
| 	"red", | ||||
| 	"green", | ||||
| 	"yellow", | ||||
| 	"#5c5cff", | ||||
| 	"magenta", | ||||
| 	"cyan", | ||||
| 	"white", | ||||
|  | ||||
| 	[255] = 0, | ||||
|  | ||||
| 	/* more colors can be added after 255 to use with DefaultXX */ | ||||
| 	"#cccccc", | ||||
| 	"#555555", | ||||
| 	"gray90", /* default foreground colour */ | ||||
| 	"black", /* default background colour */ | ||||
| 	[8]  = "#928374", /* black   */ | ||||
| 	[9]  = "#fb4934", /* red     */ | ||||
| 	[10] = "#b8bb26", /* green   */ | ||||
| 	[11] = "#fabd2f", /* yellow  */ | ||||
| 	[12] = "#83a598", /* blue    */ | ||||
| 	[13] = "#d3869b", /* magenta */ | ||||
| 	[14] = "#8ec07c", /* cyan    */ | ||||
| 	[15] = "#ebdbb2", /* white   */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -129,9 +130,9 @@ static const char *colorname[] = { | ||||
|  * Default colors (colorname index) | ||||
|  * foreground, background, cursor, reverse cursor | ||||
|  */ | ||||
| unsigned int defaultfg = 258; | ||||
| unsigned int defaultbg = 259; | ||||
| unsigned int defaultcs = 256; | ||||
| unsigned int defaultfg = 15; | ||||
| unsigned int defaultbg = 0; | ||||
| unsigned int defaultcs = 15; | ||||
| static unsigned int defaultrcs = 257; | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config | ||||
| INCS = -I$(X11INC) \ | ||||
|        `$(PKG_CONFIG) --cflags fontconfig` \ | ||||
|        `$(PKG_CONFIG) --cflags freetype2` | ||||
| LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ | ||||
| LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ | ||||
|        `$(PKG_CONFIG) --libs fontconfig` \ | ||||
|        `$(PKG_CONFIG) --libs freetype2` | ||||
|  | ||||
|   | ||||
							
								
								
									
										48
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								st.c
									
									
									
									
									
								
							| @@ -234,6 +234,33 @@ static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | ||||
| static const Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000}; | ||||
| static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | ||||
|  | ||||
| #include <time.h> | ||||
| static int su = 0; | ||||
| struct timespec sutv; | ||||
|  | ||||
| static void | ||||
| tsync_begin() | ||||
| { | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &sutv); | ||||
| 	su = 1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| tsync_end() | ||||
| { | ||||
| 	su = 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| tinsync(uint timeout) | ||||
| { | ||||
| 	struct timespec now; | ||||
| 	if (su && !clock_gettime(CLOCK_MONOTONIC, &now) | ||||
| 	       && TIMEDIFF(now, sutv) >= timeout) | ||||
| 		su = 0; | ||||
| 	return su; | ||||
| } | ||||
|  | ||||
| ssize_t | ||||
| xwrite(int fd, const char *s, size_t len) | ||||
| { | ||||
| @@ -816,6 +843,9 @@ ttynew(const char *line, char *cmd, const char *out, char **args) | ||||
| 	return cmdfd; | ||||
| } | ||||
|  | ||||
| static int twrite_aborted = 0; | ||||
| int ttyread_pending() { return twrite_aborted; } | ||||
|  | ||||
| size_t | ||||
| ttyread(void) | ||||
| { | ||||
| @@ -824,7 +854,7 @@ ttyread(void) | ||||
| 	int ret, written; | ||||
|  | ||||
| 	/* append read bytes to unprocessed bytes */ | ||||
| 	ret = read(cmdfd, buf+buflen, LEN(buf)-buflen); | ||||
| 	ret = twrite_aborted ? 1 : read(cmdfd, buf+buflen, LEN(buf)-buflen); | ||||
|  | ||||
| 	switch (ret) { | ||||
| 	case 0: | ||||
| @@ -832,7 +862,7 @@ ttyread(void) | ||||
| 	case -1: | ||||
| 		die("couldn't read from shell: %s\n", strerror(errno)); | ||||
| 	default: | ||||
| 		buflen += ret; | ||||
| 		buflen += twrite_aborted ? 0 : ret; | ||||
| 		written = twrite(buf, buflen, 0); | ||||
| 		buflen -= written; | ||||
| 		/* keep any incomplete UTF-8 byte sequence for the next call */ | ||||
| @@ -992,6 +1022,7 @@ tsetdirtattr(int attr) | ||||
| void | ||||
| tfulldirt(void) | ||||
| { | ||||
| 	tsync_end(); | ||||
| 	tsetdirt(0, term.row-1); | ||||
| } | ||||
|  | ||||
| @@ -1962,6 +1993,12 @@ strhandle(void) | ||||
| 		xsettitle(strescseq.buf); | ||||
| 		return; | ||||
| 	case 'P': /* DCS -- Device Control String */ | ||||
| 		/* https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec */ | ||||
| 		if (strstr(strescseq.buf, "=1s") == strescseq.buf) | ||||
| 			tsync_begin();  /* BSU */ | ||||
| 		else if (strstr(strescseq.buf, "=2s") == strescseq.buf) | ||||
| 			tsync_end();  /* ESU */ | ||||
| 		return; | ||||
| 	case '_': /* APC -- Application Program Command */ | ||||
| 	case '^': /* PM -- Privacy Message */ | ||||
| 		return; | ||||
| @@ -2509,6 +2546,9 @@ twrite(const char *buf, int buflen, int show_ctrl) | ||||
| 	Rune u; | ||||
| 	int n; | ||||
|  | ||||
| 	int su0 = su; | ||||
| 	twrite_aborted = 0; | ||||
|  | ||||
| 	for (n = 0; n < buflen; n += charsize) { | ||||
| 		if (IS_SET(MODE_UTF8)) { | ||||
| 			/* process a complete utf8 char */ | ||||
| @@ -2519,6 +2559,10 @@ twrite(const char *buf, int buflen, int show_ctrl) | ||||
| 			u = buf[n] & 0xFF; | ||||
| 			charsize = 1; | ||||
| 		} | ||||
| 		if (su0 && !su) { | ||||
| 			twrite_aborted = 1; | ||||
| 			break;  // ESU - allow rendering before a new BSU | ||||
| 		} | ||||
| 		if (show_ctrl && ISCONTROL(u)) { | ||||
| 			if (u & 0x80) { | ||||
| 				u &= 0x7f; | ||||
|   | ||||
							
								
								
									
										1
									
								
								st.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								st.h
									
									
									
									
									
								
							| @@ -124,3 +124,4 @@ extern unsigned int tabspaces; | ||||
| extern unsigned int defaultfg; | ||||
| extern unsigned int defaultbg; | ||||
| extern unsigned int defaultcs; | ||||
| extern float alpha; | ||||
|   | ||||
							
								
								
									
										1
									
								
								st.info
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								st.info
									
									
									
									
									
								
							| @@ -191,6 +191,7 @@ st-mono| simpleterm monocolor, | ||||
| 	Ms=\E]52;%p1%s;%p2%s\007, | ||||
| 	Se=\E[2 q, | ||||
| 	Ss=\E[%p1%d q, | ||||
| 	Sync=\EP=%p1%ds\E\\, | ||||
|  | ||||
| st| simpleterm, | ||||
| 	use=st-mono, | ||||
|   | ||||
							
								
								
									
										145
									
								
								x.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								x.c
									
									
									
									
									
								
							| @@ -81,6 +81,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 mode; /* window state/mode flags */ | ||||
| @@ -105,6 +106,7 @@ typedef struct { | ||||
| 	XSetWindowAttributes attrs; | ||||
| 	int scr; | ||||
| 	int isfixed; /* is fixed geometry? */ | ||||
| 	int depth; /* bit depth */ | ||||
| 	int l, t; /* left and top offset */ | ||||
| 	int gm; /* geometry mask */ | ||||
| } XWindow; | ||||
| @@ -243,6 +245,7 @@ static char *usedfont = NULL; | ||||
| static double usedfontsize = 0; | ||||
| static double defaultfontsize = 0; | ||||
|  | ||||
| static char *opt_alpha = NULL; | ||||
| static char *opt_class = NULL; | ||||
| static char **opt_cmd  = NULL; | ||||
| static char *opt_embed = NULL; | ||||
| @@ -331,7 +334,7 @@ ttysend(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; | ||||
| } | ||||
| @@ -339,7 +342,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; | ||||
| } | ||||
| @@ -686,6 +689,8 @@ setsel(char *str, Time t) | ||||
| 	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); | ||||
| 	if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) | ||||
| 		selclear(); | ||||
|  | ||||
| 	xclipcopy(); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -709,7 +714,9 @@ brelease(XEvent *e) | ||||
|  | ||||
| 	if (mouseaction(e, 1)) | ||||
| 		return; | ||||
| 	if (btn == Button1) | ||||
| 	if (btn == Button3) | ||||
| 		selpaste(NULL); | ||||
| 	else if (btn == Button1) | ||||
| 		mousesel(e, 1); | ||||
| } | ||||
|  | ||||
| @@ -739,6 +746,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); | ||||
| @@ -752,7 +762,7 @@ xresize(int col, int row) | ||||
|  | ||||
| 	XFreePixmap(xw.dpy, xw.buf); | ||||
| 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | ||||
| 			DefaultDepth(xw.dpy, xw.scr)); | ||||
| 			xw.depth); | ||||
| 	XftDrawChange(xw.draw, xw.buf); | ||||
| 	xclear(0, 0, win.w, win.h); | ||||
|  | ||||
| @@ -812,6 +822,13 @@ xloadcols(void) | ||||
| 			else | ||||
| 				die("could not allocate color %d\n", i); | ||||
| 		} | ||||
|  | ||||
| 	/* 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; | ||||
| 	loaded = 1; | ||||
| } | ||||
|  | ||||
| @@ -869,8 +886,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; | ||||
| @@ -1134,11 +1151,23 @@ xinit(int cols, int rows) | ||||
| 	Window parent; | ||||
| 	pid_t thispid = getpid(); | ||||
| 	XColor xmousefg, xmousebg; | ||||
| 	XWindowAttributes attr; | ||||
| 	XVisualInfo vis; | ||||
|  | ||||
| 	if (!(xw.dpy = XOpenDisplay(NULL))) | ||||
| 		die("can't open display\n"); | ||||
| 	xw.scr = XDefaultScreen(xw.dpy); | ||||
| 	xw.vis = XDefaultVisual(xw.dpy, xw.scr); | ||||
|  | ||||
| 	if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { | ||||
| 		parent = XRootWindow(xw.dpy, xw.scr); | ||||
| 		xw.depth = 32; | ||||
| 	} else { | ||||
| 		XGetWindowAttributes(xw.dpy, parent, &attr); | ||||
| 		xw.depth = attr.depth; | ||||
| 	} | ||||
|  | ||||
| 	XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); | ||||
| 	xw.vis = vis.visual; | ||||
|  | ||||
| 	/* font */ | ||||
| 	if (!FcInit()) | ||||
| @@ -1148,12 +1177,12 @@ xinit(int cols, int rows) | ||||
| 	xloadfonts(usedfont, 0); | ||||
|  | ||||
| 	/* colors */ | ||||
| 	xw.cmap = XDefaultColormap(xw.dpy, xw.scr); | ||||
| 	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 + 2 * borderpx + cols * win.cw; | ||||
| 	win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; | ||||
| 	if (xw.gm & XNegative) | ||||
| 		xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; | ||||
| 	if (xw.gm & YNegative) | ||||
| @@ -1168,19 +1197,15 @@ xinit(int cols, int rows) | ||||
| 		| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | ||||
| 	xw.attrs.colormap = xw.cmap; | ||||
|  | ||||
| 	if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) | ||||
| 		parent = XRootWindow(xw.dpy, xw.scr); | ||||
| 	xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, | ||||
| 			win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, | ||||
| 			win.w, win.h, 0, xw.depth, InputOutput, | ||||
| 			xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | ||||
| 			| CWEventMask | CWColormap, &xw.attrs); | ||||
|  | ||||
| 	memset(&gcvalues, 0, sizeof(gcvalues)); | ||||
| 	gcvalues.graphics_exposures = False; | ||||
| 	dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, | ||||
| 			&gcvalues); | ||||
| 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | ||||
| 			DefaultDepth(xw.dpy, xw.scr)); | ||||
| 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); | ||||
| 	dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); | ||||
| 	XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); | ||||
| 	XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); | ||||
|  | ||||
| @@ -1242,7 +1267,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; | ||||
| @@ -1375,7 +1400,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; | ||||
| @@ -1412,10 +1437,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i | ||||
| 		bg = &dc.col[base.bg]; | ||||
| 	} | ||||
|  | ||||
| 	/* Change basic system colors [0-7] to bright system colors [8-15] */ | ||||
| 	if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) | ||||
| 		fg = &dc.col[base.fg + 8]; | ||||
|  | ||||
| 	if (IS_SET(MODE_REVERSE)) { | ||||
| 		if (fg == &dc.col[defaultfg]) { | ||||
| 			fg = &dc.col[defaultbg]; | ||||
| @@ -1465,17 +1486,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.hborderpx, | ||||
| 			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.vborderpx); | ||||
| 	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. */ | ||||
| @@ -1520,6 +1541,7 @@ void | ||||
| xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) | ||||
| { | ||||
| 	Color drawcol; | ||||
| 	XRenderColor colbg; | ||||
|  | ||||
| 	/* remove the old cursor */ | ||||
| 	if (selected(ox, oy)) | ||||
| @@ -1548,12 +1570,22 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) | ||||
| 		if (selected(cx, cy)) { | ||||
| 			g.fg = defaultfg; | ||||
| 			g.bg = defaultrcs; | ||||
| 		} else { | ||||
| 			g.fg = defaultbg; | ||||
| 			g.bg = defaultcs; | ||||
| 		} else if (!(og.mode & ATTR_REVERSE)) { | ||||
| 			unsigned long col = g.bg; | ||||
| 			g.bg = g.fg; | ||||
| 			g.fg = col; | ||||
| 		} | ||||
|  | ||||
| 		if (IS_TRUECOL(g.bg)) { | ||||
| 			colbg.alpha = 0xffff; | ||||
| 			colbg.red = TRUERED(g.bg); | ||||
| 			colbg.green = TRUEGREEN(g.bg); | ||||
| 			colbg.blue = TRUEBLUE(g.bg); | ||||
| 			XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &drawcol); | ||||
| 		} else { | ||||
| 			drawcol = dc.col[g.bg]; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* draw the new one */ | ||||
| 	if (IS_SET(MODE_FOCUSED)) { | ||||
| @@ -1569,35 +1601,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); | ||||
| 	} | ||||
| } | ||||
| @@ -1911,6 +1943,9 @@ resize(XEvent *e) | ||||
| 	cresize(e->xconfigure.width, e->xconfigure.height); | ||||
| } | ||||
|  | ||||
| int tinsync(uint); | ||||
| int ttyread_pending(); | ||||
|  | ||||
| void | ||||
| run(void) | ||||
| { | ||||
| @@ -1945,7 +1980,7 @@ run(void) | ||||
| 		FD_SET(ttyfd, &rfd); | ||||
| 		FD_SET(xfd, &rfd); | ||||
|  | ||||
| 		if (XPending(xw.dpy)) | ||||
| 		if (XPending(xw.dpy) || ttyread_pending()) | ||||
| 			timeout = 0;  /* existing events might not set xfd */ | ||||
|  | ||||
| 		seltv.tv_sec = timeout / 1E3; | ||||
| @@ -1959,7 +1994,8 @@ run(void) | ||||
| 		} | ||||
| 		clock_gettime(CLOCK_MONOTONIC, &now); | ||||
|  | ||||
| 		if (FD_ISSET(ttyfd, &rfd)) | ||||
| 		int ttyin = FD_ISSET(ttyfd, &rfd) || ttyread_pending(); | ||||
| 		if (ttyin) | ||||
| 			ttyread(); | ||||
|  | ||||
| 		xev = 0; | ||||
| @@ -1983,7 +2019,7 @@ run(void) | ||||
| 		 * maximum latency intervals during `cat huge.txt`, and perfect | ||||
| 		 * sync with periodic updates from animations/key-repeats/etc. | ||||
| 		 */ | ||||
| 		if (FD_ISSET(ttyfd, &rfd) || xev) { | ||||
| 		if (ttyin || xev) { | ||||
| 			if (!drawing) { | ||||
| 				trigger = now; | ||||
| 				drawing = 1; | ||||
| @@ -1994,6 +2030,18 @@ run(void) | ||||
| 				continue;  /* we have time, try to find idle */ | ||||
| 		} | ||||
|  | ||||
| 		if (tinsync(su_timeout)) { | ||||
| 			/* | ||||
| 			 * on synchronized-update draw-suspension: don't reset | ||||
| 			 * drawing so that we draw ASAP once we can (just after | ||||
| 			 * ESU). it won't be too soon because we already can | ||||
| 			 * draw now but we skip. we set timeout > 0 to draw on | ||||
| 			 * SU-timeout even without new content. | ||||
| 			 */ | ||||
| 			timeout = minlatency; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		/* idle detected or maxlatency exhausted -> draw */ | ||||
| 		timeout = -1; | ||||
| 		if (blinktimeout && tattrset(ATTR_BLINK)) { | ||||
| @@ -2038,6 +2086,9 @@ main(int argc, char *argv[]) | ||||
| 	case 'a': | ||||
| 		allowaltscreen = 0; | ||||
| 		break; | ||||
| 	case 'A': | ||||
| 		opt_alpha = EARGF(usage()); | ||||
| 		break; | ||||
| 	case 'c': | ||||
| 		opt_class = EARGF(usage()); | ||||
| 		break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user