update st & tabbed
This commit is contained in:
parent
b11885eb57
commit
aba168a9cd
16 changed files with 779 additions and 226 deletions
|
@ -12,6 +12,8 @@ static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
||||||
* 0 = no border, 100 = border width is same as cell width */
|
* 0 = no border, 100 = border width is same as cell width */
|
||||||
int borderperc = 20;
|
int borderperc = 20;
|
||||||
|
|
||||||
|
/* modkey options: ControlMask, ShiftMask or XK_ANY_MOD */
|
||||||
|
static uint url_opener_modkey = XK_ANY_MOD;
|
||||||
static char *url_opener = "xdg-open";
|
static char *url_opener = "xdg-open";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -112,8 +114,6 @@ char *termname = "st-256color";
|
||||||
*/
|
*/
|
||||||
unsigned int tabspaces = 8;
|
unsigned int tabspaces = 8;
|
||||||
|
|
||||||
/* bg opacity */
|
|
||||||
float alpha = 0.8;
|
|
||||||
|
|
||||||
/* Terminal colors (16 first used in escape sequence) */
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
static const char *colorname[] = {
|
static const char *colorname[] = {
|
||||||
|
@ -225,7 +225,6 @@ ResourcePref resources[] = {
|
||||||
{ "borderperc", INTEGER, &borderperc },
|
{ "borderperc", INTEGER, &borderperc },
|
||||||
{ "cwscale", FLOAT, &cwscale },
|
{ "cwscale", FLOAT, &cwscale },
|
||||||
{ "chscale", FLOAT, &chscale },
|
{ "chscale", FLOAT, &chscale },
|
||||||
{ "alpha", FLOAT, &alpha },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -263,6 +262,10 @@ static char *openurlcmd[] = { "/bin/sh", "-c",
|
||||||
"xurls | dmenu -l 10 -w $WINDOWID | xargs -r open",
|
"xurls | dmenu -l 10 -w $WINDOWID | xargs -r open",
|
||||||
"externalpipe", NULL };
|
"externalpipe", NULL };
|
||||||
|
|
||||||
|
static char *setbgcolorcmd[] = { "/bin/sh", "-c",
|
||||||
|
"printf '\033]11;#008000\007'",
|
||||||
|
"externalpipein", NULL };
|
||||||
|
|
||||||
static Shortcut shortcuts[] = {
|
static Shortcut shortcuts[] = {
|
||||||
/* mask keysym function argument */
|
/* mask keysym function argument */
|
||||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||||
|
|
|
@ -12,6 +12,8 @@ static char *font = "FiraCode Nerd Font Mono:pixelsize=12:antialias=true:autohin
|
||||||
* 0 = no border, 100 = border width is same as cell width */
|
* 0 = no border, 100 = border width is same as cell width */
|
||||||
int borderperc = 100;
|
int borderperc = 100;
|
||||||
|
|
||||||
|
/* modkey options: ControlMask, ShiftMask or XK_ANY_MOD */
|
||||||
|
static uint url_opener_modkey = XK_ANY_MOD;
|
||||||
static char *url_opener = "xdg-open";
|
static char *url_opener = "xdg-open";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -112,8 +114,6 @@ char *termname = "st-256color";
|
||||||
*/
|
*/
|
||||||
unsigned int tabspaces = 2;
|
unsigned int tabspaces = 2;
|
||||||
|
|
||||||
/* bg opacity */
|
|
||||||
float alpha = 0.8;
|
|
||||||
|
|
||||||
/* Terminal colors (16 first used in escape sequence) */
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
static const char *colorname[] = {
|
static const char *colorname[] = {
|
||||||
|
@ -178,7 +178,7 @@ static Rune stcursor = 0x2603; /* snowman (U+2603) */
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned int cols = 90;
|
static unsigned int cols = 90;
|
||||||
static unsigned int rows = 30;
|
static unsigned int rows = 34;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default shape of the mouse cursor
|
* Default shape of the mouse cursor
|
||||||
|
@ -225,7 +225,6 @@ ResourcePref resources[] = {
|
||||||
{ "borderperc", INTEGER, &borderperc },
|
{ "borderperc", INTEGER, &borderperc },
|
||||||
{ "cwscale", FLOAT, &cwscale },
|
{ "cwscale", FLOAT, &cwscale },
|
||||||
{ "chscale", FLOAT, &chscale },
|
{ "chscale", FLOAT, &chscale },
|
||||||
{ "alpha", FLOAT, &alpha },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -244,8 +243,6 @@ static MouseShortcut mshortcuts[] = {
|
||||||
{ XK_ANY_MOD, Button2, clippaste, {.i = 0}, 1 },
|
{ XK_ANY_MOD, Button2, clippaste, {.i = 0}, 1 },
|
||||||
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
|
||||||
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
|
||||||
{ ShiftMask, Button4, kscrollup, {.i = 1} },
|
|
||||||
{ ShiftMask, Button5, kscrolldown, {.i = 1} },
|
|
||||||
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
{ XK_NO_MOD, Button4, kscrollup, {.i = 1} },
|
||||||
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1} },
|
||||||
};
|
};
|
||||||
|
@ -265,6 +262,10 @@ static char *openurlcmd[] = { "/bin/sh", "-c",
|
||||||
"xurls | dmenu -l 10 -w $WINDOWID | xargs -r open",
|
"xurls | dmenu -l 10 -w $WINDOWID | xargs -r open",
|
||||||
"externalpipe", NULL };
|
"externalpipe", NULL };
|
||||||
|
|
||||||
|
static char *setbgcolorcmd[] = { "/bin/sh", "-c",
|
||||||
|
"printf '\033]11;#008000\007'",
|
||||||
|
"externalpipein", NULL };
|
||||||
|
|
||||||
static Shortcut shortcuts[] = {
|
static Shortcut shortcuts[] = {
|
||||||
/* mask keysym function argument */
|
/* mask keysym function argument */
|
||||||
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
|
||||||
|
|
|
@ -13,7 +13,7 @@ X11LIB = /usr/X11R6/lib
|
||||||
PKG_CONFIG = pkg-config
|
PKG_CONFIG = pkg-config
|
||||||
|
|
||||||
# Uncomment this for the alpha patch / ALPHA_PATCH
|
# Uncomment this for the alpha patch / ALPHA_PATCH
|
||||||
XRENDER = -lXrender
|
#XRENDER = -lXrender
|
||||||
|
|
||||||
# Uncomment this for the themed cursor patch / THEMED_CURSOR_PATCH
|
# Uncomment this for the themed cursor patch / THEMED_CURSOR_PATCH
|
||||||
XCURSOR = -lXcursor
|
XCURSOR = -lXcursor
|
||||||
|
|
|
@ -1,59 +1,118 @@
|
||||||
|
#define TLINEURL(y) TLINE(y)
|
||||||
|
|
||||||
|
|
||||||
|
int url_x1, url_y1, url_x2, url_y2 = -1;
|
||||||
|
int url_draw, url_click, url_maxcol;
|
||||||
|
|
||||||
|
static int
|
||||||
|
isvalidurlchar(Rune u)
|
||||||
|
{
|
||||||
|
/* () and [] can appear in urls, but excluding them here will reduce false
|
||||||
|
* positives when figuring out where a given url ends. See copyurl patch.
|
||||||
|
*/
|
||||||
|
static char urlchars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789-._~:/?#@!$&'*+,;=%";
|
||||||
|
return u < 128 && strchr(urlchars, (int)u) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the end of the wrapped line */
|
||||||
|
static int
|
||||||
|
findeowl(int row)
|
||||||
|
{
|
||||||
|
int col = term.maxcol - 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (TLINEURL(row)[col].mode & ATTR_WRAP)
|
||||||
|
return col;
|
||||||
|
} while (TLINEURL(row)[col].u == ' ' && --col >= 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearurl(void)
|
||||||
|
{
|
||||||
|
while (url_y1 <= url_y2 && url_y1 < term.row)
|
||||||
|
term.dirty[url_y1++] = 1;
|
||||||
|
url_y2 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
detecturl(int col, int row, int draw)
|
||||||
|
{
|
||||||
|
static char url[2048];
|
||||||
|
int x1, y1, x2, y2, wrapped;
|
||||||
|
int row_start = row;
|
||||||
|
int col_start = col;
|
||||||
|
int i = sizeof(url)/2+1, j = sizeof(url)/2;
|
||||||
|
int minrow = term.scr - term.histn, maxrow = term.scr + term.row - 1;
|
||||||
|
/* Fixme: MODE_ALTSCREEN is not defined here, I had to use the magic number 1<<2 */
|
||||||
|
if ((term.mode & (1 << 2)) != 0)
|
||||||
|
minrow = 0, maxrow = term.row - 1;
|
||||||
|
url_maxcol = 0;
|
||||||
|
|
||||||
|
/* clear previously underlined url */
|
||||||
|
if (draw)
|
||||||
|
clearurl();
|
||||||
|
|
||||||
|
if (!isvalidurlchar(TLINEURL(row)[col].u))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* find the first character of url */
|
||||||
|
do {
|
||||||
|
x1 = col_start, y1 = row_start;
|
||||||
|
url_maxcol = MAX(url_maxcol, x1);
|
||||||
|
url[--i] = TLINEURL(row_start)[col_start].u;
|
||||||
|
if (--col_start < 0) {
|
||||||
|
if (--row_start < minrow || (col_start = findeowl(row_start)) < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (i > 0 && isvalidurlchar(TLINEURL(row_start)[col_start].u));
|
||||||
|
|
||||||
|
/* early detection */
|
||||||
|
if (url[i] != 'h')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* find the last character of url */
|
||||||
|
do {
|
||||||
|
x2 = col, y2 = row;
|
||||||
|
url_maxcol = MAX(url_maxcol, x2);
|
||||||
|
url[j++] = TLINEURL(row)[col].u;
|
||||||
|
wrapped = TLINEURL(row)[col].mode & ATTR_WRAP;
|
||||||
|
if (++col >= term.maxcol || wrapped) {
|
||||||
|
col = 0;
|
||||||
|
if (++row > maxrow || !wrapped)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (j < sizeof(url)-1 && isvalidurlchar(TLINEURL(row)[col].u));
|
||||||
|
|
||||||
|
url[j] = 0;
|
||||||
|
|
||||||
|
if (strncmp("https://", &url[i], 8) && strncmp("http://", &url[i], 7))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* underline url (see xdrawglyphfontspecs() in x.c) */
|
||||||
|
if (draw) {
|
||||||
|
url_x1 = (y1 >= 0) ? x1 : 0;
|
||||||
|
url_x2 = (y2 < term.row) ? x2 : url_maxcol;
|
||||||
|
url_y1 = MAX(y1, 0);
|
||||||
|
url_y2 = MIN(y2, term.row-1);
|
||||||
|
url_draw = 1;
|
||||||
|
for (y1 = url_y1; y1 <= url_y2; y1++)
|
||||||
|
term.dirty[y1] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &url[i];
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
openUrlOnClick(int col, int row, char* url_opener)
|
openUrlOnClick(int col, int row, char* url_opener)
|
||||||
{
|
{
|
||||||
int row_start = row;
|
char *url = detecturl(col, row, 1);
|
||||||
int col_start = col;
|
if (url) {
|
||||||
int row_end = row;
|
extern char **environ;
|
||||||
int col_end = col;
|
pid_t junk;
|
||||||
|
char *argv[] = { url_opener, url, NULL };
|
||||||
if (term.line[row][col].u == ' ')
|
posix_spawnp(&junk, argv[0], NULL, NULL, argv, environ);
|
||||||
return;
|
}
|
||||||
|
|
||||||
/* while previous character is not space */
|
|
||||||
while (term.line[row_start][col_start-1].u != ' ') {
|
|
||||||
if (col_start == 0)
|
|
||||||
{
|
|
||||||
// Before moving start pointer to the previous line we check if it ends with space
|
|
||||||
if (term.line[row_start - 1][term.col - 1].u == ' ')
|
|
||||||
break;
|
|
||||||
col_start=term.col - 1;
|
|
||||||
row_start--;
|
|
||||||
} else {
|
|
||||||
col_start--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* while next character is not space nor end of line */
|
|
||||||
while (term.line[row_end][col_end].u != ' ') {
|
|
||||||
col_end++;
|
|
||||||
if (col_end == term.col - 1)
|
|
||||||
{
|
|
||||||
if (term.line[row_end + 1][0].u == ' ')
|
|
||||||
break;
|
|
||||||
col_end=0;
|
|
||||||
row_end++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char url[200] = "";
|
|
||||||
int url_index=0;
|
|
||||||
do {
|
|
||||||
url[url_index] = term.line[row_start][col_start].u;
|
|
||||||
url_index++;
|
|
||||||
col_start++;
|
|
||||||
if (col_start == term.col)
|
|
||||||
{
|
|
||||||
col_start = 0;
|
|
||||||
row_start++;
|
|
||||||
}
|
|
||||||
} while (url_index < (sizeof(url)-1) &&
|
|
||||||
(row_start != row_end || col_start != col_end));
|
|
||||||
|
|
||||||
if (strncmp("http", url, 4) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char command[strlen(url_opener)+strlen(url)+2];
|
|
||||||
sprintf(command, "%s %s", url_opener, url);
|
|
||||||
system(command);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,8 @@
|
||||||
|
#include <spawn.h>
|
||||||
|
|
||||||
|
static inline void restoremousecursor(void) {
|
||||||
|
if (!(win.mode & MODE_MOUSE) && xw.pointerisvisible)
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||||
|
}
|
||||||
|
static void clearurl(void);
|
||||||
static void openUrlOnClick(int col, int row, char* url_opener);
|
static void openUrlOnClick(int col, int row, char* url_opener);
|
||||||
|
|
|
@ -15,6 +15,9 @@ kscrolldown(const Arg* a)
|
||||||
tfulldirt();
|
tfulldirt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
restoremousecursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -36,4 +39,7 @@ kscrollup(const Arg* a)
|
||||||
tfulldirt();
|
tfulldirt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
restoremousecursor();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* Patches */
|
/* Patches */
|
||||||
|
#include "openurlonclick.h"
|
||||||
#include "scrollback.h"
|
#include "scrollback.h"
|
||||||
#include "universcroll.h"
|
#include "universcroll.h"
|
||||||
// #if VIM_BROWSE_PATCH
|
// #if VIM_BROWSE_PATCH
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* Patches */
|
/* Patches */
|
||||||
#include "boxdraw.h"
|
#include "boxdraw.h"
|
||||||
#include "netwmicon.h"
|
#include "netwmicon.h"
|
||||||
#include "openurlonclick.h"
|
|
||||||
#include "xresources.h"
|
#include "xresources.h"
|
||||||
|
|
457
suckless/st/patches.h
Normal file
457
suckless/st/patches.h
Normal file
|
@ -0,0 +1,457 @@
|
||||||
|
/*
|
||||||
|
* This file contains patch control flags.
|
||||||
|
*
|
||||||
|
* In principle you should be able to mix and match any patches
|
||||||
|
* you may want. In cases where patches are logically incompatible
|
||||||
|
* one patch may take precedence over the other as noted in the
|
||||||
|
* relevant descriptions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Patches */
|
||||||
|
|
||||||
|
/* The alpha patch adds transparency for the terminal.
|
||||||
|
* You need to uncomment the corresponding line in config.mk to use the
|
||||||
|
* -lXrender library when including this patch.
|
||||||
|
* https://st.suckless.org/patches/alpha/
|
||||||
|
*/
|
||||||
|
#define ALPHA_PATCH 0
|
||||||
|
|
||||||
|
/* 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 windows. This depends on the alpha patch.
|
||||||
|
* https://github.com/juliusHuelsmann/st-focus/
|
||||||
|
* https://st.suckless.org/patches/alpha_focus_highlight/
|
||||||
|
*/
|
||||||
|
#define ALPHA_FOCUS_HIGHLIGHT_PATCH 0
|
||||||
|
|
||||||
|
/* Adds gradient transparency to st, depends on the alpha patch.
|
||||||
|
* https://st.suckless.org/patches/gradient/
|
||||||
|
*/
|
||||||
|
#define ALPHA_GRADIENT_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows st to resize to any pixel size rather than snapping to
|
||||||
|
* character width/height. https://st.suckless.org/patches/anysize/
|
||||||
|
*/
|
||||||
|
#define ANYSIZE_PATCH 1
|
||||||
|
|
||||||
|
/* A simple variant of the anysize patch that only changes the resize hints to
|
||||||
|
* allow the window to be resized to any size.
|
||||||
|
*/
|
||||||
|
#define ANYSIZE_SIMPLE_PATCH 0
|
||||||
|
|
||||||
|
/* Draws a background image in farbfeld format in place of the defaultbg color
|
||||||
|
* allowing for pseudo transparency.
|
||||||
|
* https://st.suckless.org/patches/background_image/
|
||||||
|
*/
|
||||||
|
#define BACKGROUND_IMAGE_PATCH 0
|
||||||
|
|
||||||
|
/* This patch adds the ability to reload the background image config when a
|
||||||
|
* SIGUSR1 signal is received, e.g.: killall -USR1 st Depends on the
|
||||||
|
* BACKGROUND_IMAGE_PATCH.
|
||||||
|
*/
|
||||||
|
#define BACKGROUND_IMAGE_RELOAD_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows the use of a blinking cursor.
|
||||||
|
* Only cursor styles 0, 1, 3, 5, and 7 blink. Set cursorstyle accordingly.
|
||||||
|
* Cursor styles are defined here:
|
||||||
|
* 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
|
||||||
|
* https://st.suckless.org/patches/blinking_cursor/
|
||||||
|
*/
|
||||||
|
#define BLINKING_CURSOR_PATCH 1
|
||||||
|
|
||||||
|
/* By default bold text is rendered with a bold font in the bright variant of
|
||||||
|
* the current color. 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
|
||||||
|
|
||||||
|
/* This patch adds custom rendering of lines/blocks/braille characters for
|
||||||
|
* gapless alignment. https://st.suckless.org/patches/boxdraw/
|
||||||
|
*/
|
||||||
|
#define BOXDRAW_PATCH 1
|
||||||
|
|
||||||
|
/* By default st only sets PRIMARY on selection.
|
||||||
|
* This patch makes st set CLIPBOARD on selection.
|
||||||
|
* https://st.suckless.org/patches/clipboard/
|
||||||
|
*/
|
||||||
|
#define CLIPBOARD_PATCH 1
|
||||||
|
|
||||||
|
/* This patch allows st to be resized without cutting off text when the terminal
|
||||||
|
* window is made larger again. Text does not wrap when the terminal window is
|
||||||
|
* made smaller.
|
||||||
|
*
|
||||||
|
* The vim browse patch takes precedence over this patch.
|
||||||
|
*
|
||||||
|
* https://github.com/bakkeby/st-flexipatch/issues/34
|
||||||
|
*/
|
||||||
|
#define COLUMNS_PATCH 1
|
||||||
|
|
||||||
|
/* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle
|
||||||
|
* through the available URLs. https://st.suckless.org/patches/copyurl/
|
||||||
|
*/
|
||||||
|
#define COPYURL_PATCH 0
|
||||||
|
|
||||||
|
/* Select and copy the last URL displayed with Mod+l. Multiple invocations cycle
|
||||||
|
* through the available URLs. This variant also highlights the selected URLs.
|
||||||
|
* https://st.suckless.org/patches/copyurl/
|
||||||
|
*/
|
||||||
|
#define COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH 0
|
||||||
|
|
||||||
|
/* This patch adds support for CSI escape sequences 22 and 23, which save and
|
||||||
|
* restores the window title (for instance nvim does this when opening and
|
||||||
|
* closing). https://st.suckless.org/patches/csi_22_23/
|
||||||
|
*/
|
||||||
|
#define CSI_22_23_PATCH 1
|
||||||
|
|
||||||
|
/* According to the specification (see link in BLINKING_CURSOR_PATCH) the "Set
|
||||||
|
* cursor style (DECSCUSR), VT520." escape sequences define both values of 0 and
|
||||||
|
* 1 as a blinking block, with 1 being the default.
|
||||||
|
*
|
||||||
|
* This patch allows the default cursor to be set when value 0 is used, as
|
||||||
|
* opposed to setting the cursor to a blinking block.
|
||||||
|
*
|
||||||
|
* This allows a command like this to restore the cursor to what st is
|
||||||
|
* configured with: $ echo -ne "\e[ q"
|
||||||
|
*
|
||||||
|
* While many terminal emulators do this it is not adhering to specification.
|
||||||
|
* xterm is an example terminal that sets a blinking block instead of the
|
||||||
|
* configured one, same as st.
|
||||||
|
*/
|
||||||
|
#define DEFAULT_CURSOR_PATCH 1
|
||||||
|
|
||||||
|
/* Return BS on pressing backspace and DEL on pressing the delete key.
|
||||||
|
* https://st.suckless.org/patches/delkey/
|
||||||
|
*/
|
||||||
|
#define DELKEY_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds the option of disabling bold fonts globally.
|
||||||
|
* https://st.suckless.org/patches/disable_bold_italic_fonts/
|
||||||
|
*/
|
||||||
|
#define DISABLE_BOLD_FONTS_PATCH 0
|
||||||
|
|
||||||
|
/* This patch adds the option of disabling italic fonts globally.
|
||||||
|
* https://st.suckless.org/patches/disable_bold_italic_fonts/
|
||||||
|
*/
|
||||||
|
#define DISABLE_ITALIC_FONTS_PATCH 0
|
||||||
|
|
||||||
|
/* This patch adds the option of disabling roman fonts globally.
|
||||||
|
* https://st.suckless.org/patches/disable_bold_italic_fonts/
|
||||||
|
*/
|
||||||
|
#define DISABLE_ROMAN_FONTS_PATCH 0
|
||||||
|
|
||||||
|
/* This patch makes the cursor color the inverse of the current cell color.
|
||||||
|
* https://st.suckless.org/patches/dynamic-cursor-color/
|
||||||
|
*/
|
||||||
|
#define DYNAMIC_CURSOR_COLOR_PATCH 1
|
||||||
|
|
||||||
|
/* Reading and writing st's screen through a pipe, e.g. pass info to dmenu.
|
||||||
|
* https://st.suckless.org/patches/externalpipe/
|
||||||
|
*/
|
||||||
|
#define EXTERNALPIPE_PATCH 0
|
||||||
|
|
||||||
|
/* This patch improves and extends the externalpipe patch in two ways:
|
||||||
|
* - it prevents the reset of the signal handler set on SIGCHILD, when
|
||||||
|
* the forked process that executes the external process exits and
|
||||||
|
* - it adds the externalpipein function to redirect the standard output
|
||||||
|
* of the external command to the slave size of the pty, that is, as if
|
||||||
|
* the external program had been manually executed on the terminal
|
||||||
|
*
|
||||||
|
* It can be used to send desired escape sequences to the terminal with a
|
||||||
|
* keyboard shortcut. The patch was created to make use of the dynamic-colors
|
||||||
|
* tool that uses the OSC escape sequences to change the colors of the terminal.
|
||||||
|
*
|
||||||
|
* This patch depends on EXTERNALPIPE_PATCH being enabled.
|
||||||
|
*
|
||||||
|
* https://github.com/sos4nt/dynamic-colors
|
||||||
|
* https://lists.suckless.org/hackers/2004/17218.html
|
||||||
|
*/
|
||||||
|
#define EXTERNALPIPEIN_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows command line applications to use all the fancy key
|
||||||
|
* combinations that are available to GUI applications.
|
||||||
|
* https://st.suckless.org/patches/fix_keyboard_input/
|
||||||
|
*/
|
||||||
|
#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. This patch append fonts defined in
|
||||||
|
* font2 variable to the beginning of the font cache. 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
|
||||||
|
|
||||||
|
/* Hide the X cursor whenever a key is pressed and show it back when the mouse
|
||||||
|
* is moved in the terminal window. https://st.suckless.org/patches/hidecursor/
|
||||||
|
*/
|
||||||
|
#define HIDECURSOR_PATCH 1
|
||||||
|
|
||||||
|
/* This patch hides the terminal cursor when the window loses focus (as opposed
|
||||||
|
* to showing a hollow cursor).
|
||||||
|
* https://www.reddit.com/r/suckless/comments/nvee8h/how_to_hide_cursor_in_st_is_there_a_patch_for_it/
|
||||||
|
*/
|
||||||
|
#define HIDE_TERMINAL_CURSOR_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds a keybinding that lets you invert the current colorscheme of
|
||||||
|
* st. This provides a simple way to temporarily switch to a light colorscheme
|
||||||
|
* if you use a dark colorscheme or visa-versa.
|
||||||
|
* https://st.suckless.org/patches/invert/
|
||||||
|
*/
|
||||||
|
#define INVERT_PATCH 0
|
||||||
|
|
||||||
|
/* Pressing the default binding Ctrl+Shift-i will popup dmenu, asking you to
|
||||||
|
* enter a unicode codepoint that will be converted to a glyph and then pushed
|
||||||
|
* to st. https://st.suckless.org/patches/iso14755/
|
||||||
|
*/
|
||||||
|
#define ISO14755_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows you to select text on the terminal using keyboard
|
||||||
|
* shortcuts. https://st.suckless.org/patches/keyboard_select/
|
||||||
|
*/
|
||||||
|
#define KEYBOARDSELECT_PATCH 0
|
||||||
|
|
||||||
|
/* 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. This patch depends on the Harfbuzz library and headers to compile.
|
||||||
|
* You need to uncomment the corresponding lines in config.mk to use the
|
||||||
|
* harfbuzz library when including this patch.
|
||||||
|
* https://github.com/cog1to/st-ligatures
|
||||||
|
* https://st.suckless.org/patches/ligatures/
|
||||||
|
*/
|
||||||
|
#define LIGATURES_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.
|
||||||
|
* https://www.reddit.com/r/suckless/comments/ixbx6z/how_to_use_black_and_white_only_for_st/
|
||||||
|
*/
|
||||||
|
#define MONOCHROME_PATCH 0
|
||||||
|
|
||||||
|
/* This patch sets the _NET_WM_ICON X property with a hardcoded icon for st.
|
||||||
|
* https://st.suckless.org/patches/netwmicon/
|
||||||
|
*/
|
||||||
|
#define NETWMICON_PATCH 1
|
||||||
|
|
||||||
|
/* This patch allows you to spawn a new st terminal using Ctrl-Shift-Return. It
|
||||||
|
* will have the same CWD (current working directory) as the original st
|
||||||
|
* instance. https://st.suckless.org/patches/newterm/
|
||||||
|
*/
|
||||||
|
#define NEWTERM_PATCH 0
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
* In dwm, if the decoration hints patch is applied, then the st window will
|
||||||
|
* start out without a border. In GNOME and KDE the window should start without
|
||||||
|
* a window title.
|
||||||
|
*/
|
||||||
|
#define NO_WINDOW_DECORATIONS_PATCH 1
|
||||||
|
|
||||||
|
/* Open contents of the clipboard in a user-defined browser.
|
||||||
|
* https://st.suckless.org/patches/open_copied_url/
|
||||||
|
*/
|
||||||
|
#define OPENCOPIED_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows for URLs to be opened directly when you click on them. This
|
||||||
|
* may not work with all terminal applications.
|
||||||
|
*
|
||||||
|
* https://www.reddit.com/r/suckless/comments/cc83om/st_open_url/
|
||||||
|
*/
|
||||||
|
#define OPENURLONCLICK_PATCH 1
|
||||||
|
|
||||||
|
/* This patch allows you to specify a border that is relative in size to the
|
||||||
|
* width of a cell in the terminal.
|
||||||
|
* https://st.suckless.org/patches/relativeborder/
|
||||||
|
*/
|
||||||
|
#define RELATIVEBORDER_PATCH 1
|
||||||
|
|
||||||
|
/* This patch allows you to right-click on some selected text to send it to the
|
||||||
|
* plumbing program of choice, e.g. open a file, view an image, open a URL.
|
||||||
|
* https://st.suckless.org/patches/right_click_to_plumb/
|
||||||
|
*/
|
||||||
|
#define RIGHTCLICKTOPLUMB_PATCH 0
|
||||||
|
|
||||||
|
/* Scroll back through terminal output using Shift+{PageUp, PageDown}.
|
||||||
|
* https://st.suckless.org/patches/scrollback/
|
||||||
|
*/
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* 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 1
|
||||||
|
|
||||||
|
/* This is the single drawable buffer patch as outlined in the FAQ to get images
|
||||||
|
* in w3m to display. While this patch does not break the alpha patch it images
|
||||||
|
* are not shown in w3m if the alpha patch is applied.
|
||||||
|
*/
|
||||||
|
#define SINGLE_DRAWABLE_BUFFER_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds SIXEL graphics support for st.
|
||||||
|
* Note that patch/sixel.c/sixel_hls.c come from mintty, licensed under GPL.
|
||||||
|
* Known issues:
|
||||||
|
* - Rendering sixel graphics may cause unusual cursor placement, this is
|
||||||
|
* not specific to this variant of st - the same issue is present in
|
||||||
|
* the xterm implementation. This is likely an issue of sixel height
|
||||||
|
* not being detected correctly.
|
||||||
|
*
|
||||||
|
* Note that you need to uncomment the corresponding lines in config.mk when
|
||||||
|
* including this patch. This patch is incompatible with the W3M patch.
|
||||||
|
*
|
||||||
|
* https://gist.github.com/saitoha/70e0fdf22e3e8f63ce937c7f7da71809
|
||||||
|
*/
|
||||||
|
#define SIXEL_PATCH 0
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*
|
||||||
|
* $ surf -e $WINDOWID
|
||||||
|
*
|
||||||
|
* The behavior is similar to Plan 9 where applications can take over windows.
|
||||||
|
* URL TBC
|
||||||
|
*/
|
||||||
|
#define ST_EMBEDDER_PATCH 0
|
||||||
|
|
||||||
|
/* Use inverted defaultbg/fg for selection when bg/fg are the same.
|
||||||
|
* https://st.suckless.org/patches/spoiler/
|
||||||
|
*/
|
||||||
|
#define SPOILER_PATCH 1
|
||||||
|
|
||||||
|
/* This patch changes the mouse shape to the global default when the running
|
||||||
|
* program subscribes for mouse events, for instance, in programs like ranger
|
||||||
|
* and fzf. It emulates the behaviour shown by vte terminals like termite.
|
||||||
|
* https://st.suckless.org/patches/swapmouse/
|
||||||
|
*/
|
||||||
|
#define SWAPMOUSE_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds synchronized-updates/application-sync support in st.
|
||||||
|
* This will have no effect except when an application uses the
|
||||||
|
* synchronized-update escape sequences. With this patch nearly all cursor
|
||||||
|
* flicker is eliminated in tmux, and tmux detects it automatically via
|
||||||
|
* terminfo.
|
||||||
|
*
|
||||||
|
* Note: this patch alters st.info to promote support for extra escape
|
||||||
|
* sequences, which can potentially cause application misbehaviour if you do not
|
||||||
|
* use this patch. Try removing or commenting out the corresponding line in
|
||||||
|
* st.info if this is causing issues.
|
||||||
|
*
|
||||||
|
* https://st.suckless.org/patches/sync/
|
||||||
|
*/
|
||||||
|
#define SYNC_PATCH 0
|
||||||
|
|
||||||
|
/* Instead of a default X cursor, use the xterm cursor from your cursor theme.
|
||||||
|
* You need to uncomment the corresponding line in config.mk to use the
|
||||||
|
* -lXcursor library when including this patch.
|
||||||
|
* https://st.suckless.org/patches/themed_cursor/
|
||||||
|
*/
|
||||||
|
#define THEMED_CURSOR_PATCH 1
|
||||||
|
|
||||||
|
/* Adds support for special underlines.
|
||||||
|
*
|
||||||
|
* Example test command:
|
||||||
|
* $ echo -e "\e[4:3m\e[58:5:10munderline\e[0m"
|
||||||
|
* ^ ^ ^ ^ ^- sets terminal color 10
|
||||||
|
* | | | \- indicates that terminal colors should be used
|
||||||
|
* | | \- indicates that underline color is being set
|
||||||
|
* | \- sets underline style to curvy
|
||||||
|
* \- set underline
|
||||||
|
*
|
||||||
|
* Note: this patch alters st.info to promote support for extra escape
|
||||||
|
* sequences, which can potentially cause application misbehaviour if you do not
|
||||||
|
* use this patch. Try removing or commenting out the corresponding line in
|
||||||
|
* st.info if this is causing issues.
|
||||||
|
*
|
||||||
|
* https://st.suckless.org/patches/undercurl/
|
||||||
|
*/
|
||||||
|
#define UNDERCURL_PATCH 1
|
||||||
|
|
||||||
|
/* Allows mouse scroll without modifier keys for regardless of alt screen using
|
||||||
|
* the external scroll program. https://st.suckless.org/patches/universcroll/
|
||||||
|
*/
|
||||||
|
#define UNIVERSCROLL_PATCH 0
|
||||||
|
|
||||||
|
/* Use XftFontMatch in place of FcFontMatch.
|
||||||
|
*
|
||||||
|
* XftFontMatch calls XftDefaultSubstitute which configures various match
|
||||||
|
* properties according to the user's configured Xft defaults (xrdb) as well as
|
||||||
|
* according to the current display and screen. Most importantly, the screen DPI
|
||||||
|
* is computed [1]. Without this, st uses a "default" DPI of 75 [2].
|
||||||
|
*
|
||||||
|
* [1]:
|
||||||
|
* https://cgit.freedesktop.org/xorg/lib/libXft/tree/src/xftdpy.c?id=libXft-2.3.2#n535
|
||||||
|
* [2]:
|
||||||
|
* https://cgit.freedesktop.org/fontconfig/tree/src/fcdefault.c?id=2.11.1#n255
|
||||||
|
*
|
||||||
|
* https://git.suckless.org/st/commit/528241aa3835e2f1f052abeeaf891737712955a0.html
|
||||||
|
*/
|
||||||
|
#define USE_XFTFONTMATCH_PATCH 1
|
||||||
|
|
||||||
|
/* Vertically center lines in the space available if you have set a larger
|
||||||
|
* chscale in config.h https://st.suckless.org/patches/vertcenter/
|
||||||
|
*/
|
||||||
|
#define VERTCENTER_PATCH 1
|
||||||
|
|
||||||
|
/* The vim-browse patch offers the possibility to move through the terminal
|
||||||
|
* history-buffer, search for strings using VIM-like motions, operations and
|
||||||
|
* quantifiers. It overlays the screen with highlighted search results and
|
||||||
|
* displays the current operation / motions / search string in the bottom right
|
||||||
|
* corner.
|
||||||
|
*
|
||||||
|
* https://github.com/juliusHuelsmann/st-history-vim
|
||||||
|
* https://st.suckless.org/patches/vim_browse/
|
||||||
|
*/
|
||||||
|
#define VIM_BROWSE_PATCH 0
|
||||||
|
|
||||||
|
/* Briefly inverts window content on terminal bell event.
|
||||||
|
* https://st.suckless.org/patches/visualbell/
|
||||||
|
*/
|
||||||
|
#define VISUALBELL_1_PATCH 0
|
||||||
|
|
||||||
|
/* Adds support for w3m images.
|
||||||
|
* https://st.suckless.org/patches/w3m/
|
||||||
|
*/
|
||||||
|
#define W3M_PATCH 1
|
||||||
|
|
||||||
|
/* Adds proper glyphs rendering in st allowing wide glyphs to be drawn as-is as
|
||||||
|
* opposed to smaller or cut glyphs being rendered.
|
||||||
|
* https://github.com/Dreomite/st/commit/e3b821dcb3511d60341dec35ee05a4a0abfef7f2
|
||||||
|
* https://www.reddit.com/r/suckless/comments/jt90ai/update_support_for_proper_glyph_rendering_in_st/
|
||||||
|
*/
|
||||||
|
#define WIDE_GLYPHS_PATCH 1
|
||||||
|
|
||||||
|
/* There is a known issue that Google's Variable Fonts (VF) can end up with
|
||||||
|
* letter spacing that is too wide in programs that use Xft, for example
|
||||||
|
* Inconsolata v3.000.
|
||||||
|
*
|
||||||
|
* This is intended as a temporary patch / hack until (if) this is fixed in the
|
||||||
|
* Xft library itself.
|
||||||
|
*
|
||||||
|
* https://github.com/googlefonts/Inconsolata/issues/42#issuecomment-737508890
|
||||||
|
*/
|
||||||
|
#define WIDE_GLYPH_SPACING_PATCH 0
|
||||||
|
|
||||||
|
/* This patch allows user to specify the initial path st should use as the
|
||||||
|
* working directory. https://st.suckless.org/patches/workingdir/
|
||||||
|
*/
|
||||||
|
#define WORKINGDIR_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds the ability to configure st via Xresources. At startup, st
|
||||||
|
* will read and apply the resources named in the resources[] array in config.h.
|
||||||
|
* https://st.suckless.org/patches/xresources/
|
||||||
|
*/
|
||||||
|
#define XRESOURCES_PATCH 1
|
||||||
|
|
||||||
|
/* This patch adds the ability to reload the Xresources config when a SIGUSR1
|
||||||
|
* signal is received e.g.: killall -USR1 st Depends on the XRESOURCES_PATCH.
|
||||||
|
*/
|
||||||
|
#define XRESOURCES_RELOAD_PATCH 1
|
|
@ -922,7 +922,7 @@ ttyresize(int tw, int th)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ttyhangup()
|
ttyhangup(void)
|
||||||
{
|
{
|
||||||
/* Send SIGHUP to shell */
|
/* Send SIGHUP to shell */
|
||||||
kill(pid, SIGHUP);
|
kill(pid, SIGHUP);
|
||||||
|
@ -1040,6 +1040,8 @@ tswapscreen(void)
|
||||||
void
|
void
|
||||||
tscrolldown(int orig, int n)
|
tscrolldown(int orig, int n)
|
||||||
{
|
{
|
||||||
|
restoremousecursor();
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
Line temp;
|
Line temp;
|
||||||
|
|
||||||
|
@ -1062,6 +1064,8 @@ tscrolldown(int orig, int n)
|
||||||
void
|
void
|
||||||
tscrollup(int orig, int n, int copyhist)
|
tscrollup(int orig, int n, int copyhist)
|
||||||
{
|
{
|
||||||
|
restoremousecursor();
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
Line temp;
|
Line temp;
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,14 @@ typedef struct {
|
||||||
Draw draw;
|
Draw draw;
|
||||||
Visual *vis;
|
Visual *vis;
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
|
/* Here, we use the term *pointer* to differentiate the cursor
|
||||||
|
* one sees when hovering the mouse over the terminal from, e.g.,
|
||||||
|
* a green rectangle where text would be entered. */
|
||||||
|
Cursor vpointer, bpointer; /* visible and hidden pointers */
|
||||||
|
int pointerisvisible;
|
||||||
|
Cursor upointer;
|
||||||
int scr;
|
int scr;
|
||||||
int isfixed; /* is fixed geometry? */
|
int isfixed; /* is fixed geometry? */
|
||||||
int depth; /* bit depth */
|
|
||||||
int l, t; /* left and top offset */
|
int l, t; /* left and top offset */
|
||||||
int gm; /* geometry mask */
|
int gm; /* geometry mask */
|
||||||
} XWindow;
|
} XWindow;
|
||||||
|
@ -287,7 +292,6 @@ extern unsigned int defaultbg;
|
||||||
extern unsigned int defaultcs;
|
extern unsigned int defaultcs;
|
||||||
|
|
||||||
extern const int boxdraw, boxdraw_bold, boxdraw_braille;
|
extern const int boxdraw, boxdraw_bold, boxdraw_braille;
|
||||||
extern float alpha;
|
|
||||||
|
|
||||||
extern DC dc;
|
extern DC dc;
|
||||||
extern XWindow xw;
|
extern XWindow xw;
|
||||||
|
|
142
suckless/st/x.c
142
suckless/st/x.c
|
@ -173,7 +173,6 @@ static char *usedfont = NULL;
|
||||||
static double usedfontsize = 0;
|
static double usedfontsize = 0;
|
||||||
static double defaultfontsize = 0;
|
static double defaultfontsize = 0;
|
||||||
|
|
||||||
static char *opt_alpha = NULL;
|
|
||||||
static char *opt_class = NULL;
|
static char *opt_class = NULL;
|
||||||
static char **opt_cmd = NULL;
|
static char **opt_cmd = NULL;
|
||||||
static char *opt_embed = NULL;
|
static char *opt_embed = NULL;
|
||||||
|
@ -451,6 +450,9 @@ bpress(XEvent *e)
|
||||||
xsel.tclick1 = now;
|
xsel.tclick1 = now;
|
||||||
|
|
||||||
selstart(evcol(e), evrow(e), snap);
|
selstart(evcol(e), evrow(e), snap);
|
||||||
|
|
||||||
|
clearurl();
|
||||||
|
url_click = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,13 +675,30 @@ brelease(XEvent *e)
|
||||||
return;
|
return;
|
||||||
if (btn == Button1) {
|
if (btn == Button1) {
|
||||||
mousesel(e, 1);
|
mousesel(e, 1);
|
||||||
openUrlOnClick(evcol(e), evrow(e), url_opener);
|
if (url_click && e->xkey.state & url_opener_modkey)
|
||||||
|
openUrlOnClick(evcol(e), evrow(e), url_opener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bmotion(XEvent *e)
|
bmotion(XEvent *e)
|
||||||
{
|
{
|
||||||
|
if (!xw.pointerisvisible) {
|
||||||
|
if (win.mode & MODE_MOUSE)
|
||||||
|
XUndefineCursor(xw.dpy, xw.win);
|
||||||
|
else
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||||
|
xw.pointerisvisible = 1;
|
||||||
|
if (!IS_SET(MODE_MOUSEMANY))
|
||||||
|
xsetpointermotion(0);
|
||||||
|
}
|
||||||
|
if (!IS_SET(MODE_MOUSE)) {
|
||||||
|
if (!(e->xbutton.state & Button1Mask) && detecturl(evcol(e), evrow(e), 1))
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.upointer);
|
||||||
|
else
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||||
|
}
|
||||||
|
url_click = 0;
|
||||||
|
|
||||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||||
mousereport(e);
|
mousereport(e);
|
||||||
|
@ -718,11 +737,6 @@ xresize(int col, int row)
|
||||||
win.tw = col * win.cw;
|
win.tw = col * win.cw;
|
||||||
win.th = row * win.ch;
|
win.th = row * win.ch;
|
||||||
|
|
||||||
XFreePixmap(xw.dpy, xw.buf);
|
|
||||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
|
|
||||||
xw.depth
|
|
||||||
);
|
|
||||||
XftDrawChange(xw.draw, xw.buf);
|
|
||||||
xclear(0, 0, win.w, win.h);
|
xclear(0, 0, win.w, win.h);
|
||||||
|
|
||||||
/* resize to new width */
|
/* resize to new width */
|
||||||
|
@ -783,12 +797,6 @@ xloadcols(void)
|
||||||
else
|
else
|
||||||
die("could not allocate color %d\n", i);
|
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;
|
|
||||||
loaded = 1;
|
loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,14 +827,6 @@ xsetcolorname(int x, const char *name)
|
||||||
XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
|
XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
|
||||||
dc.col[x] = ncolor;
|
dc.col[x] = ncolor;
|
||||||
|
|
||||||
/* set alpha value of bg color */
|
|
||||||
if (x == defaultbg) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -973,7 +973,7 @@ xloadfont(Font *f, FcPattern *pattern)
|
||||||
FcConfigSubstitute(NULL, configured, FcMatchPattern);
|
FcConfigSubstitute(NULL, configured, FcMatchPattern);
|
||||||
XftDefaultSubstitute(xw.dpy, xw.scr, configured);
|
XftDefaultSubstitute(xw.dpy, xw.scr, configured);
|
||||||
|
|
||||||
match = FcFontMatch(NULL, configured, &result);
|
match = XftFontMatch(xw.dpy, xw.scr, pattern, &result);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
FcPatternDestroy(configured);
|
FcPatternDestroy(configured);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1126,23 +1126,13 @@ void
|
||||||
xinit(int cols, int rows)
|
xinit(int cols, int rows)
|
||||||
{
|
{
|
||||||
XGCValues gcvalues;
|
XGCValues gcvalues;
|
||||||
|
Pixmap blankpm;
|
||||||
Window parent;
|
Window parent;
|
||||||
pid_t thispid = getpid();
|
pid_t thispid = getpid();
|
||||||
XWindowAttributes attr;
|
|
||||||
XVisualInfo vis;
|
|
||||||
|
|
||||||
xw.scr = XDefaultScreen(xw.dpy);
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
|
|
||||||
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
|
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
parent = XRootWindow(xw.dpy, xw.scr);
|
|
||||||
xw.depth = 32;
|
|
||||||
} else {
|
|
||||||
XGetWindowAttributes(xw.dpy, parent, &attr);
|
|
||||||
xw.depth = attr.depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
|
|
||||||
xw.vis = vis.visual;
|
|
||||||
|
|
||||||
/* font */
|
/* font */
|
||||||
if (!FcInit())
|
if (!FcInit())
|
||||||
|
@ -1153,7 +1143,7 @@ xinit(int cols, int rows)
|
||||||
|
|
||||||
|
|
||||||
/* colors */
|
/* colors */
|
||||||
xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
|
xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
|
||||||
xloadcols();
|
xloadcols();
|
||||||
|
|
||||||
/* adjust fixed window geometry */
|
/* adjust fixed window geometry */
|
||||||
|
@ -1173,17 +1163,21 @@ xinit(int cols, int rows)
|
||||||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask
|
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask
|
||||||
;
|
;
|
||||||
xw.attrs.colormap = xw.cmap;
|
xw.attrs.colormap = xw.cmap;
|
||||||
|
xw.attrs.event_mask |= PointerMotionMask;
|
||||||
|
|
||||||
|
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,
|
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
|
||||||
win.w, win.h, 0, xw.depth, InputOutput,
|
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
|
||||||
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
|
||||||
| CWEventMask | CWColormap, &xw.attrs);
|
| CWEventMask | CWColormap, &xw.attrs);
|
||||||
|
|
||||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||||
gcvalues.graphics_exposures = False;
|
gcvalues.graphics_exposures = False;
|
||||||
|
|
||||||
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
|
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
|
||||||
dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
|
&gcvalues);
|
||||||
|
xw.buf = xw.win;
|
||||||
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
|
||||||
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
|
||||||
|
|
||||||
|
@ -1200,10 +1194,16 @@ xinit(int cols, int rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* white cursor, black outline */
|
/* white cursor, black outline */
|
||||||
cursor = XcursorLibraryLoadCursor(xw.dpy, mouseshape);
|
xw.pointerisvisible = 1;
|
||||||
XDefineCursor(xw.dpy, xw.win, cursor);
|
xw.vpointer = XcursorLibraryLoadCursor(xw.dpy, mouseshape);
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||||
|
|
||||||
|
|
||||||
|
blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1);
|
||||||
|
xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm,
|
||||||
|
&xmousefg, &xmousebg, 0, 0);
|
||||||
|
|
||||||
|
xw.upointer = XCreateFontCursor(xw.dpy, XC_hand2);
|
||||||
|
|
||||||
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
|
||||||
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
|
||||||
|
@ -1215,6 +1215,11 @@ xinit(int cols, int rows)
|
||||||
XChangeProperty(xw.dpy, xw.win, xw.netwmicon, XA_CARDINAL, 32,
|
XChangeProperty(xw.dpy, xw.win, xw.netwmicon, XA_CARDINAL, 32,
|
||||||
PropModeReplace, (uchar *)&icon, LEN(icon));
|
PropModeReplace, (uchar *)&icon, LEN(icon));
|
||||||
|
|
||||||
|
Atom motifwmhints = XInternAtom(xw.dpy, "_MOTIF_WM_HINTS", False);
|
||||||
|
unsigned int data[] = { 0x2, 0x0, 0x0, 0x0, 0x0 };
|
||||||
|
XChangeProperty(xw.dpy, xw.win, motifwmhints, motifwmhints, 16,
|
||||||
|
PropModeReplace, (unsigned char *)data, 5);
|
||||||
|
|
||||||
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
|
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
|
||||||
XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
|
XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
|
||||||
PropModeReplace, (uchar *)&thispid, 1);
|
PropModeReplace, (uchar *)&thispid, 1);
|
||||||
|
@ -1333,12 +1338,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
fccharset);
|
fccharset);
|
||||||
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
|
||||||
|
|
||||||
FcConfigSubstitute(0, fcpattern,
|
|
||||||
FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(fcpattern);
|
|
||||||
|
|
||||||
fontpattern = FcFontSetMatch(0, fcsets, 1,
|
fontpattern = FcFontSetMatch(0, fcsets, 1, fcpattern, &fcres);
|
||||||
fcpattern, &fcres);
|
|
||||||
|
|
||||||
/* Allocate memory for the new cache entry. */
|
/* Allocate memory for the new cache entry. */
|
||||||
if (frclen >= frccap) {
|
if (frclen >= frccap) {
|
||||||
|
@ -1430,6 +1431,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||||
int width = charlen * win.cw;
|
int width = charlen * win.cw;
|
||||||
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
|
||||||
XRenderColor colfg, colbg;
|
XRenderColor colfg, colbg;
|
||||||
|
XRectangle r;
|
||||||
|
|
||||||
/* Fallback on color display for attributes not supported by the font */
|
/* Fallback on color display for attributes not supported by the font */
|
||||||
if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
|
if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
|
||||||
|
@ -1537,10 +1539,19 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||||
xclear(winx, winy + win.ch, winx + width, win.h);
|
xclear(winx, winy + win.ch, winx + width, win.h);
|
||||||
|
|
||||||
/* Clean up the region we want to draw to. */
|
/* 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);
|
||||||
|
|
||||||
|
/* Fill the background */
|
||||||
|
XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
|
||||||
|
}
|
||||||
|
|
||||||
if (dmode & DRAW_FG) {
|
if (dmode & DRAW_FG) {
|
||||||
if (base.mode & ATTR_BOXDRAW) {
|
if (base.mode & ATTR_BOXDRAW) {
|
||||||
drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
|
drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
|
||||||
|
@ -1910,6 +1921,20 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (url_draw && y >= url_y1 && y <= url_y2) {
|
||||||
|
int x1 = (y == url_y1) ? url_x1 : 0;
|
||||||
|
int x2 = (y == url_y2) ? MIN(url_x2, term.col-1) : url_maxcol;
|
||||||
|
if (x + charlen > x1 && x <= x2) {
|
||||||
|
int xu = MAX(x, x1);
|
||||||
|
int wu = (x2 - xu + 1) * win.cw;
|
||||||
|
xu = win.hborderpx + xu * win.cw;
|
||||||
|
XftDrawRect(xw.draw, fg, xu, winy + win.cyo + dc.font.ascent * chscale + 2, wu, 1);
|
||||||
|
url_draw = (y != url_y2 || x + charlen <= x2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset clip to none. */
|
||||||
|
XftDrawSetClip(xw.draw, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2105,6 +2130,8 @@ xfreetitlestack(void)
|
||||||
int
|
int
|
||||||
xstartdraw(void)
|
xstartdraw(void)
|
||||||
{
|
{
|
||||||
|
if (IS_SET(MODE_VISIBLE))
|
||||||
|
XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0);
|
||||||
return IS_SET(MODE_VISIBLE);
|
return IS_SET(MODE_VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,7 +2179,6 @@ xfinishdraw(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, win.h, 0, 0);
|
|
||||||
XSetForeground(xw.dpy, dc.gc,
|
XSetForeground(xw.dpy, dc.gc,
|
||||||
dc.col[IS_SET(MODE_REVERSE)?
|
dc.col[IS_SET(MODE_REVERSE)?
|
||||||
defaultfg : defaultbg].pixel);
|
defaultfg : defaultbg].pixel);
|
||||||
|
@ -2193,6 +2219,9 @@ unmap(XEvent *ev)
|
||||||
void
|
void
|
||||||
xsetpointermotion(int set)
|
xsetpointermotion(int set)
|
||||||
{
|
{
|
||||||
|
if (!set && !xw.pointerisvisible)
|
||||||
|
return;
|
||||||
|
set = 1; /* keep MotionNotify event enabled */
|
||||||
MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
|
MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
|
||||||
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
|
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
|
||||||
}
|
}
|
||||||
|
@ -2203,11 +2232,12 @@ xsetmode(int set, unsigned int flags)
|
||||||
int mode = win.mode;
|
int mode = win.mode;
|
||||||
MODBIT(win.mode, set, flags);
|
MODBIT(win.mode, set, flags);
|
||||||
if ((flags & MODE_MOUSE)
|
if ((flags & MODE_MOUSE)
|
||||||
|
&& xw.pointerisvisible
|
||||||
) {
|
) {
|
||||||
if (win.mode & MODE_MOUSE)
|
if (win.mode & MODE_MOUSE)
|
||||||
XUndefineCursor(xw.dpy, xw.win);
|
XUndefineCursor(xw.dpy, xw.win);
|
||||||
else
|
else
|
||||||
XDefineCursor(xw.dpy, xw.win, cursor);
|
XDefineCursor(xw.dpy, xw.win, xw.vpointer);
|
||||||
}
|
}
|
||||||
if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE))
|
if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE))
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -2323,6 +2353,17 @@ kpress(XEvent *ev)
|
||||||
Status status;
|
Status status;
|
||||||
Shortcut *bp;
|
Shortcut *bp;
|
||||||
|
|
||||||
|
if (xw.pointerisvisible) {
|
||||||
|
int x = e->x - win.hborderpx;
|
||||||
|
int y = e->y - win.vborderpx;
|
||||||
|
LIMIT(x, 0, win.tw - 1);
|
||||||
|
LIMIT(y, 0, win.th - 1);
|
||||||
|
if (!detecturl(x / win.cw, y / win.ch, 0)) {
|
||||||
|
XDefineCursor(xw.dpy, xw.win, xw.bpointer);
|
||||||
|
xsetpointermotion(1);
|
||||||
|
xw.pointerisvisible = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_SET(MODE_KBDLOCK))
|
if (IS_SET(MODE_KBDLOCK))
|
||||||
return;
|
return;
|
||||||
|
@ -2534,9 +2575,6 @@ main(int argc, char *argv[])
|
||||||
case 'a':
|
case 'a':
|
||||||
allowaltscreen = 0;
|
allowaltscreen = 0;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
|
||||||
opt_alpha = EARGF(usage());
|
|
||||||
break;
|
|
||||||
case 'c':
|
case 'c':
|
||||||
opt_class = EARGF(usage());
|
opt_class = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -15,7 +15,6 @@ static int tabwidth = 200;
|
||||||
static const Bool foreground = True;
|
static const Bool foreground = True;
|
||||||
static Bool urgentswitch = False;
|
static Bool urgentswitch = False;
|
||||||
|
|
||||||
static const int barheight = 0; /* 0 means derive by font (default), otherwise absolute height */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Where to place a new tab when it is opened. When npisrelative is True,
|
* Where to place a new tab when it is opened. When npisrelative is True,
|
||||||
|
@ -51,27 +50,32 @@ ResourcePref resources[] = {
|
||||||
#define MODKEY ControlMask
|
#define MODKEY ControlMask
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY|ShiftMask, 36, focusonce, { 0 } },
|
{ MODKEY|ShiftMask, XK_Return, focusonce, { 0 } },
|
||||||
{ MODKEY|ShiftMask, 36, spawn, { 0 } },
|
{ MODKEY|ShiftMask, XK_Return, spawn, { 0 } },
|
||||||
{ MODKEY|ShiftMask, 46, rotate, { .i = +1 } },
|
|
||||||
{ MODKEY|ShiftMask, 43, rotate, { .i = -1 } },
|
{ MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } },
|
||||||
{ MODKEY|ShiftMask, 44, movetab, { .i = -1 } },
|
{ MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } },
|
||||||
{ MODKEY|ShiftMask, 45, movetab, { .i = +1 } },
|
{ MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } },
|
||||||
{ MODKEY, 23, rotate, { .i = 0 } },
|
{ MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } },
|
||||||
{ MODKEY, 49, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
{ MODKEY, XK_Tab, rotate, { .i = 0 } },
|
||||||
{ MODKEY, 10, move, { .i = 0 } },
|
|
||||||
{ MODKEY, 11, move, { .i = 1 } },
|
{ MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
||||||
{ MODKEY, 12, move, { .i = 2 } },
|
{ MODKEY, XK_1, move, { .i = 0 } },
|
||||||
{ MODKEY, 13, move, { .i = 3 } },
|
{ MODKEY, XK_2, move, { .i = 1 } },
|
||||||
{ MODKEY, 14, move, { .i = 4 } },
|
{ MODKEY, XK_3, move, { .i = 2 } },
|
||||||
{ MODKEY, 15, move, { .i = 5 } },
|
{ MODKEY, XK_4, move, { .i = 3 } },
|
||||||
{ MODKEY, 16, move, { .i = 6 } },
|
{ MODKEY, XK_5, move, { .i = 4 } },
|
||||||
{ MODKEY, 17, move, { .i = 7 } },
|
{ MODKEY, XK_6, move, { .i = 5 } },
|
||||||
{ MODKEY, 18, move, { .i = 8 } },
|
{ MODKEY, XK_7, move, { .i = 6 } },
|
||||||
{ MODKEY, 19, move, { .i = 9 } },
|
{ MODKEY, XK_8, move, { .i = 7 } },
|
||||||
{ MODKEY, 24, killclient, { 0 } },
|
{ MODKEY, XK_9, move, { .i = 8 } },
|
||||||
{ MODKEY, 30, focusurgent, { .v = NULL } },
|
{ MODKEY, XK_0, move, { .i = 9 } },
|
||||||
{ MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } },
|
|
||||||
{ 0, 95, fullscreen, { 0 } },
|
{ MODKEY, XK_q, killclient, { 0 } },
|
||||||
|
|
||||||
|
{ MODKEY, XK_u, focusurgent, { 0 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } },
|
||||||
|
|
||||||
|
{ 0, XK_F11, fullscreen, { 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static char font[] = "monospace:size=9";
|
static char font[] = "FiraCode Nerd Font Mono:size=9:antialias=true:autohint=true";
|
||||||
static char* normbgcolor = "#222222";
|
static char* normbgcolor = "#222222";
|
||||||
static char* normfgcolor = "#cccccc";
|
static char* normfgcolor = "#cccccc";
|
||||||
static char* selbgcolor = "#555555";
|
static char* selbgcolor = "#555555";
|
||||||
|
@ -15,7 +15,6 @@ static int tabwidth = 200;
|
||||||
static const Bool foreground = True;
|
static const Bool foreground = True;
|
||||||
static Bool urgentswitch = False;
|
static Bool urgentswitch = False;
|
||||||
|
|
||||||
static const int barheight = 0; /* 0 means derive by font (default), otherwise absolute height */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Where to place a new tab when it is opened. When npisrelative is True,
|
* Where to place a new tab when it is opened. When npisrelative is True,
|
||||||
|
@ -51,27 +50,32 @@ ResourcePref resources[] = {
|
||||||
#define MODKEY ControlMask
|
#define MODKEY ControlMask
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY|ShiftMask, 36, focusonce, { 0 } },
|
{ MODKEY|ShiftMask, XK_Return, focusonce, { 0 } },
|
||||||
{ MODKEY|ShiftMask, 36, spawn, { 0 } },
|
{ MODKEY|ShiftMask, XK_Return, spawn, { 0 } },
|
||||||
{ MODKEY|ShiftMask, 46, rotate, { .i = +1 } },
|
|
||||||
{ MODKEY|ShiftMask, 43, rotate, { .i = -1 } },
|
{ MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } },
|
||||||
{ MODKEY|ShiftMask, 44, movetab, { .i = -1 } },
|
{ MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } },
|
||||||
{ MODKEY|ShiftMask, 45, movetab, { .i = +1 } },
|
{ MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } },
|
||||||
{ MODKEY, 23, rotate, { .i = 0 } },
|
{ MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } },
|
||||||
{ MODKEY, 49, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
{ MODKEY, XK_Tab, rotate, { .i = 0 } },
|
||||||
{ MODKEY, 10, move, { .i = 0 } },
|
|
||||||
{ MODKEY, 11, move, { .i = 1 } },
|
{ MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") },
|
||||||
{ MODKEY, 12, move, { .i = 2 } },
|
{ MODKEY, XK_1, move, { .i = 0 } },
|
||||||
{ MODKEY, 13, move, { .i = 3 } },
|
{ MODKEY, XK_2, move, { .i = 1 } },
|
||||||
{ MODKEY, 14, move, { .i = 4 } },
|
{ MODKEY, XK_3, move, { .i = 2 } },
|
||||||
{ MODKEY, 15, move, { .i = 5 } },
|
{ MODKEY, XK_4, move, { .i = 3 } },
|
||||||
{ MODKEY, 16, move, { .i = 6 } },
|
{ MODKEY, XK_5, move, { .i = 4 } },
|
||||||
{ MODKEY, 17, move, { .i = 7 } },
|
{ MODKEY, XK_6, move, { .i = 5 } },
|
||||||
{ MODKEY, 18, move, { .i = 8 } },
|
{ MODKEY, XK_7, move, { .i = 6 } },
|
||||||
{ MODKEY, 19, move, { .i = 9 } },
|
{ MODKEY, XK_8, move, { .i = 7 } },
|
||||||
{ MODKEY, 24, killclient, { 0 } },
|
{ MODKEY, XK_9, move, { .i = 8 } },
|
||||||
{ MODKEY, 30, focusurgent, { .v = NULL } },
|
{ MODKEY, XK_0, move, { .i = 9 } },
|
||||||
{ MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } },
|
|
||||||
{ 0, 95, fullscreen, { 0 } },
|
{ MODKEY, XK_q, killclient, { 0 } },
|
||||||
|
|
||||||
|
{ MODKEY, XK_u, focusurgent, { 0 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } },
|
||||||
|
|
||||||
|
{ 0, XK_F11, fullscreen, { 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ FREETYPEINC = /usr/include/freetype2
|
||||||
#FREETYPEINC = ${X11INC}/freetype2
|
#FREETYPEINC = ${X11INC}/freetype2
|
||||||
|
|
||||||
# Uncomment this for the alpha patch / ALPHA_PATCH
|
# Uncomment this for the alpha patch / ALPHA_PATCH
|
||||||
XRENDER = -lXrender
|
#XRENDER = -lXrender
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I. -I/usr/include -I$(X11INC) -I${FREETYPEINC}
|
INCS = -I. -I/usr/include -I$(X11INC) -I${FREETYPEINC}
|
||||||
|
|
|
@ -67,7 +67,7 @@ typedef union {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int mod;
|
unsigned int mod;
|
||||||
KeyCode keycode;
|
KeySym keysym;
|
||||||
void (*func)(const Arg *);
|
void (*func)(const Arg *);
|
||||||
const Arg arg;
|
const Arg arg;
|
||||||
} Key;
|
} Key;
|
||||||
|
@ -182,8 +182,6 @@ static char **cmd;
|
||||||
static char *wmname = "tabbed";
|
static char *wmname = "tabbed";
|
||||||
static const char *geometry;
|
static const char *geometry;
|
||||||
|
|
||||||
static Colormap cmap;
|
|
||||||
static Visual *visual = NULL;
|
|
||||||
|
|
||||||
char *argv0;
|
char *argv0;
|
||||||
|
|
||||||
|
@ -271,8 +269,8 @@ configurenotify(const XEvent *e)
|
||||||
ww = ev->width;
|
ww = ev->width;
|
||||||
wh = ev->height;
|
wh = ev->height;
|
||||||
XFreePixmap(dpy, dc.drawable);
|
XFreePixmap(dpy, dc.drawable);
|
||||||
dc.drawable = XCreatePixmap(dpy, win, ww, wh,
|
dc.drawable = XCreatePixmap(dpy, root, ww, wh,
|
||||||
32);
|
DefaultDepth(dpy, screen));
|
||||||
|
|
||||||
if (!obh && (wh <= bh)) {
|
if (!obh && (wh <= bh)) {
|
||||||
obh = bh;
|
obh = bh;
|
||||||
|
@ -441,7 +439,7 @@ drawtext(const char *text, XftColor col[ColLast])
|
||||||
else
|
else
|
||||||
x += (dc.w - TEXTW(buf)) / 2; // center text
|
x += (dc.w - TEXTW(buf)) / 2; // center text
|
||||||
|
|
||||||
d = XftDrawCreate(dpy, dc.drawable, visual, cmap);
|
d = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
|
||||||
XftDrawStringUtf8(d, &col[ColFG], dc.font.xfont, x, y, (XftChar8 *) buf, len);
|
XftDrawStringUtf8(d, &col[ColFG], dc.font.xfont, x, y, (XftChar8 *) buf, len);
|
||||||
XftDrawDestroy(d);
|
XftDrawDestroy(d);
|
||||||
}
|
}
|
||||||
|
@ -612,7 +610,7 @@ getcolor(const char *colstr)
|
||||||
{
|
{
|
||||||
XftColor color;
|
XftColor color;
|
||||||
|
|
||||||
if (!XftColorAllocName(dpy, visual, cmap, colstr, &color))
|
if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), colstr, &color))
|
||||||
die("%s: cannot allocate color '%s'\n", argv0, colstr);
|
die("%s: cannot allocate color '%s'\n", argv0, colstr);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
|
@ -699,9 +697,12 @@ keypress(const XEvent *e)
|
||||||
{
|
{
|
||||||
const XKeyEvent *ev = &e->xkey;
|
const XKeyEvent *ev = &e->xkey;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
KeySym keysym;
|
||||||
|
|
||||||
|
keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0);
|
||||||
for (i = 0; i < LENGTH(keys); i++) {
|
for (i = 0; i < LENGTH(keys); i++) {
|
||||||
if (
|
if (
|
||||||
ev->keycode == keys[i].keycode &&
|
keysym == keys[i].keysym &&
|
||||||
CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) &&
|
CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) &&
|
||||||
keys[i].func)
|
keys[i].func)
|
||||||
keys[i].func(&(keys[i].arg));
|
keys[i].func(&(keys[i].arg));
|
||||||
|
@ -738,6 +739,7 @@ manage(Window w)
|
||||||
int i, j, nextpos;
|
int i, j, nextpos;
|
||||||
unsigned int modifiers[] = { 0, LockMask, numlockmask,
|
unsigned int modifiers[] = { 0, LockMask, numlockmask,
|
||||||
numlockmask | LockMask };
|
numlockmask | LockMask };
|
||||||
|
KeyCode code;
|
||||||
Client *c;
|
Client *c;
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
|
||||||
|
@ -748,11 +750,13 @@ manage(Window w)
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
|
|
||||||
for (i = 0; i < LENGTH(keys); i++) {
|
for (i = 0; i < LENGTH(keys); i++) {
|
||||||
for (j = 0; j < LENGTH(modifiers); ++j) {
|
if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) {
|
||||||
XGrabKey(dpy, keys[i].keycode,
|
for (j = 0; j < LENGTH(modifiers); j++) {
|
||||||
keys[i].mod | modifiers[j], w,
|
XGrabKey(dpy, code, keys[i].mod |
|
||||||
True, GrabModeAsync, GrabModeAsync);
|
modifiers[j], w, True,
|
||||||
}
|
GrabModeAsync, GrabModeAsync);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1021,7 +1025,7 @@ setup(void)
|
||||||
screen = DefaultScreen(dpy);
|
screen = DefaultScreen(dpy);
|
||||||
root = RootWindow(dpy, screen);
|
root = RootWindow(dpy, screen);
|
||||||
initfont(font);
|
initfont(font);
|
||||||
dc.h = (barheight ? barheight : dc.font.height + 2);
|
dc.h = dc.font.height + 2;
|
||||||
vbh = dc.h;
|
vbh = dc.h;
|
||||||
|
|
||||||
/* init atoms */
|
/* init atoms */
|
||||||
|
@ -1069,34 +1073,6 @@ setup(void)
|
||||||
wy = dh + wy - wh - 1;
|
wy = dh + wy - wh - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XVisualInfo *vis;
|
|
||||||
XRenderPictFormat *fmt;
|
|
||||||
int nvi;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
XVisualInfo tpl = {
|
|
||||||
.screen = screen,
|
|
||||||
.depth = 32,
|
|
||||||
.class = TrueColor
|
|
||||||
};
|
|
||||||
|
|
||||||
vis = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &tpl, &nvi);
|
|
||||||
for(i = 0; i < nvi; i ++) {
|
|
||||||
fmt = XRenderFindVisualFormat(dpy, vis[i].visual);
|
|
||||||
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
|
||||||
visual = vis[i].visual;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(vis);
|
|
||||||
|
|
||||||
if (! visual) {
|
|
||||||
fprintf(stderr, "Couldn't find ARGB visual.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmap = XCreateColormap( dpy, root, visual, None);
|
|
||||||
|
|
||||||
dc.norm[ColBG] = getcolor(normbgcolor);
|
dc.norm[ColBG] = getcolor(normbgcolor);
|
||||||
dc.norm[ColFG] = getcolor(normfgcolor);
|
dc.norm[ColFG] = getcolor(normfgcolor);
|
||||||
|
@ -1104,22 +1080,12 @@ setup(void)
|
||||||
dc.sel[ColFG] = getcolor(selfgcolor);
|
dc.sel[ColFG] = getcolor(selfgcolor);
|
||||||
dc.urg[ColBG] = getcolor(urgbgcolor);
|
dc.urg[ColBG] = getcolor(urgbgcolor);
|
||||||
dc.urg[ColFG] = getcolor(urgfgcolor);
|
dc.urg[ColFG] = getcolor(urgfgcolor);
|
||||||
XSetWindowAttributes attrs;
|
dc.drawable = XCreatePixmap(dpy, root, ww, wh,
|
||||||
attrs.background_pixel = dc.norm[ColBG].pixel;
|
DefaultDepth(dpy, screen));
|
||||||
attrs.border_pixel = dc.norm[ColFG].pixel;
|
dc.gc = XCreateGC(dpy, root, 0, 0);
|
||||||
attrs.bit_gravity = NorthWestGravity;
|
|
||||||
attrs.event_mask = FocusChangeMask | KeyPressMask
|
|
||||||
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
|
|
||||||
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
|
|
||||||
attrs.background_pixmap = None;
|
|
||||||
attrs.colormap = cmap;
|
|
||||||
|
|
||||||
win = XCreateWindow(dpy, root, wx, wy, ww, wh, 0, 32, InputOutput,
|
win = XCreateSimpleWindow(dpy, root, wx, wy, ww, wh, 0,
|
||||||
visual, CWBackPixmap | CWBorderPixel | CWBitGravity
|
dc.norm[ColFG].pixel, dc.norm[ColBG].pixel);
|
||||||
| CWEventMask | CWColormap, &attrs);
|
|
||||||
|
|
||||||
dc.drawable = XCreatePixmap(dpy, win, ww, wh, 32);
|
|
||||||
dc.gc = XCreateGC(dpy, dc.drawable, 0, 0);
|
|
||||||
XMapRaised(dpy, win);
|
XMapRaised(dpy, win);
|
||||||
XSelectInput(dpy, win, SubstructureNotifyMask | FocusChangeMask |
|
XSelectInput(dpy, win, SubstructureNotifyMask | FocusChangeMask |
|
||||||
ButtonPressMask | ExposureMask | KeyPressMask |
|
ButtonPressMask | ExposureMask | KeyPressMask |
|
||||||
|
|
Reference in a new issue