URL: <https://savannah.gnu.org/bugs/?67349>
Summary: screen implements 256-color support but can't effectively use it (fix included) Group: GNU Screen Submitter: enveezee Submitted: Wed 23 Jul 2025 04:51:54 AM GMT Category: Program Logic Severity: 3 - Normal Priority: 5 - Normal Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any Release: 5.0.0 Fixed Release: None Planned Release: None Work Required: None _______________________________________________________ Follow-up Comments: ------------------------------------------------------- Date: Wed 23 Jul 2025 04:51:54 AM GMT By: nvz <enveezee> This problem was discovered running gemini-cli inside screen running on a mate-terminal on arch linux, the subsequent fix and bug report were generated by gemini-cli who with a little help from me, ran this issue down and resolved it to where all themes in gemini-cli now appear with color in screen on mate-terminal. I am neither familiar with screen source nor did I write this code, however it seems a trivial fix and I can confirm it works as I have built and tested the code and verified it fixes the issue. The issue existed in both the 5.0.1 in arch as well as the 5.0 gemini and I pulled from git, we fixed the issue in 5.0.0 This bug report seems a bit nonsensical in the portion related to reproducing the steps but I'm just gonna slap gemini's work below regardless cause it includes the diff to address the problem. Problem Description: When running applications that utilize 256-color or True Color themes (e.g., `gemini-cli`, or a simple `node` script using `chalk.hex()`) inside a `GNU Screen` session, the colors are downgraded to grayscale or a basic 8-color palette. This occurs even when the `TERM` environment variable is set to `screen.xterm-256color` (or `xterm-256color`) and `FORCE_COLOR=3` is exported. This behavior is observed despite the `screen-256color` terminfo entry explicitly advertising `colors#256`. Reproduction Steps: 1. **System Information:** Arch Linux (or any Linux distribution with `GNU Screen` and `ncurses`/`terminfo` installed). 2. **Prerequisites:** `node`, `npm`, `git`, `gcc`, `gdb`. 3. **Clone `GNU Screen` source:** ```bash git clone https://git.savannah.gnu.org/git/screen.git screen-source ``` 4. **Navigate to source directory:** ```bash cd screen-source/src ``` 5. **Generate build files:** ```bash autoreconf -fi ``` 6. **Configure `screen` (without the fix applied):** ```bash ./configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-pam --enable-rxvt_osc --enable-telnet --with-pty-group=5 --with-socket-dir=/run/screens --with-sys-screenrc=/etc/screenrc ``` *(Note: The `--enable-colors256` flag is not recognized by `configure`, which is part of the problem's root cause.)* 7. **Compile `screen`:** ```bash make ``` 8. **Create `test_colors.js`:** ```javascript // Save this as /home/nvz/Desktop/test_colors.js import chalk from 'chalk'; // Explicitly set chalk.level to 3 (256 colors) for this test chalk.level = 3; console.log('--- Basic Named Colors (should work in screen) ---'); console.log(chalk.red('This is red.')); console.log(chalk.green('This is green.')); console.log(chalk.blue('This is blue.')); console.log(chalk.yellow('This is yellow.')); console.log(chalk.cyan('This is cyan.')); console.log(chalk.magenta('This is magenta.')); console.log(chalk.white('This is white.')); console.log(chalk.gray('This is gray.')); console.log('\n--- Hex Colors (may fail in screen) ---'); console.log(chalk.hex('#FF0000')('This is hex red.')); console.log(chalk.hex('#00FF00')('This is hex green.')); console.log(chalk.hex('#0000FF')('This is hex blue.')); console.log(chalk.hex('#FFA500')('This is hex orange.')); console.log(chalk.hex('#800080')('This is hex purple.')); console.log(chalk.hex('#ADD8E6')('This is hex light blue.')); ``` 9. **Install `chalk` for the test script:** ```bash npm install chalk # Run in /home/nvz/Desktop ``` 10. **Run `test_colors.js` outside `screen`:** ```bash node /home/nvz/Desktop/test_colors.js ``` *Expected:* All colors (named and hex) display correctly. 11. **Run `test_colors.js` inside `screen`:** ```bash /home/nvz/Desktop/screen-source/src/screen # Inside screen: node /home/nvz/Desktop/test_colors.js ``` *Observed:* Hex colors display in grayscale or incorrect colors. Named colors display correctly. Analysis of the Bug: 1. **`terminfo` reports 256 colors:** Running `test_tgetnum` (a simple C program that calls `tgetnum("Co")`) with `TERM=screen.xterm-256color` confirms that the system's `ncurses`/`terminfo` library correctly reports `256` for the `Co` (colors) capability. ``` TERM=screen.xterm-256color, tgetnum("Co") returns: 256 ``` This indicates the `screen-256color` terminfo entry itself is correct. 2. **`screen` internally downgrades color capability:** Despite `tgetnum("Co")` returning `256`, `screen`'s internal `dumptermcap` command reports `:Co#8:`. This means `screen` is internally setting its `Co` capability to `8`, leading to a color downgrade. 3. **Root Cause:** The bug lies in `screen`'s `src/termcap.c`, specifically in the `InitTermcap` function. While `screen` correctly retrieves the `Co` value from `terminfo` (which is 256), its logic for setting `D_hascolor` and `hastruecolor` (which influence the `SetColor` function in `src/display.c`) does not fully account for the 256-color capability. The `SetColor` function then downgrades colors if `D_CCO` (which is `D_tcs[68].num`, the `Co` value) is not `256`. The problem is that `D_tcs[68].num` is being implicitly set to `8` somewhere, or `screen` is not correctly using the `256` value it retrieves. Proposed Fix: The fix involves modifying `src/termcap.c` to ensure `D_hascolor` and `hastruecolor` are correctly set based on the `Co` capability. Diff for `src/termcap.c`: ```diff diff --git a/src/termcap.c b/src/termcap.c index b49818b..3267d2c 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -271,8 +271,15 @@ int InitTermcap(int width, int height) t = D_attrtyp[i]; } } -+ if (D_CAF || D_CAB || D_CSF || D_CSB) -+ D_hascolor = 1; + if (D_tcs[55].num >= 8) { + D_hascolor = 1; + } + if (D_tcs[55].num >= 256) { + D_hascolor = 1; + } + if (D_tcs[55].num >= 16000000) { /* True Color */ + hastruecolor = true; + } if (D_UT) D_BE = 1; /* screen erased with background color */ _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?67349> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/
signature.asc
Description: PGP signature