Manager: Fix style not reacting to Windows light/dark mode change

Add a native event filter for dark mode update, move the function
that queries the current theme to qt_util.cpp and make widgets
with custom stylesheets update their style on update
This commit is contained in:
Alexander Babikov
2025-08-05 20:16:09 +05:00
parent 7bf7d341d4
commit 5de3af3df7
17 changed files with 337 additions and 64 deletions

View File

@@ -374,6 +374,8 @@ if (WIN32)
target_sources(ui PRIVATE
qt_winrawinputfilter.hpp
qt_winrawinputfilter.cpp
qt_vmmanager_windarkmodefilter.hpp
qt_vmmanager_windarkmodefilter.cpp
qt_winmanagerfilter.hpp
qt_winmanagerfilter.cpp
)

View File

@@ -66,6 +66,7 @@ extern "C" {
# include "qt_rendererstack.hpp"
# include "qt_winrawinputfilter.hpp"
# include "qt_winmanagerfilter.hpp"
# include "qt_vmmanager_windarkmodefilter.hpp"
# include <86box/win.h>
# include <shobjidl.h>
# include <windows.h>
@@ -514,10 +515,6 @@ main_thread_fn()
static std::thread *main_thread;
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
#endif
int
main(int argc, char *argv[])
{
@@ -548,7 +545,7 @@ main(int argc, char *argv[])
}
QApplication::setAttribute(Qt::AA_NativeWindows);
if (!windows_is_light_theme()) {
if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists()) {
@@ -558,6 +555,10 @@ main(int argc, char *argv[])
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
}
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
}
#endif
@@ -632,8 +633,19 @@ main(int argc, char *argv[])
// QApplication::setApplicationDisplayName("86Box VM Manager");
// vmm.show();
// vmm.exec();
#ifdef Q_OS_WINDOWS
auto darkModeFilter = std::unique_ptr<WindowsDarkModeFilter>(new WindowsDarkModeFilter());
if (darkModeFilter) {
qApp->installNativeEventFilter(darkModeFilter.get());
}
QTimer::singleShot(0, [&darkModeFilter] {
#else
QTimer::singleShot(0, [] {
#endif
const auto vmm_main_window = new VMManagerMainWindow();
#ifdef Q_OS_WINDOWS
darkModeFilter.get()->setWindow(vmm_main_window);
#endif
vmm_main_window->show();
});
QApplication::exec();

View File

@@ -15,6 +15,7 @@
* Copyright 2022 Teemu Korhonen
*/
#include "qt_styleoverride.hpp"
#include "qt_util.hpp"
#include <QComboBox>
#include <QAbstractItemView>
@@ -64,8 +65,7 @@ StyleOverride::polish(QWidget *widget)
}
widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
BOOL DarkMode = !windows_is_light_theme();
BOOL DarkMode = !util::isWindowsLightTheme();
DwmSetWindowAttribute((HWND)widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&DarkMode, sizeof(DarkMode));
#endif
}

View File

@@ -27,6 +27,7 @@
#include "qt_util.hpp"
#ifdef Q_OS_WINDOWS
# include <windows.h>
# include <dwmapi.h>
# ifndef DWMWA_WINDOW_CORNER_PREFERENCE
# define DWMWA_WINDOW_CORNER_PREFERENCE 33
@@ -62,6 +63,36 @@ screenOfWidget(QWidget *widget)
}
#ifdef Q_OS_WINDOWS
bool
isWindowsLightTheme(void) {
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);
if (res != ERROR_SUCCESS) {
return 1;
}
// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);
return i == 1;
}
void
setWin11RoundedCorners(WId hwnd, bool enable)
{

View File

@@ -15,6 +15,7 @@ QString DlgFilter(QStringList extensions, bool last = false);
/* Returns screen the widget is on */
QScreen *screenOfWidget(QWidget *widget);
#ifdef Q_OS_WINDOWS
bool isWindowsLightTheme(void);
void setWin11RoundedCorners(WId hwnd, bool enable);
#endif
QString currentUuid();

View File

@@ -19,12 +19,19 @@
#include <QDebug>
#include <QStyle>
#include "qt_util.hpp"
#include "qt_vmmanager_details.hpp"
#include "ui_qt_vmmanager_details.h"
#define TOOLBUTTON_STYLESHEET_LIGHT "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}"
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
# define TOOLBUTTON_STYLESHEET_DARK "QToolButton {padding: 5px}"
# define SCREENSHOTBORDER_STYLESHEET_DARK "QLabel { border: 1px solid gray }"
#else
# define TOOLBUTTON_STYLESHEET_DARK "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}"
#endif
#define SCROLLAREA_STYLESHEET_LIGHT "QWidget {background-color: palette(light)} QScrollBar{ background-color: none }"
#define SYSTEMLABEL_STYLESHEET_LIGHT "background-color: palette(midlight);"
using namespace VMManager;
@@ -100,18 +107,14 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) :
QString toolButtonStyleSheet;
// Simple method to try and determine if light mode is enabled
#ifdef Q_OS_WINDOWS
const bool lightMode = windows_is_light_theme();
const bool lightMode = util::isWindowsLightTheme();
#else
const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value();
#endif
if (lightMode) {
toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}";
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_LIGHT;
} else {
#ifndef Q_OS_WINDOWS
toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}";
#else
toolButtonStyleSheet = "QToolButton {padding: 5px}";
#endif
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_DARK;
}
ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet);
@@ -150,6 +153,17 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) :
ui->notesTextEdit->setEnabled(false);
#ifdef Q_OS_WINDOWS
connect(this, &VMManagerDetails::styleUpdated, systemSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, videoSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, storageSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, audioSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, networkSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, inputSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, portsSection, &VMManagerDetailSection::updateStyle);
connect(this, &VMManagerDetails::styleUpdated, otherSection, &VMManagerDetailSection::updateStyle);
#endif
sysconfig = new VMManagerSystem();
}
@@ -163,12 +177,11 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) {
// Set the scrollarea background but also set the scroll bar to none. Otherwise it will also
// set the scrollbar background to the same.
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
if (windows_is_light_theme())
if (util::isWindowsLightTheme())
#endif
{
ui->scrollArea->setStyleSheet("QWidget {background-color: palette(light)} QScrollBar{ background-color: none }");
ui->systemLabel->setStyleSheet("background-color: palette(midlight);");
ui->scrollArea->setStyleSheet(SCROLLAREA_STYLESHEET_LIGHT);
ui->systemLabel->setStyleSheet(SYSTEMLABEL_STYLESHEET_LIGHT);
}
// Margins are a little different on macos
#ifdef Q_OS_MACOS
@@ -331,8 +344,8 @@ VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) {
ui->screenshot->setEnabled(false);
ui->screenshot->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
#ifdef Q_OS_WINDOWS
if (!windows_is_light_theme()) {
ui->screenshot->setStyleSheet("QLabel { border: 1px solid gray }");
if (!util::isWindowsLightTheme()) {
ui->screenshot->setStyleSheet(SCREENSHOTBORDER_STYLESHEET_DARK);
} else {
ui->screenshot->setStyleSheet("");
}
@@ -390,6 +403,32 @@ VMManagerDetails::updateWindowStatus()
updateProcessStatus();
}
#ifdef Q_OS_WINDOWS
void
VMManagerDetails::updateStyle()
{
QString toolButtonStyleSheet;
const bool lightMode = util::isWindowsLightTheme();
if (lightMode) {
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_LIGHT;
ui->scrollArea->setStyleSheet(SCROLLAREA_STYLESHEET_LIGHT);
ui->systemLabel->setStyleSheet(SYSTEMLABEL_STYLESHEET_LIGHT);
if (!ui->screenshot->isEnabled())
ui->screenshot->setStyleSheet("");
} else {
toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_DARK;
ui->scrollArea->setStyleSheet("");
ui->systemLabel->setStyleSheet("");
if (!ui->screenshot->isEnabled())
ui->screenshot->setStyleSheet(SCREENSHOTBORDER_STYLESHEET_DARK);
}
ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet);
ui->toolButtonHolder->setStyleSheet(toolButtonStyleSheet);
emit styleUpdated();
}
#endif
QWidget *
VMManagerDetails::createHorizontalLine(const int leftSpacing, const int rightSpacing)
{

View File

@@ -42,8 +42,18 @@ public:
void updateProcessStatus();
void updateWindowStatus();
#ifdef Q_OS_WINDOWS
void updateStyle();
#endif
// CollapseButton *systemCollapseButton;
#ifdef Q_OS_WINDOWS
signals:
void styleUpdated();
#endif
private:
Ui::VMManagerDetails *ui;
VMManagerSystem *sysconfig;

View File

@@ -19,6 +19,15 @@
#include "ui_qt_vmmanager_detailsection.h"
#include <QPushButton>
#include "qt_util.hpp"
#define HEADER_STYLESHEET_LIGHT "background-color: palette(midlight);"
#ifdef Q_OS_WINDOWS
# define HEADER_STYLESHEET_DARK "background-color: #616161;"
# define BACKGROUND_STYLESHEET_DARK "background-color: #272727;"
#else
# define HEADER_STYLESHEET_DARK "background-color: palette(mid);"
#endif
const QString VMManagerDetailSection::sectionSeparator = ";";
using namespace VMManager;
@@ -40,21 +49,18 @@ VMManagerDetailSection(const QString &sectionName)
// Simple method to try and determine if light mode is enabled on the host
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
const bool lightMode = windows_is_light_theme();
const bool lightMode = util::isWindowsLightTheme();
#else
const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value();
#endif
// Alternate layout
if (lightMode) {
ui->collapseButtonHolder->setStyleSheet("background-color: palette(midlight);");
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_LIGHT);
} else {
#ifdef Q_OS_WINDOWS
ui->outerFrame->setStyleSheet("background-color: #272727;");
ui->collapseButtonHolder->setStyleSheet("background-color: #616161;");
#else
ui->collapseButtonHolder->setStyleSheet("background-color: palette(mid);");
ui->outerFrame->setStyleSheet(BACKGROUND_STYLESHEET_DARK);
#endif
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_DARK);
}
const auto sectionLabel = new QLabel(sectionName);
sectionLabel->setStyleSheet(sectionLabel->styleSheet().append("font-weight: bold;"));
@@ -214,6 +220,21 @@ VMManagerDetailSection::clear()
ui->detailFrame->setLayout(frameGridLayout);
}
#ifdef Q_OS_WINDOWS
void
VMManagerDetailSection::updateStyle()
{
const bool lightMode = util::isWindowsLightTheme();
if (lightMode) {
ui->outerFrame->setStyleSheet("");
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_LIGHT);
} else {
ui->outerFrame->setStyleSheet(BACKGROUND_STYLESHEET_DARK);
ui->collapseButtonHolder->setStyleSheet(HEADER_STYLESHEET_DARK);
}
}
#endif
// QT for Linux and Windows doesn't have the same default margins as QT on MacOS.
// For consistency in appearance we'll have to return the margins on a per-OS basis
QMargins

View File

@@ -74,6 +74,10 @@ public:
static const QString sectionSeparator;
#ifdef Q_OS_WINDOWS
public slots:
void updateStyle();
#endif
private:
enum class MarginSection {

View File

@@ -18,13 +18,10 @@
#include <QApplication>
#include "qt_util.hpp"
#include "qt_vmmanager_listviewdelegate.hpp"
#include "qt_vmmanager_model.hpp"
#ifdef Q_OS_WINDOWS
extern bool windows_is_light_theme();
#endif
// Thanks to scopchanov https://github.com/scopchanov/SO-MessageLog
// from https://stackoverflow.com/questions/53105343/is-it-possible-to-add-a-custom-widget-into-a-qlistview
@@ -52,7 +49,7 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI
const QModelIndex &index) const {
bool windows_light_mode = true;
#ifdef Q_OS_WINDOWS
windows_light_mode = windows_is_light_theme();
windows_light_mode = util::isWindowsLightTheme();
#endif
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);

View File

@@ -349,7 +349,7 @@ illegal_chars:
});
// Initial default details view
vm_details = new VMManagerDetails();
vm_details = new VMManagerDetails(ui->detailsArea);
ui->detailsArea->layout()->addWidget(vm_details);
const QItemSelectionModel *selection_model = ui->listView->selectionModel();
@@ -785,6 +785,14 @@ VMManagerMain::onLanguageUpdated()
vm_details->updateData(selected_sysconfig);
}
#ifdef Q_OS_WINDOWS
void
VMManagerMain::onDarkModeUpdated()
{
vm_details->updateStyle();
}
#endif
int
VMManagerMain::getActiveMachineCount()
{

View File

@@ -80,6 +80,9 @@ public slots:
void modelDataChange();
void onPreferencesUpdated();
void onLanguageUpdated();
#ifdef Q_OS_WINDOWS
void onDarkModeUpdated();
#endif
void onConfigUpdated(const QString &uuid);
int getActiveMachineCount();

View File

@@ -116,6 +116,9 @@ VMManagerMainWindow(QWidget *parent)
// Inform the main view when preferences are updated
connect(this, &VMManagerMainWindow::preferencesUpdated, vmm, &VMManagerMain::onPreferencesUpdated);
connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated);
#ifdef Q_OS_WINDOWS
connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated);
#endif
}
@@ -178,6 +181,15 @@ VMManagerMainWindow::updateLanguage()
emit languageUpdated();
}
#ifdef Q_OS_WINDOWS
void
VMManagerMainWindow::updateDarkMode()
{
emit darkModeUpdated();
}
#endif
void
VMManagerMainWindow::changeEvent(QEvent *event)
{

View File

@@ -37,6 +37,9 @@ public:
signals:
void preferencesUpdated();
void languageUpdated();
#ifdef Q_OS_WINDOWS
void darkModeUpdated();
#endif
private:
Ui::VMManagerMainWindow *ui;
@@ -48,6 +51,9 @@ public slots:
void setStatusLeft(const QString &text) const;
void setStatusRight(const QString &text) const;
void updateLanguage();
#ifdef Q_OS_WINDOWS
void updateDarkMode();
#endif
private slots:
void vmmSelectionChanged(const QModelIndex &currentSelection, QProcess::ProcessState processState) const;

View File

@@ -0,0 +1,99 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Generic Windows native event filter for dark mode handling
*
*
*
* Authors: Teemu Korhonen
* Cacodemon345
*
* Copyright 2021 Teemu Korhonen
* Copyright 2024-2025 Cacodemon345.
*/
#include "qt_vmmanager_windarkmodefilter.hpp"
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <QApplication>
#include <QTimer>
#include <windows.h>
#include <dwmapi.h>
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
#include <86box/86box.h>
#include <86box/plat.h>
#include "qt_util.hpp"
static bool NewDarkMode = FALSE;
void
WindowsDarkModeFilter::setWindow(VMManagerMainWindow *window)
{
this->window = window;
}
bool
WindowsDarkModeFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result)
{
if ((window != nullptr) && (eventType == "windows_generic_MSG")) {
MSG *msg = static_cast<MSG *>(message);
if ((msg != nullptr) && (msg->message == WM_SETTINGCHANGE)) {
if ((((void *) msg->lParam) != nullptr) &&
(wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0)) {
bool OldDarkMode = NewDarkMode;
if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists())
printf("Unable to set stylesheet, file not found\n");
else {
f.open(QFile::ReadOnly | QFile::Text);
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
}
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
window->resize(window->size());
NewDarkMode = TRUE;
} else {
qApp->setStyleSheet("");
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::blue);
palette.setColor(QPalette::LinkVisited, Qt::magenta);
qApp->setPalette(palette);
window->resize(window->size());
NewDarkMode = FALSE;
}
window->updateDarkMode();
if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () {
BOOL DarkMode = NewDarkMode;
DwmSetWindowAttribute((HWND) window->winId(),
DWMWA_USE_IMMERSIVE_DARK_MODE,
(LPCVOID) &DarkMode,
sizeof(DarkMode));
});
}
}
}
return false;
}

View File

@@ -0,0 +1,47 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Header file for Windows dark mode native messages filter
*
*
*
* Authors: Teemu Korhonen
*
* Copyright 2022 Teemu Korhonen
*/
#ifndef QT_WINDOWSDARKMODEEVENTFILTER_HPP
#define QT_WINDOWSDARKMODEEVENTFILTER_HPP
#include <QObject>
#include <QAbstractNativeEventFilter>
#include <QByteArray>
#include <QEvent>
#include <QWindow>
#include "qt_vmmanager_mainwindow.hpp"
#if QT_VERSION_MAJOR >= 6
# define result_t qintptr
#else
# define result_t long
#endif
class WindowsDarkModeFilter : public QObject, public QAbstractNativeEventFilter {
Q_OBJECT
public:
WindowsDarkModeFilter() = default;
void setWindow(VMManagerMainWindow *window);
bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override;
private:
VMManagerMainWindow *window;
};
#endif // QT_WINDOWSDARKMODEEVENTFILTER_HPP

View File

@@ -71,38 +71,11 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
#include <memory>
#include "qt_rendererstack.hpp"
#include "qt_util.hpp"
#include "ui_qt_mainwindow.h"
static bool NewDarkMode = FALSE;
bool windows_is_light_theme() {
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);
if (res != ERROR_SUCCESS) {
return 1;
}
// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);
return i == 1;
}
struct
{
HANDLE done_event = 0, ready_event = 0;
@@ -365,7 +338,7 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess
}
#endif
if (!windows_is_light_theme()) {
if (!util::isWindowsLightTheme()) {
QFile f(":qdarkstyle/dark/darkstyle.qss");
if (!f.exists())
@@ -375,9 +348,17 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
}
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::white);
palette.setColor(QPalette::LinkVisited, Qt::lightGray);
qApp->setPalette(palette);
NewDarkMode = TRUE;
} else {
qApp->setStyleSheet("");
QPalette palette(qApp->palette());
palette.setColor(QPalette::Link, Qt::blue);
palette.setColor(QPalette::LinkVisited, Qt::magenta);
qApp->setPalette(palette);
NewDarkMode = FALSE;
}