[vlc-commits] [Git][videolan/vlc][3.0.x] 4 commits: qt: Use QColor(r, g, b) instead of string in dark palette definition
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Sat Dec 6 19:42:04 UTC 2025
Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC
Commits:
f88c0f28 by Pratik Patel at 2025-12-06T20:21:25+01:00
qt: Use QColor(r,g,b) instead of string in dark palette definition
- - - - -
72a5f4a0 by Pratik Patel at 2025-12-06T20:21:25+01:00
qt: Use Windows accent color in dark palette
- - - - -
7b5e4180 by Pratik Patel at 2025-12-06T20:21:25+01:00
qt: update seekstyle for dark palette and accent highlight
- - - - -
7dc62530 by Pratik Patel at 2025-12-06T20:21:25+01:00
qt: adapt volume slider to dark palette
- - - - -
5 changed files:
- modules/gui/qt/qt.cpp
- modules/gui/qt/styles/seekstyle.cpp
- modules/gui/qt/util/input_slider.cpp
- modules/gui/qt/util/input_slider.hpp
- modules/gui/qt/util/qvlcframe.hpp
Changes:
=====================================
modules/gui/qt/qt.cpp
=====================================
@@ -38,6 +38,7 @@
#include "dialogs_provider.hpp" /* THEDP creation */
#ifdef _WIN32
# include "main_interface_win32.hpp"
+# include "util/qvlcframe.hpp" /* Accent Color */
#else
# include "main_interface.hpp" /* MainInterface creation */
#endif
@@ -415,45 +416,52 @@ bool isDarkPaletteEnabled(intf_thread_t *p_intf) {
void applyDarkPalette() {
QPalette darkPalette;
- QColor darkColor("#2d2d2d");
- QColor gray("#808080");
- QColor lightGray("#aaaaaa");
- QColor baseColor("#191919");
+ static const QColor darkColor (33, 33, 33);
+ static const QColor gray (75,75,75);
+ static const QColor lightGray (138, 138, 138);
+ static const QColor baseColor (18, 18, 18);
+ static const QColor linkColor (255, 168, 81);
+
+#ifdef Q_OS_WIN
+ QColor accentColor = getWindowsAccentColor();
+#else
+ QColor accentColor (42, 130, 218);
+#endif
// Active group (the currently focused window)
- darkPalette.setColor(QPalette::Active, QPalette::Window, darkColor);
- darkPalette.setColor(QPalette::Active, QPalette::WindowText, Qt::white);
- darkPalette.setColor(QPalette::Active, QPalette::Base, baseColor);
- darkPalette.setColor(QPalette::Active, QPalette::AlternateBase, darkColor);
- darkPalette.setColor(QPalette::Active, QPalette::Button, darkColor);
- darkPalette.setColor(QPalette::Active, QPalette::ButtonText, Qt::white);
- darkPalette.setColor(QPalette::Active, QPalette::Text, Qt::white);
- darkPalette.setColor(QPalette::Active, QPalette::Highlight, QColor("#2A82DA"));
+ darkPalette.setColor(QPalette::Active, QPalette::Window, darkColor);
+ darkPalette.setColor(QPalette::Active, QPalette::WindowText, Qt::white);
+ darkPalette.setColor(QPalette::Active, QPalette::Base, baseColor);
+ darkPalette.setColor(QPalette::Active, QPalette::AlternateBase, darkColor);
+ darkPalette.setColor(QPalette::Active, QPalette::Button, darkColor);
+ darkPalette.setColor(QPalette::Active, QPalette::ButtonText, Qt::white);
+ darkPalette.setColor(QPalette::Active, QPalette::Text, Qt::white);
+ darkPalette.setColor(QPalette::Active, QPalette::Highlight, accentColor);
darkPalette.setColor(QPalette::Active, QPalette::HighlightedText, Qt::white);
- darkPalette.setColor(QPalette::Active, QPalette::Link, QColor("#FFA851"));
+ darkPalette.setColor(QPalette::Active, QPalette::Link, linkColor);
// Inactive group (unfocused window)
- darkPalette.setColor(QPalette::Inactive, QPalette::Window, darkColor);
- darkPalette.setColor(QPalette::Inactive, QPalette::WindowText, lightGray);
- darkPalette.setColor(QPalette::Inactive, QPalette::Base, baseColor);
- darkPalette.setColor(QPalette::Inactive, QPalette::AlternateBase, darkColor);
- darkPalette.setColor(QPalette::Inactive, QPalette::Button, darkColor);
- darkPalette.setColor(QPalette::Inactive, QPalette::ButtonText, lightGray);
- darkPalette.setColor(QPalette::Inactive, QPalette::Text, lightGray);
- darkPalette.setColor(QPalette::Inactive, QPalette::Highlight, QColor("#2A82DA"));
+ darkPalette.setColor(QPalette::Inactive, QPalette::Window, darkColor);
+ darkPalette.setColor(QPalette::Inactive, QPalette::WindowText, lightGray);
+ darkPalette.setColor(QPalette::Inactive, QPalette::Base, baseColor);
+ darkPalette.setColor(QPalette::Inactive, QPalette::AlternateBase, darkColor);
+ darkPalette.setColor(QPalette::Inactive, QPalette::Button, darkColor);
+ darkPalette.setColor(QPalette::Inactive, QPalette::ButtonText, lightGray);
+ darkPalette.setColor(QPalette::Inactive, QPalette::Text, lightGray);
+ darkPalette.setColor(QPalette::Inactive, QPalette::Highlight, accentColor);
darkPalette.setColor(QPalette::Inactive, QPalette::HighlightedText, lightGray);
// Disabled group (grayed-out widgets)
- darkPalette.setColor(QPalette::Disabled, QPalette::Window, darkColor);
- darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, lightGray);
- darkPalette.setColor(QPalette::Disabled, QPalette::Base, baseColor);
- darkPalette.setColor(QPalette::Disabled, QPalette::AlternateBase, darkColor);
- darkPalette.setColor(QPalette::Disabled, QPalette::Button, lightGray.darker());
- darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
- darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
- darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, gray);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Window, darkColor);
+ darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, lightGray);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Base, baseColor);
+ darkPalette.setColor(QPalette::Disabled, QPalette::AlternateBase, darkColor);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Button, baseColor);
+ darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, gray);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Text, gray);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, gray);
darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, gray);
- darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkColor);
+ darkPalette.setColor(QPalette::Disabled, QPalette::Light, darkColor);
// Apply the dark palette globally
QApplication::setPalette(darkPalette);
=====================================
modules/gui/qt/styles/seekstyle.cpp
=====================================
@@ -73,6 +73,8 @@ void SeekStyle::drawComplexControl( ComplexControl cc, const QStyleOptionComplex
if ( const SeekStyle::SeekStyleOption *slideroptions =
qstyleoption_cast<const SeekStyle::SeekStyleOption *>( option ) )
{
+ /* theme detection */
+ bool dark = isDarkPaletteEnabled(nullptr);
qreal sliderPos = -1;
/* Get the needed subcontrols to draw the slider */
@@ -94,19 +96,52 @@ void SeekStyle::drawComplexControl( ComplexControl cc, const QStyleOptionComplex
* (qreal)slideroptions->sliderPosition;
/* set the background color and gradient */
- QColor backgroundBase( slideroptions->palette.window().color() );
+ QColor backgroundBase = slideroptions->palette.color(QPalette::Window);
QLinearGradient backgroundGradient( 0, 0, 0, slideroptions->rect.height() );
- backgroundGradient.setColorAt( 0.0, backgroundBase.darker( 140 ) );
- backgroundGradient.setColorAt( 1.0, backgroundBase );
+
+ if (dark)
+ {
+ QColor top(0x25, 0x25, 0x25);
+ QColor bot(0x65, 0x65, 0x65);
+
+ backgroundGradient.setColorAt(0.00, top);
+ backgroundGradient.setColorAt(1.00, bot);
+ } else {
+ backgroundGradient.setColorAt(0.0, backgroundBase.darker(140));
+ backgroundGradient.setColorAt(1.0, backgroundBase);
+ }
/* set the foreground color and gradient */
QColor foregroundBase( 50, 156, 255 );
QLinearGradient foregroundGradient( 0, 0, 0, groove.height() );
- foregroundGradient.setColorAt( 0.0, foregroundBase );
- foregroundGradient.setColorAt( 1.0, foregroundBase.darker( 125 ) );
+
+ if (dark) {
+ #ifdef Q_OS_WIN
+ /* use accent color on windows dark mode */
+ foregroundBase = slideroptions->palette.color(QPalette::Highlight);
+ #endif
+ /* adjust gradient dynamically based on accent */
+ int v = foregroundBase.value();
+ int lighterFactor = 130 + (255 - v) / 3;
+ lighterFactor = qBound(130, lighterFactor, 200);
+
+ int darkerFactor = 100 + v / 20;
+ darkerFactor = qBound(100, darkerFactor, 115);
+
+ foregroundGradient.setColorAt(0.0, foregroundBase.lighter(lighterFactor));
+ foregroundGradient.setColorAt(1.0, foregroundBase.darker(darkerFactor));
+ } else {
+ /* original vlc blue gloss */
+ foregroundGradient.setColorAt(0.0, foregroundBase);
+ foregroundGradient.setColorAt(1.0, foregroundBase.darker(125));
+ }
/* draw a slight 3d effect on the bottom */
- painter->setPen( QColor( 230, 230, 230 ) );
+ if (dark)
+ painter->setPen(slideroptions->palette.color(QPalette::Mid));
+ else
+ painter->setPen(QColor(230, 230, 230));
+
painter->setBrush( Qt::NoBrush );
painter->drawRoundedRect( groove.adjusted( 0, 2, 0, 0 ), RADIUS, RADIUS );
@@ -180,7 +215,10 @@ void SeekStyle::drawComplexControl( ComplexControl cc, const QStyleOptionComplex
foreach( int64_t time, slideroptions->points )
{
int x = groove.x() + time / 1000000.0 / slideroptions->length * groove.width();
- painter->setPen( foreground );
+ QColor tick = p.color(QPalette::Mid);
+ if (dark)
+ tick = p.color(QPalette::Light);
+ painter->setPen(tick);
painter->setBrush( Qt::NoBrush );
painter->drawLine( x, slideroptions->rect.height(), x, slideroptions->rect.height() - CHAPTERSSPOTSIZE );
}
@@ -198,16 +236,45 @@ void SeekStyle::drawComplexControl( ComplexControl cc, const QStyleOptionComplex
/* prepare the handle's gradient */
QLinearGradient handleGradient( 0, 0, 0, hSize.height() );
- handleGradient.setColorAt( 0.0, p.window().color().lighter( 120 ) );
- handleGradient.setColorAt( 0.9, p.window().color().darker( 120 ) );
+
+ // pick theme-based base color
+ QColor base = p.color(QPalette::Window);
+
+ QColor handleTop;
+ QColor handleBottom;
+
+ if (dark) {
+ handleTop = base.lighter(105);
+ handleBottom = base.darker(110);
+ } else {
+ handleTop = base.lighter(120);
+ handleBottom = base.darker(120);
+ }
+
+ handleGradient.setColorAt(0.0, handleTop);
+ handleGradient.setColorAt(0.9, handleBottom);
/* prepare the handle's shadow gradient */
- QColor shadowBase = p.shadow().color();
- if( shadowBase.lightness() > 100 )
- shadowBase = QColor( 60, 60, 60 ); // Palette's shadow is too bright
- QColor shadowDark( shadowBase.darker( 150 ) );
- QColor shadowLight( shadowBase.lighter( 180 ) );
- shadowLight.setAlpha( 50 );
+ QColor shadowBase = p.color(QPalette::Shadow);
+
+ QColor shadowDark;
+ QColor shadowLight;
+
+ if (dark) {
+ if (shadowBase.lightness() > 70)
+ shadowBase = QColor(20,20,20);
+
+ shadowDark = shadowBase.darker(130);
+ shadowLight = shadowBase.lighter(140);
+ shadowLight.setAlpha(40);
+ } else {
+ if (shadowBase.lightness() < 200)
+ shadowBase = QColor(60,60,60);
+
+ shadowDark = shadowBase.darker(150);
+ shadowLight = shadowBase.lighter(180);
+ shadowLight.setAlpha(60);
+}
QRadialGradient shadowGradient( shadowPos.x() + ( sSize.width() / 2 ),
shadowPos.y() + ( sSize.height() / 2 ),
=====================================
modules/gui/qt/util/input_slider.cpp
=====================================
@@ -634,6 +634,8 @@ SoundSlider::SoundSlider( QWidget *_parent, float _i_step,
pixGradient = QPixmap( pixOutside.size() );
pixGradient2 = QPixmap( pixOutside.size() );
+ dark = isDarkPaletteEnabled(nullptr);
+
#if HAS_QT56
pixGradient.setDevicePixelRatio(QApplication::primaryScreen()->devicePixelRatio());
pixGradient2.setDevicePixelRatio(QApplication::primaryScreen()->devicePixelRatio());
@@ -817,7 +819,10 @@ void SoundSlider::paintEvent( QPaintEvent *e )
painter.drawPixmap( 0, 0, offsetDst, height(), *paintGradient, 0, 0, offsetSrc, paintGradient->height() );
painter.drawPixmap( 0, 0, width(), height(), pixOutside, 0, 0, pixOutside.width(), pixOutside.height() );
- painter.setPen( foreground );
+ if (dark)
+ painter.setPen(Qt::white);
+ else
+ painter.setPen(foreground);
painter.setFont( textfont );
painter.drawText( textrect, Qt::AlignRight | Qt::AlignVCenter,
QString::number( value() ) + '%' );
=====================================
modules/gui/qt/util/input_slider.hpp
=====================================
@@ -177,6 +177,7 @@ private:
QColor foreground;
QFont textfont;
QRect textrect;
+ bool dark = false;
WheelToVLCConverter wheelEventConverter;
=====================================
modules/gui/qt/util/qvlcframe.hpp
=====================================
@@ -37,10 +37,16 @@
#ifdef _WIN32
#include <QLibrary>
- #include <dwmapi.h>
+
+ // Typedefs for functions
+ typedef HRESULT(WINAPI *DwmSetWindowAttributeFunc)(HWND, DWORD, LPCVOID, DWORD);
+ typedef HRESULT(WINAPI *DwmGetColorizationColorFunc)(DWORD*, BOOL*);
+
+ // Dark mode constants
+ constexpr DWORD DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
+ constexpr DWORD DWMWA_USE_DARK_MODE_UNDOCUMENTED = 19;
inline bool setImmersiveDarkModeAttribute(HWND hwnd, bool enable) {
- typedef HRESULT(WINAPI *DwmSetWindowAttributeFunc)(HWND, DWORD, LPCVOID, DWORD);
static const auto dwmSetWindowAttributeFunc = []() -> DwmSetWindowAttributeFunc {
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (GetProcAddress(hKernel32, "GetSystemCpuSetInformation") == NULL)
@@ -55,13 +61,8 @@
const BOOL pvAttribute = enable ? TRUE : FALSE;
- enum Attribute : DWORD {
- DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
- DWMWA_USE_DARK_MODE_UNDOCUMENTED = 19
- };
-
- return SUCCEEDED(dwmSetWindowAttributeFunc(hwnd, Attribute::DWMWA_USE_IMMERSIVE_DARK_MODE, &pvAttribute, sizeof(pvAttribute)))
- || SUCCEEDED(dwmSetWindowAttributeFunc(hwnd, Attribute::DWMWA_USE_DARK_MODE_UNDOCUMENTED, &pvAttribute, sizeof(pvAttribute)));
+ return SUCCEEDED(dwmSetWindowAttributeFunc(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &pvAttribute, sizeof(pvAttribute)))
+ || SUCCEEDED(dwmSetWindowAttributeFunc(hwnd, DWMWA_USE_DARK_MODE_UNDOCUMENTED, &pvAttribute, sizeof(pvAttribute)));
}
// Overloaded function to apply dark mode to QWidget*
@@ -74,6 +75,63 @@
return false;
}
+ // Get Windows accent color
+ inline QColor getWindowsAccentColor()
+ {
+ static const auto dwmGetColorizationColorFunc = []() -> DwmGetColorizationColorFunc {
+ QLibrary dwmapidll("dwmapi");
+ return reinterpret_cast<DwmGetColorizationColorFunc>(dwmapidll.resolve("DwmGetColorizationColor"));
+ }();
+ static const QColor fallbackColor(42, 130, 218);
+ if (!dwmGetColorizationColorFunc) return fallbackColor;
+
+ DWORD color = 0;
+ BOOL opaque = FALSE;
+ HRESULT hr = dwmGetColorizationColorFunc(&color, &opaque);
+
+ if (FAILED(hr)) return fallbackColor;
+
+ QColor c(qRed(color), qGreen(color), qBlue(color));
+
+ int h = c.hue();
+ int s = c.saturation();
+ int v = c.value();
+
+ // 1) Make the color DARKER overall (to match dark-theme highlights)
+ v = qBound(60, v, 160); // Old: 120–220, New: 60–160 → much darker
+
+ // 2) Ensure enough saturation so it's not muddy/gray
+ s = qBound(80, s, 255); // Old: s >= 55 → now greater minimum
+
+ // 3) Prevent neon colors (very bright + very saturated)
+ if (s > 220 && v > 140) {
+ s = 200;
+ v = 120;
+ }
+
+ // 4) Special casing for yellow / green hues.
+ // These colors have poor contrast with white unless darkened heavily.
+ if (h >= 30 && h <= 85) { // Yellow to yellow-green
+ h = (h - 10 + 360) % 360; // Shift toward orange (warmer, safer)
+ s = qBound(100, s, 180); // Prevent neon yellows
+ v = qBound(70, v, 130); // Ensure dark-ish gold
+ }
+ else if (h >= 85 && h <= 140) { // Greens → shift toward teal
+ h = (h + 20) % 360; // Move green → teal for better white contrast
+ s = qBound(100, s, 220);
+ v = qBound(60, v, 140);
+ }
+
+ // 5) Final normalization: ensure contras
+ if (v > 150) v = 150; // Hard cap brightness
+ if (s < 80) s = 80; // Hard floor saturation
+
+ // Rebuild safe accent
+ c.setHsv(h, s, v);
+
+ return c;
+ }
+
#endif
class QVLCTools
@@ -147,7 +205,7 @@ public:
if (isDarkPaletteEnabled(p_intf))
setImmersiveDarkModeAttribute(this);
#endif
- };
+ };
virtual ~QVLCFrame() {};
void toggleVisible()
@@ -241,12 +299,12 @@ class QVLCMW : public QMainWindow
{
public:
QVLCMW( intf_thread_t *_p_intf ) : QMainWindow( NULL ), p_intf( _p_intf )
- {
+ {
#ifdef Q_OS_WIN
if (isDarkPaletteEnabled(p_intf))
setImmersiveDarkModeAttribute(this);
#endif
- }
+ }
void toggleVisible()
{
if( isVisible() ) hide();
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/38d64f6cb714475f8277a24c9d8316b1c213cecb...7dc62530b805c4104f38af1b8308b38f43a238f4
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/38d64f6cb714475f8277a24c9d8316b1c213cecb...7dc62530b805c4104f38af1b8308b38f43a238f4
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list