Compare commits

...

21 commits

Author SHA1 Message Date
ant
4c439e7b8e use "emoji" as fallback font to prevent crash when emoji is not found 2026-03-12 21:13:02 +01:00
ant
0814fc7a5d symplify nix flake 2026-03-12 21:12:53 +01:00
Antoine Vaure
3d9c53068d fix: missing else in previous commit 2026-03-12 19:31:43 +01:00
Antoine Vaure
9e96ffc61e fix: alt key with two bytes keys 2026-03-12 19:31:43 +01:00
ant
f2fdc033cb Revert "change colors for light theme"
This reverts commit 042af42400.
2026-03-12 19:31:43 +01:00
Antoine Vaure
f627e69374 change colors for light theme 2026-03-12 19:31:43 +01:00
Antoine Vaure
5efe76d0f6 add keybinnds to scroll 2026-03-12 19:31:43 +01:00
Antoine Vaure
a2c1ab5706 decrease default font size 2026-03-12 19:31:43 +01:00
ant
4a5abeb82a Enable alpha patch 2026-03-12 19:31:43 +01:00
ant
89749e9515 enable boxdraw 2026-03-12 19:31:43 +01:00
ant
405415b61d Add a nix flake 2026-03-12 19:31:43 +01:00
ant
cc4388ac0d enable patches I want 2026-03-12 19:31:43 +01:00
ant
a3de76da58 change keys to keyboard select and zoom 2026-03-12 19:31:43 +01:00
ant
03c0eb9d1e change default colors 2026-03-12 19:31:43 +01:00
ant
d8bf6e236f Add darkman patch
a patch to choose between two color themes by executing a command
2026-03-12 19:31:43 +01:00
ant
74ca31c0ec font default to caskadia 2026-03-12 19:31:43 +01:00
Antoine Vaure
51ba63e165 config: increase scroll speed 2026-03-12 19:31:43 +01:00
ant
a7d0ea2d33 fontfeature patch 2026-03-12 19:31:43 +01:00
Bakkeby
dab1ddca8c Bump to 688f70a. st: guard tsetdirt() against zero-sized terminal
tsetdirt() assumes term.row > 0. During early init or
resize paths this may not hold, leading to out-of-bounds
access. Bail out early if there are no rows.

https://git.suckless.org/st/commit/688f70add0d1da8a416bf7df763328d694a24a3a.html
2026-02-18 11:21:22 +01:00
Bakkeby
721a690877 Bump to 0723b7e. Disable bracked paste in reset.
Sadly, there are too many programs today that enable this mode
and it is becoming very common to find the terminal adding
characters before and after in every of your pastes. A reset
should disable this mode.

https://git.suckless.org/st/commit/0723b7e39e73b2bcfce047b047f6e795d6184028.html
2026-02-18 11:19:39 +01:00
Bakkeby
cc852e9a86 Skip DCS escape sequences if buffer is full ref. #190 2026-02-14 21:09:51 +01:00
10 changed files with 308 additions and 76 deletions

View file

@ -1,4 +1,4 @@
Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.9.3 (6e97047, 2025-08-09) project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more.
Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.9.3 (688f70a, 2026-01-15) project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more.
For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/st-flexipatch/blob/master/patches.def.h):
```c

View file

@ -5,13 +5,10 @@
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
static char *font = "Cascadia Code NF:regular:pixelsize=13.5:fontfeatures=calt,ss01:antialias=true:autohint=true";
#if FONT2_PATCH
/* Spare fonts */
static char *font2[] = {
/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */
/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */
};
static char *font2[] = { "emoji:pixelsize=13.5:antialias=true:autohint=true" };
#endif // FONT2_PATCH
#if BACKGROUND_IMAGE_PATCH
@ -130,11 +127,11 @@ int hidecursor = 1;
* Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored.
* 0: disable (render all U25XX glyphs normally from the font).
*/
const int boxdraw = 0;
const int boxdraw_bold = 0;
const int boxdraw = 1;
const int boxdraw_bold = 1;
/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */
const int boxdraw_braille = 0;
const int boxdraw_braille = 1;
#endif // BOXDRAW_PATCH
/*
@ -185,35 +182,68 @@ char *xdndescchar = " !\"#$&'()*;<>?[\\]^`{|}~";
#endif // DRAG_AND_DROP_PATCH
/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
/* 8 normal colors */
"black",
"red3",
"green3",
"yellow3",
"blue2",
"magenta3",
"cyan3",
"gray90",
/* 8 bright colors */
"gray50",
"red",
"green",
"yellow",
"#5c5cff",
"magenta",
"cyan",
"white",
static char *colorname[] = {
"#011627", /* hard contrast: #1d2021 / soft contrast: #32302f */
"#d3423e",
"#2aa298",
"#daaa01",
"#4876d6",
"#403f53",
"#08916a",
"#7a8181",
"#7a8181",
"#f76e6e",
"#49d0c5",
"#dac26b",
"#5ca7e4",
"#697098",
"#00c990",
"#989fb1",
[255] = 0,
/* more colors can be added after 255 to use with DefaultXX */
"#add8e6", /* 256 -> cursor */
"#403f53", /* 256 -> cursor */
"#f2f2f2", /* 257 -> rev cursor*/
"#ffffff", /* 258 -> bg */
"#403f53", /* 259 -> fg */
};
#if DARKMAN_PATCH
#define colorname_len (sizeof(colorname) / sizeof(char *))
enum theme {
THEME_LIGHT,
THEME_DARK,
THEME_NUM,
};
/* Terminal colors (16 first used in escape sequence) */
static const char *colornames[THEME_NUM][colorname_len] = {
{ }, {
"#1a1a1a", /* hard contrast: #1d2021 / soft contrast: #32302f */
"#f4005f",
"#98e024",
"#fa8419",
"#9d65ff",
"#f4005f",
"#58d1eb",
"#c4c5b5",
"#625e4c",
"#f4005f",
"#98e024",
"#e0d561",
"#9d65ff",
"#f4005f",
"#58d1eb",
"#f6f6ef",
[255] = 0,
/* more colors can be added after 255 to use with DefaultXX */
"#aaaaaa", /* 256 -> cursor */
"#555555", /* 257 -> rev cursor*/
"#000000", /* 258 -> bg */
"#e5e5e5", /* 259 -> fg */
};
"#ffffff", /* 259 -> fg */
}};
#endif // DARKMAN_PATCH
/*
@ -380,8 +410,8 @@ static MouseShortcut mshortcuts[] = {
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
#endif // CLIPBOARD_PATCH
#if SCROLLBACK_MOUSE_PATCH
{ ShiftMask, Button4, kscrollup, {.i = 1}, 0, S_PRI},
{ ShiftMask, Button5, kscrolldown, {.i = 1}, 0, S_PRI},
{ ShiftMask, Button4, kscrollup, {.i = 4}, 0, S_PRI},
{ ShiftMask, Button5, kscrolldown, {.i = 4}, 0, S_PRI},
#elif UNIVERSCROLL_PATCH
{ XK_ANY_MOD, Button4, ttysend, {.s = "\033[5;2~"}, 0, S_PRI },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, S_PRI },
@ -390,8 +420,8 @@ static MouseShortcut mshortcuts[] = {
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
#endif // SCROLLBACK_MOUSE_PATCH
#if SCROLLBACK_MOUSE_ALTSCREEN_PATCH || REFLOW_PATCH
{ XK_ANY_MOD, Button4, kscrollup, {.i = 1}, 0, S_PRI },
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, S_PRI },
{ XK_ANY_MOD, Button4, kscrollup, {.i = 4}, 0, S_PRI },
{ XK_ANY_MOD, Button5, kscrolldown, {.i = 4}, 0, S_PRI },
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"}, 0, S_ALT },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"}, 0, S_ALT },
#else
@ -422,8 +452,8 @@ static Shortcut shortcuts[] = {
{ ControlMask, XK_Print, toggleprinter, {.i = 0} },
{ ShiftMask, XK_Print, printscreen, {.i = 0} },
{ XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
{ TERMMOD, XK_Prior, zoom, {.f = +1} },
{ TERMMOD, XK_Next, zoom, {.f = -1} },
{ MODKEY | ControlMask, XK_comma, zoom, {.f = +1} },
{ MODKEY | ControlMask, XK_semicolon, zoom, {.f = -1} },
{ TERMMOD, XK_Home, zoomreset, {.f = 0} },
{ TERMMOD, XK_C, clipcopy, {.i = 0} },
{ TERMMOD, XK_V, clippaste, {.i = 0} },
@ -442,6 +472,10 @@ static Shortcut shortcuts[] = {
#if SCROLLBACK_PATCH || REFLOW_PATCH
{ ShiftMask, XK_Page_Up, kscrollup, {.i = -1}, S_PRI },
{ ShiftMask, XK_Page_Down, kscrolldown, {.i = -1}, S_PRI },
{ TERMMOD, XK_U, kscrollup, {.i = -1}, S_PRI },
{ TERMMOD, XK_D, kscrolldown, {.i = -1}, S_PRI },
{ TERMMOD, XK_K, kscrollup, {.i = 4}, S_PRI },
{ TERMMOD, XK_J, kscrolldown, {.i = 4}, S_PRI },
#endif // SCROLLBACK_PATCH || REFLOW_PATCH
#if CLIPBOARD_PATCH
{ TERMMOD, XK_Y, clippaste, {.i = 0} },
@ -467,7 +501,7 @@ static Shortcut shortcuts[] = {
#endif // EXTERNALPIPEIN_PATCH
#endif // EXTERNALPIPE_PATCH
#if KEYBOARDSELECT_PATCH
{ TERMMOD, XK_Escape, keyboard_select, { 0 } },
{ TERMMOD, XK_space, keyboard_select, { 0 } },
#endif // KEYBOARDSELECT_PATCH
#if KEYBOARDSELECT_PATCH && REFLOW_PATCH
{ TERMMOD, XK_F, searchforward, { 0 } },

View file

@ -21,14 +21,14 @@ PKG_CONFIG = pkg-config
#XCURSOR = `$(PKG_CONFIG) --libs xcursor`
# Uncomment the lines below for the ligatures patch / LIGATURES_PATCH
#LIGATURES_C = hb.c
#LIGATURES_H = hb.h
#LIGATURES_INC = `$(PKG_CONFIG) --cflags harfbuzz`
#LIGATURES_LIBS = `$(PKG_CONFIG) --libs harfbuzz`
LIGATURES_C = hb.c
LIGATURES_H = hb.h
LIGATURES_INC = `$(PKG_CONFIG) --cflags harfbuzz`
LIGATURES_LIBS = `$(PKG_CONFIG) --libs harfbuzz`
# Uncomment this for the SIXEL patch / SIXEL_PATCH
#SIXEL_C = sixel.c sixel_hls.c
#SIXEL_LIBS = `$(PKG_CONFIG) --libs imlib2`
SIXEL_C = sixel.c sixel_hls.c
SIXEL_LIBS = `$(PKG_CONFIG) --libs imlib2`
# Uncomment for the netwmicon patch / NETWMICON_PATCH
#NETWMICON_LIBS = `$(PKG_CONFIG) --libs gdlib`

61
flake.lock generated Normal file
View file

@ -0,0 +1,61 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1773122722,
"narHash": "sha256-FIqHByVqxCprNjor1NqF80F2QQoiiyqanNNefdlvOg4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "62dc67aa6a52b4364dd75994ec00b51fbf474e50",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

63
flake.nix Normal file
View file

@ -0,0 +1,63 @@
{
description = "st terminal";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in rec {
packages.st = pkgs.stdenv.mkDerivation {
pname = "st";
version = "ant";
src = ./.;
postPatch = pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
substituteInPlace config.mk --replace "-lrt" ""
'';
strictDeps = true;
makeFlags = [ "PKG_CONFIG=${pkgs.stdenv.cc.targetPrefix}pkg-config" ];
nativeBuildInputs = with pkgs; [ pkg-config ncurses fontconfig freetype ];
buildInputs = with pkgs; [ libx11 libxft harfbuzz gd glib imlib2 ];
preInstall = ''
export TERMINFO=$out/share/terminfo
'';
installFlags = [ "PREFIX=$(out)" ];
passthru.tests.test = pkgs.nixosTests.terminal-emulators.st;
meta = with pkgs.lib; {
description = "st terminal";
license = licenses.mit;
maintainers = [ "ant" ];
platforms = platforms.unix;
};
};
apps.st = flake-utils.lib.mkApp {
drv = packages.st;
exePath = "/bin/st";
};
apps.default = apps.st;
packages.default = packages.st;
defaultApp = apps.st;
devShell = pkgs.mkShell {
inputsFrom = [ packages.st ];
hardeningDisable = [ "fortify" ];
packages = with pkgs; [
bear
clang-tools
gdb
];
};
});
}

13
hb.c
View file

@ -35,13 +35,6 @@ typedef struct {
static RuneBuffer hbrunebuffer = { 0, NULL };
static hb_buffer_t *hbbuffer;
/*
* 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[] = { };
void
hbcreatebuffer(void)
{
@ -125,7 +118,11 @@ hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int star
hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length);
/* Shape the segment. */
hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t));
#if FONTFEATURES_PATCH
hb_shape(font, buffer, data->features, data->features_count);
#else
hb_shape(font, buffer, NULL, 0);
#endif
/* Get new glyph info. */
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count);

4
hb.h
View file

@ -7,6 +7,10 @@ typedef struct {
hb_glyph_info_t *glyphs;
hb_glyph_position_t *positions;
unsigned int count;
#if FONTFEATURES_PATCH
hb_feature_t *features;
int features_count;
#endif // FONTFEATURES_PATCH
} HbTransformData;
void hbcreatebuffer(void);

View file

@ -14,7 +14,7 @@
* when including this patch.
* https://st.suckless.org/patches/alpha/
*/
#define ALPHA_PATCH 0
#define ALPHA_PATCH 1
/* The alpha focus highlight patch allows the user to specify two distinct opacity values or
* background colors in order to easily differentiate between focused and unfocused terminal
@ -70,12 +70,12 @@
* This patch makes bold text rendered simply as bold, leaving the color unaffected.
* https://st.suckless.org/patches/bold-is-not-bright/
*/
#define BOLD_IS_NOT_BRIGHT_PATCH 0
#define BOLD_IS_NOT_BRIGHT_PATCH 1
/* This patch adds custom rendering of lines/blocks/braille characters for gapless alignment.
* https://st.suckless.org/patches/boxdraw/
*/
#define BOXDRAW_PATCH 0
#define BOXDRAW_PATCH 1
/* By default st only sets PRIMARY on selection.
* This patch makes st set CLIPBOARD on selection.
@ -192,7 +192,7 @@
* that are available to GUI applications.
* https://st.suckless.org/patches/fix_keyboard_input/
*/
#define FIXKEYBOARDINPUT_PATCH 0
#define FIXKEYBOARDINPUT_PATCH 1
/* This patch allows you to add spare font besides the default. Some glyphs can be not present in
* the default font. For this glyphs st uses font-config and try to find them in font cache first.
@ -200,7 +200,7 @@
* So they will be used first for glyphs that are absent in the default font.
* https://st.suckless.org/patches/font2/
*/
#define FONT2_PATCH 0
#define FONT2_PATCH 1
/* This patch adds the ability to toggle st into fullscreen mode.
* Two key bindings are defined: F11 which is typical with other applications and Alt+Enter
@ -239,7 +239,7 @@
*
* https://st.suckless.org/patches/keyboard_select/
*/
#define KEYBOARDSELECT_PATCH 0
#define KEYBOARDSELECT_PATCH 1
/* This patch adds support for drawing ligatures using the Harfbuzz library to transform
* original text of a single line to a list of glyphs with ligatures included.
@ -249,7 +249,14 @@
* https://github.com/cog1to/st-ligatures
* https://st.suckless.org/patches/ligatures/
*/
#define LIGATURES_PATCH 0
#define LIGATURES_PATCH 1
/* This patch add support for custom font features. It depends on the LIGATURES_PATCH patch
*/
#define FONTFEATURES_PATCH 1
#define DARKMAN_PATCH 1
/* This patch makes st ignore terminal color attributes by forcing display of the default
* foreground and background colors only - making for a monochrome look. Idea ref.
@ -295,7 +302,7 @@
* same CWD (current working directory) as the original st instance.
* https://st.suckless.org/patches/newterm/
*/
#define NEWTERM_PATCH 0
#define NEWTERM_PATCH 1
/* This patch will set the _MOTIF_WM_HINTS property for the st window which, if the window manager
* respects it, will show the st window without window decorations.
@ -320,7 +327,7 @@
*
* https://www.reddit.com/r/suckless/comments/cc83om/st_open_url/
*/
#define OPENURLONCLICK_PATCH 0
#define OPENURLONCLICK_PATCH 1
/* This patch allows st to fetch the current working directory through the OSC 7 escape
* sequence emitted by shells. Must be used with newterm patch.
@ -342,7 +349,7 @@
* Text wraps when the terminal window is made smaller.
* Comes with scrollback.
*/
#define REFLOW_PATCH 0
#define REFLOW_PATCH 1
/* This patch allows you to specify a border that is relative in size to the width of a cell
* in the terminal.
@ -359,19 +366,19 @@
/* Scroll back through terminal output using Shift+{PageUp, PageDown}.
* https://st.suckless.org/patches/scrollback/
*/
#define SCROLLBACK_PATCH 0
#define SCROLLBACK_PATCH 1
/* Scroll back through terminal output using Shift+MouseWheel.
* This variant depends on SCROLLBACK_PATCH being enabled.
* https://st.suckless.org/patches/scrollback/
*/
#define SCROLLBACK_MOUSE_PATCH 0
#define SCROLLBACK_MOUSE_PATCH 1
/* Scroll back through terminal output using mouse wheel (when not in MODE_ALTSCREEN).
* This variant depends on SCROLLBACK_PATCH being enabled.
* https://st.suckless.org/patches/scrollback/
*/
#define SCROLLBACK_MOUSE_ALTSCREEN_PATCH 0
#define SCROLLBACK_MOUSE_ALTSCREEN_PATCH 1
/* This patch adds the two color-settings selectionfg and selectionbg to config.def.h.
* Those define the fore- and background colors which are used when text on the screen is selected
@ -405,7 +412,7 @@
*
* https://gist.github.com/saitoha/70e0fdf22e3e8f63ce937c7f7da71809
*/
#define SIXEL_PATCH 0
#define SIXEL_PATCH 1
/* This patch allows clients to embed into the st window and is useful if you tend to
* start X applications from the terminal. For example:
@ -465,7 +472,7 @@
*
* https://st.suckless.org/patches/undercurl/
*/
#define UNDERCURL_PATCH 0
#define UNDERCURL_PATCH 1
/* Allows mouse scroll without modifier keys for regardless of alt screen using the external
* scroll program.

9
st.c
View file

@ -1102,6 +1102,9 @@ tsetdirt(int top, int bot)
{
int i;
if (term.row <= 0)
return;
LIMIT(top, 0, term.row-1);
LIMIT(bot, 0, term.row-1);
@ -3332,6 +3335,7 @@ eschandle(uchar ascii)
resettitle();
xloadcols();
xsetmode(0, MODE_HIDE);
xsetmode(0, MODE_BRCKTPASTE);
#if SCROLLBACK_PATCH && !REFLOW_PATCH
if (!IS_SET(MODE_ALTSCREEN)) {
term.scr = 0;
@ -3466,6 +3470,11 @@ check_control_code:
return;
#if SIXEL_PATCH
} else if (term.esc & ESC_DCS) {
/* Skip if DCS escape sequence buffer is full */
if (csiescseq.len >= sizeof(csiescseq.buf) - 1) {
return;
}
csiescseq.buf[csiescseq.len++] = u;
if (BETWEEN(u, 0x40, 0x7E)
|| csiescseq.len >= \

63
x.c
View file

@ -802,10 +802,13 @@ setsel(char *str, Time t)
#endif // CLIPBOARD_PATCH
}
#if XRESOURCES_PATCH && XRESOURCES_RELOAD_PATCH || BACKGROUND_IMAGE_PATCH && BACKGROUND_IMAGE_RELOAD_PATCH
#if XRESOURCES_PATCH && XRESOURCES_RELOAD_PATCH || BACKGROUND_IMAGE_PATCH && BACKGROUND_IMAGE_RELOAD_PATCH || DARKMAN_PATCH
void
sigusr1_reload(int sig)
{
#if DARKMAN_PATCH
xloadcols();
#endif // DARKMAN_PATCH
#if XRESOURCES_PATCH && XRESOURCES_RELOAD_PATCH
reload_config(sig);
#endif // XRESOURCES_RELOAD_PATCH
@ -988,6 +991,28 @@ xloadalpha(void)
}
#endif // ALPHA_FOCUS_HIGHLIGHT_PATCH
#if DARKMAN_PATCH
void
darkmanThemeChoose() {
FILE *fp;
char path[128];
fp = popen("darkman get", "r");
if (fp == NULL) {
memcpy(colorname, colornames[0], sizeof(colorname));
} else {
/* match the stdout with the theme */
while (fgets(path, sizeof(path)-1, fp) != NULL) {
if (strcmp(path, "light\n") == 0) {
memcpy(colorname, colornames[0], sizeof(colorname));
} else if (strcmp(path, "dark\n") == 0) {
memcpy(colorname, colornames[1], sizeof(colorname));
}
}
}
}
#endif // DARKMAN_PATCH
#if ALPHA_PATCH && ALPHA_FOCUS_HIGHLIGHT_PATCH
void
xloadcols(void)
@ -1021,6 +1046,8 @@ xloadcols(void)
static int loaded;
Color *cp;
darkmanThemeChoose();
if (loaded) {
for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
@ -1770,6 +1797,26 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
xp = winx, yp = winy + font->ascent;
#endif // VERTCENTER_PATCH
cluster_xp = xp; cluster_yp = yp;
#if FONTFEATURES_PATCH
{ // Get font features
shaped.features = (hb_feature_t *) malloc(sizeof(hb_feature_t) * 128);
FcChar8 *s;
int feature_idx = 0;
while (FcPatternGetString(font->pattern, FC_FONT_FEATURES, feature_idx, &s) == FcResultMatch) {
if (strlen(s) != 4)
die("Invalid font feature tag");
if (feature_idx >= 128)
die("Too many font features");
shaped.features[feature_idx].tag = HB_TAG(s[0], s[1], s[2], s[3]);
shaped.features[feature_idx].value = 1;
shaped.features[feature_idx].start = HB_FEATURE_GLOBAL_START;
shaped.features[feature_idx].end = HB_FEATURE_GLOBAL_END;
feature_idx++;
}
shaped.features_count = feature_idx;
}
#endif // FONTFEATURES_PATCH
/* Shape the segment. */
hbtransform(&shaped, font->match, glyphs, 0, len);
#endif // LIGATURES_PATCH
@ -3693,6 +3740,13 @@ kpress(XEvent *ev)
len = 2;
}
}
else if (len > 1 && len != 64 && e->state & Mod1Mask) {
// TODO: does this work with MODE_8BIT ?
for (int i = len; i != 0; i -= 1)
buf[i] = buf[i-1];
buf[0] = '\033';
len += 1;
}
ttywrite(buf, len, 1);
}
@ -4025,9 +4079,12 @@ run:
setlocale(LC_CTYPE, "");
XSetLocaleModifiers("");
#if XRESOURCES_PATCH && XRESOURCES_RELOAD_PATCH || BACKGROUND_IMAGE_PATCH && BACKGROUND_IMAGE_RELOAD_PATCH
#if XRESOURCES_PATCH && XRESOURCES_RELOAD_PATCH || BACKGROUND_IMAGE_PATCH && BACKGROUND_IMAGE_RELOAD_PATCH || DARKMAN_PATCH
signal(SIGUSR1, sigusr1_reload);
#endif // XRESOURCES_RELOAD_PATCH | BACKGROUND_IMAGE_RELOAD_PATCH
#endif // XRESOURCES_RELOAD_PATCH | BACKGROUND_IMAGE_RELOAD_PATCH | DARKMAN_PATCH
#if DARKMAN_PATCH
memcpy(colornames[0], colorname, sizeof(colorname));
#endif // DARKMAN_PATCH
#if XRESOURCES_PATCH
if (!(xw.dpy = XOpenDisplay(NULL)))
die("Can't open display\n");