Skip to content

Instantly share code, notes, and snippets.

@christianparpart
Created October 3, 2024 10:15
Show Gist options
  • Save christianparpart/8a6d590a15e94064e5fd7c76c2757bee to your computer and use it in GitHub Desktop.
Save christianparpart/8a6d590a15e94064e5fd7c76c2757bee to your computer and use it in GitHub Desktop.
Detect OS dark/light color mode setting from within the terminal
// SPDX-License-Identifier: Apache-2.0
// Implements https://contour-terminal.org/vt-extensions/color-palette-update-notifications/
#include <cstdlib>
#include <iostream>
#include <string_view>
#include <termios.h>
#include <unistd.h>
int main()
{
struct termios oldt {};
struct termios newt {};
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
// Also send DA1 to detect end of reply, in case the terminal does not support color mode detection
std::cout << "\033[?996n\033[c";
std::cout.flush();
char buf[32];
size_t n = 0;
size_t i = 0;
while (i < sizeof(buf))
{
if (read(STDIN_FILENO, buf + i, 1) != 1)
break;
else if (buf[i] == 'n')
n = i + 1;
else if (buf[i] == 'c')
{
++i;
break;
}
++i;
}
// restore terminal
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
auto const response = std::string_view(buf, n);
if (response == "\033[?997;1n")
std::cout << "dark\n";
else if (response == "\033[?997;2n")
std::cout << "light\n";
else
std::cout << "unknown\n";
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment