From aba168a9cdbe5957bbe30e4140f808411af50f29 Mon Sep 17 00:00:00 2001 From: Daryl Ronningen Date: Wed, 31 Aug 2022 21:45:44 -0700 Subject: [PATCH] update st & tabbed --- suckless/st/config.def.h | 9 +- suckless/st/config.h | 13 +- suckless/st/config.mk | 2 +- suckless/st/patch/openurlonclick.c | 169 +++++++---- suckless/st/patch/openurlonclick.h | 7 + suckless/st/patch/scrollback.c | 6 + suckless/st/patch/st_include.h | 1 + suckless/st/patch/x_include.h | 1 - suckless/st/patches.h | 457 +++++++++++++++++++++++++++++ suckless/st/st.c | 6 +- suckless/st/st.h | 8 +- suckless/st/x.c | 142 +++++---- suckless/tabbed/config.def.h | 50 ++-- suckless/tabbed/config.h | 52 ++-- suckless/tabbed/config.mk | 2 +- suckless/tabbed/tabbed.c | 80 ++--- 16 files changed, 779 insertions(+), 226 deletions(-) create mode 100644 suckless/st/patches.h diff --git a/suckless/st/config.def.h b/suckless/st/config.def.h index c9e6e15..bb494c4 100644 --- a/suckless/st/config.def.h +++ b/suckless/st/config.def.h @@ -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 */ 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"; /* @@ -112,8 +114,6 @@ char *termname = "st-256color"; */ unsigned int tabspaces = 8; -/* bg opacity */ -float alpha = 0.8; /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { @@ -225,7 +225,6 @@ ResourcePref resources[] = { { "borderperc", INTEGER, &borderperc }, { "cwscale", FLOAT, &cwscale }, { "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", "externalpipe", NULL }; +static char *setbgcolorcmd[] = { "/bin/sh", "-c", + "printf '\033]11;#008000\007'", + "externalpipein", NULL }; + static Shortcut shortcuts[] = { /* mask keysym function argument */ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, diff --git a/suckless/st/config.h b/suckless/st/config.h index a7ecbf8..8ea039b 100644 --- a/suckless/st/config.h +++ b/suckless/st/config.h @@ -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 */ 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"; /* @@ -112,8 +114,6 @@ char *termname = "st-256color"; */ unsigned int tabspaces = 2; -/* bg opacity */ -float alpha = 0.8; /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { @@ -178,7 +178,7 @@ static Rune stcursor = 0x2603; /* snowman (U+2603) */ */ static unsigned int cols = 90; -static unsigned int rows = 30; +static unsigned int rows = 34; /* * Default shape of the mouse cursor @@ -225,7 +225,6 @@ ResourcePref resources[] = { { "borderperc", INTEGER, &borderperc }, { "cwscale", FLOAT, &cwscale }, { "chscale", FLOAT, &chscale }, - { "alpha", FLOAT, &alpha }, }; /* @@ -244,8 +243,6 @@ static MouseShortcut mshortcuts[] = { { XK_ANY_MOD, Button2, clippaste, {.i = 0}, 1 }, { ShiftMask, Button4, ttysend, {.s = "\033[5;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, Button5, kscrolldown, {.i = 1} }, }; @@ -265,6 +262,10 @@ static char *openurlcmd[] = { "/bin/sh", "-c", "xurls | dmenu -l 10 -w $WINDOWID | xargs -r open", "externalpipe", NULL }; +static char *setbgcolorcmd[] = { "/bin/sh", "-c", + "printf '\033]11;#008000\007'", + "externalpipein", NULL }; + static Shortcut shortcuts[] = { /* mask keysym function argument */ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, diff --git a/suckless/st/config.mk b/suckless/st/config.mk index d3540dc..330cd2f 100644 --- a/suckless/st/config.mk +++ b/suckless/st/config.mk @@ -13,7 +13,7 @@ X11LIB = /usr/X11R6/lib PKG_CONFIG = pkg-config # Uncomment this for the alpha patch / ALPHA_PATCH -XRENDER = -lXrender +#XRENDER = -lXrender # Uncomment this for the themed cursor patch / THEMED_CURSOR_PATCH XCURSOR = -lXcursor diff --git a/suckless/st/patch/openurlonclick.c b/suckless/st/patch/openurlonclick.c index 7b4b82f..a5a2c4b 100644 --- a/suckless/st/patch/openurlonclick.c +++ b/suckless/st/patch/openurlonclick.c @@ -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 openUrlOnClick(int col, int row, char* url_opener) { - int row_start = row; - int col_start = col; - int row_end = row; - int col_end = col; - - if (term.line[row][col].u == ' ') - 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); + char *url = detecturl(col, row, 1); + if (url) { + extern char **environ; + pid_t junk; + char *argv[] = { url_opener, url, NULL }; + posix_spawnp(&junk, argv[0], NULL, NULL, argv, environ); + } } diff --git a/suckless/st/patch/openurlonclick.h b/suckless/st/patch/openurlonclick.h index 0e57d84..5aa09de 100644 --- a/suckless/st/patch/openurlonclick.h +++ b/suckless/st/patch/openurlonclick.h @@ -1 +1,8 @@ +#include + +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); diff --git a/suckless/st/patch/scrollback.c b/suckless/st/patch/scrollback.c index cdc34bd..eb3077f 100644 --- a/suckless/st/patch/scrollback.c +++ b/suckless/st/patch/scrollback.c @@ -15,6 +15,9 @@ kscrolldown(const Arg* a) tfulldirt(); } + + if (n > 0) + restoremousecursor(); } void @@ -36,4 +39,7 @@ kscrollup(const Arg* a) tfulldirt(); } + + if (n > 0) + restoremousecursor(); } diff --git a/suckless/st/patch/st_include.h b/suckless/st/patch/st_include.h index 5667a65..7f138ec 100644 --- a/suckless/st/patch/st_include.h +++ b/suckless/st/patch/st_include.h @@ -1,4 +1,5 @@ /* Patches */ +#include "openurlonclick.h" #include "scrollback.h" #include "universcroll.h" // #if VIM_BROWSE_PATCH diff --git a/suckless/st/patch/x_include.h b/suckless/st/patch/x_include.h index e2a32b8..920c684 100644 --- a/suckless/st/patch/x_include.h +++ b/suckless/st/patch/x_include.h @@ -1,5 +1,4 @@ /* Patches */ #include "boxdraw.h" #include "netwmicon.h" -#include "openurlonclick.h" #include "xresources.h" diff --git a/suckless/st/patches.h b/suckless/st/patches.h new file mode 100644 index 0000000..cf9f9c4 --- /dev/null +++ b/suckless/st/patches.h @@ -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 diff --git a/suckless/st/st.c b/suckless/st/st.c index f280a71..66bd94d 100644 --- a/suckless/st/st.c +++ b/suckless/st/st.c @@ -922,7 +922,7 @@ ttyresize(int tw, int th) } void -ttyhangup() +ttyhangup(void) { /* Send SIGHUP to shell */ kill(pid, SIGHUP); @@ -1040,6 +1040,8 @@ tswapscreen(void) void tscrolldown(int orig, int n) { + restoremousecursor(); + int i; Line temp; @@ -1062,6 +1064,8 @@ tscrolldown(int orig, int n) void tscrollup(int orig, int n, int copyhist) { + restoremousecursor(); + int i; Line temp; diff --git a/suckless/st/st.h b/suckless/st/st.h index c9eff83..83efa29 100644 --- a/suckless/st/st.h +++ b/suckless/st/st.h @@ -163,9 +163,14 @@ typedef struct { Draw draw; Visual *vis; 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 isfixed; /* is fixed geometry? */ - int depth; /* bit depth */ int l, t; /* left and top offset */ int gm; /* geometry mask */ } XWindow; @@ -287,7 +292,6 @@ extern unsigned int defaultbg; extern unsigned int defaultcs; extern const int boxdraw, boxdraw_bold, boxdraw_braille; -extern float alpha; extern DC dc; extern XWindow xw; diff --git a/suckless/st/x.c b/suckless/st/x.c index 005f6fa..88314a0 100644 --- a/suckless/st/x.c +++ b/suckless/st/x.c @@ -173,7 +173,6 @@ 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; @@ -451,6 +450,9 @@ bpress(XEvent *e) xsel.tclick1 = now; selstart(evcol(e), evrow(e), snap); + + clearurl(); + url_click = 1; } } @@ -673,13 +675,30 @@ brelease(XEvent *e) return; if (btn == Button1) { 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 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)) { mousereport(e); @@ -718,11 +737,6 @@ xresize(int col, int row) win.tw = col * win.cw; 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); /* resize to new width */ @@ -783,12 +797,6 @@ xloadcols(void) else 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; } @@ -819,14 +827,6 @@ xsetcolorname(int x, const char *name) XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); 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; } @@ -973,7 +973,7 @@ xloadfont(Font *f, FcPattern *pattern) FcConfigSubstitute(NULL, configured, FcMatchPattern); XftDefaultSubstitute(xw.dpy, xw.scr, configured); - match = FcFontMatch(NULL, configured, &result); + match = XftFontMatch(xw.dpy, xw.scr, pattern, &result); if (!match) { FcPatternDestroy(configured); return 1; @@ -1126,23 +1126,13 @@ void xinit(int cols, int rows) { XGCValues gcvalues; + Pixmap blankpm; Window parent; pid_t thispid = getpid(); - XWindowAttributes attr; - XVisualInfo vis; xw.scr = XDefaultScreen(xw.dpy); - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { - 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; + xw.vis = XDefaultVisual(xw.dpy, xw.scr); /* font */ if (!FcInit()) @@ -1153,7 +1143,7 @@ xinit(int cols, int rows) /* colors */ - xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xw.cmap = XDefaultColormap(xw.dpy, xw.scr); xloadcols(); /* adjust fixed window geometry */ @@ -1173,17 +1163,21 @@ xinit(int cols, int rows) | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask ; 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, - win.w, win.h, 0, xw.depth, InputOutput, + win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &xw.attrs); memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False; - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); - dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); + dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, + &gcvalues); + xw.buf = xw.win; XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); 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 */ - cursor = XcursorLibraryLoadCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); + xw.pointerisvisible = 1; + 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.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, 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); XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, PropModeReplace, (uchar *)&thispid, 1); @@ -1333,12 +1338,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x fccharset); FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); + fontpattern = FcFontSetMatch(0, fcsets, 1, fcpattern, &fcres); /* Allocate memory for the new cache entry. */ if (frclen >= frccap) { @@ -1430,6 +1431,7 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i int width = charlen * win.cw; Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; XRenderColor colfg, colbg; + XRectangle r; /* Fallback on color display for attributes not supported by the font */ 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); /* 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 (base.mode & ATTR_BOXDRAW) { 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 @@ -2105,6 +2130,8 @@ xfreetitlestack(void) int 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); } @@ -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, dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg].pixel); @@ -2193,6 +2219,9 @@ unmap(XEvent *ev) void xsetpointermotion(int set) { + if (!set && !xw.pointerisvisible) + return; + set = 1; /* keep MotionNotify event enabled */ MODBIT(xw.attrs.event_mask, set, PointerMotionMask); XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); } @@ -2203,11 +2232,12 @@ xsetmode(int set, unsigned int flags) int mode = win.mode; MODBIT(win.mode, set, flags); if ((flags & MODE_MOUSE) + && xw.pointerisvisible ) { if (win.mode & MODE_MOUSE) XUndefineCursor(xw.dpy, xw.win); else - XDefineCursor(xw.dpy, xw.win, cursor); + XDefineCursor(xw.dpy, xw.win, xw.vpointer); } if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) redraw(); @@ -2323,6 +2353,17 @@ kpress(XEvent *ev) Status status; 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)) return; @@ -2534,9 +2575,6 @@ main(int argc, char *argv[]) case 'a': allowaltscreen = 0; break; - case 'A': - opt_alpha = EARGF(usage()); - break; case 'c': opt_class = EARGF(usage()); break; diff --git a/suckless/tabbed/config.def.h b/suckless/tabbed/config.def.h index 3240392..d1a2af5 100644 --- a/suckless/tabbed/config.def.h +++ b/suckless/tabbed/config.def.h @@ -15,7 +15,6 @@ static int tabwidth = 200; static const Bool foreground = True; 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, @@ -51,27 +50,32 @@ ResourcePref resources[] = { #define MODKEY ControlMask static Key keys[] = { /* modifier key function argument */ - { MODKEY|ShiftMask, 36, focusonce, { 0 } }, - { MODKEY|ShiftMask, 36, spawn, { 0 } }, - { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, - { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, - { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, - { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, - { MODKEY, 23, rotate, { .i = 0 } }, - { MODKEY, 49, spawn, SETPROP("_TABBED_SELECT_TAB") }, - { MODKEY, 10, move, { .i = 0 } }, - { MODKEY, 11, move, { .i = 1 } }, - { MODKEY, 12, move, { .i = 2 } }, - { MODKEY, 13, move, { .i = 3 } }, - { MODKEY, 14, move, { .i = 4 } }, - { MODKEY, 15, move, { .i = 5 } }, - { MODKEY, 16, move, { .i = 6 } }, - { MODKEY, 17, move, { .i = 7 } }, - { MODKEY, 18, move, { .i = 8 } }, - { MODKEY, 19, move, { .i = 9 } }, - { MODKEY, 24, killclient, { 0 } }, - { MODKEY, 30, focusurgent, { .v = NULL } }, - { MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } }, - { 0, 95, fullscreen, { 0 } }, + { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, + { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, + + { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, + { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, + { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, + { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, + { MODKEY, XK_Tab, rotate, { .i = 0 } }, + + { MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") }, + { MODKEY, XK_1, move, { .i = 0 } }, + { MODKEY, XK_2, move, { .i = 1 } }, + { MODKEY, XK_3, move, { .i = 2 } }, + { MODKEY, XK_4, move, { .i = 3 } }, + { MODKEY, XK_5, move, { .i = 4 } }, + { MODKEY, XK_6, move, { .i = 5 } }, + { MODKEY, XK_7, move, { .i = 6 } }, + { MODKEY, XK_8, move, { .i = 7 } }, + { MODKEY, XK_9, move, { .i = 8 } }, + { MODKEY, XK_0, move, { .i = 9 } }, + + { MODKEY, XK_q, killclient, { 0 } }, + + { MODKEY, XK_u, focusurgent, { 0 } }, + { MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } }, + + { 0, XK_F11, fullscreen, { 0 } }, }; diff --git a/suckless/tabbed/config.h b/suckless/tabbed/config.h index 3240392..a588c02 100644 --- a/suckless/tabbed/config.h +++ b/suckless/tabbed/config.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ /* 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* normfgcolor = "#cccccc"; static char* selbgcolor = "#555555"; @@ -15,7 +15,6 @@ static int tabwidth = 200; static const Bool foreground = True; 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, @@ -51,27 +50,32 @@ ResourcePref resources[] = { #define MODKEY ControlMask static Key keys[] = { /* modifier key function argument */ - { MODKEY|ShiftMask, 36, focusonce, { 0 } }, - { MODKEY|ShiftMask, 36, spawn, { 0 } }, - { MODKEY|ShiftMask, 46, rotate, { .i = +1 } }, - { MODKEY|ShiftMask, 43, rotate, { .i = -1 } }, - { MODKEY|ShiftMask, 44, movetab, { .i = -1 } }, - { MODKEY|ShiftMask, 45, movetab, { .i = +1 } }, - { MODKEY, 23, rotate, { .i = 0 } }, - { MODKEY, 49, spawn, SETPROP("_TABBED_SELECT_TAB") }, - { MODKEY, 10, move, { .i = 0 } }, - { MODKEY, 11, move, { .i = 1 } }, - { MODKEY, 12, move, { .i = 2 } }, - { MODKEY, 13, move, { .i = 3 } }, - { MODKEY, 14, move, { .i = 4 } }, - { MODKEY, 15, move, { .i = 5 } }, - { MODKEY, 16, move, { .i = 6 } }, - { MODKEY, 17, move, { .i = 7 } }, - { MODKEY, 18, move, { .i = 8 } }, - { MODKEY, 19, move, { .i = 9 } }, - { MODKEY, 24, killclient, { 0 } }, - { MODKEY, 30, focusurgent, { .v = NULL } }, - { MODKEY|ShiftMask, 30, toggle, { .v = (void*) &urgentswitch } }, - { 0, 95, fullscreen, { 0 } }, + { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } }, + { MODKEY|ShiftMask, XK_Return, spawn, { 0 } }, + + { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } }, + { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } }, + { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } }, + { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } }, + { MODKEY, XK_Tab, rotate, { .i = 0 } }, + + { MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") }, + { MODKEY, XK_1, move, { .i = 0 } }, + { MODKEY, XK_2, move, { .i = 1 } }, + { MODKEY, XK_3, move, { .i = 2 } }, + { MODKEY, XK_4, move, { .i = 3 } }, + { MODKEY, XK_5, move, { .i = 4 } }, + { MODKEY, XK_6, move, { .i = 5 } }, + { MODKEY, XK_7, move, { .i = 6 } }, + { MODKEY, XK_8, move, { .i = 7 } }, + { MODKEY, XK_9, move, { .i = 8 } }, + { MODKEY, XK_0, move, { .i = 9 } }, + + { MODKEY, XK_q, killclient, { 0 } }, + + { MODKEY, XK_u, focusurgent, { 0 } }, + { MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } }, + + { 0, XK_F11, fullscreen, { 0 } }, }; diff --git a/suckless/tabbed/config.mk b/suckless/tabbed/config.mk index 149b160..4aa5a08 100644 --- a/suckless/tabbed/config.mk +++ b/suckless/tabbed/config.mk @@ -17,7 +17,7 @@ FREETYPEINC = /usr/include/freetype2 #FREETYPEINC = ${X11INC}/freetype2 # Uncomment this for the alpha patch / ALPHA_PATCH -XRENDER = -lXrender +#XRENDER = -lXrender # includes and libs INCS = -I. -I/usr/include -I$(X11INC) -I${FREETYPEINC} diff --git a/suckless/tabbed/tabbed.c b/suckless/tabbed/tabbed.c index 8143f62..f42b207 100644 --- a/suckless/tabbed/tabbed.c +++ b/suckless/tabbed/tabbed.c @@ -67,7 +67,7 @@ typedef union { typedef struct { unsigned int mod; - KeyCode keycode; + KeySym keysym; void (*func)(const Arg *); const Arg arg; } Key; @@ -182,8 +182,6 @@ static char **cmd; static char *wmname = "tabbed"; static const char *geometry; -static Colormap cmap; -static Visual *visual = NULL; char *argv0; @@ -271,8 +269,8 @@ configurenotify(const XEvent *e) ww = ev->width; wh = ev->height; XFreePixmap(dpy, dc.drawable); - dc.drawable = XCreatePixmap(dpy, win, ww, wh, - 32); + dc.drawable = XCreatePixmap(dpy, root, ww, wh, + DefaultDepth(dpy, screen)); if (!obh && (wh <= bh)) { obh = bh; @@ -441,7 +439,7 @@ drawtext(const char *text, XftColor col[ColLast]) else 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); XftDrawDestroy(d); } @@ -612,7 +610,7 @@ getcolor(const char *colstr) { 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); return color; @@ -699,9 +697,12 @@ keypress(const XEvent *e) { const XKeyEvent *ev = &e->xkey; unsigned int i; + KeySym keysym; + + keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); for (i = 0; i < LENGTH(keys); i++) { if ( - ev->keycode == keys[i].keycode && + keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) keys[i].func(&(keys[i].arg)); @@ -738,6 +739,7 @@ manage(Window w) int i, j, nextpos; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; + KeyCode code; Client *c; XEvent e; @@ -748,11 +750,13 @@ manage(Window w) XSync(dpy, False); for (i = 0; i < LENGTH(keys); i++) { - for (j = 0; j < LENGTH(modifiers); ++j) { - XGrabKey(dpy, keys[i].keycode, - keys[i].mod | modifiers[j], w, - True, GrabModeAsync, GrabModeAsync); - } + if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) { + for (j = 0; j < LENGTH(modifiers); j++) { + XGrabKey(dpy, code, keys[i].mod | + modifiers[j], w, True, + GrabModeAsync, GrabModeAsync); + } + } } @@ -1021,7 +1025,7 @@ setup(void) screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); initfont(font); - dc.h = (barheight ? barheight : dc.font.height + 2); + dc.h = dc.font.height + 2; vbh = dc.h; /* init atoms */ @@ -1069,34 +1073,6 @@ setup(void) 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[ColFG] = getcolor(normfgcolor); @@ -1104,22 +1080,12 @@ setup(void) dc.sel[ColFG] = getcolor(selfgcolor); dc.urg[ColBG] = getcolor(urgbgcolor); dc.urg[ColFG] = getcolor(urgfgcolor); - XSetWindowAttributes attrs; - attrs.background_pixel = dc.norm[ColBG].pixel; - attrs.border_pixel = dc.norm[ColFG].pixel; - attrs.bit_gravity = NorthWestGravity; - attrs.event_mask = FocusChangeMask | KeyPressMask - | ExposureMask | VisibilityChangeMask | StructureNotifyMask - | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; - attrs.background_pixmap = None; - attrs.colormap = cmap; + dc.drawable = XCreatePixmap(dpy, root, ww, wh, + DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, root, 0, 0); - win = XCreateWindow(dpy, root, wx, wy, ww, wh, 0, 32, InputOutput, - visual, CWBackPixmap | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &attrs); - - dc.drawable = XCreatePixmap(dpy, win, ww, wh, 32); - dc.gc = XCreateGC(dpy, dc.drawable, 0, 0); + win = XCreateSimpleWindow(dpy, root, wx, wy, ww, wh, 0, + dc.norm[ColFG].pixel, dc.norm[ColBG].pixel); XMapRaised(dpy, win); XSelectInput(dpy, win, SubstructureNotifyMask | FocusChangeMask | ButtonPressMask | ExposureMask | KeyPressMask |