Merge st-next into speedie/st main branch. Old st build can be found in

the 'previous' branch. This build is better in every way though!
This commit is contained in:
speediegq 2022-10-07 14:47:14 +02:00
parent 375093bac1
commit 7f65a6a7b9
30 changed files with 1185 additions and 1523 deletions

View file

@ -14,6 +14,7 @@ MIT/X Consortium License
© 2013 Michael Forney <mforney at mforney dot org>
© 2013-2014 Markus Teich <markus dot teich at stusta dot mhn dot de>
© 2014-2015 Laslo Hunhold <dev at frign dot de>
© 2021-2022 speedie <speedie at duck dot com>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

View file

@ -2,7 +2,7 @@
# See LICENSE file for copyright and license details.
.POSIX:
include config.mk
include options.mk
SRC = st.c x.c boxdraw.c hb.c
OBJ = $(SRC:.c=.o)
@ -14,64 +14,67 @@ options:
@echo "CFLAGS = $(STCFLAGS)"
@echo "LDFLAGS = $(STLDFLAGS)"
@echo "CC = $(CC)"
@echo "======================"
.c.o:
$(CC) $(STCFLAGS) -c $<
st.o: options.h st.h win.h
x.o: arg.h options.h st.h win.h hb.h
hb.o: st.h
x.o: arg.h options.h st.h win.h
boxdraw.o: options.h st.h boxdraw_data.h
hb.o: st.h
$(OBJ): options.h config.mk
$(OBJ): options.h options.mk
st: $(OBJ)
$(CC) -o $@ $(OBJ) $(STLDFLAGS)
clean:
rm -f st $(OBJ) st-spde-$(VERSION).tar.gz
rm -f st $(OBJ) st-$(VERSION).tar.gz
dist: clean
mkdir -p st-spde-$(VERSION)
cp -R LICENSE Makefile *.mk *.info *.h *.png *.desktop *.ttf docs scripts $(SRC)\
st-spde-$(VERSION)
tar -cf - st-spde-$(VERSION) | gzip > st-spde-$(VERSION).tar.gz
rm -rf st-spde-$(VERSION)
mkdir -p st-$(VERSION)
cp -R LICENSE Makefile README *.mk\
*.h *.info *.c *.png *.desktop *.ttf docs/ scripts/ \
st-$(VERSION)
tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz
rm -rf st-$(VERSION)
install: st
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f st $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/st
tic -sx st.info
@echo Please see the README file regarding the terminfo entry of st.
mkdir -p $(DESTDIR)$(ICONPREFIX)
[ -f $(ICONNAME) ] && cp -f $(ICONNAME) $(DESTDIR)$(ICONPREFIX) || :
mkdir -p $(DESTDIR)$(APPPREFIX)
cp -f st.desktop $(DESTDIR)$(APPPREFIX)
rm -f *.o st
cp -f scripts/st_urllist $(DESTDIR)$(PREFIX)/bin
cp -f scripts/st_buffer $(DESTDIR)$(PREFIX)/bin
cp -f scripts/st_xurls $(DESTDIR)$(PREFIX)/bin
cp -f scripts/st_help $(DESTDIR)$(PREFIX)/bin
chmod +x $(DESTDIR)$(PREFIX)/bin/st_urllist
chmod +x $(DESTDIR)$(PREFIX)/bin/st_buffer
chmod +x $(DESTDIR)$(PREFIX)/bin/st_xurls
rm -f ./st
rm -f *.o
chmod +x $(DESTDIR)$(PREFIX)/bin/st_help
mkdir -p $(DESTDIR)$(ICONPREFIX)
[ -f $(ICONNAME) ] && cp -f $(ICONNAME) $(DESTDIR)$(ICONPREFIX) || :
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/st
rm -f $(DESTDIR)$(APPPREFIX)/st.desktop
rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
rm -f $(DESTDIR)$(ICONPREFIX)/$(ICONNAME)
enablefont:
fontctrl install font.ttf
fontctrl enable font.ttf
help:
@echo "install: Install st"
@echo "uninstall: Uninstall st"
@echo "dist: Package st into st-spde-$(VERSION).tar.gz (Used for Gentoo overlays and the AUR for example)."
@echo "clean: Remove .o files and st binary"
@echo "help: Display this list"
@echo "enablefont: Install and enable the included font.ttf. You must have fontctrl installed for this to be used. If you do not, install it here: https://codeberg.org/speedie/fontctrl"
@echo "st Makefile help"
@echo
@echo "install Install st."
@echo "uninstall Uninstall st."
@echo "clean Remove st tarball and binary"
@echo "options Print compilation options."
@echo "enablefont Install the font.ttf using fontctrl."
@echo "dist Create a tarball for use with package managers or for releases."
@echo "help List of all options."
.PHONY: all options clean dist install uninstall help enablefont
enablefont:
fontctrl install font.ttf --global
fontctrl enable font.ttf --global
.PHONY: all options clean dist install uninstall enablefont help

34
README Normal file
View file

@ -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.

5
arg.h
View file

@ -1,8 +1,3 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef ARG_H__
#define ARG_H__

View file

@ -1,3 +1,11 @@
/* st key array */
/*
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
* to be mapped below, add them to this array.
*/
static KeySym mappedkeys[] = { -1 };
static Key key[] = {
/* keysym mask string appkey appcursor */
{ XK_KP_Home, ShiftMask, "\033[2J", 0, -1},

39
char.h
View file

@ -1,39 +0,0 @@
/* This header contains options most people probably don't want to change
*
* It is therefore hidden to keep the configuration file easy and clean to read.
*/
char *utmp = NULL;
char *scroll = NULL;
char *vtiden = "\033[?6c";
/* More advanced example: L" `'\"()[]{}" */
wchar_t *worddelimiters = L" ";
static uint selmasks[] = { [SEL_RECTANGULAR] = Mod1Mask };
static char ascii_printable[] = {
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~"
};
static char *colorname[] = {
col_1, /* black */
col_2, /* red3 */
col_3, /* green3 */
col_4, /* yellow3 */
col_5, /* blue2 */
col_6, /* magenta3 */
col_7, /* cyan3 */
col_8, /* gray90 */
col_9, /* gray50 */
col_10, /* red */
col_11, /* green */
col_12, /* yellow */
col_13, /* #5c5cff */
col_14, /* magenta */
col_15, /* cyan */
col_16, /* white */
[255] = 0,
"#cccccc",
"#555555",
"#c0c5ce",
"#696969",
};

25
colors.h Normal file
View file

@ -0,0 +1,25 @@
/* st color array */
static char *colorname[] = {
col_1, /* black */
col_2, /* red3 */
col_3, /* green3 */
col_4, /* yellow3 */
col_5, /* blue2 */
col_6, /* magenta3 */
col_7, /* cyan3 */
col_8, /* gray90 */
col_9, /* gray50 */
col_10, /* red */
col_11, /* green */
col_12, /* yellow */
col_13, /* #5c5cff */
col_14, /* magenta */
col_15, /* cyan */
col_16, /* white */
[255] = 0,
"#cccccc",
"#555555",
"#c0c5ce",
"#696969",
};

View file

@ -1 +0,0 @@
bind list, not complete yet.

View file

@ -1,7 +0,0 @@
! This is an example .Xresources file for speedie.gq's build of st.
!
! Copy the values here to your .Xresources file by running:
! 'cat example.Xresources >> ~/.Xresources # This assumes your .Xresources is in $HOME and you're in the docs directory.'
!
! Then to load these values, add 'xrdb /path/to/.Xresources' to a script which autostarts.
! If you use Pywal then this will already be done for you.

View file

@ -1,29 +0,0 @@
patchlist, not complete yet
st-title-parsing-fix
st-boxdraw
st-scrollback
st-scrollback-mouse
st-boldisnotbright
st-ligatures
st-xresources
st-w3m
st-clipboard
st-columns
st-blinkingcursor
st-alpha
st-desktopentry
st-dynamiccursorcolor
st-font2
st-netwmicon
st-clickurls
st-vertcenter
st-xclearwin
st-charoffsets
st-undercurl
st-anysize
st-xrandrfontsize
st-delkey
st-extenralpipe
st-externalpipe-eternal
st-externalpipe-signal

View file

@ -1,4 +1,9 @@
/* This is the header used to control extenralpipe.
/* st externalpipe
*
* Externalpipe allows the user to write scripts that can read the text on the screen and perform actions on it (basically st | <script>).
*
* Below you can set the commands that will run, that can be, for example, bound to a key (see keybinds.h)
*/
char *externalpipe_sigusr1[] = { "/bin/sh", "-c", "st_buffer st_strings_read" };
static char *listurl[] = { "/bin/sh", "-c", "st_urllist", NULL };

13
hb.c
View file

@ -7,8 +7,6 @@
#include "st.h"
#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END }
void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length);
hb_font_t *hbfindfont(XftFont *match);
@ -20,13 +18,6 @@ typedef struct {
static int hbfontslen = 0;
static HbFontMatch *hbfontcache = NULL;
/*
* Poplulate the array with a list of font features, wrapped in FEATURE macro,
* e. g.
* FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g')
*/
hb_feature_t features[] = { 0 };
void
hbunloadfonts()
{
@ -68,7 +59,7 @@ void
hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y)
{
int start = 0, length = 1, gstart = 0;
hb_codepoint_t *codepoints = calloc((unsigned int)len, sizeof(hb_codepoint_t));
hb_codepoint_t *codepoints = calloc(len, sizeof(hb_codepoint_t));
for (int idx = 1, specidx = 1; idx < len; idx++) {
if (glyphs[idx].mode & ATTR_WDUMMY) {
@ -133,7 +124,7 @@ hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoin
}
/* Shape the segment. */
hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t));
hb_shape(font, buffer, NULL, 0);
/* Get new glyph info. */
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL);

View file

@ -1,22 +1,34 @@
/* This header file contains the keybinds available to the user.
* This is not a complete list, the rest can be changed in array.h and mouse.h respectively.
*
* CONTROL = Left Control/Ctrl key
* SHIFT = Left Shift key
* ALT = Left Alt key
* ALTR = Right Alt key
* SUPER = Left Super/Windows/Command key
* SUPERR = Right Super/Windows/Command key
* ANY = Any of the above modifiers
* NONE = No modifier at all
*/
static Shortcut shortcuts[] = {
/* mask keysym function argument */
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
{ ControlMask, XK_equal, zoom, {.f = +1} },
{ ControlMask, XK_minus, zoom, {.f = -1} },
{ ControlMask, XK_0, zoomreset, {.f = 0} },
{ XK_ANY_MOD, XK_End, refreshxrandr, {.i = 0} },
{ ControlMask, XK_y, clipcopy, {.i = 0} },
{ ControlMask, XK_p, clippaste, {.i = 0} },
{ TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
{ ControlMask|ShiftMask, XK_E, kexec, {.ca = "nvim" } },
{ ControlMask|ShiftMask, XK_K, kscrollup, {.i = +1} },
{ ControlMask|ShiftMask, XK_J, kscrolldown, {.i = +1} },
{ ControlMask|ShiftMask, XK_U, externalpipe, {.v = listurl } },
/* modifier keysym function argument */
{ NONE, XK_Break, sendbreak, {.i = 0} },
{ CONTROL, XK_Print, toggleprinter, {.i = 0} },
{ SHIFT, XK_Print, printscreen, {.i = 0} },
{ NONE, XK_Print, printsel, {.i = 0} },
{ CONTROL, XK_equal, zoom, {.f = +1} },
{ CONTROL, XK_minus, zoom, {.f = -1} },
{ CONTROL, XK_0, zoomreset, {.f = 0} },
{ CONTROL, XK_y, clipcopy, {.i = 0} },
{ CONTROL, XK_p, clippaste, {.i = 0} },
{ CONTROL|SHIFT, XK_Num_Lock, numlock, {.i = 0} },
{ CONTROL|SHIFT, XK_Escape, keyboard_select,{.i = 0} },
{ CONTROL|SHIFT, XK_C, kexec, {.scmd = "clear" } },
{ CONTROL|SHIFT, XK_H, kexec, {.scmd = "st_help" } },
{ CONTROL|SHIFT, XK_E, kexec, {.scmd = "$EDITOR" } },
{ CONTROL|SHIFT, XK_D, kexec, {.scmd = "$PERM !!" } },
{ CONTROL|SHIFT, XK_K, kscrollup, {.i = +1} },
{ CONTROL|SHIFT, XK_J, kscrolldown, {.i = +1} },
{ CONTROL|SHIFT, XK_U, externalpipeout,{.v = listurl } },
};

View file

@ -1,78 +0,0 @@
/*
* If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
* to be mapped below, add them to this array.
*/
static KeySym mappedkeys[] = {
XK_space,
XK_m,
XK_i,
XK_A,
XK_B,
XK_C,
XK_D,
XK_E,
XK_F,
XK_G,
XK_H,
XK_I,
XK_K,
XK_J,
XK_L,
XK_M,
XK_N,
XK_O,
XK_P,
XK_Q,
XK_R,
XK_S,
XK_T,
XK_U,
XK_V,
XK_W,
XK_X,
XK_Y,
XK_Z,
XK_Z,
XK_0,
XK_1,
XK_2,
XK_3,
XK_4,
XK_5,
XK_6,
XK_7,
XK_8,
XK_9,
XK_exclam,
XK_quotedbl,
XK_numbersign,
XK_dollar,
XK_percent,
XK_ampersand,
XK_apostrophe,
XK_parenleft,
XK_parenright,
XK_asterisk,
XK_plus,
XK_comma,
XK_minus,
XK_period,
XK_slash,
XK_colon,
XK_semicolon,
XK_less,
XK_equal,
XK_greater,
XK_question,
XK_at,
XK_bracketleft,
XK_backslash,
XK_bracketright,
XK_asciicircum,
XK_underscore,
XK_grave,
XK_braceleft,
XK_bar,
XK_braceright,
XK_asciitilde,
};

24
modifiers.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
* Note that if you want to use ShiftMask with selmasks, set this to an other
* modifier, set to 0 to not use it.
*/
static uint forcemousemod = SHIFT;
/* Modifier header
* State bits to ignore when matching key or button events. By default,
* numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
*/
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
/*
* Selection types' masks.
* Use the same masks as usual.
* Button1Mask is always unset, to make masks match between ButtonPress.
* ButtonRelease and MotionNotify.
* If no match is found, regular selection is used.
*/
static uint selmasks[] = {
[SEL_RECTANGULAR] = Mod1Mask,
};

16
mouse.h
View file

@ -7,13 +7,13 @@
*/
static MouseShortcut mshortcuts[] = {
/* mask button function argument release */
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
{ XK_NO_MOD, 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"} },
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
/* mask button function argument release */
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
{ XK_NO_MOD, 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"} },
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
};

215
options.h
View file

@ -7,32 +7,7 @@
* If you use GNU/Linux, you should be able to recompile st.
*
* To find out what to enter in the font and font2 chars, run 'fc-list | grep <fontname>'.
*/
/* Options
*
* This configuration file (options.h) contains the many options you can change about this terminal.
* It is configured in C syntax and needs to be recompiled after a change has been made.
*
* You can also configure st using .Xresources.
* In order to do this, create a .Xresources file somewhere.
*
* If you prefer, you can copy 'docs/example.Xresources' somewhere and add 'xrdb /path/to/.Xresources' to a script that auto starts such as .xinitrc.
* If you use Pywal, it should "just work" out of the box without any additional configuration necessary.
*
* Recompiling is done by running the command 'make clean install' when in the source code directory.
*
* If recompiling fails, check config.mk.
*/
/* Modifier key options */
#define MODKEY Mod1Mask
#define TERMMOD (ControlMask|ShiftMask)
static uint forcemousemod = ShiftMask; /* Force mouse select/shortcuts while mask is active when MODE_MOUSE is set. */
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
/* Font options
* Font options
*/
static char *font = "DejaVuSansMono Nerd Font:style=Bold:pixelsize=12:antialias=true:autohint=true"; /* Main font to use */
/* This font should be bundled with st. Install it manually or with fontctrl (available here: https://codeberg.org/speedie/fontctrl)
@ -48,86 +23,53 @@ static char *font = "DejaVuSansMono Nerd Font:style=Bold:pi
* If you don't need these, you can of course omit them.
*/
static char *font2[] = { "DejaVu Sans Mono:pixelsize=12:antialias=true:autohint=true",
// "Noto Color Emoji:pixelsize=12:antialias=true:autohint=true",
"JoyPixels:pixelsize=12:antialias=true:autohint=true",
"Noto Color Emoji:pixelsize=12:antialias=true:autohint=true",
"fontawesome:pixelsize=12:antialias=true:autohint=true",
};
/* Appearance
*
* This is where most appearance related options can be found and changed.
*/
/* Window options */
static int borderpx = 0; /* Size of a small border around the text. */
int allowaltscreen = 1; /* Allow alt screen (1) */
int allowwindowops = 1; /* Allow (insecure) window operations such as setting the clipboard text */
int windowdecorations = 1; /* Display window decoration (1) */
static int borderpx = 0; /* Size of a small border around the text */
int allowaltscreen = 1; /* Allow alt screen */
int allowwindowops = 1; /* Allow non-interactive, insecure window operations such as setting the clipboard text */
int windowdecorations = 1; /* Use window decorations */
/* Text drawing options */
int boldbright = 0; /* Draw bold text using bright colors */
static unsigned int cols = 80; /* Number of columns */
static unsigned int rows = 24; /* Number of rows */
wchar_t *worddelimiters = L" ";
/* Text latency options */
static uint synctimeout = 200; /* Time before refreshing */
static double minlatency = 8; /* Minimum latency */
static double maxlatency = 33; /* Maximum latency */
/* Mouse options */
static unsigned int doubleclicktimeout = 300;
static unsigned int tripleclicktimeout = 600;
/* URL clicker options */
static char *url_opener = "xdg-open"; /* Application to open the clicked URL in */
/*
* Override/adjust fontsize of choosen monitors:
* Default colour and shape of the mouse cursor
*/
MonitorConfig monitors_config[] = {
/* skip = fixed relative points size (monitor dpi) */
/* =0 : fixed absolute pixel size (default screen dpi) */
/* >0 : auto absolute pixel size (monitor dpi) */
/* <0 : auto relative points size (monitor dpi) */
{"HDMI-0~2", -14},
{"LVDS1", -8},
{"DVI-D", -10},
};
float winmovethreshold = 0.6;
static unsigned int mouseshape = XC_xterm;
static unsigned int mousefg = 7;
static unsigned int mousebg = 0;
/* Cursor options */
/* Execution options */
static char *shell = "/bin/sh"; /* Shell to execute with the '-e' (execute command) flag. */
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
/* List of cursor styles:
*
* 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 Rune stcursor = 0x2603; /* snowman ("☃") */
static unsigned int cursorstyle = 1;
static unsigned int mouseshape = XC_xterm; /* Shape of the mouse cursor */
static unsigned int mousefg = 7;
static unsigned int mousebg = 0;
static unsigned int blinktimeout = 800; /* Blink timeout for the cursor in milliseconds */
static unsigned int cursorthickness = 2; /* Thickness of the cursor in pixels. */
static unsigned int dctimeout = 300; /* Double click timeout in milliseconds */
static unsigned int tctimeout = 600; /* Triple click timeout in milliseconds */
static unsigned int defaultattr = 11;
/* Text rendering options */
static float cwscale = 1.0;
static float chscale = 1.0;
static short cxoffset = 0; /* Horizontal character rendering offsets in pixels */
static short cyoffset = 0; /* Vertical character rendering offsets in pixels */
static double minlatency = 8; /* Minimum draw latency in milliseconds */
static double maxlatency = 33; /* Max draw latency in milliseconds */
static uint su_timeout = 200; /* Synchronized timeout in milliseconds */
/* URL options
*
* This build of st allows you to click on links with your mouse.
* These will then be opened in whatever you define below.
*
* This could be a web browser or a clipboard if you prefer to copy the link.
*
* 'xdg-open' is the default but this could be set to 'firefox' or 'chrome'.
*/
static char *url_opener = "xdg-open"; /* Open the URL in this char */
static int clickeditalic = 1; /* Should clicked links show up as italic (1) or not (0) */
static int clickedunderline = 1; /* Should clicked links show up underlined (1) or not (0) */
/* Character bounding-box multipliers */
static float cwscale = 1.0;
static float chscale = 1.0;
/* Color options
*
* Regular colors (1-8)
* Note that these can also be set in .Xresources, despite being #defined here.
*/
#define col_1 "#5c5c5c" /* regular color 1 */
#define col_2 "#e57373" /* regular color 2 */
@ -148,27 +90,51 @@ static int clickedunderline = 1; /* Should clicked links show up underli
#define col_15 "#cccccc" /* bright color 7 */
#define col_16 "#555555" /* bright color 8 */
/* Default foreground/background colors */
unsigned int defaultfg = 258; /* Default foreground (text) color */
unsigned int defaultbg = 232; /* Default background (bg) color */
unsigned int defaultcs = 256;
static unsigned int defaultrcs = 257;
/* Alpha options */
float alpha = 0.8; /* Background opacity (0 is transparent, 1 is opaque, 0.8 is default) */
float alpha = 0.8;
/*
* Default colors (colorname index)
* foreground, background, cursor, reverse cursor
*/
unsigned int defaultfg = 258; /* Foreground */
unsigned int defaultbg = 259; /* Background */
unsigned int defaultcs = 256; /* Cursor */
unsigned int defaultrc = 257; /* Reverse cursor */
unsigned int defaultattr = 11; /* Invalid font returned by fontconfig */
/* Cursor options
*
* Thickness of underline and bar cursors
*/
static unsigned int cursorthickness = 2;
static unsigned int blinktimeout = 800; /* Timeout in milliseconds between cursor blink.
* Setting this to 0 will disable the blinking 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 ccursor cursor
* 8: Steady ccursor cursor
*/
static unsigned int cursorstyle = 1; /* Style to draw the cursor in */
static Rune ccursor = 0x2603; /* Snowman ("☃") */
/* Boxdraw options
*
* 1: render most of the lines/blocks characters without using the font for
* 1: Render most of the lines/blocks characters without using the font for
* perfect alignment between cells (U2500 - U259F except dashes/diagonals).
* Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored.
* 0: disable (render all U25XX glyphs normally from the font).
*
* Boxdraw can cause some compatibility issues so do not enable this unless you want to use it.
* 0: Disable boxdraw (render all U25XX glyphs normally from the font).
*/
const int boxdraw = 0; /* Enable (1) or disable boxdraw (0) */
const int boxdraw_bold = 0; /* Enable (1) or disable bold boxdraw (0) */
const int boxdraw_braille = 0; /* Render as adjacent "pixels" (1) or use the fonts (0) */
int boxdraw = 1; /* Enable boxdraw */
int boxdraw_bold = 1; /* Draw boxdraw bold */
int boxdraw_braille = 1; /* Render braille as adjecent pixels */
/* Undercurl options
*
@ -203,33 +169,16 @@ const int boxdraw_braille = 0; /* Render as adjacent "pixels" (1) or us
static char *understyle = "1"; /* Undercurl style to use */
/* Default column and row options */
static unsigned int cols = 80; /* Number of columns to have by default */
static unsigned int rows = 24; /* Number of rows to have by default */
static unsigned int width = 564;
static unsigned int height = 364;
/* Bell options */
static int bellvolume = 0; /* Bell volume. It must be a value between -100 and 100. 0 will disable it. */
/* Shell options
*
* This is where most options related to the Shell can be found and changed.
/* Bell options
*/
static char *shell = "/bin/sh";
char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
static int bellvolume = 0; /* Bell volume value between -100 and 100. 0 will disable it! */
/* $TERM options
* Some software uses the TERM export variable to determine what features the terminal supports.
* 'st-256color' is the default and will work for most but if you're having compatibility issues
* try setting it to 'xterm-256color'.
/* Default $TERM value
*
* You can also set it to 'st-mono' if you want to disable colors completely.
* If you find that you need it, you may set this to xterm-256color for extra compatibility
* Or if you prefer, you may also use no color or 16 color to disable full color support.
*/
char *termname = "st-256color"; /* $TERM value */
char *termname = "st-256color"; /* $TERM value to export */
/* Tab space options */
unsigned int tabspaces = 8;
/* Misc */
#define USEXRESOURCES 1 /* Use .Xresources. Set to 0 if you do not want .Xresources support. */
/* Tab spacing options */
unsigned int tabspaces = 4; /* Spaces per tab */

View file

@ -1,10 +1,10 @@
# st version
VERSION = 0.8.5
VERSION = 0.1
# Customize below to fit your system
# paths
PREFIX = /usr
PREFIX = /usr/local
APPPREFIX = $(PREFIX)/share/applications
MANPREFIX = $(PREFIX)/share/man
ICONPREFIX = $(PREFIX)/share/pixmaps
@ -18,23 +18,23 @@ PKG_CONFIG = pkg-config
# includes and libs
INCS = -I$(X11INC) \
`$(PKG_CONFIG) --cflags fontconfig` \
`$(PKG_CONFIG) --cflags freetype2` \
`$(PKG_CONFIG) --cflags harfbuzz`
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lgd -lXrandr \
`$(PKG_CONFIG) --cflags harfbuzz` \
`$(PKG_CONFIG) --cflags freetype2`
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender -lgd \
`$(PKG_CONFIG) --libs fontconfig` \
`$(PKG_CONFIG) --libs freetype2` \
`$(PKG_CONFIG) --libs harfbuzz`
`$(PKG_CONFIG) --libs harfbuzz` \
`$(PKG_CONFIG) --libs freetype2`
# flags
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -DICON=\"$(ICONPREFIX)/$(ICONNAME)\" -D_XOPEN_SOURCE=600
STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) -Ofast
STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS)
STLDFLAGS = $(LIBS) $(LDFLAGS)
# OpenBSD:
#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
# `$(PKG_CONFIG) --libs fontconfig` \
# `$(PKG_CONFIG) --libs harfbuzz` \
# `$(PKG_CONFIG) --libs freetype2`
#MANPREFIX = ${PREFIX}/man

0
scripts/st_buffer Normal file → Executable file
View file

6
scripts/st_help Normal file
View file

@ -0,0 +1,6 @@
#!/bin/sh
#
clear
echo "This is a test of the st help keybind!"
echo "It is still work in progress, I will get to writing documentation and stuff here soon!"

0
scripts/st_urllist Normal file → Executable file
View file

0
scripts/st_xurls Normal file → Executable file
View file

1543
st.c

File diff suppressed because it is too large Load diff

View file

@ -9,4 +9,4 @@ Categories=System;TerminalEmulator;
Name=st
GenericName=Terminal
Comment=st is a simple terminal implementation for X
StartupWMClass=xterm-256color
StartupWMClass=st-256color

49
st.h
View file

@ -22,24 +22,23 @@
#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
#define IS_TRUECOL(x) (1 << 24 & (x))
#define HISTSIZE 2000
enum glyph_attribute {
ATTR_NULL = 0,
ATTR_SET = 1 << 0,
ATTR_BOLD = 1 << 1,
ATTR_FAINT = 1 << 2,
ATTR_ITALIC = 1 << 3,
ATTR_UNDERLINE = 1 << 4,
ATTR_BLINK = 1 << 5,
ATTR_REVERSE = 1 << 6,
ATTR_INVISIBLE = 1 << 7,
ATTR_STRUCK = 1 << 8,
ATTR_WRAP = 1 << 9,
ATTR_WIDE = 1 << 10,
ATTR_WDUMMY = 1 << 11,
ATTR_BOXDRAW = 1 << 12,
ATTR_LIGA = 1 << 13,
ATTR_SELECTED = 1 << 14,
ATTR_NULL = 0,
ATTR_BOLD = 1 << 0,
ATTR_FAINT = 1 << 1,
ATTR_ITALIC = 1 << 2,
ATTR_UNDERLINE = 1 << 3,
ATTR_BLINK = 1 << 4,
ATTR_REVERSE = 1 << 5,
ATTR_INVISIBLE = 1 << 6,
ATTR_STRUCK = 1 << 7,
ATTR_WRAP = 1 << 8,
ATTR_WIDE = 1 << 9,
ATTR_WDUMMY = 1 << 10,
ATTR_BOXDRAW = 1 << 11,
ATTR_LIGA = 1 << 12,
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
ATTR_DIRTYUNDERLINE = 1 << 15,
};
@ -83,7 +82,7 @@ typedef union {
int i;
uint ui;
float f;
char *ca;
char *scmd;
const void *v;
const char *s;
} Arg;
@ -92,10 +91,9 @@ void die(const char *, ...);
void redraw(void);
void draw(void);
void kscrolldown(const Arg *);
void kscrollup(const Arg *);
void externalpipe(const Arg *);
void externalpipe(const Arg *, int in);
void externalpipein(const Arg *);
void externalpipeout(const Arg *);
void kexec(const Arg *);
void kwrite(const Arg *);
void printscreen(const Arg *);
@ -105,7 +103,6 @@ void toggleprinter(const Arg *);
int tattrset(int);
void tnew(int, int);
int tisaltscreen(void);
void tresize(int, int);
void tsetdirtattr(int);
void ttyhangup(void);
@ -128,8 +125,7 @@ size_t utf8encode(Rune, char *);
void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *);
void openUrlOnClick(int, int, char *);
int trt_kbdselect(KeySym, char *, int);
int isboxdraw(Rune);
ushort boxdrawindex(const Glyph *);
@ -139,8 +135,9 @@ void boxdraw_xinit(Display *, Colormap, XftDraw *, Visual *);
void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpec *, int);
#endif
void openUrlOnClick(int, int, char *);
/* config.h globals */
extern char *externalpipe_sigusr1[];
extern char *utmp;
extern char *scroll;
extern char *stty_args;
@ -153,4 +150,6 @@ extern unsigned int tabspaces;
extern unsigned int defaultfg;
extern unsigned int defaultbg;
extern unsigned int defaultcs;
extern const int boxdraw, boxdraw_bold, boxdraw_braille;
extern int uexternalpipe;
extern int boxdraw, boxdraw_bold, boxdraw_braille;
extern float alpha;

View file

@ -173,7 +173,7 @@ st-mono| simpleterm monocolor,
sitm=\E[3m,
sgr0=\E[0m,
smacs=\E(0,
smcup=\E[?1049h,
smcup=\E[?1049h\E[22;0;0t,
smir=\E[4h,
smkx=\E[?1h\E=,
smso=\E[7m,
@ -204,7 +204,6 @@ st| simpleterm,
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
st-256color| simpleterm with 256 colors,
Su,
use=st,
ccc,
colors#256,
@ -214,8 +213,6 @@ st-256color| simpleterm with 256 colors,
initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
Smulx=\E[4:%p1%dm,
st-meta| simpleterm with meta key,
use=st,

7
text.h Normal file
View file

@ -0,0 +1,7 @@
/* Miscellanious text related options that you probably do not need to change. */
/* Ascii characters used to estimate the advance width of single wide characters */
static char ascii_printable[] =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";

8
win.h
View file

@ -21,6 +21,7 @@ enum win_mode {
MODE_NUMLOCK = 1 << 17,
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|MODE_MOUSEMANY,
MODE_KBDSELECT = 1 << 18,
};
void xbell(void);
@ -32,11 +33,14 @@ void xloadcols(void);
int xsetcolorname(int, const char *);
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
void xseticontitle(char *);
void xsettitle(char *);
void xfreetitlestack(void);
void xsettitle(char *, int);
void xpushtitle(void);
int xsetcursor(int);
void xsetmode(int, unsigned int);
void xsetpointermotion(int);
void xsetsel(char *);
int xstartdraw(void);
void toggle_winmode(int);
void keyboard_select(const Arg *);
void xximspot(int, int);
void xclearwin(void);

384
x.c
View file

@ -14,7 +14,6 @@
#include <X11/keysym.h>
#include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xresource.h>
char *argv0;
@ -23,7 +22,7 @@ char *argv0;
#include "win.h"
#include "hb.h"
/* types used in config.h */
/* types used in options.h */
typedef struct {
uint mod;
KeySym keysym;
@ -69,27 +68,12 @@ enum undercurl_slope_type {
UNDERCURL_SLOPE_BOTTOM_CAP = 3
};
typedef struct {
const char *name;
float defaultfontsize;
} MonitorConfig;
typedef struct {
Atom name;
int x, y, w, h;
float defaultfontsize, usedfontsize;
} MonitorInfo;
static void refreshxrandr(const Arg *dummy);
/* X modifiers */
#define XK_ANY_MOD UINT_MAX
#define XK_NO_MOD 0
#define XK_SWITCH_MOD (1<<13|1<<14)
static int cursorblinks = 0;
/* function definitions used in config.h */
/* function definitions used in options.h */
static void clipcopy(const Arg *);
static void clippaste(const Arg *);
static void numlock(const Arg *);
@ -98,25 +82,33 @@ static void zoom(const Arg *);
static void zoomabs(const Arg *);
static void zoomreset(const Arg *);
static void ttysend(const Arg *);
void kscrollup(const Arg *);
void kscrolldown(const Arg *);
/* define undercurl values to use later */
#define UNDERCURL_CURLY 0
#define UNDERCURL_SPIKY 1
#define UNDERCURL_CAPPED 2
#include "options.h" /* include user configuration */
#include "external.h" /* include externalpipe options */
#include "char.h" /* include misc chars */
#if USEXRESOURCES
#include "xresources.h" /* include .xresources/xrdb options */
#endif
/* define keys */
#define CONTROL ControlMask
#define SHIFT ShiftMask
#define ALT Mod1Mask
#define ALTR Mod3Mask
#define SUPER Mod4Mask
#define SUPERR Mod5Mask
#define ANY UINT_MAX
#define NONE 0
/* headers */
#include "options.h" /* include user options */
#include "text.h" /* include text related misc options */
#include "external.h" /* include externalpipe chars */
#include "modifiers.h" /* include modifiers */
#include "keybinds.h" /* include keybinds */
#include "mouse.h" /* include mouse binds */
#include "mapped.h" /* include list of mapped keys */
#include "mouse.h" /* include mouse options */
#include "colors.h" /* include color array */
#include "xresources.h" /* include xresources options */
#include "array.h" /* include key array */
/* size of title stack */
#define TITLESTACKSIZE 8
/* XEMBED messages */
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
@ -138,6 +130,7 @@ typedef struct {
int hborderpx, vborderpx;
int ch; /* char height */
int cw; /* char width */
int cyo; /* char y offset */
int mode; /* window state/mode flags */
int cursor; /* cursor style */
} TermWindow;
@ -163,7 +156,6 @@ typedef struct {
int depth; /* bit depth */
int l, t; /* left and top offset */
int gm; /* geometry mask */
int cyo;
} XWindow;
typedef struct {
@ -274,17 +266,13 @@ static void (*handler[LASTEvent])(XEvent *) = {
[SelectionRequest] = selrequest,
};
static double defaultrelfontsize = 0;
static MonitorInfo *monitors_info = NULL;
static int monitors_num = 0;
static int prev_mindex = -1;
/* Globals */
static DC dc;
static XWindow xw;
static XSelection xsel;
static TermWindow win;
static int pendingkpress = 0;
static int tstki; /* title stack index */
static char *titlestack[TITLESTACKSIZE]; /* title stack */
/* Font Ring Cache */
enum {
@ -308,6 +296,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;
@ -317,6 +306,7 @@ static char *opt_line = NULL;
static char *opt_name = NULL;
static char *opt_title = NULL;
static int cursorblinks = 0;
static uint buttons; /* bit field of pressed buttons */
void
@ -555,9 +545,9 @@ bpress(XEvent *e)
* snapping behaviour is exposed.
*/
clock_gettime(CLOCK_MONOTONIC, &now);
if (TIMEDIFF(now, xsel.tclick2) <= tctimeout) {
if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) {
snap = SNAP_LINE;
} else if (TIMEDIFF(now, xsel.tclick1) <= dctimeout) {
} else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) {
snap = SNAP_WORD;
} else {
snap = 0;
@ -884,6 +874,9 @@ xloadcols(void)
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;
@ -917,12 +910,6 @@ xsetcolorname(int x, const char *name)
XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
dc.col[x] = ncolor;
if (x == defaultbg) {
dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha);
dc.col[defaultbg].pixel &= 0x00FFFFFF;
dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24;
}
return 0;
}
@ -937,12 +924,6 @@ xclear(int x1, int y1, int x2, int y2)
x1, y1, x2-x1, y2-y1);
}
void
xclearwin(void)
{
xclear(0, 0, win.w, win.h);
}
void
xhints(void)
{
@ -1015,7 +996,7 @@ xloadfont(Font *f, FcPattern *pattern)
FcConfigSubstitute(NULL, configured, FcMatchPattern);
XftDefaultSubstitute(xw.dpy, xw.scr, configured);
match = XftFontMatch(xw.dpy, xw.scr, pattern, &result);
match = FcFontMatch(NULL, configured, &result);
if (!match) {
FcPatternDestroy(configured);
return 1;
@ -1118,7 +1099,7 @@ xloadfonts(const char *fontstr, double fontsize)
/* Setting character width and height. */
win.cw = ceilf(dc.font.width * cwscale);
win.ch = ceilf(dc.font.height * chscale);
xw.cyo = ceilf(dc.font.height * (chscale - 1) / 2);
win.cyo = ceilf(dc.font.height * (chscale - 1) / 2);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
@ -1494,7 +1475,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
FcCharSet *fccharset;
int i, f, numspecs = 0;
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
for (i = 0, xp = winx, yp = winy + font->ascent + win.cyo; i < len; ++i) {
/* Fetch rune and mode for current glyph. */
rune = glyphs[i].u;
mode = glyphs[i].mode;
@ -1519,7 +1500,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
font = &dc.bfont;
frcflags = FRC_BOLD;
}
yp = winy + font->ascent + xw.cyo;
yp = winy + font->ascent + win.cyo;
}
if (mode & ATTR_BOXDRAW) {
@ -1532,8 +1513,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
if (glyphidx) {
specs[numspecs].font = font->match;
specs[numspecs].glyph = glyphidx;
specs[numspecs].x = (short)xp + cxoffset;
specs[numspecs].y = (short)yp + cyoffset;
specs[numspecs].x = (short)xp;
specs[numspecs].y = (short)yp;
xp += runewidth;
numspecs++;
continue;
@ -1673,20 +1654,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
XRenderColor colfg, colbg;
XRectangle r;
/*
if (understyle = "1") {
#define UNDERCURL_STYLE UNDERCURL_CURLY
}
if (understyle = "2") {
#define UNDERCURL_STYLE UNDERCURL_SPIKY
}
if (understyle = "3") {
#define UNDERCURL_STYLE UNDERCURL_CAPPED
}
*/
/* Fallback on color display for attributes not supported by the font */
if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
if (dc.ibfont.badslant || dc.ibfont.badweight)
@ -1720,7 +1687,8 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* 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 (boldbright)
fg = &dc.col[base.fg + 8];
if (IS_SET(MODE_REVERSE)) {
if (fg == &dc.col[defaultfg]) {
@ -1803,8 +1771,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Render underline and strikethrough. */
if (base.mode & ATTR_UNDERLINE) {
//XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
// width, 1);
// Underline Color
const int widthThreshold = 28; // +1 width every widthThreshold px of font
int wlw = (win.ch / widthThreshold) + 1; // Wave Line Width
@ -1900,7 +1866,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
*/
wh *= 2;
// Set the angle of the slope to 45°
// Set the angle of the slope to 45°
ww = wh;
// Position of wave is independent of word, it's absolute
@ -1992,15 +1958,14 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
// Free resources
free(points);
}
} else if (understyle = "3") {
// Cap is half of wave width
}
} else if (understyle = "3") {
float capRatio = 0.5f;
// Make the underline corridor larger
wh *= 2;
// Set the angle of the slope to 45°
// Set the angle of the slope to 45°
ww = wh;
ww *= 1 + capRatio; // Add a bit of width for the cap
@ -2159,7 +2124,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
}
if (base.mode & ATTR_STRUCK) {
XftDrawRect(xw.draw, fg, winx, winy + xw.cyo + 2 * dc.font.ascent * chscale / 3,
XftDrawRect(xw.draw, fg, winx, winy + win.cyo + 2 * dc.font.ascent * chscale / 3,
width, 1);
}
@ -2186,7 +2151,6 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int le
/* remove the old cursor */
if (selected(ox, oy))
og.mode ^= ATTR_REVERSE;
//xdrawglyph(og, ox, oy);
xdrawline(line, 0, oy, len);
if (IS_SET(MODE_HIDE))
@ -2202,15 +2166,15 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int le
g.bg = defaultfg;
if (selected(cx, cy)) {
drawcol = dc.col[defaultcs];
g.fg = defaultrcs;
g.fg = defaultrc;
} else {
drawcol = dc.col[defaultrcs];
drawcol = dc.col[defaultrc];
g.fg = defaultcs;
}
} else {
if (selected(cx, cy)) {
g.fg = defaultfg;
g.bg = defaultrcs;
g.bg = defaultrc;
} else {
/** this is the main part of the dynamic cursor color patch */
g.bg = g.fg;
@ -2261,16 +2225,16 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int le
/* FALLTHROUGH */
case 6: /* steady bar */
XftDrawRect(xw.draw, &drawcol,
win.hborderpx + cx * win.cw,
win.vborderpx + cy * win.ch,
cursorthickness, win.ch);
win.hborderpx + cx * win.cw,
win.vborderpx + 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;
g.u = ccursor;
xdrawglyph(g, cx, cy);
break;
}
@ -2318,10 +2282,30 @@ xseticontitle(char *p)
}
void
xsettitle(char *p)
xfreetitlestack(void)
{
XTextProperty prop;
DEFAULT(p, opt_title);
for (int i = 0; i < LEN(titlestack); i++) {
free(titlestack[i]);
titlestack[i] = NULL;
}
}
void
xsettitle(char *p, int pop)
{
XTextProperty prop;
free(titlestack[tstki]);
if (pop) {
titlestack[tstki] = NULL;
tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE;
p = titlestack[tstki] ? titlestack[tstki] : opt_title;
} else if (p) {
titlestack[tstki] = xstrdup(p);
} else {
titlestack[tstki] = NULL;
p = opt_title;
}
if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
&prop) != Success)
@ -2331,6 +2315,16 @@ xsettitle(char *p)
XFree(prop.value);
}
void
xpushtitle(void)
{
int tstkin = (tstki + 1) % TITLESTACKSIZE;
free(titlestack[tstkin]);
titlestack[tstkin] = titlestack[tstki] ? xstrdup(titlestack[tstki]) : NULL;
tstki = tstkin;
}
int
xstartdraw(void)
{
@ -2346,8 +2340,6 @@ xdrawline(Line line, int x1, int y1, int x2)
Glyph base, new;
XftGlyphFontSpec *specs = xw.specbuf;
pendingkpress = 0;
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
i = ox = 0;
for (x = x1; x < x2 && i < numspecs; x++) {
@ -2452,144 +2444,6 @@ xseturgency(int add)
XFree(h);
}
static void
cachemonitorinfo()
{
int prev_num = monitors_num;
MonitorInfo *prev_info = monitors_info;
XRRMonitorInfo *xmonitors = XRRGetMonitors(xw.dpy, XRootWindow(xw.dpy, xw.scr), 1, &monitors_num);
if (!monitors_num)
die("xrandr found no monitors");
monitors_info = xmalloc(monitors_num * sizeof(MonitorInfo));
for (int i = 0; i < monitors_num; ++i) {
XRRMonitorInfo *xm = &xmonitors[i];
MonitorInfo *m = &monitors_info[i];
m->name = xm->name;
m->x = xm->x;
m->y = xm->y;
m->w = xm->width;
m->h = xm->height;
float px_mm = ((float)m->w / xm->mwidth + (float)m->h / xm->mheight) / 2;
float px_pt = 25.4 * px_mm / 72;
m->defaultfontsize = defaultrelfontsize * px_pt;
// Override defaultfontsize (dpi) by user config
char *name = XGetAtomName(xw.dpy, xm->name);
for (int j = 0; j < LEN(monitors_config); ++j)
if (!strcmp(name, monitors_config[j].name)) {
m->defaultfontsize = monitors_config[j].defaultfontsize;
if (m->defaultfontsize < 0)
m->defaultfontsize *= -px_pt;
break;
}
// fprintf(stderr, "%s: %fpx, %f\n", name, m->defaultfontsize, m->usedfontsize);
XFree(name);
// Restore usedfontsize (zoom) after re-cache for monitors with the same name
m->usedfontsize = m->defaultfontsize;
for (int j = 0; j < prev_num; ++j)
if (prev_info[j].name == m->name) {
m->usedfontsize = prev_info[j].usedfontsize;
break;
}
}
XRRFreeMonitors(xmonitors);
free(prev_info);
}
static int
getmonitorindex_threshold(int w, int h, int x, int y)
{
int mindex = -1;
float fontsize = 0;
int thresholdarea = winmovethreshold * w * h;
for (int i = 0; i < monitors_num; ++i) {
MonitorInfo *m = &monitors_info[i];
int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x));
int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y));
int area = overlap_w * overlap_h;
// Choose monitor with largest dpi (defaultfontsize)
// from all "mirrored"/overlapped (e.g. projector)
if (area >= thresholdarea && fontsize < m->defaultfontsize) {
fontsize = m->defaultfontsize;
mindex = i;
}
}
return mindex;
}
static int
getmonitorindex_nearest(int w, int h, int x, int y)
{
int mindex = -1;
float fontsize = 0;
int overlaparea = 0;
for (int i = 0; i < monitors_num; ++i) {
MonitorInfo *m = &monitors_info[i];
int overlap_w = MAX(0, MIN(x + w, m->x + m->w) - MAX(x, m->x));
int overlap_h = MAX(0, MIN(y + h, m->y + m->h) - MAX(y, m->y));
int area = overlap_w * overlap_h;
// Choose monitor with largest overlapping area
// e.g. when "st" is initially spawned in-between monitors
if (area > overlaparea) {
overlaparea = area;
mindex = i;
}
}
return mindex;
}
static void
adjustmonitorfontsize(int mindex)
{
if (mindex < 0 || prev_mindex == mindex)
return;
// Save zoom of current monitor before switching
if (prev_mindex >= 0)
monitors_info[prev_mindex].usedfontsize = usedfontsize;
defaultfontsize = monitors_info[mindex].defaultfontsize;
// fprintf(stderr, "Crossing: %fpx\n", defaultfontsize);
// NOTE: do nothing if font size differs by less than 1%
double fontsize = monitors_info[mindex].usedfontsize;
double delta = 0.01 * usedfontsize;
if (!BETWEEN(fontsize - usedfontsize, -delta, delta)) {
// fprintf(stderr, "Adjusted: %fpx\n", fontsize);
xunloadfonts();
xloadfonts(usedfont, fontsize);
}
prev_mindex = mindex;
}
void
refreshxrandr(const Arg *dummy)
{
// Reset index to detect change of window association on "xrandr ... --primary"
// otherwise: zoom won't be saved on switching and new font size won't be loaded
// CRIT!!! event from xrandr may place another monitor into same index
if (prev_mindex >= 0)
monitors_info[prev_mindex].usedfontsize = usedfontsize;
prev_mindex = -1;
XWindowAttributes xattr = {0};
cachemonitorinfo();
XGetWindowAttributes(xw.dpy, xw.win, &xattr);
int mindex = getmonitorindex_threshold(xattr.width, xattr.height, xattr.x, xattr.y);
if (mindex < 0)
mindex = getmonitorindex_nearest(xattr.width, xattr.height, xattr.x, xattr.y);
adjustmonitorfontsize(mindex);
}
void
xbell(void)
{
@ -2677,8 +2531,6 @@ kpress(XEvent *ev)
Status status;
Shortcut *bp;
pendingkpress = 1;
if (IS_SET(MODE_KBDLOCK))
return;
@ -2686,6 +2538,12 @@ kpress(XEvent *ev)
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
else
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
if ( IS_SET(MODE_KBDSELECT) ) {
if ( match(XK_NO_MOD, e->state) ||
(XK_Shift_L | XK_Shift_R) & e->state )
win.mode ^= trt_kbdselect(ksym, buf, len);
return;
}
/* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) {
@ -2694,7 +2552,7 @@ kpress(XEvent *ev)
}
}
/* 2. custom keys from config.h */
/* 2. custom keys from options.h */
if ((customkey = kmap(ksym, e->state))) {
ttywrite(customkey, strlen(customkey), 1);
return;
@ -2741,14 +2599,6 @@ cmessage(XEvent *e)
void
resize(XEvent *e)
{
// BAD: no resize on monitor plug/unplug/reconfigure -- until window itself is kept in the same place
// NOTE: no resize event on zoomabs()
// fprintf(stderr, "Resize: %dx%d+%d+%d\n",
// e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y);
adjustmonitorfontsize(getmonitorindex_threshold(
e->xconfigure.width, e->xconfigure.height, e->xconfigure.x, e->xconfigure.y));
if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
return;
@ -2784,22 +2634,6 @@ run(void)
}
} while (ev.type != MapNotify);
int rr_event_base, rr_error_base, rr_major, rr_minor;
if (!XRRQueryExtension (xw.dpy, &rr_event_base, &rr_error_base) ||
!XRRQueryVersion (xw.dpy, &rr_major, &rr_minor) ||
rr_major < 1 || (rr_major == 1 && rr_minor < 5))
{
die("RandR 1.5 extension isn't available\n");
}
XRRSelectInput(xw.dpy, xw.win, RRCrtcChangeNotifyMask);
// WARN: can query actual window size/pos only after window is mapped and its width/height are adjusted by WM
// * x/y are WM-dependent and can't be determined beforehand anyway
// * defaultfontsize isn't available until font is loaded and actual Fc*() size queried
// BAD: fonts on startup are always reloaded -- how to specify their size beforehand ?
FcPatternGetDouble(dc.font.match->pattern, FC_SIZE, 0, &defaultrelfontsize);
refreshxrandr(0);
ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
cresize(w, h);
@ -2815,9 +2649,6 @@ run(void)
seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec);
tv = timeout >= 0 ? &seltv : NULL;
if (pendingkpress)
draw();
if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
if (errno == EINTR)
continue;
@ -2835,16 +2666,6 @@ run(void)
XNextEvent(xw.dpy, &ev);
if (XFilterEvent(&ev, None))
continue;
if (LASTEvent <= ev.type) {
if (rr_event_base + RRNotify == ev.type &&
RRNotify_CrtcChange == ((XRRNotifyEvent *)&ev)->subtype)
{
XRRUpdateConfiguration(&ev);
// fprintf(stderr, "Monitor change: %d > %d\n", rr_event_base, LASTEvent);
refreshxrandr(0);
}
continue;
}
if (handler[ev.type])
(handler[ev.type])(&ev);
}
@ -2875,7 +2696,7 @@ run(void)
continue; /* we have time, try to find idle */
}
if (tinsync(su_timeout)) {
if (tinsync(synctimeout)) {
/*
* on synchronized-update draw-suspension: don't reset
* drawing so that we draw ASAP once we can (just after
@ -2922,7 +2743,7 @@ resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
snprintf(fullname, sizeof(fullname), "%s.%s",
opt_name ? opt_name : "st", name);
snprintf(fullclass, sizeof(fullclass), "%s.%s",
opt_class ? opt_class : "St", name);
opt_class ? opt_class : "st", name);
fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
XrmGetResource(db, fullname, fullclass, &type, &ret);
@ -2956,10 +2777,8 @@ config_init(void)
return;
db = XrmGetStringDatabase(resm);
#if USEXRESOURCES
for (p = resources; p < resources + LEN(resources); p++)
resource_load(db, p->name, p->type, p->dst);
#endif
}
void
@ -2975,6 +2794,14 @@ usage(void)
" [stty_args ...]\n", argv0, argv0);
}
void toggle_winmode(int flag) {
win.mode ^= flag;
}
void keyboard_select(const Arg *dummy) {
win.mode ^= trt_kbdselect(-1, NULL, 0);
}
int
main(int argc, char *argv[])
{
@ -2987,8 +2814,7 @@ main(int argc, char *argv[])
allowaltscreen = 0;
break;
case 'A':
alpha = strtof(EARGF(usage()), NULL);
LIMIT(alpha, 0.0, 1.0);
opt_alpha = EARGF(usage());
break;
case 'c':
opt_class = EARGF(usage());

View file

@ -1,38 +1,45 @@
/* This header contains .Xresources/xrdb options that st can load and use.
* If available, these will be used instead of the compiled in options meaning you can change options without recompiling st.
*
* A full list of all options as well as an example .Xresources file can be found in 'docs/example.Xresources'.
*/
ResourcePref resources[] = {
{ "font", STRING, &font },
{ "color0", STRING, &colorname[0] },
{ "color1", STRING, &colorname[1] },
{ "color2", STRING, &colorname[2] },
{ "color3", STRING, &colorname[3] },
{ "color4", STRING, &colorname[4] },
{ "color5", STRING, &colorname[5] },
{ "color6", STRING, &colorname[6] },
{ "color7", STRING, &colorname[7] },
{ "color8", STRING, &colorname[8] },
{ "color9", STRING, &colorname[9] },
{ "color10", STRING, &colorname[10] },
{ "color11", STRING, &colorname[11] },
{ "color12", STRING, &colorname[12] },
{ "color13", STRING, &colorname[13] },
{ "color14", STRING, &colorname[14] },
{ "color15", STRING, &colorname[15] },
{ "background", STRING, &colorname[259] },
{ "foreground", STRING, &colorname[258] },
{ "cursorColor", STRING, &colorname[256] },
{ "termname", STRING, &termname },
{ "shell", STRING, &shell },
{ "minlatency", INTEGER, &minlatency },
{ "maxlatency", INTEGER, &maxlatency },
{ "blinktimeout", INTEGER, &blinktimeout },
{ "bellvolume", INTEGER, &bellvolume },
{ "tabspaces", INTEGER, &tabspaces },
{ "borderpx", INTEGER, &borderpx },
{ "cwscale", FLOAT, &cwscale },
{ "chscale", FLOAT, &chscale },
{ "font", STRING, &font },
{ "color0", STRING, &colorname[0] },
{ "color1", STRING, &colorname[1] },
{ "color2", STRING, &colorname[2] },
{ "color3", STRING, &colorname[3] },
{ "color4", STRING, &colorname[4] },
{ "color5", STRING, &colorname[5] },
{ "color6", STRING, &colorname[6] },
{ "color7", STRING, &colorname[7] },
{ "color8", STRING, &colorname[8] },
{ "color9", STRING, &colorname[9] },
{ "color10", STRING, &colorname[10] },
{ "color11", STRING, &colorname[11] },
{ "color12", STRING, &colorname[12] },
{ "color13", STRING, &colorname[13] },
{ "color14", STRING, &colorname[14] },
{ "color15", STRING, &colorname[15] },
{ "background", STRING, &colorname[259] },
{ "foreground", STRING, &colorname[258] },
{ "cursorColor", STRING, &colorname[257] },
{ "termname", STRING, &termname },
{ "shell", STRING, &shell },
{ "understyle", STRING, &understyle },
{ "url_opener", STRING, &url_opener },
{ "minlatency", INTEGER, &minlatency },
{ "synctimeout", INTEGER, &synctimeout },
{ "maxlatency", INTEGER, &maxlatency },
{ "blinktimeout", INTEGER, &blinktimeout },
{ "bellvolume", INTEGER, &bellvolume },
{ "tabspaces", INTEGER, &tabspaces },
{ "borderpx", INTEGER, &borderpx },
{ "boxdraw", INTEGER, &boxdraw },
{ "boxdraw_bold", INTEGER, &boxdraw_bold },
{ "boxdraw_braille", INTEGER, &boxdraw_braille },
{ "defaultfg", INTEGER, &defaultfg },
{ "defaultbg", INTEGER, &defaultbg },
{ "defaultcs", INTEGER, &defaultcs },
{ "defaultrc", INTEGER, &defaultrc },
{ "cursorstyle", INTEGER, &cursorstyle },
{ "boldbright", INTEGER, &boldbright },
{ "alpha", FLOAT, &alpha },
{ "cwscale", FLOAT, &cwscale },
{ "chscale", FLOAT, &chscale },
};