merged blinking cursor

blink
spinach 2 years ago
parent 1e154fc5d4
commit 3e535542dd

@ -139,13 +139,20 @@ static unsigned int defaultrcs = 257;
unsigned int bg = 17, bgUnfocused = 16;
/*
* Default shape of cursor
* 2: Block ("")
* 4: Underline ("_")
* 6: Bar ("|")
* 7: Snowman ("")
* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
* Default style of cursor
* 0: blinking block
* 1: blinking block (default)
* 2: steady block ("")
* 3: blinking underline
* 4: steady underline ("_")
* 5: blinking bar
* 6: steady bar ("|")
* 7: blinking st cursor
* 8: steady st cursor
*/
static unsigned int cursorshape = 2;
static unsigned int cursorstyle = 1;
static Rune stcursor = 0x2603; /* snowman ("☃") */
/*
* Default columns and rows numbers

@ -93,6 +93,9 @@ char *termname = "st-256color";
*/
unsigned int tabspaces = 8;
/* bg opacity */
float alpha = 0.8, alphaUnfocused = 0.6;
/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
/* 8 normal colors */
@ -133,6 +136,7 @@ unsigned int defaultfg = 258;
unsigned int defaultbg = 259;
unsigned int defaultcs = 256;
static unsigned int defaultrcs = 257;
unsigned int bg = 17, bgUnfocused = 16;
/*
* Default shape of cursor

@ -139,13 +139,20 @@ static unsigned int defaultrcs = 257;
unsigned int bg = 17, bgUnfocused = 16;
/*
* Default shape of cursor
* 2: Block ("")
* 4: Underline ("_")
* 6: Bar ("|")
* 7: Snowman ("")
* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
* Default style of cursor
* 0: blinking block
* 1: blinking block (default)
* 2: steady block ("")
* 3: blinking underline
* 4: steady underline ("_")
* 5: blinking bar
* 6: steady bar ("|")
* 7: blinking st cursor
* 8: steady st cursor
*/
static unsigned int cursorshape = 2;
static unsigned int cursorstyle = 1;
static Rune stcursor = 0x2603; /* snowman ("☃") */
/*
* Default columns and rows numbers

BIN
st

Binary file not shown.

@ -0,0 +1,153 @@
From a3cdd0753bf578cd4e6db7c6507481f3b5c38aea Mon Sep 17 00:00:00 2001
From: Steve Ward <planet36@gmail.com>
Date: Tue, 16 Nov 2021 14:15:06 -0500
Subject: [PATCH] Allow blinking cursor
---
config.def.h | 19 +++++++++++++------
x.c | 47 +++++++++++++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/config.def.h b/config.def.h
index 6f05dce..1a5fed0 100644
--- a/config.def.h
+++ b/config.def.h
@@ -133,13 +133,20 @@ static unsigned int defaultcs = 256;
static unsigned int defaultrcs = 257;
/*
- * Default shape of cursor
- * 2: Block ("█")
- * 4: Underline ("_")
- * 6: Bar ("|")
- * 7: Snowman ("☃")
+ * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
+ * Default style of cursor
+ * 0: blinking block
+ * 1: blinking block (default)
+ * 2: steady block ("█")
+ * 3: blinking underline
+ * 4: steady underline ("_")
+ * 5: blinking bar
+ * 6: steady bar ("|")
+ * 7: blinking st cursor
+ * 8: steady st cursor
*/
-static unsigned int cursorshape = 2;
+static unsigned int cursorstyle = 1;
+static Rune stcursor = 0x2603; /* snowman ("☃") */
/*
* Default columns and rows numbers
diff --git a/x.c b/x.c
index 89786b8..7d2447d 100644
--- a/x.c
+++ b/x.c
@@ -253,6 +253,7 @@ static char *opt_name = NULL;
static char *opt_title = NULL;
static int oldbutton = 3; /* button event on startup: 3 = release */
+static int cursorblinks = 0;
void
clipcopy(const Arg *dummy)
@@ -1529,29 +1530,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
/* draw the new one */
if (IS_SET(MODE_FOCUSED)) {
switch (win.cursor) {
- case 7: /* st extension */
- g.u = 0x2603; /* snowman (U+2603) */
+ default:
+ case 0: /* blinking block */
+ case 1: /* blinking block (default) */
+ if (IS_SET(MODE_BLINK))
+ break;
/* FALLTHROUGH */
- case 0: /* Blinking Block */
- case 1: /* Blinking Block (Default) */
- case 2: /* Steady Block */
+ case 2: /* steady block */
xdrawglyph(g, cx, cy);
break;
- case 3: /* Blinking Underline */
- case 4: /* Steady Underline */
+ case 3: /* blinking underline */
+ if (IS_SET(MODE_BLINK))
+ break;
+ /* FALLTHROUGH */
+ case 4: /* steady underline */
XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + (cy + 1) * win.ch - \
cursorthickness,
win.cw, cursorthickness);
break;
- case 5: /* Blinking bar */
- case 6: /* Steady bar */
+ case 5: /* blinking bar */
+ if (IS_SET(MODE_BLINK))
+ break;
+ /* FALLTHROUGH */
+ case 6: /* steady bar */
XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + cy * win.ch,
cursorthickness, win.ch);
break;
+ case 7: /* blinking st cursor */
+ if (IS_SET(MODE_BLINK))
+ break;
+ /* FALLTHROUGH */
+ case 8: /* steady st cursor */
+ g.u = stcursor;
+ xdrawglyph(g, cx, cy);
+ break;
}
} else {
XftDrawRect(xw.draw, &drawcol,
@@ -1708,9 +1724,12 @@ xsetmode(int set, unsigned int flags)
int
xsetcursor(int cursor)
{
- if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
+ if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
return 1;
win.cursor = cursor;
+ cursorblinks = win.cursor == 0 || win.cursor == 1 ||
+ win.cursor == 3 || win.cursor == 5 ||
+ win.cursor == 7;
return 0;
}
@@ -1954,6 +1973,10 @@ run(void)
if (FD_ISSET(ttyfd, &rfd) || xev) {
if (!drawing) {
trigger = now;
+ if (IS_SET(MODE_BLINK)) {
+ win.mode ^= MODE_BLINK;
+ }
+ lastblink = now;
drawing = 1;
}
timeout = (maxlatency - TIMEDIFF(now, trigger)) \
@@ -1964,7 +1987,7 @@ run(void)
/* idle detected or maxlatency exhausted -> draw */
timeout = -1;
- if (blinktimeout && tattrset(ATTR_BLINK)) {
+ if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
timeout = blinktimeout - TIMEDIFF(now, lastblink);
if (timeout <= 0) {
if (-timeout > blinktimeout) /* start visible */
@@ -2000,7 +2023,7 @@ main(int argc, char *argv[])
{
xw.l = xw.t = 0;
xw.isfixed = False;
- xsetcursor(cursorshape);
+ xsetcursor(cursorstyle);
ARGBEGIN {
case 'a':
--
2.34.0

@ -126,3 +126,5 @@ extern unsigned int defaultfg;
extern unsigned int defaultbg;
extern unsigned int defaultcs;
extern float alpha, alphaUnfocused;
//extern unsigned int cursorstyle;
//extern Rune stcursor;

47
x.c

@ -256,6 +256,7 @@ static char *opt_title = NULL;
static int focused = 0;
static uint buttons; /* bit field of pressed buttons */
static int cursorblinks = 0;
void
clipcopy(const Arg *dummy)
@ -1579,29 +1580,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
/* draw the new one */
if (IS_SET(MODE_FOCUSED)) {
switch (win.cursor) {
case 7: /* st extension */
g.u = 0x2603; /* snowman (U+2603) */
default:
case 0: /* blinking block */
case 1: /* blinking block (default) */
if (IS_SET(MODE_BLINK))
break;
/* FALLTHROUGH */
case 0: /* Blinking Block */
case 1: /* Blinking Block (Default) */
case 2: /* Steady Block */
case 2: /* steady block */
xdrawglyph(g, cx, cy);
break;
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
case 3: /* blinking underline */
if (IS_SET(MODE_BLINK))
break;
/* FALLTHROUGH */
case 4: /* steady underline */
XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + (cy + 1) * win.ch - \
cursorthickness,
win.cw, cursorthickness);
break;
case 5: /* Blinking bar */
case 6: /* Steady bar */
case 5: /* blinking bar */
if (IS_SET(MODE_BLINK))
break;
/* FALLTHROUGH */
case 6: /* steady bar */
XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + cy * win.ch,
cursorthickness, win.ch);
break;
case 7: /* blinking st cursor */
if (IS_SET(MODE_BLINK))
break;
/* FALLTHROUGH */
case 8: /* steady st cursor */
g.u = stcursor;
xdrawglyph(g, cx, cy);
break;
}
} else {
XftDrawRect(xw.draw, &drawcol,
@ -1758,9 +1774,12 @@ xsetmode(int set, unsigned int flags)
int
xsetcursor(int cursor)
{
if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
return 1;
win.cursor = cursor;
cursorblinks = win.cursor == 0 || win.cursor == 1 ||
win.cursor == 3 || win.cursor == 5 ||
win.cursor == 7;
return 0;
}
@ -2014,6 +2033,10 @@ run(void)
if (FD_ISSET(ttyfd, &rfd) || xev) {
if (!drawing) {
trigger = now;
if (IS_SET(MODE_BLINK)) {
win.mode ^= MODE_BLINK;
}
lastblink = now;
drawing = 1;
}
timeout = (maxlatency - TIMEDIFF(now, trigger)) \
@ -2024,7 +2047,7 @@ run(void)
/* idle detected or maxlatency exhausted -> draw */
timeout = -1;
if (blinktimeout && tattrset(ATTR_BLINK)) {
if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
timeout = blinktimeout - TIMEDIFF(now, lastblink);
if (timeout <= 0) {
if (-timeout > blinktimeout) /* start visible */
@ -2060,7 +2083,7 @@ main(int argc, char *argv[])
{
xw.l = xw.t = 0;
xw.isfixed = False;
xsetcursor(cursorshape);
xsetcursor(cursorstyle);
ARGBEGIN {
case 'a':

@ -105,6 +105,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 +244,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;
@ -252,6 +254,7 @@ static char *opt_line = NULL;
static char *opt_name = NULL;
static char *opt_title = NULL;
static int focused = 0;
static uint buttons; /* bit field of pressed buttons */
void
@ -752,7 +755,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);
@ -790,28 +793,38 @@ xloadcolor(int i, const char *name, Color *ncolor)
return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
}
void
xloadalpha(void)
{
float const usedAlpha = focused ? alpha : alphaUnfocused;
if (opt_alpha) alpha = strtof(opt_alpha, NULL);
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * usedAlpha);
dc.col[defaultbg].pixel &= 0x00FFFFFF;
dc.col[defaultbg].pixel |= (unsigned char)(0xff * usedAlpha) << 24;
}
void
xloadcols(void)
{
int i;
static int loaded;
Color *cp;
if (loaded) {
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
} else {
dc.collen = MAX(LEN(colorname), 256);
dc.col = xmalloc(dc.collen * sizeof(Color));
if (!loaded) {
dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256));
dc.col = xmalloc((dc.collen) * sizeof(Color));
}
for (i = 0; i < dc.collen; i++)
for (int i = 0; i+1 < dc.collen; ++i)
if (!xloadcolor(i, NULL, &dc.col[i])) {
if (colorname[i])
die("could not allocate color '%s'\n", colorname[i]);
else
die("could not allocate color %d\n", i);
}
if (dc.collen) // cannot die, as the color is already loaded.
xloadcolor(focused ?bg :bgUnfocused, NULL, &dc.col[defaultbg]);
xloadalpha();
loaded = 1;
}
@ -1134,11 +1147,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,7 +1173,7 @@ 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 */
@ -1168,19 +1193,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);
@ -1777,12 +1798,22 @@ focus(XEvent *ev)
xseturgency(0);
if (IS_SET(MODE_FOCUS))
ttywrite("\033[I", 3, 0);
if (!focused) {
focused = 1;
xloadcols();
tfulldirt();
}
} else {
if (xw.ime.xic)
XUnsetICFocus(xw.ime.xic);
win.mode &= ~MODE_FOCUSED;
if (IS_SET(MODE_FOCUS))
ttywrite("\033[O", 3, 0);
if (focused) {
focused = 0;
xloadcols();
tfulldirt();
}
}
}
@ -2035,6 +2066,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;
@ -2086,6 +2120,7 @@ run:
XSetLocaleModifiers("");
cols = MAX(cols, 1);
rows = MAX(rows, 1);
defaultbg = MAX(LEN(colorname), 256);
tnew(cols, rows);
xinit(cols, rows);
xsetenv();

@ -1,11 +1,10 @@
--- x.c
+++ x.c
@@ -254,6 +256,8 @@ static char *opt_line = NULL;
static char *opt_name = NULL;
@@ -253,6 +253,7 @@ static char *opt_name = NULL;
static char *opt_title = NULL;
+static int focused = 0;
+
static int oldbutton = 3; /* button event on startup: 3 = release */
+static int cursorblinks = 0;
void
clipcopy(const Arg *dummy)

BIN
x.o

Binary file not shown.
Loading…
Cancel
Save