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 minlatency = 8; | ||||||
| static double maxlatency = 33; | 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 |  * blinking timeout (set to 0 to disable blinking) for the terminal blinking | ||||||
|  * attribute. |  * attribute. | ||||||
| @@ -93,35 +99,30 @@ char *termname = "st-256color"; | |||||||
|  */ |  */ | ||||||
| unsigned int tabspaces = 8; | unsigned int tabspaces = 8; | ||||||
|  |  | ||||||
|  | /* bg opacity */ | ||||||
|  | float alpha = 0.8; | ||||||
|  |  | ||||||
| /* Terminal colors (16 first used in escape sequence) */ | /* Terminal colors (16 first used in escape sequence) */ | ||||||
| static const char *colorname[] = { | static const char *colorname[] = { | ||||||
| 	/* 8 normal colors */ | 	/* 8 normal colors */ | ||||||
| 	"black", | 	[0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ | ||||||
| 	"red3", | 	[1] = "#cc241d", /* red     */ | ||||||
| 	"green3", | 	[2] = "#98971a", /* green   */ | ||||||
| 	"yellow3", | 	[3] = "#d79921", /* yellow  */ | ||||||
| 	"blue2", | 	[4] = "#458588", /* blue    */ | ||||||
| 	"magenta3", | 	[5] = "#b16286", /* magenta */ | ||||||
| 	"cyan3", | 	[6] = "#689d6a", /* cyan    */ | ||||||
| 	"gray90", | 	[7] = "#a89984", /* white   */ | ||||||
|  |  | ||||||
| 	/* 8 bright colors */ | 	/* 8 bright colors */ | ||||||
| 	"gray50", | 	[8]  = "#928374", /* black   */ | ||||||
| 	"red", | 	[9]  = "#fb4934", /* red     */ | ||||||
| 	"green", | 	[10] = "#b8bb26", /* green   */ | ||||||
| 	"yellow", | 	[11] = "#fabd2f", /* yellow  */ | ||||||
| 	"#5c5cff", | 	[12] = "#83a598", /* blue    */ | ||||||
| 	"magenta", | 	[13] = "#d3869b", /* magenta */ | ||||||
| 	"cyan", | 	[14] = "#8ec07c", /* cyan    */ | ||||||
| 	"white", | 	[15] = "#ebdbb2", /* white   */ | ||||||
|  |  | ||||||
| 	[255] = 0, |  | ||||||
|  |  | ||||||
| 	/* more colors can be added after 255 to use with DefaultXX */ |  | ||||||
| 	"#cccccc", |  | ||||||
| 	"#555555", |  | ||||||
| 	"gray90", /* default foreground colour */ |  | ||||||
| 	"black", /* default background colour */ |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -129,9 +130,9 @@ static const char *colorname[] = { | |||||||
|  * Default colors (colorname index) |  * Default colors (colorname index) | ||||||
|  * foreground, background, cursor, reverse cursor |  * foreground, background, cursor, reverse cursor | ||||||
|  */ |  */ | ||||||
| unsigned int defaultfg = 258; | unsigned int defaultfg = 15; | ||||||
| unsigned int defaultbg = 259; | unsigned int defaultbg = 0; | ||||||
| unsigned int defaultcs = 256; | unsigned int defaultcs = 15; | ||||||
| static unsigned int defaultrcs = 257; | static unsigned int defaultrcs = 257; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config | |||||||
| INCS = -I$(X11INC) \ | INCS = -I$(X11INC) \ | ||||||
|        `$(PKG_CONFIG) --cflags fontconfig` \ |        `$(PKG_CONFIG) --cflags fontconfig` \ | ||||||
|        `$(PKG_CONFIG) --cflags freetype2` |        `$(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 fontconfig` \ | ||||||
|        `$(PKG_CONFIG) --libs freetype2` |        `$(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 utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000}; | ||||||
| static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | 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 | ssize_t | ||||||
| xwrite(int fd, const char *s, size_t len) | 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; | 	return cmdfd; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int twrite_aborted = 0; | ||||||
|  | int ttyread_pending() { return twrite_aborted; } | ||||||
|  |  | ||||||
| size_t | size_t | ||||||
| ttyread(void) | ttyread(void) | ||||||
| { | { | ||||||
| @@ -824,7 +854,7 @@ ttyread(void) | |||||||
| 	int ret, written; | 	int ret, written; | ||||||
|  |  | ||||||
| 	/* append read bytes to unprocessed bytes */ | 	/* 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) { | 	switch (ret) { | ||||||
| 	case 0: | 	case 0: | ||||||
| @@ -832,7 +862,7 @@ ttyread(void) | |||||||
| 	case -1: | 	case -1: | ||||||
| 		die("couldn't read from shell: %s\n", strerror(errno)); | 		die("couldn't read from shell: %s\n", strerror(errno)); | ||||||
| 	default: | 	default: | ||||||
| 		buflen += ret; | 		buflen += twrite_aborted ? 0 : ret; | ||||||
| 		written = twrite(buf, buflen, 0); | 		written = twrite(buf, buflen, 0); | ||||||
| 		buflen -= written; | 		buflen -= written; | ||||||
| 		/* keep any incomplete UTF-8 byte sequence for the next call */ | 		/* keep any incomplete UTF-8 byte sequence for the next call */ | ||||||
| @@ -992,6 +1022,7 @@ tsetdirtattr(int attr) | |||||||
| void | void | ||||||
| tfulldirt(void) | tfulldirt(void) | ||||||
| { | { | ||||||
|  | 	tsync_end(); | ||||||
| 	tsetdirt(0, term.row-1); | 	tsetdirt(0, term.row-1); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1962,6 +1993,12 @@ strhandle(void) | |||||||
| 		xsettitle(strescseq.buf); | 		xsettitle(strescseq.buf); | ||||||
| 		return; | 		return; | ||||||
| 	case 'P': /* DCS -- Device Control String */ | 	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 '_': /* APC -- Application Program Command */ | ||||||
| 	case '^': /* PM -- Privacy Message */ | 	case '^': /* PM -- Privacy Message */ | ||||||
| 		return; | 		return; | ||||||
| @@ -2509,6 +2546,9 @@ twrite(const char *buf, int buflen, int show_ctrl) | |||||||
| 	Rune u; | 	Rune u; | ||||||
| 	int n; | 	int n; | ||||||
|  |  | ||||||
|  | 	int su0 = su; | ||||||
|  | 	twrite_aborted = 0; | ||||||
|  |  | ||||||
| 	for (n = 0; n < buflen; n += charsize) { | 	for (n = 0; n < buflen; n += charsize) { | ||||||
| 		if (IS_SET(MODE_UTF8)) { | 		if (IS_SET(MODE_UTF8)) { | ||||||
| 			/* process a complete utf8 char */ | 			/* process a complete utf8 char */ | ||||||
| @@ -2519,6 +2559,10 @@ twrite(const char *buf, int buflen, int show_ctrl) | |||||||
| 			u = buf[n] & 0xFF; | 			u = buf[n] & 0xFF; | ||||||
| 			charsize = 1; | 			charsize = 1; | ||||||
| 		} | 		} | ||||||
|  | 		if (su0 && !su) { | ||||||
|  | 			twrite_aborted = 1; | ||||||
|  | 			break;  // ESU - allow rendering before a new BSU | ||||||
|  | 		} | ||||||
| 		if (show_ctrl && ISCONTROL(u)) { | 		if (show_ctrl && ISCONTROL(u)) { | ||||||
| 			if (u & 0x80) { | 			if (u & 0x80) { | ||||||
| 				u &= 0x7f; | 				u &= 0x7f; | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								st.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								st.h
									
									
									
									
									
								
							| @@ -124,3 +124,4 @@ extern unsigned int tabspaces; | |||||||
| extern unsigned int defaultfg; | extern unsigned int defaultfg; | ||||||
| extern unsigned int defaultbg; | extern unsigned int defaultbg; | ||||||
| extern unsigned int defaultcs; | 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, | 	Ms=\E]52;%p1%s;%p2%s\007, | ||||||
| 	Se=\E[2 q, | 	Se=\E[2 q, | ||||||
| 	Ss=\E[%p1%d q, | 	Ss=\E[%p1%d q, | ||||||
|  | 	Sync=\EP=%p1%ds\E\\, | ||||||
|  |  | ||||||
| st| simpleterm, | st| simpleterm, | ||||||
| 	use=st-mono, | 	use=st-mono, | ||||||
|   | |||||||
							
								
								
									
										147
									
								
								x.c
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								x.c
									
									
									
									
									
								
							| @@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; | |||||||
| typedef struct { | typedef struct { | ||||||
| 	int tw, th; /* tty width and height */ | 	int tw, th; /* tty width and height */ | ||||||
| 	int w, h; /* window width and height */ | 	int w, h; /* window width and height */ | ||||||
|  | 	int hborderpx, vborderpx; | ||||||
| 	int ch; /* char height */ | 	int ch; /* char height */ | ||||||
| 	int cw; /* char width  */ | 	int cw; /* char width  */ | ||||||
| 	int mode; /* window state/mode flags */ | 	int mode; /* window state/mode flags */ | ||||||
| @@ -105,6 +106,7 @@ typedef struct { | |||||||
| 	XSetWindowAttributes attrs; | 	XSetWindowAttributes attrs; | ||||||
| 	int scr; | 	int scr; | ||||||
| 	int isfixed; /* is fixed geometry? */ | 	int isfixed; /* is fixed geometry? */ | ||||||
|  | 	int depth; /* bit depth */ | ||||||
| 	int l, t; /* left and top offset */ | 	int l, t; /* left and top offset */ | ||||||
| 	int gm; /* geometry mask */ | 	int gm; /* geometry mask */ | ||||||
| } XWindow; | } XWindow; | ||||||
| @@ -243,6 +245,7 @@ static char *usedfont = NULL; | |||||||
| static double usedfontsize = 0; | static double usedfontsize = 0; | ||||||
| static double defaultfontsize = 0; | static double defaultfontsize = 0; | ||||||
|  |  | ||||||
|  | static char *opt_alpha = NULL; | ||||||
| static char *opt_class = NULL; | static char *opt_class = NULL; | ||||||
| static char **opt_cmd  = NULL; | static char **opt_cmd  = NULL; | ||||||
| static char *opt_embed = NULL; | static char *opt_embed = NULL; | ||||||
| @@ -331,7 +334,7 @@ ttysend(const Arg *arg) | |||||||
| int | int | ||||||
| evcol(XEvent *e) | evcol(XEvent *e) | ||||||
| { | { | ||||||
| 	int x = e->xbutton.x - borderpx; | 	int x = e->xbutton.x - win.hborderpx; | ||||||
| 	LIMIT(x, 0, win.tw - 1); | 	LIMIT(x, 0, win.tw - 1); | ||||||
| 	return x / win.cw; | 	return x / win.cw; | ||||||
| } | } | ||||||
| @@ -339,7 +342,7 @@ evcol(XEvent *e) | |||||||
| int | int | ||||||
| evrow(XEvent *e) | evrow(XEvent *e) | ||||||
| { | { | ||||||
| 	int y = e->xbutton.y - borderpx; | 	int y = e->xbutton.y - win.vborderpx; | ||||||
| 	LIMIT(y, 0, win.th - 1); | 	LIMIT(y, 0, win.th - 1); | ||||||
| 	return y / win.ch; | 	return y / win.ch; | ||||||
| } | } | ||||||
| @@ -686,6 +689,8 @@ setsel(char *str, Time t) | |||||||
| 	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); | 	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); | ||||||
| 	if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) | 	if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) | ||||||
| 		selclear(); | 		selclear(); | ||||||
|  |  | ||||||
|  | 	xclipcopy(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -709,7 +714,9 @@ brelease(XEvent *e) | |||||||
|  |  | ||||||
| 	if (mouseaction(e, 1)) | 	if (mouseaction(e, 1)) | ||||||
| 		return; | 		return; | ||||||
| 	if (btn == Button1) | 	if (btn == Button3) | ||||||
|  | 		selpaste(NULL); | ||||||
|  | 	else if (btn == Button1) | ||||||
| 		mousesel(e, 1); | 		mousesel(e, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -739,6 +746,9 @@ cresize(int width, int height) | |||||||
| 	col = MAX(1, col); | 	col = MAX(1, col); | ||||||
| 	row = MAX(1, row); | 	row = MAX(1, row); | ||||||
|  |  | ||||||
|  | 	win.hborderpx = (win.w - col * win.cw) / 2; | ||||||
|  | 	win.vborderpx = (win.h - row * win.ch) / 2; | ||||||
|  |  | ||||||
| 	tresize(col, row); | 	tresize(col, row); | ||||||
| 	xresize(col, row); | 	xresize(col, row); | ||||||
| 	ttyresize(win.tw, win.th); | 	ttyresize(win.tw, win.th); | ||||||
| @@ -752,7 +762,7 @@ xresize(int col, int row) | |||||||
|  |  | ||||||
| 	XFreePixmap(xw.dpy, xw.buf); | 	XFreePixmap(xw.dpy, xw.buf); | ||||||
| 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | ||||||
| 			DefaultDepth(xw.dpy, xw.scr)); | 			xw.depth); | ||||||
| 	XftDrawChange(xw.draw, xw.buf); | 	XftDrawChange(xw.draw, xw.buf); | ||||||
| 	xclear(0, 0, win.w, win.h); | 	xclear(0, 0, win.w, win.h); | ||||||
|  |  | ||||||
| @@ -812,6 +822,13 @@ xloadcols(void) | |||||||
| 			else | 			else | ||||||
| 				die("could not allocate color %d\n", i); | 				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; | 	loaded = 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -869,8 +886,8 @@ xhints(void) | |||||||
| 	sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; | 	sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; | ||||||
| 	sizeh->height = win.h; | 	sizeh->height = win.h; | ||||||
| 	sizeh->width = win.w; | 	sizeh->width = win.w; | ||||||
| 	sizeh->height_inc = win.ch; | 	sizeh->height_inc = 1; | ||||||
| 	sizeh->width_inc = win.cw; | 	sizeh->width_inc = 1; | ||||||
| 	sizeh->base_height = 2 * borderpx; | 	sizeh->base_height = 2 * borderpx; | ||||||
| 	sizeh->base_width = 2 * borderpx; | 	sizeh->base_width = 2 * borderpx; | ||||||
| 	sizeh->min_height = win.ch + 2 * borderpx; | 	sizeh->min_height = win.ch + 2 * borderpx; | ||||||
| @@ -1134,11 +1151,23 @@ xinit(int cols, int rows) | |||||||
| 	Window parent; | 	Window parent; | ||||||
| 	pid_t thispid = getpid(); | 	pid_t thispid = getpid(); | ||||||
| 	XColor xmousefg, xmousebg; | 	XColor xmousefg, xmousebg; | ||||||
|  | 	XWindowAttributes attr; | ||||||
|  | 	XVisualInfo vis; | ||||||
|  |  | ||||||
| 	if (!(xw.dpy = XOpenDisplay(NULL))) | 	if (!(xw.dpy = XOpenDisplay(NULL))) | ||||||
| 		die("can't open display\n"); | 		die("can't open display\n"); | ||||||
| 	xw.scr = XDefaultScreen(xw.dpy); | 	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 */ | 	/* font */ | ||||||
| 	if (!FcInit()) | 	if (!FcInit()) | ||||||
| @@ -1148,12 +1177,12 @@ xinit(int cols, int rows) | |||||||
| 	xloadfonts(usedfont, 0); | 	xloadfonts(usedfont, 0); | ||||||
|  |  | ||||||
| 	/* colors */ | 	/* colors */ | ||||||
| 	xw.cmap = XDefaultColormap(xw.dpy, xw.scr); | 	xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); | ||||||
| 	xloadcols(); | 	xloadcols(); | ||||||
|  |  | ||||||
| 	/* adjust fixed window geometry */ | 	/* adjust fixed window geometry */ | ||||||
| 	win.w = 2 * borderpx + cols * win.cw; | 	win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; | ||||||
| 	win.h = 2 * borderpx + rows * win.ch; | 	win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; | ||||||
| 	if (xw.gm & XNegative) | 	if (xw.gm & XNegative) | ||||||
| 		xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; | 		xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; | ||||||
| 	if (xw.gm & YNegative) | 	if (xw.gm & YNegative) | ||||||
| @@ -1168,19 +1197,15 @@ xinit(int cols, int rows) | |||||||
| 		| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | 		| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | ||||||
| 	xw.attrs.colormap = xw.cmap; | 	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, | 	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 | 			xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | ||||||
| 			| CWEventMask | CWColormap, &xw.attrs); | 			| CWEventMask | CWColormap, &xw.attrs); | ||||||
|  |  | ||||||
| 	memset(&gcvalues, 0, sizeof(gcvalues)); | 	memset(&gcvalues, 0, sizeof(gcvalues)); | ||||||
| 	gcvalues.graphics_exposures = False; | 	gcvalues.graphics_exposures = False; | ||||||
| 	dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, | 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); | ||||||
| 			&gcvalues); | 	dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); | ||||||
| 	xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, |  | ||||||
| 			DefaultDepth(xw.dpy, xw.scr)); |  | ||||||
| 	XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); | 	XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); | ||||||
| 	XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); | 	XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); | ||||||
|  |  | ||||||
| @@ -1242,7 +1267,7 @@ xinit(int cols, int rows) | |||||||
| int | int | ||||||
| xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) | 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; | 	ushort mode, prevmode = USHRT_MAX; | ||||||
| 	Font *font = &dc.font; | 	Font *font = &dc.font; | ||||||
| 	int frcflags = FRC_NORMAL; | 	int frcflags = FRC_NORMAL; | ||||||
| @@ -1375,7 +1400,7 @@ void | |||||||
| xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) | xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) | ||||||
| { | { | ||||||
| 	int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); | 	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; | 	    width = charlen * win.cw; | ||||||
| 	Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; | 	Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; | ||||||
| 	XRenderColor colfg, colbg; | 	XRenderColor colfg, colbg; | ||||||
| @@ -1412,10 +1437,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i | |||||||
| 		bg = &dc.col[base.bg]; | 		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 (IS_SET(MODE_REVERSE)) { | ||||||
| 		if (fg == &dc.col[defaultfg]) { | 		if (fg == &dc.col[defaultfg]) { | ||||||
| 			fg = &dc.col[defaultbg]; | 			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. */ | 	/* Intelligent cleaning up of the borders. */ | ||||||
| 	if (x == 0) { | 	if (x == 0) { | ||||||
| 		xclear(0, (y == 0)? 0 : winy, borderpx, | 		xclear(0, (y == 0)? 0 : winy, win.hborderpx, | ||||||
| 			winy + win.ch + | 			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, | 		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) | 	if (y == 0) | ||||||
| 		xclear(winx, 0, winx + width, borderpx); | 		xclear(winx, 0, winx + width, win.vborderpx); | ||||||
| 	if (winy + win.ch >= borderpx + win.th) | 	if (winy + win.ch >= win.vborderpx + win.th) | ||||||
| 		xclear(winx, winy + win.ch, winx + width, win.h); | 		xclear(winx, winy + win.ch, winx + width, win.h); | ||||||
|  |  | ||||||
| 	/* Clean up the region we want to draw to. */ | 	/* 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) | xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) | ||||||
| { | { | ||||||
| 	Color drawcol; | 	Color drawcol; | ||||||
|  | 	XRenderColor colbg; | ||||||
|  |  | ||||||
| 	/* remove the old cursor */ | 	/* remove the old cursor */ | ||||||
| 	if (selected(ox, oy)) | 	if (selected(ox, oy)) | ||||||
| @@ -1548,11 +1570,21 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) | |||||||
| 		if (selected(cx, cy)) { | 		if (selected(cx, cy)) { | ||||||
| 			g.fg = defaultfg; | 			g.fg = defaultfg; | ||||||
| 			g.bg = defaultrcs; | 			g.bg = defaultrcs; | ||||||
| 		} else { | 		} else if (!(og.mode & ATTR_REVERSE)) { | ||||||
| 			g.fg = defaultbg; | 			unsigned long col = g.bg; | ||||||
| 			g.bg = defaultcs; | 			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]; | ||||||
| 		} | 		} | ||||||
| 		drawcol = dc.col[g.bg]; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* draw the new one */ | 	/* draw the new one */ | ||||||
| @@ -1569,35 +1601,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) | |||||||
| 		case 3: /* Blinking Underline */ | 		case 3: /* Blinking Underline */ | ||||||
| 		case 4: /* Steady Underline */ | 		case 4: /* Steady Underline */ | ||||||
| 			XftDrawRect(xw.draw, &drawcol, | 			XftDrawRect(xw.draw, &drawcol, | ||||||
| 					borderpx + cx * win.cw, | 					win.hborderpx + cx * win.cw, | ||||||
| 					borderpx + (cy + 1) * win.ch - \ | 					win.vborderpx + (cy + 1) * win.ch - \ | ||||||
| 						cursorthickness, | 						cursorthickness, | ||||||
| 					win.cw, cursorthickness); | 					win.cw, cursorthickness); | ||||||
| 			break; | 			break; | ||||||
| 		case 5: /* Blinking bar */ | 		case 5: /* Blinking bar */ | ||||||
| 		case 6: /* Steady bar */ | 		case 6: /* Steady bar */ | ||||||
| 			XftDrawRect(xw.draw, &drawcol, | 			XftDrawRect(xw.draw, &drawcol, | ||||||
| 					borderpx + cx * win.cw, | 					win.hborderpx + cx * win.cw, | ||||||
| 					borderpx + cy * win.ch, | 					win.vborderpx + cy * win.ch, | ||||||
| 					cursorthickness, win.ch); | 					cursorthickness, win.ch); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		XftDrawRect(xw.draw, &drawcol, | 		XftDrawRect(xw.draw, &drawcol, | ||||||
| 				borderpx + cx * win.cw, | 				win.hborderpx + cx * win.cw, | ||||||
| 				borderpx + cy * win.ch, | 				win.vborderpx + cy * win.ch, | ||||||
| 				win.cw - 1, 1); | 				win.cw - 1, 1); | ||||||
| 		XftDrawRect(xw.draw, &drawcol, | 		XftDrawRect(xw.draw, &drawcol, | ||||||
| 				borderpx + cx * win.cw, | 				win.hborderpx + cx * win.cw, | ||||||
| 				borderpx + cy * win.ch, | 				win.vborderpx + cy * win.ch, | ||||||
| 				1, win.ch - 1); | 				1, win.ch - 1); | ||||||
| 		XftDrawRect(xw.draw, &drawcol, | 		XftDrawRect(xw.draw, &drawcol, | ||||||
| 				borderpx + (cx + 1) * win.cw - 1, | 				win.hborderpx + (cx + 1) * win.cw - 1, | ||||||
| 				borderpx + cy * win.ch, | 				win.vborderpx + cy * win.ch, | ||||||
| 				1, win.ch - 1); | 				1, win.ch - 1); | ||||||
| 		XftDrawRect(xw.draw, &drawcol, | 		XftDrawRect(xw.draw, &drawcol, | ||||||
| 				borderpx + cx * win.cw, | 				win.hborderpx + cx * win.cw, | ||||||
| 				borderpx + (cy + 1) * win.ch - 1, | 				win.vborderpx + (cy + 1) * win.ch - 1, | ||||||
| 				win.cw, 1); | 				win.cw, 1); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -1911,6 +1943,9 @@ resize(XEvent *e) | |||||||
| 	cresize(e->xconfigure.width, e->xconfigure.height); | 	cresize(e->xconfigure.width, e->xconfigure.height); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int tinsync(uint); | ||||||
|  | int ttyread_pending(); | ||||||
|  |  | ||||||
| void | void | ||||||
| run(void) | run(void) | ||||||
| { | { | ||||||
| @@ -1945,7 +1980,7 @@ run(void) | |||||||
| 		FD_SET(ttyfd, &rfd); | 		FD_SET(ttyfd, &rfd); | ||||||
| 		FD_SET(xfd, &rfd); | 		FD_SET(xfd, &rfd); | ||||||
|  |  | ||||||
| 		if (XPending(xw.dpy)) | 		if (XPending(xw.dpy) || ttyread_pending()) | ||||||
| 			timeout = 0;  /* existing events might not set xfd */ | 			timeout = 0;  /* existing events might not set xfd */ | ||||||
|  |  | ||||||
| 		seltv.tv_sec = timeout / 1E3; | 		seltv.tv_sec = timeout / 1E3; | ||||||
| @@ -1959,7 +1994,8 @@ run(void) | |||||||
| 		} | 		} | ||||||
| 		clock_gettime(CLOCK_MONOTONIC, &now); | 		clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
|  |  | ||||||
| 		if (FD_ISSET(ttyfd, &rfd)) | 		int ttyin = FD_ISSET(ttyfd, &rfd) || ttyread_pending(); | ||||||
|  | 		if (ttyin) | ||||||
| 			ttyread(); | 			ttyread(); | ||||||
|  |  | ||||||
| 		xev = 0; | 		xev = 0; | ||||||
| @@ -1983,7 +2019,7 @@ run(void) | |||||||
| 		 * maximum latency intervals during `cat huge.txt`, and perfect | 		 * maximum latency intervals during `cat huge.txt`, and perfect | ||||||
| 		 * sync with periodic updates from animations/key-repeats/etc. | 		 * sync with periodic updates from animations/key-repeats/etc. | ||||||
| 		 */ | 		 */ | ||||||
| 		if (FD_ISSET(ttyfd, &rfd) || xev) { | 		if (ttyin || xev) { | ||||||
| 			if (!drawing) { | 			if (!drawing) { | ||||||
| 				trigger = now; | 				trigger = now; | ||||||
| 				drawing = 1; | 				drawing = 1; | ||||||
| @@ -1994,6 +2030,18 @@ run(void) | |||||||
| 				continue;  /* we have time, try to find idle */ | 				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 */ | 		/* idle detected or maxlatency exhausted -> draw */ | ||||||
| 		timeout = -1; | 		timeout = -1; | ||||||
| 		if (blinktimeout && tattrset(ATTR_BLINK)) { | 		if (blinktimeout && tattrset(ATTR_BLINK)) { | ||||||
| @@ -2038,6 +2086,9 @@ main(int argc, char *argv[]) | |||||||
| 	case 'a': | 	case 'a': | ||||||
| 		allowaltscreen = 0; | 		allowaltscreen = 0; | ||||||
| 		break; | 		break; | ||||||
|  | 	case 'A': | ||||||
|  | 		opt_alpha = EARGF(usage()); | ||||||
|  | 		break; | ||||||
| 	case 'c': | 	case 'c': | ||||||
| 		opt_class = EARGF(usage()); | 		opt_class = EARGF(usage()); | ||||||
| 		break; | 		break; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user