Compare commits
No commits in common. "dccdd5397debeffbc24850548e79bfe8e4a74768" and "3285ec77ca47ab6c6c9cdf49339a4835c16639ed" have entirely different histories.
dccdd5397d
...
3285ec77ca
|
@ -1,4 +0,0 @@
|
|||
st
|
||||
*.o
|
||||
*.orig
|
||||
*.rej
|
12
Makefile
12
Makefile
|
@ -7,13 +7,7 @@ include config.mk
|
|||
SRC = st.c x.c hb.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
all: options st
|
||||
|
||||
options:
|
||||
@echo st build options:
|
||||
@echo "CFLAGS = $(STCFLAGS)"
|
||||
@echo "LDFLAGS = $(STLDFLAGS)"
|
||||
@echo "CC = $(CC)"
|
||||
all: st
|
||||
|
||||
config.h:
|
||||
cp config.def.h config.h
|
||||
|
@ -31,7 +25,7 @@ st: $(OBJ)
|
|||
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f st $(OBJ) st-$(VERSION).tar.gz config.h
|
||||
rm -f st $(OBJ) st-$(VERSION).tar.gz
|
||||
|
||||
dist: clean
|
||||
mkdir -p st-$(VERSION)
|
||||
|
@ -55,4 +49,4 @@ uninstall:
|
|||
rm -f $(DESTDIR)$(PREFIX)/bin/st
|
||||
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
||||
.PHONY: all clean dist install uninstall
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
st - simple terminal
|
||||
--------------------
|
||||
st is a simple terminal emulator for X which sucks less.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build st you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (st is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install st (if
|
||||
necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
|
||||
Running st
|
||||
----------
|
||||
If you did not install st with make clean install, you must compile
|
||||
the st terminfo entry with the following command:
|
||||
|
||||
tic -sx st.info
|
||||
|
||||
See the man page for additional details.
|
||||
|
||||
Credits
|
||||
-------
|
||||
Based on Aurélien APTEL <aurelien dot aptel at gmail dot com> bt source code.
|
||||
|
93
README.md
93
README.md
|
@ -1,93 +0,0 @@
|
|||
# st - simple terminal
|
||||
|
||||
st is a simple terminal emulator for X which sucks less.
|
||||
|
||||
## Notes about this fork
|
||||
|
||||
This is a fork of st, the original repo can be found here: [https://git.suckless.org/st/](https://git.suckless.org/st/)
|
||||
|
||||
The original st webpage is here: [https://st.suckless.org/](https://st.suckless.org/)
|
||||
|
||||
### Available patches
|
||||
|
||||
* [Alpha](https://st.suckless.org/patches/alpha/) : This patch allows users to change the opacity of the background. Note that you need an X composite manager (e.g. compton, xcompmgr) to make this patch effective.
|
||||
* [Clipboard](https://st.suckless.org/patches/clipboard/) : This trivial patch sets CLIPBOARD on selection.
|
||||
* [font2](https://st.suckless.org/patches/font2/) : This patch allows to add spare font besides default.
|
||||
* [Wide glyph](https://st.suckless.org/patches/glyph_wide_support/) : This patch allows to display the full glyph instead of it being cut off. See also [here](https://github.com/LukeSmithxyz/st/pull/349)
|
||||
|
||||
#### Colorscheme patch
|
||||
The colorscheme patch is a custom patch, it is not the ones from [colorscheme](https://st.suckless.org/patches/colorschemes/)
|
||||
It is `solarized.dark` exported from https://terminal.sexy with a different bg and fg color.
|
||||
Also the `defaultfg`, `defaultbg` and `defaultcs` are not `static`s, otherwise it won't compile.
|
||||
|
||||
### Previous available patches
|
||||
|
||||
* [Fix Keyboard Input](https://st.suckless.org/patches/fix_keyboard_input/) : Add a few previously undefined keys.
|
||||
Removed as this was used for additional keys for zooming.
|
||||
|
||||
### Applying/Removing Patches
|
||||
Applying patches from this repository use:
|
||||
|
||||
- applied all at once without committing:
|
||||
```
|
||||
git apply patches/*
|
||||
```
|
||||
|
||||
- applied as individual commits
|
||||
```
|
||||
git am patches/*
|
||||
```
|
||||
|
||||
Applying patches from https://st.suckless.org/patches/ use:
|
||||
```
|
||||
# Add custom patch
|
||||
patch -Np1 -i patches/custom.diff
|
||||
or
|
||||
patch < patch.diff
|
||||
|
||||
# Remove st-alpha-201806-16-0.81 patch
|
||||
patch -R patches/st-alpha-20180616-0.8.1.diff
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
In order to build st you need the Xlib header files.
|
||||
|
||||
## Installation
|
||||
|
||||
Edit config.mk to match your local setup (st is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install st (if
|
||||
necessary as root):
|
||||
|
||||
```bash
|
||||
make clean install
|
||||
```
|
||||
|
||||
## Running st
|
||||
|
||||
Start `st` from a launcher like dmenu or rofi.
|
||||
|
||||
If you did not install st with make clean install, you must compile
|
||||
the st terminfo entry with the following command:
|
||||
|
||||
```bash
|
||||
tic -sx st.info
|
||||
```
|
||||
|
||||
See the man page for additional details.
|
||||
|
||||
### Keyboard Shortcuts
|
||||
Action | Key Combination
|
||||
--- | ---
|
||||
Copy | `ctrl` + `shift` + `c`
|
||||
Paste | `ctrl` + `shift` + `v`
|
||||
Zoom In | `ctrl` + `shift` + `PageUp`
|
||||
Zoom Out | `ctrl` + `shift` + `PageDown`
|
||||
Reset Zoom | `ctrl` + `shift` + `Home`
|
||||
|
||||
## Credits
|
||||
|
||||
* Forked from [https://st.suckless.org/](https://st.suckless.org/)
|
||||
* Based on Aurélien APTEL aurelien.aptel@gmail.com bt source code.
|
34
config.def.h
34
config.def.h
|
@ -53,7 +53,7 @@ int allowwindowops = 0;
|
|||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 8;
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
|
@ -129,14 +129,19 @@ unsigned int defaultbg = 256;
|
|||
unsigned int defaultcs = 257;
|
||||
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 cursorshape = 0;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
|
@ -170,15 +175,9 @@ static uint forcemousemod = ShiftMask;
|
|||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ ShiftMask, Button4, kscrollup, {.i = 1} },
|
||||
{ ShiftMask, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, -1 },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
/* mask button function argument release alt */
|
||||
{ XK_ANY_MOD, Button4, kscrollup, {.i = 1}, 0, -1 },
|
||||
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, -1 },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
|
@ -203,6 +202,7 @@ static Shortcut shortcuts[] = {
|
|||
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
|
|
34
config.h
34
config.h
|
@ -53,7 +53,7 @@ int allowwindowops = 0;
|
|||
* near minlatency, but it waits longer for slow updates to avoid partial draw.
|
||||
* low minlatency will tear/flicker more, as it can "detect" idle too early.
|
||||
*/
|
||||
static double minlatency = 8;
|
||||
static double minlatency = 2;
|
||||
static double maxlatency = 33;
|
||||
|
||||
/*
|
||||
|
@ -129,14 +129,19 @@ unsigned int defaultbg = 256;
|
|||
unsigned int defaultcs = 257;
|
||||
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 cursorshape = 0;
|
||||
|
||||
/*
|
||||
* Default columns and rows numbers
|
||||
|
@ -170,15 +175,9 @@ static uint forcemousemod = ShiftMask;
|
|||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* mask button function argument release */
|
||||
{ ShiftMask, Button4, kscrollup, {.i = 1} },
|
||||
{ ShiftMask, Button5, kscrolldown, {.i = 1} },
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, -1 },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
/* mask button function argument release alt */
|
||||
{ XK_ANY_MOD, Button4, kscrollup, {.i = 1}, 0, -1 },
|
||||
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, -1 },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
|
@ -203,6 +202,7 @@ static Shortcut shortcuts[] = {
|
|||
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Special keys (change & recompile st.info accordingly)
|
||||
*
|
||||
|
|
|
@ -36,3 +36,4 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
|
|||
|
||||
# compiler and linker
|
||||
# CC = c99
|
||||
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
From 5770f2fc02afca341c275fc340bbc5003ecc3df8 Mon Sep 17 00:00:00 2001
|
||||
From: Iskustvo <iskustvo@yahoo.com>
|
||||
Date: Sat, 7 Jan 2023 01:23:37 +0100
|
||||
Subject: [PATCH] [PATCH] add glyph wide support patch
|
||||
|
||||
---
|
||||
st.c | 3 +-
|
||||
st.h | 6 +++
|
||||
win.h | 2 +-
|
||||
x.c | 141 ++++++++++++++++++++++++++++++----------------------------
|
||||
4 files changed, 81 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/st.c b/st.c
|
||||
index 62def59..cc6c78e 100644
|
||||
--- a/st.c
|
||||
+++ b/st.c
|
||||
@@ -2640,7 +2640,8 @@ draw(void)
|
||||
|
||||
drawregion(0, 0, term.col, term.row);
|
||||
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
|
||||
+ term.ocx, term.ocy, term.line[term.ocy][term.ocx],
|
||||
+ term.line[term.ocy], term.col);
|
||||
term.ocx = cx;
|
||||
term.ocy = term.c.y;
|
||||
xfinishdraw();
|
||||
diff --git a/st.h b/st.h
|
||||
index fd3b0d8..0053050 100644
|
||||
--- a/st.h
|
||||
+++ b/st.h
|
||||
@@ -36,6 +36,12 @@ enum glyph_attribute {
|
||||
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||
};
|
||||
|
||||
+enum drawing_mode {
|
||||
+ DRAW_NONE = 0,
|
||||
+ DRAW_BG = 1 << 0,
|
||||
+ DRAW_FG = 1 << 1,
|
||||
+};
|
||||
+
|
||||
enum selection_mode {
|
||||
SEL_IDLE = 0,
|
||||
SEL_EMPTY = 1,
|
||||
diff --git a/win.h b/win.h
|
||||
index 6de960d..94679e4 100644
|
||||
--- a/win.h
|
||||
+++ b/win.h
|
||||
@@ -25,7 +25,7 @@ enum win_mode {
|
||||
|
||||
void xbell(void);
|
||||
void xclipcopy(void);
|
||||
-void xdrawcursor(int, int, Glyph, int, int, Glyph);
|
||||
+void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
|
||||
void xdrawline(Line, int, int, int);
|
||||
void xfinishdraw(void);
|
||||
void xloadcols(void);
|
||||
diff --git a/x.c b/x.c
|
||||
index aa09997..85deee6 100644
|
||||
--- a/x.c
|
||||
+++ b/x.c
|
||||
@@ -142,7 +142,7 @@ typedef struct {
|
||||
|
||||
static inline ushort sixd_to_16bit(int);
|
||||
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
|
||||
-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
||||
+static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
|
||||
static void xdrawglyph(Glyph, int, int);
|
||||
static void xclear(int, int, int, int);
|
||||
static int xgeommasktogravity(int);
|
||||
@@ -1372,7 +1372,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||
}
|
||||
|
||||
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 dmode)
|
||||
{
|
||||
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
|
||||
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
|
||||
@@ -1463,47 +1463,40 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||
if (base.mode & ATTR_INVISIBLE)
|
||||
fg = bg;
|
||||
|
||||
- /* Intelligent cleaning up of the borders. */
|
||||
- if (x == 0) {
|
||||
- xclear(0, (y == 0)? 0 : winy, borderpx,
|
||||
- winy + win.ch +
|
||||
- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
|
||||
- }
|
||||
- if (winx + width >= borderpx + win.tw) {
|
||||
- xclear(winx + width, (y == 0)? 0 : winy, win.w,
|
||||
- ((winy + win.ch >= borderpx + 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, winy + win.ch, winx + width, win.h);
|
||||
-
|
||||
- /* Clean up the region we want to draw to. */
|
||||
- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||
-
|
||||
- /* Set the clip region because Xft is sometimes dirty. */
|
||||
- r.x = 0;
|
||||
- r.y = 0;
|
||||
- r.height = win.ch;
|
||||
- r.width = width;
|
||||
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
|
||||
-
|
||||
- /* Render the glyphs. */
|
||||
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
|
||||
-
|
||||
- /* Render underline and strikethrough. */
|
||||
- if (base.mode & ATTR_UNDERLINE) {
|
||||
- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
|
||||
- width, 1);
|
||||
- }
|
||||
-
|
||||
- if (base.mode & ATTR_STRUCK) {
|
||||
- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
|
||||
- width, 1);
|
||||
- }
|
||||
-
|
||||
- /* Reset clip to none. */
|
||||
- XftDrawSetClip(xw.draw, 0);
|
||||
+ if (dmode & DRAW_BG) {
|
||||
+ /* Intelligent cleaning up of the borders. */
|
||||
+ if (x == 0) {
|
||||
+ xclear(0, (y == 0)? 0 : winy, borderpx,
|
||||
+ winy + win.ch +
|
||||
+ ((winy + win.ch >= borderpx + win.th)? win.h : 0));
|
||||
+ }
|
||||
+ if (winx + width >= borderpx + win.tw) {
|
||||
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
|
||||
+ ((winy + win.ch >= borderpx + 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, winy + win.ch, winx + width, win.h);
|
||||
+ /* Fill the background */
|
||||
+ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||
+ }
|
||||
+
|
||||
+ if (dmode & DRAW_FG) {
|
||||
+ /* Render the glyphs. */
|
||||
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
|
||||
+
|
||||
+ /* Render underline and strikethrough. */
|
||||
+ if (base.mode & ATTR_UNDERLINE) {
|
||||
+ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
|
||||
+ width, 1);
|
||||
+ }
|
||||
+
|
||||
+ if (base.mode & ATTR_STRUCK) {
|
||||
+ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
|
||||
+ width, 1);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1513,18 +1506,21 @@ xdrawglyph(Glyph g, int x, int y)
|
||||
XftGlyphFontSpec spec;
|
||||
|
||||
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
|
||||
- xdrawglyphfontspecs(&spec, g, numspecs, x, y);
|
||||
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG);
|
||||
}
|
||||
|
||||
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, Line line, int len)
|
||||
{
|
||||
Color drawcol;
|
||||
|
||||
/* remove the old cursor */
|
||||
if (selected(ox, oy))
|
||||
og.mode ^= ATTR_REVERSE;
|
||||
- xdrawglyph(og, ox, oy);
|
||||
+
|
||||
+ /* Redraw the line where cursor was previously.
|
||||
+ * It will restore wide glyphs and ligatures broken by the cursor. */
|
||||
+ xdrawline(line, 0, oy, len);
|
||||
|
||||
if (IS_SET(MODE_HIDE))
|
||||
return;
|
||||
@@ -1648,32 +1644,39 @@ xstartdraw(void)
|
||||
void
|
||||
xdrawline(Line line, int x1, int y1, int x2)
|
||||
{
|
||||
- int i, x, ox, numspecs;
|
||||
+ int i, x, ox, numspecs, numspecs_cached;
|
||||
Glyph base, new;
|
||||
- XftGlyphFontSpec *specs = xw.specbuf;
|
||||
-
|
||||
- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
|
||||
- i = ox = 0;
|
||||
- for (x = x1; x < x2 && i < numspecs; x++) {
|
||||
- new = line[x];
|
||||
- if (new.mode == ATTR_WDUMMY)
|
||||
- continue;
|
||||
- if (selected(x, y1))
|
||||
- new.mode ^= ATTR_REVERSE;
|
||||
- if (i > 0 && ATTRCMP(base, new)) {
|
||||
- xdrawglyphfontspecs(specs, base, i, ox, y1);
|
||||
- specs += i;
|
||||
- numspecs -= i;
|
||||
- i = 0;
|
||||
- }
|
||||
- if (i == 0) {
|
||||
- ox = x;
|
||||
- base = new;
|
||||
+ XftGlyphFontSpec *specs;
|
||||
+
|
||||
+ numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1);
|
||||
+
|
||||
+ /* Draw line in 2 passes: background and foreground. This way wide glyphs
|
||||
+ won't get truncated (#223) */
|
||||
+ for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) {
|
||||
+ specs = xw.specbuf;
|
||||
+ numspecs = numspecs_cached;
|
||||
+ i = ox = 0;
|
||||
+ for (x = x1; x < x2 && i < numspecs; x++) {
|
||||
+ new = line[x];
|
||||
+ if (new.mode == ATTR_WDUMMY)
|
||||
+ continue;
|
||||
+ if (selected(x, y1))
|
||||
+ new.mode ^= ATTR_REVERSE;
|
||||
+ if (i > 0 && ATTRCMP(base, new)) {
|
||||
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
|
||||
+ specs += i;
|
||||
+ numspecs -= i;
|
||||
+ i = 0;
|
||||
+ }
|
||||
+ if (i == 0) {
|
||||
+ ox = x;
|
||||
+ base = new;
|
||||
+ }
|
||||
+ i++;
|
||||
}
|
||||
- i++;
|
||||
+ if (i > 0)
|
||||
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
|
||||
}
|
||||
- if (i > 0)
|
||||
- xdrawglyphfontspecs(specs, base, i, ox, y1);
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
2.39.0
|
||||
|
45
st.c
45
st.c
|
@ -1164,7 +1164,7 @@ tscrollup(int orig, int n, int copyhist)
|
|||
void
|
||||
selscroll(int orig, int n)
|
||||
{
|
||||
if (sel.ob.x == -1)
|
||||
if (sel.ob.x == -1 || sel.alt != IS_SET(MODE_ALTSCREEN))
|
||||
return;
|
||||
|
||||
if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) {
|
||||
|
@ -1199,6 +1199,7 @@ csiparse(void)
|
|||
{
|
||||
char *p = csiescseq.buf, *np;
|
||||
long int v;
|
||||
int sep = ';'; /* colon or semi-colon, but not both */
|
||||
|
||||
csiescseq.narg = 0;
|
||||
if (*p == '?') {
|
||||
|
@ -1216,7 +1217,9 @@ csiparse(void)
|
|||
v = -1;
|
||||
csiescseq.arg[csiescseq.narg++] = v;
|
||||
p = np;
|
||||
if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
|
||||
if (sep == ';' && *p == ':')
|
||||
sep = ':'; /* allow override to colon once */
|
||||
if (*p != sep || csiescseq.narg == ESC_ARG_SIZ)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
@ -1710,7 +1713,7 @@ csihandle(void)
|
|||
ttywrite(vtiden, strlen(vtiden), 0);
|
||||
break;
|
||||
case 'b': /* REP -- if last char is printable print it <n> more times */
|
||||
DEFAULT(csiescseq.arg[0], 1);
|
||||
LIMIT(csiescseq.arg[0], 1, 65535);
|
||||
if (term.lastc)
|
||||
while (csiescseq.arg[0]-- > 0)
|
||||
tputc(term.lastc);
|
||||
|
@ -1795,6 +1798,7 @@ csihandle(void)
|
|||
}
|
||||
break;
|
||||
case 'S': /* SU -- Scroll <n> line up */
|
||||
if (csiescseq.priv) break;
|
||||
DEFAULT(csiescseq.arg[0], 1);
|
||||
tscrollup(term.top, csiescseq.arg[0], 0);
|
||||
break;
|
||||
|
@ -1836,11 +1840,18 @@ csihandle(void)
|
|||
case 'm': /* SGR -- Terminal attribute (color) */
|
||||
tsetattr(csiescseq.arg, csiescseq.narg);
|
||||
break;
|
||||
case 'n': /* DSR – Device Status Report (cursor position) */
|
||||
if (csiescseq.arg[0] == 6) {
|
||||
case 'n': /* DSR -- Device Status Report */
|
||||
switch (csiescseq.arg[0]) {
|
||||
case 5: /* Status Report "OK" `0n` */
|
||||
ttywrite("\033[0n", sizeof("\033[0n") - 1, 0);
|
||||
break;
|
||||
case 6: /* Report Cursor Position (CPR) "<row>;<column>R" */
|
||||
len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
|
||||
term.c.y+1, term.c.x+1);
|
||||
term.c.y+1, term.c.x+1);
|
||||
ttywrite(buf, len, 0);
|
||||
break;
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
case 'r': /* DECSTBM -- Set Scrolling Region */
|
||||
|
@ -1999,8 +2010,10 @@ strhandle(void)
|
|||
if (p && !strcmp(p, "?")) {
|
||||
osc_color_response(j, 0, 1);
|
||||
} else if (xsetcolorname(j, p)) {
|
||||
if (par == 104 && narg <= 1)
|
||||
if (par == 104 && narg <= 1) {
|
||||
xloadcols();
|
||||
return; /* color reset without parameter */
|
||||
}
|
||||
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
||||
j, p ? p : "(null)");
|
||||
} else {
|
||||
|
@ -2388,6 +2401,7 @@ eschandle(uchar ascii)
|
|||
treset();
|
||||
resettitle();
|
||||
xloadcols();
|
||||
xsetmode(0, MODE_HIDE);
|
||||
break;
|
||||
case '=': /* DECPAM -- Application keypad */
|
||||
xsetmode(1, MODE_APPKEYPAD);
|
||||
|
@ -2480,6 +2494,9 @@ check_control_code:
|
|||
* they must not cause conflicts with sequences.
|
||||
*/
|
||||
if (control) {
|
||||
/* in UTF-8 mode ignore handling C1 control characters */
|
||||
if (IS_SET(MODE_UTF8) && ISCONTROLC1(u))
|
||||
return;
|
||||
tcontrolcode(u);
|
||||
/*
|
||||
* control codes are not shown ever
|
||||
|
@ -2526,11 +2543,16 @@ check_control_code:
|
|||
gp = &term.line[term.c.y][term.c.x];
|
||||
}
|
||||
|
||||
if (IS_SET(MODE_INSERT) && term.c.x+width < term.col)
|
||||
if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) {
|
||||
memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph));
|
||||
gp->mode &= ~ATTR_WIDE;
|
||||
}
|
||||
|
||||
if (term.c.x+width > term.col) {
|
||||
tnewline(1);
|
||||
if (IS_SET(MODE_WRAP))
|
||||
tnewline(1);
|
||||
else
|
||||
tmoveto(term.col - width, term.c.y);
|
||||
gp = &term.line[term.c.y][term.c.x];
|
||||
}
|
||||
|
||||
|
@ -2714,12 +2736,9 @@ draw(void)
|
|||
cx--;
|
||||
|
||||
drawregion(0, 0, term.col, term.row);
|
||||
|
||||
if (term.scr == 0)
|
||||
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||
term.ocx, term.ocy, term.line[term.ocy][term.ocx],
|
||||
term.line[term.ocy], term.col);
|
||||
|
||||
term.ocx = cx;
|
||||
term.ocy = term.c.y;
|
||||
xfinishdraw();
|
||||
|
|
1
st.h
1
st.h
|
@ -90,7 +90,6 @@ void sendbreak(const Arg *);
|
|||
void toggleprinter(const Arg *);
|
||||
|
||||
int tattrset(int);
|
||||
int tisaltscr(void);
|
||||
void tnew(int, int);
|
||||
void tresize(int, int);
|
||||
void tsetdirtattr(int);
|
||||
|
|
4
st.info
4
st.info
|
@ -184,6 +184,10 @@ st-mono| simpleterm monocolor,
|
|||
# XTerm extensions
|
||||
rmxx=\E[29m,
|
||||
smxx=\E[9m,
|
||||
BE=\E[?2004h,
|
||||
BD=\E[?2004l,
|
||||
PS=\E[200~,
|
||||
PE=\E[201~,
|
||||
# disabled rep for now: causes some issues with older ncurses versions.
|
||||
# rep=%p1%c\E[%p2%{1}%-%db,
|
||||
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
|
||||
|
|
68
x.c
68
x.c
|
@ -35,7 +35,6 @@ typedef struct {
|
|||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
uint release;
|
||||
int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
|
||||
} MouseShortcut;
|
||||
|
||||
typedef struct {
|
||||
|
@ -256,6 +255,7 @@ static char *opt_name = NULL;
|
|||
static char *opt_title = NULL;
|
||||
|
||||
static uint buttons; /* bit field of pressed buttons */
|
||||
static int cursorblinks = 0;
|
||||
|
||||
void
|
||||
clipcopy(const Arg *dummy)
|
||||
|
@ -458,7 +458,6 @@ mouseaction(XEvent *e, uint release)
|
|||
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
if (ms->release == release &&
|
||||
ms->button == e->xbutton.button &&
|
||||
(!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
|
||||
(match(ms->mod, state) || /* exact or forced */
|
||||
match(ms->mod, state & ~forcemousemod))) {
|
||||
ms->func(&(ms->arg));
|
||||
|
@ -822,7 +821,7 @@ xloadcols(void)
|
|||
int
|
||||
xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b)
|
||||
{
|
||||
if (!BETWEEN(x, 0, dc.collen))
|
||||
if (!BETWEEN(x, 0, dc.collen - 1))
|
||||
return 1;
|
||||
|
||||
*r = dc.col[x].color.red >> 8;
|
||||
|
@ -837,7 +836,7 @@ xsetcolorname(int x, const char *name)
|
|||
{
|
||||
Color ncolor;
|
||||
|
||||
if (!BETWEEN(x, 0, dc.collen))
|
||||
if (!BETWEEN(x, 0, dc.collen - 1))
|
||||
return 1;
|
||||
|
||||
if (!xloadcolor(x, name, &ncolor))
|
||||
|
@ -1138,7 +1137,7 @@ xinit(int cols, int rows)
|
|||
{
|
||||
XGCValues gcvalues;
|
||||
Cursor cursor;
|
||||
Window parent;
|
||||
Window parent, root;
|
||||
pid_t thispid = getpid();
|
||||
XColor xmousefg, xmousebg;
|
||||
|
||||
|
@ -1175,16 +1174,19 @@ xinit(int cols, int rows)
|
|||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
||||
xw.attrs.colormap = xw.cmap;
|
||||
|
||||
root = XRootWindow(xw.dpy, xw.scr);
|
||||
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,
|
||||
parent = root;
|
||||
xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t,
|
||||
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||
| CWEventMask | CWColormap, &xw.attrs);
|
||||
if (parent != root)
|
||||
XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t);
|
||||
|
||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||
gcvalues.graphics_exposures = False;
|
||||
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||
dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures,
|
||||
&gcvalues);
|
||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
||||
DefaultDepth(xw.dpy, xw.scr));
|
||||
|
@ -1612,29 +1614,44 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int le
|
|||
/* 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 = xsetcursor;
|
||||
xdrawglyph(g, cx, cy);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
XftDrawRect(xw.draw, &drawcol,
|
||||
|
@ -1671,6 +1688,9 @@ xseticontitle(char *p)
|
|||
XTextProperty prop;
|
||||
DEFAULT(p, opt_title);
|
||||
|
||||
if (p[0] == '\0')
|
||||
p = opt_title;
|
||||
|
||||
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||
&prop) != Success)
|
||||
return;
|
||||
|
@ -1685,6 +1705,9 @@ xsettitle(char *p)
|
|||
XTextProperty prop;
|
||||
DEFAULT(p, opt_title);
|
||||
|
||||
if (p[0] == '\0')
|
||||
p = opt_title;
|
||||
|
||||
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
|
||||
&prop) != Success)
|
||||
return;
|
||||
|
@ -1791,9 +1814,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;
|
||||
}
|
||||
|
||||
|
@ -2040,6 +2066,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)) \
|
||||
|
@ -2050,7 +2080,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 */
|
||||
|
|
Loading…
Reference in New Issue