Urxvt: change background color on the fly

urxvt 2.6 in 2004 added support for xterm's dynamic colors feature. In XTerm Control Sequences, this is OSC 11. OSC 10 sets the default text color. The changelog mentioned part of the change:

2.6  Fri Apr  2 03:24:10 CEST 2004
        - minor doc corrections.
        - WARNING: changed menu sequence from ESC ] 10 to ESC ] 703 to
          avoid clashes with xterm.
        - changed OSC701/OSC702 sequence to return standard escaped reports.
        - xterm-compat: make set window colour and other requests report
          window colour when arg is "?".

but the source-code tells the story, as usual:

 /*
  * XTerm escape sequences: ESC ] Ps;Pt (ST|BEL)
  *       0 = change iconName/title  
  *       1 = change iconName
  *       2 = change title
  *       4 = change color
+ *      10 = change fg color 
+ *      11 = change bg color 
  *      12 = change text color
  *      13 = change mouse foreground color
  *      17 = change highlight character colour
@@ -2949,20 +3236,21 @@ 
  *      50 = change font
  *
  * rxvt extensions:
- *      10 = menu (may change in future) 
  *      20 = bg pixmap
  *      39 = change default fg color
  *      49 = change default bg color
  *      55 = dump scrollback buffer and all of screen
  *     701 = change locale
  *     702 = find font
+ *     703 = menu 
  */

The manual rxvt(7) gives no useful information:

   XTerm Operating System Commands
       "ESC ] Ps;Pt ST"
           Set XTerm Parameters. 8-bit ST: 0x9c, 7-bit ST sequence: ESC \
           (0x1b, 0x5c), backwards compatible terminator BEL (0x07) is also
           accepted. any octet can be escaped by prefixing it with SYN (0x16,
           ^V).

This simple example sets both foreground (text) and background default colors:

#!/bin/sh
printf '\033]10;red\007'
printf '\033]11;green\007'

Like xterm, these default colors can be overridden temporarily by "ANSI" colors.

The feature can be disabled in xterm using the dynamicColors resource. Unlike xterm, urxvt has no resource-setting for the feature.

VTE also implements the feature, and likewise doesn't document it. urxvt at least started with documentation from rxvt. For VTE, you have to read the source code. The relevant feature in vteseq.cc looks like this:

/* Change the default background cursor, BEL terminated */
static void
vte_sequence_handler_change_background_color_bel (VteTerminalPrivate *that, GValueArray *params)
{
        vte_sequence_handler_change_special_color_internal (that, params,
                                                            VTE_DEFAULT_BG, -1, 11, BEL);
}

/* Change the default background cursor, ST terminated */
static void
vte_sequence_handler_change_background_color_st (VteTerminalPrivate *that, GValueArray *params)
{
        vte_sequence_handler_change_special_color_internal (that, params,
                                                            VTE_DEFAULT_BG, -1, 11, ST);
}

That code dates back to sometime in 2003 (when it was written in C):

commit f39e281529827f68fd0e9bba41785d66a21efc1c
Author: Nalin Dahyabhai <[email protected]>
Date:   Wed Jan 22 21:35:22 2003 +0000

    accept OSC{number};{string}ST as set-text-parameters, per XTerm docs (part

    * src/caps.c: accept OSC{number};{string}ST as set-text-parameters, per XTerm
        docs (part of #104154).
    * src/keymap.c: revert change to prepend "1;" to keys with modifiers (#104139).

Further reading:

  • Can I set a color by its number? (xterm FAQ)

I added the following to my ~/.Xresources file to change to colors on the fly pressing Ctrl and 7 or 8 or 9.

! change to red background
URxvt.keysym.C-7: command:\033]11;#ff0000\007

! change to light background
URxvt.keysym.C-8: command:\033]11;#ffffff\007

! change to dark gray background
URxvt.keysym.C-9: command:\033]11;#777777\007

If you want to set foreground and background color at the same time, just concatenate the commands (some colors are defined by names):

! change to red background
URxvt.keysym.C-7: command:\033]11;#ff0000\007\033]10;yellow\007

You can test your colors with a simple echo command, like this one:

echo -e '\033]11;#ff0000\007\033]10;yellow\007'   # changes to red background and yellow foreground

Attention

I used code 11 for background color and code 10 for foreground color. The definitions for Urxvt cited by Thomas Dickey indicate to use 49 and 39 instead (which I tested and also work).


I have the following in my Xresources for quick switching (yes, it's based on dynamic colors).

URxvt*keysym.Control-Shift-F10: command:\033]11;#2c2c2c\007\033]10;#dcdcdc\007\033]12;#dcdcdc\007\033]4;0;#3f3f3f\007\033]4;1;#705050\007\033]4;2;#60b48a\007\033]4;3;#dfaf8f\007\033]4;4;#9ab8d7\007\033]4;5;#dc8cc3\007\033]4;6;#8cd0d3\007\033]4;7;#dcdcdc\007\033]4;8;#709080\007\033]4;9;#dca3a3\007\033]4;10;#72d5a3\007\033]4;11;#f0dfaf\007\033]4;12;#94bff3\007\033]4;13;#ec93d3\007\033]4;14;#93e0e3\007\033]4;15;#ffffff\007
URxvt*keysym.Control-Shift-F11: command:\033]11;#000000\007\033]10;#ffffff\007\033]12;#ffffff\007\033]4;0;#000000\007\033]4;1;#cc0000\007\033]4;2;#4e9a06\007\033]4;3;#c4a000\007\033]4;4;#3465a4\007\033]4;5;#75507b\007\033]4;6;#06989a\007\033]4;7;#d3d7cf\007\033]4;8;#555753\007\033]4;9;#ef2929\007\033]4;10;#8ae234\007\033]4;11;#fce94f\007\033]4;12;#729fcf\007\033]4;13;#ad7fa8\007\033]4;14;#34e2e2\007\033]4;15;#eeeeec\007
URxvt*keysym.Control-Shift-F12: command:\033]11;#000000\007\033]10;#a9a9a9\007\033]12;#a9a9a9\007\033]4;0;#000000\007\033]4;1;#cc0000\007\033]4;2;#00cc00\007\033]4;3;#cccc00\007\033]4;4;#0000cc\007\033]4;5;#cc00cc\007\033]4;6;#00cccc\007\033]4;7;#cccccc\007\033]4;8;#555555\007\033]4;9;#ff0000\007\033]4;10;#00ff00\007\033]4;11;#ffff00\007\033]4;12;#0000ff\007\033]4;13;#ff00ff\007\033]4;14;#00ffff\007\033]4;15;#ffffff\007

You can also take a look for another approach here: https://github.com/sos4nt/dynamic-colors

Tags:

Colors

Rxvt