Reflect language and color scheme changes in global config in manager and all its VMs

This commit is contained in:
Cacodemon345
2025-08-28 17:56:33 +06:00
parent 4f81c12b81
commit 30524acbbd
22 changed files with 194 additions and 44 deletions

View File

@@ -515,6 +515,10 @@ main_thread_fn()
static std::thread *main_thread;
#ifdef Q_OS_WINDOWS
WindowsDarkModeFilter* vmm_dark_mode_filter = nullptr;
#endif
int
main(int argc, char *argv[])
{
@@ -657,6 +661,8 @@ main(int argc, char *argv[])
const auto vmm_main_window = new VMManagerMainWindow();
#ifdef Q_OS_WINDOWS
darkModeFilter.get()->setWindow(vmm_main_window);
// HACK
vmm_dark_mode_filter = darkModeFilter.get();
#endif
vmm_main_window->show();
});
@@ -843,6 +849,7 @@ main(int argc, char *argv[])
});
QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged);
QObject::connect(main_window, &MainWindow::vmmConfigurationChanged, &manager_socket, &VMManagerClientSocket::configurationChanged);
QObject::connect(main_window, &MainWindow::vmmGlobalConfigurationChanged, &manager_socket, &VMManagerClientSocket::globalConfigurationChanged);
main_window->installEventFilter(&manager_socket);
manager_socket.sendWinIdMessage(main_window->winId());

View File

@@ -2244,7 +2244,9 @@ void
MainWindow::on_actionPreferences_triggered()
{
ProgSettings progsettings(this);
progsettings.exec();
if (progsettings.exec() == QDialog::Accepted) {
emit vmmGlobalConfigurationChanged();
}
}
void

View File

@@ -68,6 +68,7 @@ signals:
void vmmRunningStateChanged(VMManagerProtocol::RunningState state);
void vmmConfigurationChanged();
void vmmGlobalConfigurationChanged();
public slots:
void showSettings();
void hardReset();

View File

@@ -138,6 +138,7 @@ ProgSettings::accept()
connect(main_window, &MainWindow::updateStatusBarTip, main_window->status.get(), &MachineStatus::updateTip);
connect(main_window, &MainWindow::statusBarMessage, main_window->status.get(), &MachineStatus::message, Qt::QueuedConnection);
mouse_sensitivity = mouseSensitivity;
config_save_global();
QDialog::accept();
}

View File

@@ -23,6 +23,7 @@
extern "C" {
#include "86box/plat.h"
#include "86box/config.h"
}
VMManagerClientSocket::VMManagerClientSocket(QObject* obj) : server_connected(false)
@@ -183,6 +184,15 @@ VMManagerClientSocket::jsonReceived(const QJsonObject &json)
case VMManagerProtocol::ManagerMessage::RequestStatus:
qDebug("Status request command received from manager");
break;
case VMManagerProtocol::ManagerMessage::GlobalConfigurationChanged:
{
config_load_global();
#ifdef Q_OS_WINDOWS
void selectDarkMode();
selectDarkMode();
#endif
break;
}
default:
qDebug("Unknown client message type received:");
qDebug() << json;
@@ -248,6 +258,12 @@ VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState
sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object);
}
void
VMManagerClientSocket::globalConfigurationChanged() const
{
sendMessage(VMManagerProtocol::ClientMessage::GlobalConfigurationChanged);
}
void
VMManagerClientSocket::configurationChanged() const
{

View File

@@ -45,6 +45,7 @@ signals:
public slots:
void clientRunningStateChanged(VMManagerProtocol::RunningState state) const;
void configurationChanged() const;
void globalConfigurationChanged() const;
private:
QString server_name;

View File

@@ -31,10 +31,13 @@
#include <atomic>
#include "qt_vmmanager_main.hpp"
#include "qt_vmmanager_mainwindow.hpp"
#include "ui_qt_vmmanager_main.h"
#include "qt_vmmanager_model.hpp"
#include "qt_vmmanager_addmachine.hpp"
extern VMManagerMainWindow* vmm_main_window;
// https://stackoverflow.com/a/36460740
bool copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory)
{
@@ -348,6 +351,10 @@ illegal_chars:
}
});
connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [this] () {
vmm_main_window->updateSettings();
});
// Initial default details view
vm_details = new VMManagerDetails(ui->detailsArea);
ui->detailsArea->layout()->addWidget(vm_details);
@@ -400,6 +407,12 @@ VMManagerMain::~VMManagerMain() {
delete vm_model;
}
void
VMManagerMain::updateGlobalSettings()
{
vmm_main_window->updateSettings();
}
void
VMManagerMain::currentSelectionChanged(const QModelIndex &current,
const QModelIndex &previous)
@@ -768,6 +781,10 @@ VMManagerMain::onPreferencesUpdated()
if (oldRegexSearch != regexSearch) {
ui->searchBar->clear();
}
if (vm_model) {
vm_model->sendGlobalConfigurationChanged();
}
}
void

View File

@@ -70,6 +70,7 @@ public slots:
void shutdownForceButtonPressed() const;
void searchSystems(const QString &text) const;
void newMachineWizard();
void updateGlobalSettings();
void deleteSystem(VMManagerSystem *sysconfig);
void addNewSystem(const QString &name, const QString &dir, const QString &displayName = QString(), const QString &configFile = {});
#if __GNUC__ >= 11

View File

@@ -18,6 +18,7 @@
#include "qt_vmmanager_mainwindow.hpp"
#include "qt_vmmanager_main.hpp"
#include "qt_vmmanager_preferences.hpp"
#include "qt_vmmanager_windarkmodefilter.hpp"
#include "ui_qt_vmmanager_mainwindow.h"
#if EMU_BUILD_NUM != 0
# include "qt_updatecheckdialog.hpp"
@@ -32,6 +33,15 @@
#include <QCloseEvent>
#include <QDesktopServices>
extern "C"
{
extern void config_load_global();
extern void config_save_global();
}
VMManagerMainWindow* vmm_main_window = nullptr;
extern WindowsDarkModeFilter* vmm_dark_mode_filter;
VMManagerMainWindow::
VMManagerMainWindow(QWidget *parent)
: ui(new Ui::VMManagerMainWindow)
@@ -41,6 +51,8 @@ VMManagerMainWindow(QWidget *parent)
{
ui->setupUi(this);
vmm_main_window = this;
// Connect signals from the VMManagerMain widget
connect(vmm, &VMManagerMain::selectionChanged, this, &VMManagerMainWindow::vmmSelectionChanged);
@@ -118,6 +130,7 @@ VMManagerMainWindow(QWidget *parent)
connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated);
#ifdef Q_OS_WINDOWS
connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated);
connect(this, &VMManagerMainWindow::preferencesUpdated, [this] () { vmm_dark_mode_filter->reselectDarkMode(); });
#endif
{
@@ -187,6 +200,14 @@ VMManagerMainWindow::preferencesTriggered()
}
}
void
VMManagerMainWindow::updateSettings()
{
config_load_global();
emit preferencesUpdated();
updateLanguage();
}
void
VMManagerMainWindow::saveSettings() const
{

View File

@@ -34,6 +34,7 @@ class VMManagerMainWindow final : public QMainWindow
public:
explicit VMManagerMainWindow(QWidget *parent = nullptr);
~VMManagerMainWindow() override;
void updateSettings();
signals:
void preferencesUpdated();
void languageUpdated();

View File

@@ -23,6 +23,7 @@ VMManagerModel::VMManagerModel() {
for ( const auto& each_config : machines_vec) {
machines.append(each_config);
connect(each_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged);
connect(each_config, &VMManagerSystem::globalConfigurationChanged, this, &VMManagerModel::globalConfigurationChanged);
}
}
@@ -138,6 +139,7 @@ VMManagerModel::addConfigToModel(VMManagerSystem *system_config)
beginInsertRows(QModelIndex(), this->rowCount(QModelIndex()), this->rowCount(QModelIndex()));
machines.append(system_config);
connect(system_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged);
connect(system_config, &VMManagerSystem::globalConfigurationChanged, this, &VMManagerModel::globalConfigurationChanged);
endInsertRows();
}
@@ -177,6 +179,16 @@ VMManagerModel::getProcessStats()
return stats;
}
void
VMManagerModel::sendGlobalConfigurationChanged()
{
for (auto& system: machines) {
if (system->getProcessStatus() != VMManagerSystem::ProcessStatus::Stopped) {
system->sendGlobalConfigurationChanged();
}
}
}
int
VMManagerModel::getActiveMachineCount()
{

View File

@@ -60,8 +60,10 @@ public:
QMap<VMManagerSystem::ProcessStatus, int> getProcessStats();
int getActiveMachineCount();
void refreshConfigs();
void sendGlobalConfigurationChanged();
signals:
void systemDataChanged();
void globalConfigurationChanged();
private:
QVector<VMManagerSystem *> machines;

View File

@@ -24,6 +24,11 @@
#include "qt_vmmanager_config.hpp"
#include "ui_qt_vmmanager_preferences.h"
#ifdef Q_OS_WINDOWS
#include "qt_vmmanager_windarkmodefilter.hpp"
extern WindowsDarkModeFilter* vmm_dark_mode_filter;
#endif
extern "C" {
#include <86box/86box.h>
#include <86box/config.h>
@@ -66,7 +71,13 @@ VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences)
const auto useRegexSearch = config->getStringValue("regex_search").toInt();
ui->regexSearchCheckBox->setChecked(useRegexSearch);
ui->radioButtonSystem->setChecked(color_scheme == 0);
ui->radioButtonLight->setChecked(color_scheme == 1);
ui->radioButtonDark->setChecked(color_scheme == 2);
#ifndef Q_OS_WINDOWS
ui->groupBoxColorScheme->setHidden(true);
#endif
}
VMManagerPreferences::~
@@ -95,6 +106,7 @@ VMManagerPreferences::accept()
strncpy(vmm_path_cfg, QDir::cleanPath(ui->systemDirectory->text()).toUtf8().constData(), sizeof(vmm_path_cfg) - 1);
lang_id = ui->comboBoxLanguage->currentData().toInt();
color_scheme = (ui->radioButtonSystem->isChecked()) ? 0 : (ui->radioButtonLight->isChecked() ? 1 : 2);
config_save_global();
#if EMU_BUILD_NUM != 0

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<height>475</height>
</rect>
</property>
<property name="windowTitle">
@@ -103,10 +103,40 @@
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxColorScheme">
<property name="title">
<string>Color scheme</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="radioButtonSystem">
<property name="text">
<string>System</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonLight">
<property name="text">
<string>Light</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonDark">
<property name="text">
<string>Dark</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -119,10 +149,10 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>

View File

@@ -95,6 +95,8 @@ VMManagerProtocol::getClientMessageType(const QJsonObject &json_document)
return VMManagerProtocol::ClientMessage::ConfigurationChanged;
} else if (message_type == "WinIdMessage") {
return VMManagerProtocol::ClientMessage::WinIdMessage;
} else if (message_type == "GlobalConfigurationChanged") {
return VMManagerProtocol::ClientMessage::GlobalConfigurationChanged;
}
return VMManagerProtocol::ClientMessage::UnknownMessage;
}
@@ -119,6 +121,8 @@ VMManagerProtocol::getManagerMessageType(const QJsonObject &json_document)
return VMManagerProtocol::ManagerMessage::RequestShutdown;
} if (message_type == "ForceShutdown") {
return VMManagerProtocol::ManagerMessage::ForceShutdown;
} if (message_type == "GlobalConfigurationChanged") {
return VMManagerProtocol::ManagerMessage::GlobalConfigurationChanged;
}
return VMManagerProtocol::ManagerMessage::UnknownMessage;
}

View File

@@ -43,6 +43,7 @@ public:
ResetVM,
RequestShutdown,
ForceShutdown,
GlobalConfigurationChanged,
UnknownMessage,
};
@@ -56,6 +57,7 @@ public:
RunningStateChanged,
ConfigurationChanged,
WinIdMessage,
GlobalConfigurationChanged,
UnknownMessage,
};
Q_ENUM(ClientMessage);

View File

@@ -189,6 +189,10 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json)
qDebug("Configuration change received from client");
emit configurationChanged();
break;
case VMManagerProtocol::ClientMessage::GlobalConfigurationChanged:
qDebug("Global configuration change received from client");
emit globalConfigurationChanged();
break;
default:
qDebug("Unknown client message type received:");
qDebug() << json;

View File

@@ -76,6 +76,7 @@ signals:
void windowStatusChanged(int status);
void runningStatusChanged(VMManagerProtocol::RunningState state);
void configurationChanged();
void globalConfigurationChanged();
void winIdReceived(WId id);

View File

@@ -1081,6 +1081,7 @@ VMManagerSystem::startServer() {
connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::configurationChanged, this, &VMManagerSystem::configurationChangeReceived);
connect(socket_server, &VMManagerServerSocket::globalConfigurationChanged, this, &VMManagerSystem::globalConfigurationChanged);
connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; });
return true;
} else {
@@ -1124,6 +1125,12 @@ VMManagerSystem::getDisplayValue(Display::Name key)
return (display_table.contains(key)) ? display_table[key] : "";
}
void
VMManagerSystem::sendGlobalConfigurationChanged()
{
socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::GlobalConfigurationChanged);
}
void
VMManagerSystem::shutdownRequestButtonPressed()
{

View File

@@ -129,6 +129,7 @@ public slots:
void shutdownForceButtonPressed();
void cadButtonPressed();
void reloadConfig();
void sendGlobalConfigurationChanged();
public:
QDateTime timestamp();
void setIcon(const QString &newIcon);
@@ -157,6 +158,7 @@ signals:
void itemDataChanged();
void clientProcessStatusChanged();
void configurationChanged(const QString &uuid);
void globalConfigurationChanged();
private:
void loadSettings();

View File

@@ -38,6 +38,48 @@
static bool NewDarkMode = FALSE;
void
WindowsDarkModeFilter::reselectDarkMode()
{
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));
});
}
void
WindowsDarkModeFilter::setWindow(VMManagerMainWindow *window)
{
@@ -54,44 +96,7 @@ WindowsDarkModeFilter::nativeEventFilter(const QByteArray &eventType, void *mess
if ((((void *) msg->lParam) != nullptr) &&
(wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0) &&
color_scheme == 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));
});
reselectDarkMode();
}
}
}

View File

@@ -39,6 +39,7 @@ public:
WindowsDarkModeFilter() = default;
void setWindow(VMManagerMainWindow *window);
bool nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) override;
void reselectDarkMode();
private:
VMManagerMainWindow *window;