Cannot set custom palette colors through the Windows API #11842

Closed
opened 2026-01-31 02:59:07 +00:00 by claunia · 3 comments
Owner

Originally created by @MCJack123 on GitHub (Dec 19, 2020).

When using the Windows API to set color information, the colors do not get changed. Instead they remain the same as the theme set. (This might conflict with user settings, but it breaks programs that rely on changing colors.)

I'm using PDCurses to set the colors, which I believe uses the Windows API. I haven't looked through the source very deeply, but it seems to call SetConsoleScreenBufferInfoEx, or sends a WM_SETCONSOLEINFO message to the console window if that isn't available.

Environment

Windows build number: 10.0.19042.631
Windows Terminal version (if applicable): 1.4.3243.0

PDCurses 3.9
CraftOS-PC v2.5 beta

Steps to reproduce

Compile this C program with PDCurses (available through vcpkg):

#include <curses.h>

static char hexstr[16] = "0123456789abcdef";
static unsigned char palette[16][3] = {
    {0xf0, 0xf0, 0xf0},
    {0xf2, 0xb2, 0x33},
    {0xe5, 0x7f, 0xd8},
    {0x99, 0xb2, 0xf2},
    {0xde, 0xde, 0x6c},
    {0x7f, 0xcc, 0x19},
    {0xf2, 0xb2, 0xcc},
    {0x4c, 0x4c, 0x4c},
    {0x99, 0x99, 0x99},
    {0x4c, 0x99, 0xb2},
    {0xb2, 0x66, 0xe5},
    {0x33, 0x66, 0xcc},
    {0x7f, 0x66, 0x4c},
    {0x57, 0xa6, 0x4e},
    {0xcc, 0x4c, 0x4c},
    {0x11, 0x11, 0x11}
};

int main() {
    initscr();
    start_color();
    if (can_change_color()) {
        for (int i = 0; i < 16 && i < COLORS; i++) {
            init_color(i, palette[15-i][0] * (1000/255), palette[15-i][1] * (1000/255), palette[15-i][2] * (1000/255));
            init_pair(i, i, i);
            addch(hexstr[i] | COLOR_PAIR(i));
        }
    } else printw("Can't change colors on this terminal!");
    getch();
    endwin();
    return 0;
}

(Warning: this will mess with the colors of CMD!)

Then run the program in both Windows Terminal and CMD. Notice the difference between the colors. One noticeable difference is that you can see the 7 in Windows Terminal, but not in CMD (since the colors are properly set in CMD).

Expected behavior

The colors are set as written in the code.

image

Actual behavior

The colors are not changed.

image


Here's a comparison between the two in a real program:

image

Originally created by @MCJack123 on GitHub (Dec 19, 2020). <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> <!-- This bug tracker is monitored by Windows Terminal development team and other technical folks. **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link. Please use this form and describe your issue, concisely but precisely, with as much detail as possible. --> When using the Windows API to set color information, the colors do not get changed. Instead they remain the same as the theme set. (This might conflict with user settings, but it breaks programs that rely on changing colors.) I'm using PDCurses to set the colors, which I believe uses the Windows API. I haven't looked through the source very deeply, but it seems to call `SetConsoleScreenBufferInfoEx`, or sends a `WM_SETCONSOLEINFO` message to the console window if that isn't available. # Environment ```none Windows build number: 10.0.19042.631 Windows Terminal version (if applicable): 1.4.3243.0 PDCurses 3.9 CraftOS-PC v2.5 beta ``` # Steps to reproduce Compile this C program with PDCurses (available through `vcpkg`): ```c #include <curses.h> static char hexstr[16] = "0123456789abcdef"; static unsigned char palette[16][3] = { {0xf0, 0xf0, 0xf0}, {0xf2, 0xb2, 0x33}, {0xe5, 0x7f, 0xd8}, {0x99, 0xb2, 0xf2}, {0xde, 0xde, 0x6c}, {0x7f, 0xcc, 0x19}, {0xf2, 0xb2, 0xcc}, {0x4c, 0x4c, 0x4c}, {0x99, 0x99, 0x99}, {0x4c, 0x99, 0xb2}, {0xb2, 0x66, 0xe5}, {0x33, 0x66, 0xcc}, {0x7f, 0x66, 0x4c}, {0x57, 0xa6, 0x4e}, {0xcc, 0x4c, 0x4c}, {0x11, 0x11, 0x11} }; int main() { initscr(); start_color(); if (can_change_color()) { for (int i = 0; i < 16 && i < COLORS; i++) { init_color(i, palette[15-i][0] * (1000/255), palette[15-i][1] * (1000/255), palette[15-i][2] * (1000/255)); init_pair(i, i, i); addch(hexstr[i] | COLOR_PAIR(i)); } } else printw("Can't change colors on this terminal!"); getch(); endwin(); return 0; } ``` (Warning: this will mess with the colors of CMD!) Then run the program in both Windows Terminal and CMD. Notice the difference between the colors. One noticeable difference is that you can see the 7 in Windows Terminal, but not in CMD (since the colors are properly set in CMD). # Expected behavior The colors are set as written in the code. ![image](https://user-images.githubusercontent.com/6236912/102684897-6b936680-41aa-11eb-9884-d7849a5946b3.png) # Actual behavior The colors are not changed. ![image](https://user-images.githubusercontent.com/6236912/102684908-7948ec00-41aa-11eb-9f7a-cf5ab0f36669.png) ----- Here's a comparison between the two in a real program: ![image](https://user-images.githubusercontent.com/6236912/102683362-75af6800-419e-11eb-8c88-3fda95324340.png)
claunia added the Needs-TriageNeeds-Tag-Fix labels 2026-01-31 02:59:07 +00:00
Author
Owner

@j4james commented on GitHub (Dec 19, 2020):

I believe this is a duplicate of #2985. When you change the console palette with SetConsoleScreenBufferInfoEx it needs to convert those colors into OSC escape sequences to propagate the changes over conpty to the Windows Terminal. That hasn't been done yet.

@j4james commented on GitHub (Dec 19, 2020): I believe this is a duplicate of #2985. When you change the console palette with `SetConsoleScreenBufferInfoEx` it needs to convert those colors into OSC escape sequences to propagate the changes over conpty to the Windows Terminal. That hasn't been done yet.
Author
Owner

@MCJack123 commented on GitHub (Dec 19, 2020):

Yeah, that does appear to be the case. However, that doesn't mention the function or message explicitly - might be a good idea to mention both if necessary.

@MCJack123 commented on GitHub (Dec 19, 2020): Yeah, that does appear to be the case. However, that doesn't mention the function or message explicitly - might be a good idea to mention both if necessary.
Author
Owner

@DHowett commented on GitHub (Dec 19, 2020):

Programs that rely on being able to redefine color indices 0-15 really just... shouldn’t do that. It was our mistake to allow applications destructive runtime access to the user’s preferences back when we did (about 30 years ago.)

Applications that want to specify arbitrary colors at runtime in a way that does not damage the user’s selected palette should use the 24-bit RGB SGR control sequences. They stand a better chance of working and looking the same across platforms and when remoted using technologies like SSH and Telnet.

@DHowett commented on GitHub (Dec 19, 2020): Programs that rely on being able to redefine color indices 0-15 really just... shouldn’t do that. It was our mistake to allow applications destructive runtime access to the user’s preferences back when we did (about 30 years ago.) Applications that want to specify arbitrary colors at runtime in a way that does not damage the user’s selected palette should use the 24-bit RGB SGR control sequences. They stand a better chance of working and looking the same across platforms and when remoted using technologies like SSH and Telnet.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11842