Some of my hosts, namely those running FreeBSD, have had GNU Screen 5.x for a
about a year now, while most of the others running various flavors of Linux
still have version 4.x. One major change that happened in GNU Screen 5.0 is
that they migrated to a new hardstatus color syntax and deprecated the old
style. This means that if you have a nice color status bar at the bottom of
your screen windows, it almost certainly will need manually changed to the
new syntax. I don’t rely on the status bar as much on the FreeBSD hosts so it
had escaped my attention that my customized version had been broken on the hosts
with screen 5.
Why don’t I use tmux? Well, I’ve been using GNU Screen for 30 years, I like it,
I’m used to it, and it can talk directly to serial ports without involving any
extra software.
Old Syntax Example
In my previous post
about using GNU screen as a part of a Raspberry Pi serial console server, I
included a status bar example which is actually the default FreeBSD status bar
they include in /usr/local/etc/screenrc:
hardstatus alwayslastline
hardstatus string '%{gk}[%{G}%H%{g}][%= %{wk}%?%-Lw%?%{=b kR}(%{W}%n*%f %t%?(%u)%?%{=b kR})%{= kw}%?%+Lw%?%?%= %{g}]%{=b C}[%m/%d/%y %C %A]%{W}'
This example is the older Screen 4.x color syntax, which specifies colors using letters, and is now deprecated in Screen 5.x.
Color Code Changes
In the new style, colors are coded as 0-15 for basic ANSI, 0-255 for 256 color
mode, and for truecolor terminals it can either use a hexadecimal code starting
with x, or HTML notation as hexadecimal digits following a #. Foreground
and background are specified by separating them with a semicolon.
The screen(1) man page says that 3-character HTML style notation should also work, but in my brief testing it did not produce the expected results.
| Color Name | Old Color | New Color | Truecolor |
|---|---|---|---|
| Black | k |
0 |
#000000 |
| Maroon | r |
1 |
#800000 |
| Green | g |
2 |
#008000 |
| Yellow | y |
3 |
#808000 |
| Blue | b |
4 |
#000080 |
| Magenta | m |
5 |
#800080 |
| Cyan | c |
6 |
#008080 |
| Light Gray | w |
7 |
#C0C0C0 |
| Dark Gray | K |
8 |
#808080 |
| Bright Red | R |
9 |
#FF0000 |
| Bright Green | G |
10 |
#00FF00 |
| Bright Yellow | Y |
11 |
#FFFF00 |
| Bright Blue | B |
12 |
#0000FF |
| Bright Magenta | M |
13 |
#FF00FF |
| Bright Cyan | C |
14 |
#00FFFF |
| White | W |
15 |
#FFFFFF |
Color Order Changes
In addition to the change in color format, the order also changed. In the old style the background color was first, then foreground. In the new style it is foreground then background. While that is a much better choice logically, it adds to the confusion when updating.
| Colors | Old Style | New Style |
|---|---|---|
| White Text on Black | %{kW} |
%{15;0} |
| Black Text on Yellow | %{yk} |
%{0;3} |
New Syntax Example
Fortunately, the fine folks at FreeBSD have updated their default screenrc to
have the new syntax, so we can use that as the new example:
hardstatus alwayslastline
hardstatus string '%{2;0}[%{+b10;0}%H%{-}][%= %{7;0}%?%-Lw%?%{+9;0}(%{+15;0}%n%f %t%?(%u)%?%{-})%{-} ^H%?%+Lw%?%= %{-}]%{+b14;0}[%m/%d/%y %c]%{-}%{-}'
I tried converting my slightly modified version to the new syntax and ended up with nearly the same line, but theirs works better. See my note at the end of this post about the bug I hit, which the FreeBSD example works around.
If your terminal supports truecolor, you can enable support for that in screen and use the HTML style color syntax instead:
truecolor on
hardstatus alwayslastline
hardstatus string '%{#008000;#000000}[%{+b#00FF00;#000000}%H%{-}][%= %{#C0C0C0;#000000}%?%-Lw%?%{+#FF0000;#000000}(%{+b#FFFFFF;#000000}%n%f %t%?(%u)%?%{-})%{-} ^H%?%+Lw%?%= %{-}]%{+b#00FFFF;#000000}[%m/%d/%y %C %A]%{-}%{-}'
Unfortunately, the new syntax and old syntax are incompatible both ways, so you can’t form a status line that works on both GNU Screen 4.x and 5.x. You also don’t appear to be able to form a status line that falls back to 16 or 256 colors if the terminal doesn’t support truecolor. So you might want to keep several variations on hand to use in appropriate circumstances.
Padding Bug
When converting my status line I hit a bug where if you have padding on both the left and right sides, the color of the last window entry in the list didn’t have color applied properly.
Using a smaller example, the background color was being applied way to the left.
Small example that demonstrates the bug:
hardstatus alwayslastline 'Left%=%-Lw%{7;4}%n%f %t%{-}%+Lw%=Right'
Using the FreeBSD default line as an example, I noticed they had a space and a backspace after the active window, which appears to work around the problem:
hardstatus alwayslastline 'Left%= %-Lw%{7;4}%n%f %t%{-} ^H%+Lw%= Right'
I submitted a bug report upstream, but since there is a workaround it’s fairly low priority.