notcurses
notcurses copied to clipboard
Erroneous colors inside a tmux session
I'm writing a rasterizer and I've noticed that colors differ between the xfce terminal and from inside of a tmux session. So, here's the version running without tmux on xfce terminal (version 0.8.10) where LANG=en_US.UTF-8, TERM=xfce, and LC_CTYPE="", notcurses version 3.0.7 on Linux 5.17.1-zen1-1-zen (distro is Arch Linux):
https://user-images.githubusercontent.com/95090318/160998630-a4bcfb8e-4571-4769-a380-06572035d32e.mp4
Here's the same code running inside tmux session will all the same parameters except TERM=tmux-256color:
https://user-images.githubusercontent.com/95090318/160998907-c76a8bd9-36f0-48ac-a1e1-298ad2536184.mp4
I tested this again in tmux with TERM=xfce and it produced the same result.
How can I debug this? I'd like to find the source of the problem but I don't even know where to look.
Also sometimes the terminal gets corrupted after I exit from the rasterizer inside tmux, but it never happens outside the tmux session.
tmux definitely introduces a layer between us and the true terminal that leads to complexity, but as far as i'm aware, we're able to work around most of it. i can't look into this right now, but i'll load up tmux this weekend and get to the bottom of it. is it possible for you to post your test code, ideally minimized to show the problem?
This is pretty much the gist of what's happening:
/// We go inside the render loop
while (true) {
struct ncvisual_options options = {
.n = renderPlane,
.scaling = NCSCALE_NONE,
.leny = (unsigned)framebufferHeight,
.lenx = (unsigned)framebufferWidth,
.blitter = NCBLIT_1x1
};
int cnt = 0;
for (int i = 0; i < framebufferHeight; ++i) {
for (int j = 0; j < framebufferWidth; ++j) {
/// This is the pixel structure used by the rasterizer
/// It contains things like color and depth value,
/// but at this point the final color is determined and
/// ready to be displayed
TXpixel_t* currentPixel = txGetPixelFromFrontFramebuffer(i, j);
/// Since the colors are stored as floating point values 0.0f <= X <= 1.0f
/// we turn them into their integer equivalents 0 <= I <= 255
uint32_t u_r = (uint32_t)(currentPixel->color[0] * 255.0f);
uint32_t u_g = (uint32_t)(currentPixel->color[1] * 255.0f);
uint32_t u_b = (uint32_t)(currentPixel->color[2] * 255.0f);
/// Store the color as a 32-bit unsigned integer
raw_framebuffer[cnt++] = (((uint32_t)255 << 24) |
(u_b << 16) |
(u_g << 8) |
(u_r << 0));
}
}
/// Blit our color buffer onto a plane
ncblit_rgba(raw_framebuffer,
txGetFramebufferWidth() * (int)(sizeof(uint32_t)),
&options);
/// Display it on the terminal
notcurses_render(txGetContext());
}