summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Ward <planet36@gmail.com>2023-08-19 08:05:36 -0500
committersalmonik <raisersoft@proton.me>2026-02-05 23:26:17 +0100
commit27a29b8b81063847b23c7bb7c03f3d8492261bc4 (patch)
treeacf96021dfb8a43a180a7d0b7580036ea005d136
parentst: guard tsetdirt() against zero-sized terminal (diff)
downloadst-27a29b8b81063847b23c7bb7c03f3d8492261bc4.tar.gz
st-27a29b8b81063847b23c7bb7c03f3d8492261bc4.zip
Add different cursor styles
-rw-r--r--config.def.h19
-rw-r--r--x.c47
2 files changed, 48 insertions, 18 deletions
diff --git a/config.def.h b/config.def.h
index 2cd740a..36c10d1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -135,13 +135,20 @@ unsigned int defaultcs = 256;
135static unsigned int defaultrcs = 257; 135static unsigned int defaultrcs = 257;
136 136
137/* 137/*
138 * Default shape of cursor 138 * 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
139 * 2: Block ("█") 139 * Default style of cursor
140 * 4: Underline ("_") 140 * 0: blinking block
141 * 6: Bar ("|") 141 * 1: blinking block (default)
142 * 7: Snowman ("☃") 142 * 2: steady block ("█")
143 * 3: blinking underline
144 * 4: steady underline ("_")
145 * 5: blinking bar
146 * 6: steady bar ("|")
147 * 7: blinking st cursor
148 * 8: steady st cursor
143 */ 149 */
144static unsigned int cursorshape = 2; 150static unsigned int cursorstyle = 1;
151static Rune stcursor = 0x2603; /* snowman ("☃") */
145 152
146/* 153/*
147 * Default columns and rows numbers 154 * Default columns and rows numbers
diff --git a/x.c b/x.c
index d73152b..d8aafee 100644
--- a/x.c
+++ b/x.c
@@ -253,6 +253,7 @@ static char *opt_name = NULL;
253static char *opt_title = NULL; 253static char *opt_title = NULL;
254 254
255static uint buttons; /* bit field of pressed buttons */ 255static uint buttons; /* bit field of pressed buttons */
256static int cursorblinks = 0;
256 257
257void 258void
258clipcopy(const Arg *dummy) 259clipcopy(const Arg *dummy)
@@ -1561,29 +1562,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
1561 /* draw the new one */ 1562 /* draw the new one */
1562 if (IS_SET(MODE_FOCUSED)) { 1563 if (IS_SET(MODE_FOCUSED)) {
1563 switch (win.cursor) { 1564 switch (win.cursor) {
1564 case 7: /* st extension */ 1565 default:
1565 g.u = 0x2603; /* snowman (U+2603) */ 1566 case 0: /* blinking block */
1567 case 1: /* blinking block (default) */
1568 if (IS_SET(MODE_BLINK))
1569 break;
1566 /* FALLTHROUGH */ 1570 /* FALLTHROUGH */
1567 case 0: /* Blinking Block */ 1571 case 2: /* steady block */
1568 case 1: /* Blinking Block (Default) */
1569 case 2: /* Steady Block */
1570 xdrawglyph(g, cx, cy); 1572 xdrawglyph(g, cx, cy);
1571 break; 1573 break;
1572 case 3: /* Blinking Underline */ 1574 case 3: /* blinking underline */
1573 case 4: /* Steady Underline */ 1575 if (IS_SET(MODE_BLINK))
1576 break;
1577 /* FALLTHROUGH */
1578 case 4: /* steady underline */
1574 XftDrawRect(xw.draw, &drawcol, 1579 XftDrawRect(xw.draw, &drawcol,
1575 borderpx + cx * win.cw, 1580 borderpx + cx * win.cw,
1576 borderpx + (cy + 1) * win.ch - \ 1581 borderpx + (cy + 1) * win.ch - \
1577 cursorthickness, 1582 cursorthickness,
1578 win.cw, cursorthickness); 1583 win.cw, cursorthickness);
1579 break; 1584 break;
1580 case 5: /* Blinking bar */ 1585 case 5: /* blinking bar */
1581 case 6: /* Steady bar */ 1586 if (IS_SET(MODE_BLINK))
1587 break;
1588 /* FALLTHROUGH */
1589 case 6: /* steady bar */
1582 XftDrawRect(xw.draw, &drawcol, 1590 XftDrawRect(xw.draw, &drawcol,
1583 borderpx + cx * win.cw, 1591 borderpx + cx * win.cw,
1584 borderpx + cy * win.ch, 1592 borderpx + cy * win.ch,
1585 cursorthickness, win.ch); 1593 cursorthickness, win.ch);
1586 break; 1594 break;
1595 case 7: /* blinking st cursor */
1596 if (IS_SET(MODE_BLINK))
1597 break;
1598 /* FALLTHROUGH */
1599 case 8: /* steady st cursor */
1600 g.u = stcursor;
1601 xdrawglyph(g, cx, cy);
1602 break;
1587 } 1603 }
1588 } else { 1604 } else {
1589 XftDrawRect(xw.draw, &drawcol, 1605 XftDrawRect(xw.draw, &drawcol,
@@ -1746,9 +1762,12 @@ xsetmode(int set, unsigned int flags)
1746int 1762int
1747xsetcursor(int cursor) 1763xsetcursor(int cursor)
1748{ 1764{
1749 if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ 1765 if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
1750 return 1; 1766 return 1;
1751 win.cursor = cursor; 1767 win.cursor = cursor;
1768 cursorblinks = win.cursor == 0 || win.cursor == 1 ||
1769 win.cursor == 3 || win.cursor == 5 ||
1770 win.cursor == 7;
1752 return 0; 1771 return 0;
1753} 1772}
1754 1773
@@ -1995,6 +2014,10 @@ run(void)
1995 if (FD_ISSET(ttyfd, &rfd) || xev) { 2014 if (FD_ISSET(ttyfd, &rfd) || xev) {
1996 if (!drawing) { 2015 if (!drawing) {
1997 trigger = now; 2016 trigger = now;
2017 if (IS_SET(MODE_BLINK)) {
2018 win.mode ^= MODE_BLINK;
2019 }
2020 lastblink = now;
1998 drawing = 1; 2021 drawing = 1;
1999 } 2022 }
2000 timeout = (maxlatency - TIMEDIFF(now, trigger)) \ 2023 timeout = (maxlatency - TIMEDIFF(now, trigger)) \
@@ -2005,7 +2028,7 @@ run(void)
2005 2028
2006 /* idle detected or maxlatency exhausted -> draw */ 2029 /* idle detected or maxlatency exhausted -> draw */
2007 timeout = -1; 2030 timeout = -1;
2008 if (blinktimeout && tattrset(ATTR_BLINK)) { 2031 if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
2009 timeout = blinktimeout - TIMEDIFF(now, lastblink); 2032 timeout = blinktimeout - TIMEDIFF(now, lastblink);
2010 if (timeout <= 0) { 2033 if (timeout <= 0) {
2011 if (-timeout > blinktimeout) /* start visible */ 2034 if (-timeout > blinktimeout) /* start visible */
@@ -2041,7 +2064,7 @@ main(int argc, char *argv[])
2041{ 2064{
2042 xw.l = xw.t = 0; 2065 xw.l = xw.t = 0;
2043 xw.isfixed = False; 2066 xw.isfixed = False;
2044 xsetcursor(cursorshape); 2067 xsetcursor(cursorstyle);
2045 2068
2046 ARGBEGIN { 2069 ARGBEGIN {
2047 case 'a': 2070 case 'a':