Add support for loading profiles on suspend/resume

This commit is contained in:
Zach Deibert 2024-11-12 22:42:32 -06:00 committed by Adam Honse
parent 7d96b27f28
commit bd3cc94212
17 changed files with 612 additions and 91 deletions

View file

@ -122,7 +122,8 @@ INCLUDEPATH +=
AutoStart/ \
KeyboardLayoutManager/ \
RGBController/ \
qt/
qt/ \
SuspendResume/
HEADERS += \
$$GUI_H \
@ -156,6 +157,7 @@ HEADERS +=
serial_port/serial_port.h \
StringUtils.h \
super_io/super_io.h \
SuspendResume/SuspendResume.h \
AutoStart/AutoStart.h \
KeyboardLayoutManager/KeyboardLayoutManager.h \
RGBController/RGBController.h \
@ -388,6 +390,7 @@ win32:SOURCES +=
i2c_smbus/i2c_smbus_piix4.cpp \
scsiapi/scsiapi_windows.c \
serial_port/find_usb_serial_port_win.cpp \
SuspendResume/SuspendResume_Windows.cpp \
wmi/wmi.cpp \
AutoStart/AutoStart-Windows.cpp \
@ -405,6 +408,7 @@ win32:HEADERS +=
i2c_smbus/i2c_smbus_piix4.h \
wmi/wmi.h \
AutoStart/AutoStart-Windows.h \
SuspendResume/SuspendResume_Windows.h \
win32:contains(QMAKE_TARGET.arch, x86_64) {
LIBS += \
@ -499,6 +503,7 @@ contains(QMAKE_PLATFORM, linux) {
dependencies/NVFC/nvapi.h \
i2c_smbus/i2c_smbus_linux.h \
AutoStart/AutoStart-Linux.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
INCLUDEPATH += \
dependencies/NVFC \
@ -516,6 +521,8 @@ contains(QMAKE_PLATFORM, linux) {
LIBS += -lstdc++fs
}
QT += dbus
QMAKE_CXXFLAGS += -Wno-implicit-fallthrough -Wno-psabi
#-------------------------------------------------------------------------------------------#
@ -550,6 +557,7 @@ contains(QMAKE_PLATFORM, linux) {
scsiapi/scsiapi_linux.c \
serial_port/find_usb_serial_port_linux.cpp \
AutoStart/AutoStart-Linux.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
#-------------------------------------------------------------------------------------------#
# Set up install paths #
@ -622,6 +630,7 @@ contains(QMAKE_PLATFORM, freebsd) {
HEADERS += \
AutoStart/AutoStart-FreeBSD.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
HEADERS -= \
Controllers/SeagateController/RGBController_Seagate.h \
@ -639,6 +648,8 @@ contains(QMAKE_PLATFORM, freebsd) {
LIBS += -lstdc++fs
}
QT += dbus
#-------------------------------------------------------------------------------------------#
# Determine which hidapi to use based on availability #
# Prefer hidraw backend, then libusb #
@ -667,6 +678,7 @@ contains(QMAKE_PLATFORM, freebsd) {
dependencies/hueplusplus-1.1.0/src/LinHttpHandler.cpp \
serial_port/find_usb_serial_port_linux.cpp \
AutoStart/AutoStart-FreeBSD.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
SOURCES -= \
Controllers/SeagateController/RGBController_Seagate.cpp \
@ -726,6 +738,7 @@ macx {
HEADERS += \
AutoStart/AutoStart-MacOS.h \
qt/macutils.h \
SuspendResume/SuspendResume_MacOS.h \
HEADERS += $$CONTROLLER_H_MACOS
@ -734,6 +747,7 @@ macx {
serial_port/find_usb_serial_port_macos.cpp \
AutoStart/AutoStart-MacOS.cpp \
qt/macutils.mm \
SuspendResume/SuspendResume_MacOS.cpp \
SOURCES += $$CONTROLLER_CPP_MACOS

View file

@ -232,7 +232,7 @@ void PluginManager::AddPlugin(const filesystem::path& path, bool is_system)
if(entry.enabled)
{
LoadPlugin(path);
LoadPlugin(&ActivePlugins.back());
}
}
else
@ -319,7 +319,7 @@ void PluginManager::RemovePlugin(const filesystem::path& path)
if(ActivePlugins[plugin_idx].loader->isLoaded())
{
LOG_TRACE("[PluginManager] Plugin %s is active, unloading", path.c_str());
UnloadPlugin(path);
UnloadPlugin(&ActivePlugins[plugin_idx]);
}
/*---------------------------------------------------------------------*\
@ -328,7 +328,7 @@ void PluginManager::RemovePlugin(const filesystem::path& path)
ActivePlugins.erase(ActivePlugins.begin() + plugin_idx);
}
void PluginManager::LoadPlugin(const filesystem::path& path)
void PluginManager::EnablePlugin(const filesystem::path& path)
{
unsigned int plugin_idx;
@ -351,10 +351,16 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
return;
}
ActivePlugins[plugin_idx].enabled = true;
LoadPlugin(&ActivePlugins[plugin_idx]);
}
void PluginManager::LoadPlugin(OpenRGBPluginEntry* plugin_entry)
{
/*---------------------------------------------------------------------*\
| If the plugin is in the list but is incompatible, return |
\*---------------------------------------------------------------------*/
if(ActivePlugins[plugin_idx].incompatible)
if(plugin_entry->incompatible)
{
return;
}
@ -362,11 +368,11 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
/*---------------------------------------------------------------------*\
| If the selected plugin is in the list but not loaded, load it |
\*---------------------------------------------------------------------*/
if(!ActivePlugins[plugin_idx].loader->isLoaded())
if(!plugin_entry->loader->isLoaded())
{
ActivePlugins[plugin_idx].loader->load();
plugin_entry->loader->load();
QObject* instance = ActivePlugins[plugin_idx].loader->instance();
QObject* instance = plugin_entry->loader->instance();
bool dark_theme = OpenRGBThemeManager::IsDarkTheme();
@ -378,7 +384,7 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
{
if(plugin->GetPluginAPIVersion() == OPENRGB_PLUGIN_API_VERSION)
{
ActivePlugins[plugin_idx].plugin = plugin;
plugin_entry->plugin = plugin;
plugin->Load(dark_theme, ResourceManager::get());
@ -387,7 +393,7 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
\*-------------------------------------------------*/
if(AddPluginCallbackArg != nullptr)
{
AddPluginCallbackVal(AddPluginCallbackArg, &ActivePlugins[plugin_idx]);
AddPluginCallbackVal(AddPluginCallbackArg, plugin_entry);
}
}
}
@ -395,7 +401,7 @@ void PluginManager::LoadPlugin(const filesystem::path& path)
}
}
void PluginManager::UnloadPlugin(const filesystem::path& path)
void PluginManager::DisablePlugin(const filesystem::path& path)
{
unsigned int plugin_idx;
@ -418,48 +424,62 @@ void PluginManager::UnloadPlugin(const filesystem::path& path)
return;
}
ActivePlugins[plugin_idx].enabled = false;
UnloadPlugin(&ActivePlugins[plugin_idx]);
}
void PluginManager::UnloadPlugin(OpenRGBPluginEntry* plugin_entry)
{
/*---------------------------------------------------------------------*\
| If the selected plugin is in the list and loaded, unload it |
\*---------------------------------------------------------------------*/
if(ActivePlugins[plugin_idx].loader->isLoaded())
if(plugin_entry->loader->isLoaded())
{
/*-------------------------------------------------*\
| Call plugin's Unload function before GUI removal |
\*-------------------------------------------------*/
ActivePlugins[plugin_idx].plugin->Unload();
plugin_entry->plugin->Unload();
/*-------------------------------------------------*\
| Call the Remove Plugin callback |
\*-------------------------------------------------*/
if(RemovePluginCallbackVal != nullptr)
{
RemovePluginCallbackVal(RemovePluginCallbackArg, &ActivePlugins[plugin_idx]);
RemovePluginCallbackVal(RemovePluginCallbackArg, plugin_entry);
}
bool unloaded = ActivePlugins[plugin_idx].loader->unload();
bool unloaded = plugin_entry->loader->unload();
if(!unloaded)
{
LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", path.c_str());
LOG_WARNING("[PluginManager] Plugin %s cannot be unloaded", plugin_entry->path.c_str());
}
else
{
LOG_TRACE("[PluginManager] Plugin %s successfully unloaded", path.c_str());
LOG_TRACE("[PluginManager] Plugin %s successfully unloaded", plugin_entry->path.c_str());
}
}
else
{
LOG_TRACE("[PluginManager] Plugin %s was already unloaded", path.c_str());
LOG_TRACE("[PluginManager] Plugin %s was already unloaded", plugin_entry->path.c_str());
}
}
void PluginManager::LoadPlugins()
{
for(OpenRGBPluginEntry& plugin_entry: ActivePlugins)
{
if(plugin_entry.enabled)
{
LoadPlugin(&plugin_entry);
}
}
}
void PluginManager::UnloadPlugins()
{
for(const OpenRGBPluginEntry& plugin_entry: ActivePlugins)
for(OpenRGBPluginEntry& plugin_entry: ActivePlugins)
{
if(plugin_entry.loader->isLoaded())
{
plugin_entry.plugin->Unload();
}
UnloadPlugin(&plugin_entry);
}
}

View file

@ -47,14 +47,18 @@ public:
void AddPlugin(const filesystem::path& path, bool is_system);
void RemovePlugin(const filesystem::path& path);
void LoadPlugin(const filesystem::path& path);
void UnloadPlugin(const filesystem::path& path);
void EnablePlugin(const filesystem::path& path);
void DisablePlugin(const filesystem::path& path);
void LoadPlugins();
void UnloadPlugins();
std::vector<OpenRGBPluginEntry> ActivePlugins;
private:
void LoadPlugin(OpenRGBPluginEntry* plugin_entry);
void UnloadPlugin(OpenRGBPluginEntry* plugin_entry);
void ScanAndLoadPluginsFrom(const filesystem::path & plugins_dir, bool is_system);
AddPluginCallback AddPluginCallbackVal;

View file

@ -0,0 +1,31 @@
/*---------------------------------------------------------*\
| SuspendResume.h |
| |
| Suspend/resume common implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
class SuspendResumeListenerBase
{
protected:
virtual void OnSuspend() = 0;
virtual void OnResume() = 0;
};
#ifdef _WIN32
#include "SuspendResume_Windows.h"
#endif
#ifdef __APPLE__
#include "SuspendResume_MacOS.h"
#endif
#if defined(__linux__) || defined(__FreeBSD__)
#include "SuspendResume_Linux_FreeBSD.h"
#endif

View file

@ -0,0 +1,39 @@
/*---------------------------------------------------------*\
| SuspendResume_Linux_FreeBSD.cpp |
| |
| Suspend/resume Linux/FreeBSD implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <QDBusConnection>
#include "SuspendResume.h"
SuspendResumeLoginManager::SuspendResumeLoginManager(SuspendResumeListener *srl) : srl(srl), bus(QDBusConnection::systemBus())
{
bus.connect("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "PrepareForSleep", this, SLOT(PrepareForSleep()));
}
SuspendResumeLoginManager::~SuspendResumeLoginManager()
{
bus.disconnect("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "PrepareForSleep", this, SLOT(PrepareForSleep()));
}
void SuspendResumeLoginManager::PrepareForSleep(bool mode)
{
if(mode)
{
srl->OnSuspend();
}
else
{
srl->OnResume();
}
}
SuspendResumeListener::SuspendResumeListener() : login_manager(this)
{
}

View file

@ -0,0 +1,45 @@
/*---------------------------------------------------------*\
| SuspendResume_Linux_FreeBSD.h |
| |
| Suspend/resume Linux/FreeBSD implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
#include <QDBusConnection>
#include <QObject>
#include "SuspendResume.h"
class SuspendResumeListener;
class SuspendResumeLoginManager : public QObject
{
Q_OBJECT
public:
SuspendResumeLoginManager(SuspendResumeListener *srl);
~SuspendResumeLoginManager();
public slots:
void PrepareForSleep(bool mode);
private:
SuspendResumeListener *srl;
QDBusConnection bus;
};
class SuspendResumeListener : public SuspendResumeListenerBase
{
friend class SuspendResumeLoginManager;
protected:
SuspendResumeListener();
private:
SuspendResumeLoginManager login_manager;
};

View file

@ -0,0 +1,45 @@
/*---------------------------------------------------------*\
| SuspendResume_MacOS.cpp |
| |
| Suspend/resume MacOS implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <stdint.h>
#include "SuspendResume.h"
#include "IOKit/pwr_mgt/IOPMLib.h"
#include "IOKit/IOMessage.h"
SuspendResumeListener::SuspendResumeListener()
{
root_port = IORegisterForSystemPower(this, &port_ref, &SuspendResumeListener::SystemPowerCallback, &notifier);
CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(port_ref), kCFRunLoopCommonModes);
}
SuspendResumeListener::~SuspendResumeListener()
{
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(port_ref), kCFRunLoopCommonModes);
IODeregisterForSystemPower(&notifier);
IOServiceClose(root_port);
IONotificationPortDestroy(port_ref);
}
void SuspendResumeListener::SystemPowerCallback(void *refcon, io_service_t service, uint32_t message_type, void *message_argument)
{
(void)service;
SuspendResumeListener *spl = (SuspendResumeListener *)refcon;
switch(message_type)
{
case kIOMessageSystemWillSleep:
spl->OnSuspend();
IOAllowPowerChange(spl->root_port, (intptr_t)message_argument);
break;
case kIOMessageSystemHasPoweredOn:
spl->OnResume();
break;
}
}

View file

@ -0,0 +1,31 @@
/*---------------------------------------------------------*\
| SuspendResume_MacOS.h |
| |
| Suspend/resume MacOS implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
#include <stdint.h>
#include "SuspendResume.h"
#include "IOKit/pwr_mgt/IOPMLib.h"
#include "IOKit/IOMessage.h"
class SuspendResumeListener : public SuspendResumeListenerBase
{
protected:
SuspendResumeListener();
virtual ~SuspendResumeListener();
private:
static void SystemPowerCallback(void *refcon, io_service_t service, uint32_t message_type, void *message_argument);
io_connect_t root_port;
IONotificationPortRef port_ref;
io_object_t notifier;
};

View file

@ -0,0 +1,48 @@
/*---------------------------------------------------------*\
| SuspendResume_Windows.cpp |
| |
| Suspend/resume Windows implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <QByteArray>
#include <QCoreApplication>
#include "SuspendResume.h"
#include "windows.h"
SuspendResumeListener::SuspendResumeListener()
{
QCoreApplication::instance()->installNativeEventFilter(this);
}
SuspendResumeListener::~SuspendResumeListener()
{
QCoreApplication::instance()->removeNativeEventFilter(this);
}
bool SuspendResumeListener::nativeEventFilter(const QByteArray &event_type, void *message, long *result)
{
(void)result;
if(event_type == "windows_generic_MSG")
{
switch(((MSG *)message)->message)
{
case WM_POWERBROADCAST:
switch(((MSG *)message)->wParam)
{
case PBT_APMSUSPEND:
OnSuspend();
break;
case PBT_APMRESUMEAUTOMATIC:
OnResume();
break;
}
break;
}
}
return false;
}

View file

@ -0,0 +1,26 @@
/*---------------------------------------------------------*\
| SuspendResume_Windows.h |
| |
| Suspend/resume Windows implementation |
| |
| Zach Deibert (zachdeibert) 12 Nov 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
#include <QAbstractNativeEventFilter>
#include <QByteArray>
#include "SuspendResume.h"
class SuspendResumeListener : public SuspendResumeListenerBase, private QAbstractNativeEventFilter
{
protected:
SuspendResumeListener();
virtual ~SuspendResumeListener();
private:
bool nativeEventFilter(const QByteArray &event_type, void *message, long *result);
};

View file

@ -236,6 +236,15 @@ int main(int argc, char* argv[])
if(ret_flags & RET_FLAG_START_MINIMIZED)
{
#ifdef _WIN32
/*---------------------------------------------------------*\
| Show the window always, even if it will immediately be |
| hidden. On Windows, events are not delivered to |
| nativeEventFilter (for SuspendResume) until the window |
| has been shown once. |
\*---------------------------------------------------------*/
dlg.showMinimized();
#endif
#ifdef __APPLE__
MacUtils::ToggleApplicationDocklessState(false);
#endif

View file

@ -7,6 +7,7 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <string>
#include <functional>
#include "OpenRGBDialog2.h"
#include "LogManager.h"
@ -182,6 +183,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
std::string ui_string = "UserInterface";
json ui_settings;
bool new_settings_keys = false;
ui_settings = settings_manager->GetSettings(ui_string);
@ -205,9 +207,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
geometry_settings["height"] = 0;
ui_settings["geometry"] = geometry_settings;
settings_manager->SetSettings(ui_string, ui_settings);
settings_manager->SaveSettings();
new_settings_keys = true;
}
/*-----------------------------------------------------*\
@ -247,20 +247,47 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
}
/*-----------------------------------------------------*\
| If set_on_exit doesn't exist, write it to config |
| If autoload_profiles doesn't exist or has missing |
| profiles, write it to config |
\*-----------------------------------------------------*/
if(!ui_settings.contains("exit_profile"))
json autoload_profiles;
if(ui_settings.contains("autoload_profiles"))
{
json on_exit_settings;
on_exit_settings["set_on_exit"] = false;
on_exit_settings["profile_name"] = "";
ui_settings["exit_profile"] = on_exit_settings;
settings_manager->SetSettings(ui_string, ui_settings);
settings_manager->SaveSettings();
autoload_profiles = ui_settings["autoload_profiles"];
}
else
{
new_settings_keys = true;
}
if(!autoload_profiles.contains("exit_profile"))
{
json profile;
profile["enabled"] = false;
profile["name"] = "";
autoload_profiles["exit_profile"] = profile;
new_settings_keys = true;
}
if(!autoload_profiles.contains("resume_profile"))
{
json profile;
profile["enabled"] = false;
profile["name"] = "";
autoload_profiles["resume_profile"] = profile;
new_settings_keys = true;
}
if(!autoload_profiles.contains("suspend_profile"))
{
json profile;
profile["enabled"] = false;
profile["name"] = "";
autoload_profiles["suspend_profile"] = profile;
new_settings_keys = true;
}
ui_settings["autoload_profiles"] = autoload_profiles;
/*-----------------------------------------------------*\
| Register detection progress callback with resource |
@ -362,9 +389,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
if(!ui_settings.contains("minimize_on_close"))
{
ui_settings["minimize_on_close"] = false;
settings_manager->SetSettings(ui_string, ui_settings);
settings_manager->SaveSettings();
new_settings_keys = true;
}
connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(on_ReShow(QSystemTrayIcon::ActivationReason)));
@ -376,9 +401,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
if(!ui_settings.contains("greyscale_tray_icon"))
{
ui_settings["greyscale_tray_icon"] = false;
settings_manager->SetSettings(ui_string, ui_settings);
settings_manager->SaveSettings();
new_settings_keys = true;
}
/*-----------------------------------------------------*\
@ -390,6 +413,16 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
SetTrayIcon(ui_settings["greyscale_tray_icon"].get<bool>());
}
/*-----------------------------------------------------*\
| Save the settings if new default values have been |
| inserted |
\*-----------------------------------------------------*/
if(new_settings_keys)
{
settings_manager->SetSettings(ui_string, ui_settings);
settings_manager->SaveSettings();
}
trayIcon->setToolTip("OpenRGB");
trayIcon->setContextMenu(trayIconMenu);
trayIcon->show();
@ -616,48 +649,53 @@ void OpenRGBDialog2::closeEvent(QCloseEvent *event)
else
{
plugin_manager->UnloadPlugins();
LoadExitProfile();
if(SelectConfigProfile("exit_profile"))
{
on_ButtonLoadProfile_clicked();
/*-----------------------------------------------------*\
| Pause briefly to ensure that all profiles are loaded. |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
event->accept();
QApplication::exit(0);
}
}
void OpenRGBDialog2::LoadExitProfile()
bool OpenRGBDialog2::SelectConfigProfile(const std::string name)
{
/*-----------------------------------------------------*\
| Set Exit Profile (if enabled and valid) |
| Set automatic profile (if enabled and valid) |
\*-----------------------------------------------------*/
const std::string exit_profile = "exit_profile";
const std::string set_on_exit = "set_on_exit";
const std::string profile_name = "profile_name";
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
if(ui_settings.contains(exit_profile))
if(ui_settings.contains("autoload_profiles"))
{
if( ui_settings[exit_profile].contains(set_on_exit)
&& ui_settings[exit_profile].contains(profile_name) )
json autoload_profiles = ui_settings["autoload_profiles"];
if(autoload_profiles.contains(name))
{
if(ui_settings[exit_profile][set_on_exit].get<bool>())
json profile = autoload_profiles[name];
if (profile.contains("enabled") && profile["enabled"].get<bool>() && profile.contains("name"))
{
/*-----------------------------------------------------*\
| Set the profile name from settings and check the |
| profile combobox for a match |
\*-----------------------------------------------------*/
std::string profile = ui_settings[exit_profile][profile_name].get<std::string>();
int profile_index = ui->ProfileBox->findText(QString::fromStdString(profile));
std::string profile_name = profile["name"].get<std::string>();
int profile_index = ui->ProfileBox->findText(QString::fromStdString(profile_name));
if(profile_index > -1)
{
ui->ProfileBox->setCurrentIndex(profile_index);
on_ButtonLoadProfile_clicked();
/*-----------------------------------------------------*\
| Pause briefly to ensure that all profiles are loaded. |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(250));
return true;
}
}
}
}
return false;
}
void OpenRGBDialog2::AddPluginsPage()
@ -1381,6 +1419,24 @@ void OpenRGBDialog2::UpdateProfileList()
emit ProfileListChanged();
}
void OpenRGBDialog2::OnSuspend()
{
if(SelectConfigProfile("suspend_profile"))
{
plugin_manager->UnloadPlugins();
on_ButtonLoadProfile_clicked();
}
}
void OpenRGBDialog2::OnResume()
{
if(SelectConfigProfile("resume_profile"))
{
on_ButtonLoadProfile_clicked();
}
plugin_manager->LoadPlugins();
}
void OpenRGBDialog2::on_Exit()
{
/*-----------------------------------------------*\
@ -1506,6 +1562,15 @@ void OpenRGBDialog2::on_ShowHide()
MacUtils::ToggleApplicationDocklessState(true);
#endif
show();
if(isMinimized())
{
bool maximize = isMaximized();
showNormal();
if(maximize)
{
showMaximized();
}
}
}
else
{
@ -1592,6 +1657,15 @@ void OpenRGBDialog2::on_ReShow(QSystemTrayIcon::ActivationReason reason)
if (isHidden())
{
show();
if(isMinimized())
{
bool maximize = isMaximized();
showNormal();
if(maximize)
{
showMaximized();
}
}
}
}
}

View file

@ -9,6 +9,7 @@
#pragma once
#include <string>
#include <vector>
#include <QMainWindow>
#include <QTimer>
@ -37,6 +38,7 @@
#include "OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.h"
#include "OpenRGBNanoleafSettingsPage/OpenRGBNanoleafSettingsPage.h"
#include "PluginManager.h"
#include "SuspendResume.h"
#include "i2c_smbus.h"
#include "LogManager.h"
@ -50,7 +52,7 @@ namespace Ui
class OpenRGBDialog2;
}
class Ui::OpenRGBDialog2 : public QMainWindow
class Ui::OpenRGBDialog2 : public QMainWindow, private SuspendResumeListener
{
Q_OBJECT
@ -144,7 +146,7 @@ private:
void UpdateDevicesList();
void UpdateProfileList();
void closeEvent(QCloseEvent *event);
void LoadExitProfile();
bool SelectConfigProfile(const std::string name);
void SetDetectionViewState(bool detection_showing);
void SaveProfile();
@ -162,6 +164,9 @@ private:
void ShowLEDView();
void HideLEDView();
void OnSuspend();
void OnResume();
private slots:
void on_Exit();
void on_LightsOff();

View file

@ -335,11 +335,11 @@ void Ui::OpenRGBPluginsPage::on_EnableButton_clicked(OpenRGBPluginsEntry* entry)
if(enabled)
{
plugin_manager->LoadPlugin(entry_path);
plugin_manager->EnablePlugin(entry_path);
}
else
{
plugin_manager->UnloadPlugin(entry_path);
plugin_manager->DisablePlugin(entry_path);
}
}

View file

@ -288,9 +288,13 @@ void OpenRGBSettingsPage::UpdateProfiles()
if(profile_manager != NULL)
{
ui->ComboBoxAutoStartProfile->blockSignals(true);
ui->ComboBoxSuspendProfile->blockSignals(true);
ui->ComboBoxResumeProfile->blockSignals(true);
ui->ComboBoxExitProfile->blockSignals(true);
ui->ComboBoxAutoStartProfile->clear();
ui->ComboBoxSuspendProfile->clear();
ui->ComboBoxResumeProfile->clear();
ui->ComboBoxExitProfile->clear();
for(std::size_t profile_index = 0; profile_index < profile_manager->profile_list.size(); profile_index++)
@ -298,10 +302,14 @@ void OpenRGBSettingsPage::UpdateProfiles()
QString new_profile = QString(profile_manager->profile_list[profile_index].c_str());
ui->ComboBoxAutoStartProfile->addItem(new_profile);
ui->ComboBoxSuspendProfile->addItem(new_profile);
ui->ComboBoxResumeProfile->addItem(new_profile);
ui->ComboBoxExitProfile->addItem(new_profile);
}
ui->ComboBoxAutoStartProfile->blockSignals(false);
ui->ComboBoxSuspendProfile->blockSignals(false);
ui->ComboBoxResumeProfile->blockSignals(false);
ui->ComboBoxExitProfile->blockSignals(false);
}
@ -330,28 +338,88 @@ void OpenRGBSettingsPage::UpdateProfiles()
\*---------------------------------------------------------*/
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
if(ui_settings.contains("exit_profile"))
if(ui_settings.contains("autoload_profiles"))
{
if(ui_settings["exit_profile"].contains("set_on_exit"))
{
bool is_set_on_exit = ui_settings["exit_profile"]["set_on_exit"];
json autoload_profiles = ui_settings["autoload_profiles"];
ui->CheckboxSetOnExit->setChecked(is_set_on_exit);
ui->ComboBoxExitProfile->setEnabled(is_set_on_exit);
if(autoload_profiles.contains("exit_profile"))
{
json profile = autoload_profiles["exit_profile"];
if(profile.contains("enabled"))
{
bool is_enabled = profile["enabled"].get<bool>();
ui->CheckboxSetOnExit->setChecked(is_enabled);
ui->ComboBoxExitProfile->setEnabled(is_enabled);
}
if(profile.contains("name"))
{
/*-----------------------------------------------------*\
| Set the profile name from settings and check the |
| profile combobox for a match |
\*-----------------------------------------------------*/
std::string profile_name = profile["name"].get<std::string>();
int profile_index = ui->ComboBoxExitProfile->findText(QString::fromStdString(profile_name));
if(profile_index > -1)
{
ui->ComboBoxExitProfile->setCurrentIndex(profile_index);
}
}
}
if(ui_settings["exit_profile"].contains("profile_name"))
if(autoload_profiles.contains("resume_profile"))
{
/*-----------------------------------------------------*\
| Set the profile name from settings and check the |
| profile combobox for a match |
\*-----------------------------------------------------*/
std::string profile_name = ui_settings["exit_profile"]["profile_name"].get<std::string>();
int profile_index = ui->ComboBoxExitProfile->findText(QString::fromStdString(profile_name));
json profile = autoload_profiles["resume_profile"];
if(profile_index > -1)
if(profile.contains("enabled"))
{
ui->ComboBoxExitProfile->setCurrentIndex(profile_index);
bool is_enabled = profile["enabled"].get<bool>();
ui->CheckboxSetOnResume->setChecked(is_enabled);
ui->ComboBoxResumeProfile->setEnabled(is_enabled);
}
if(profile.contains("name"))
{
/*-----------------------------------------------------*\
| Set the profile name from settings and check the |
| profile combobox for a match |
\*-----------------------------------------------------*/
std::string profile_name = profile["name"].get<std::string>();
int profile_index = ui->ComboBoxResumeProfile->findText(QString::fromStdString(profile_name));
if(profile_index > -1)
{
ui->ComboBoxResumeProfile->setCurrentIndex(profile_index);
}
}
}
if(autoload_profiles.contains("suspend_profile"))
{
json profile = autoload_profiles["suspend_profile"];
if(profile.contains("enabled"))
{
bool is_enabled = profile["enabled"].get<bool>();
ui->CheckboxSetOnSuspend->setChecked(is_enabled);
ui->ComboBoxSuspendProfile->setEnabled(is_enabled);
}
if(profile.contains("name"))
{
/*-----------------------------------------------------*\
| Set the profile name from settings and check the |
| profile combobox for a match |
\*-----------------------------------------------------*/
std::string profile_name = profile["name"].get<std::string>();
int profile_index = ui->ComboBoxSuspendProfile->findText(QString::fromStdString(profile_name));
if(profile_index > -1)
{
ui->ComboBoxSuspendProfile->setCurrentIndex(profile_index);
}
}
}
}
@ -463,9 +531,9 @@ void Ui::OpenRGBSettingsPage::on_CheckboxRunZoneChecks_clicked()
void Ui::OpenRGBSettingsPage::on_CheckboxSetOnExit_clicked(bool checked)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["exit_profile"]["set_on_exit"] = checked;
ui_settings["exit_profile"]["profile_name"] = ui->ComboBoxExitProfile->currentText().toStdString();
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["exit_profile"]["enabled"] = checked;
ui_settings["autoload_profiles"]["exit_profile"]["name"] = ui->ComboBoxExitProfile->currentText().toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
@ -474,8 +542,46 @@ void Ui::OpenRGBSettingsPage::on_CheckboxSetOnExit_clicked(bool checked)
void Ui::OpenRGBSettingsPage::on_ComboBoxExitProfile_currentTextChanged(const QString exit_profile_name)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["exit_profile"]["profile_name"] = exit_profile_name.toStdString();
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["exit_profile"]["name"] = exit_profile_name.toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
}
void Ui::OpenRGBSettingsPage::on_CheckboxSetOnResume_clicked(bool checked)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["resume_profile"]["enabled"] = checked;
ui_settings["autoload_profiles"]["resume_profile"]["name"] = ui->ComboBoxResumeProfile->currentText().toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
ui->ComboBoxResumeProfile->setEnabled(checked);
}
void Ui::OpenRGBSettingsPage::on_ComboBoxResumeProfile_currentTextChanged(const QString resume_profile_name)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["resume_profile"]["name"] = resume_profile_name.toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
}
void Ui::OpenRGBSettingsPage::on_CheckboxSetOnSuspend_clicked(bool checked)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["suspend_profile"]["enabled"] = checked;
ui_settings["autoload_profiles"]["suspend_profile"]["name"] = ui->ComboBoxSuspendProfile->currentText().toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
ui->ComboBoxSuspendProfile->setEnabled(checked);
}
void Ui::OpenRGBSettingsPage::on_ComboBoxSuspendProfile_currentTextChanged(const QString suspend_profile_name)
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["autoload_profiles"]["suspend_profile"]["name"] = suspend_profile_name.toStdString();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
}

View file

@ -83,6 +83,10 @@ private slots:
void on_CheckboxSetOnExit_clicked(bool checked);
void on_ComboBoxExitProfile_currentTextChanged(const QString exit_profile_name);
void on_CheckboxSetOnResume_clicked(bool checked);
void on_ComboBoxResumeProfile_currentTextChanged(const QString resume_profile_name);
void on_CheckboxSetOnSuspend_clicked(bool checked);
void on_ComboBoxSuspendProfile_currentTextChanged(const QString suspend_profile_name);
void on_CheckboxDisableKeyExpansion_clicked();
void on_CheckboxShowLEDView_clicked();
};

View file

@ -85,7 +85,7 @@
</property>
</widget>
</item>
<item row="30" column="0">
<item row="32" column="0">
<widget class="QCheckBox" name="CheckboxSetOnExit">
<property name="text">
<string>Set Profile on Exit</string>
@ -119,7 +119,7 @@
</property>
</widget>
</item>
<item row="30" column="1">
<item row="32" column="1">
<widget class="QComboBox" name="ComboBoxExitProfile"/>
</item>
<item row="14" column="0">
@ -146,14 +146,14 @@
</property>
</widget>
</item>
<item row="31" column="0">
<item row="33" column="0">
<widget class="QLabel" name="AutoStartStatusLabel">
<property name="text">
<string>Start at Login Status</string>
</property>
</widget>
</item>
<item row="32" column="0">
<item row="34" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -278,6 +278,26 @@
<item row="12" column="1">
<widget class="QComboBox" name="ComboBoxHexFormat"/>
</item>
<item row="30" column="0">
<widget class="QCheckBox" name="CheckboxSetOnSuspend">
<property name="text">
<string>Set Profile on Suspend</string>
</property>
</widget>
</item>
<item row="30" column="1">
<widget class="QComboBox" name="ComboBoxSuspendProfile"/>
</item>
<item row="31" column="0">
<widget class="QCheckBox" name="CheckboxSetOnResume">
<property name="text">
<string>Set Profile on Resume</string>
</property>
</widget>
</item>
<item row="31" column="1">
<widget class="QComboBox" name="ComboBoxResumeProfile"/>
</item>
</layout>
</widget>
</widget>