[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