diff --git a/vkconfig_core/layer_manager.cpp b/vkconfig_core/layer_manager.cpp index 6dc76f9d92..c277ddea56 100644 --- a/vkconfig_core/layer_manager.cpp +++ b/vkconfig_core/layer_manager.cpp @@ -28,6 +28,10 @@ #include #include +#include +#include +#include + static std::vector GetEnvVariablePaths(const char *variable_name, LayerType type) { std::vector result; @@ -457,47 +461,77 @@ void LayerManager::ApplyLayerDescriptor() { void LayerManager::LoadAllInstalledLayers(ConfiguratorMode configurator_mode) { std::array, LAYERS_PATHS_COUNT> paths; - // Search new layers paths[LAYERS_PATHS_IMPLICIT_SYSTEM] = GetImplicitLayerPaths(); - - // LAYERS_PATHS_IMPLICIT_ENV_SET: VK_IMPLICIT_LAYER_PATH env variables paths[LAYERS_PATHS_IMPLICIT_ENV_SET] = GetEnvVariablePaths("VK_IMPLICIT_LAYER_PATH", LAYER_TYPE_IMPLICIT); - - // LAYERS_PATHS_IMPLICIT_ENV_ADD: VK_ADD_IMPLICIT_LAYER_PATH env variables paths[LAYERS_PATHS_IMPLICIT_ENV_ADD] = GetEnvVariablePaths("VK_ADD_IMPLICIT_LAYER_PATH", LAYER_TYPE_IMPLICIT); - - // LAYERS_PATHS_EXPLICIT_SYSTEM paths[LAYERS_PATHS_EXPLICIT_SYSTEM] = GetExplicitLayerPaths(); - - // LAYERS_PATHS_EXPLICIT_ENV_SET: VK_LAYER_PATH env variables paths[LAYERS_PATHS_EXPLICIT_ENV_SET] = GetEnvVariablePaths("VK_LAYER_PATH", LAYER_TYPE_EXPLICIT); - - // LAYERS_PATHS_EXPLICIT_ENV_ADD: VK_ADD_LAYER_PATH env variables paths[LAYERS_PATHS_EXPLICIT_ENV_ADD] = GetEnvVariablePaths("VK_ADD_LAYER_PATH", LAYER_TYPE_EXPLICIT); - - // LAYERS_PATHS_SDK paths[LAYERS_PATHS_SDK].push_back(Path(Path::SDK_EXPLICIT_LAYERS)); - // LAYERS_PATHS_GUI std::vector added_paths = this->BuildLayerPaths(); paths[LAYERS_PATHS_GUI].insert(paths[LAYERS_PATHS_GUI].begin(), added_paths.begin(), added_paths.end()); + + struct PendingFile { + Path path; + LayerType type; + }; + std::vector pending_files; + for (std::size_t group_index = 0, group_count = paths.size(); group_index < group_count; ++group_index) { const LayersPaths layers_path = static_cast(group_index); - const std::vector &paths_group = paths[group_index]; + for (std::size_t i = 0, n = paths_group.size(); i < n; ++i) { const std::vector &layers_paths = ::CollectLayersPaths(paths_group[i]); for (std::size_t p = 0, o = layers_paths.size(); p < o; ++p) { - this->LoadLayers(layers_paths[p], ::GetLayerType(layers_path), configurator_mode); + pending_files.push_back({layers_paths[p], ::GetLayerType(layers_path)}); + } + } + } + + const std::size_t file_count = pending_files.size(); + std::vector parse_results(file_count); + + const unsigned int hw_threads = std::max(1u, std::thread::hardware_concurrency()); + const std::size_t thread_count = std::min(hw_threads, file_count); + + if (thread_count <= 1 || file_count == 0) { + for (std::size_t i = 0; i < file_count; ++i) { + parse_results[i] = ParseLayerFile(pending_files[i].path, pending_files[i].type); + } + } else { + std::vector> futures; + std::atomic next_index{0}; + + auto worker = [&]() { + for (;;) { + const std::size_t index = next_index.fetch_add(1); + if (index >= file_count) break; + parse_results[index] = ParseLayerFile(pending_files[index].path, pending_files[index].type); } + }; + + for (std::size_t t = 0; t < thread_count; ++t) { + futures.push_back(std::async(std::launch::async, worker)); + } + for (auto &f : futures) { + f.wait(); } } - // this->ApplyLayerDescriptor(); + for (std::size_t i = 0; i < file_count; ++i) { + const LayerParseResult &parsed = parse_results[i]; + if (parsed.status == LAYER_LOAD_INVALID) { + continue; + } + this->ApplyParsedLayer(parsed, configurator_mode); + } } + LayerValidated LayerManager::Validate(const Path &layer_path, QString json_text, ConfiguratorMode configurator_mode) const { JsonValidator validator; bool result = validator.Check(json_text); @@ -559,44 +593,46 @@ LayerDescriptor LayerManager::GetDescriptor(const Path &layer_path, const std::s return LayerDescriptor(); } -LayerLoadStatus LayerManager::LoadLayers(const Path &layer_path, LayerType type, ConfiguratorMode configurator_mode) { - QFile file(layer_path.AbsolutePath().c_str()); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - assert(0); - return LAYER_LOAD_INVALID; - } - - QString json_text = file.readAll(); - file.close(); +LayerLoadStatus LayerManager::LoadLayer(const QJsonObject &json_layer_object, const Path &layer_path, LayerType type, + Version file_format_version, LayerDescriptor descriptor) { + Layer layer; + layer.type = type; + layer.manifest_path = layer_path; + layer.file_format_version = file_format_version; + layer.descriptor = descriptor; - // Convert the text to a JSON document & validate it. - // It does need to be a valid json formatted file. - QJsonParseError json_parse_error; - const QJsonDocument &json_document = QJsonDocument::fromJson(json_text.toUtf8(), &json_parse_error); - if (json_parse_error.error != QJsonParseError::NoError) { - return LAYER_LOAD_INVALID; + LayerLoadStatus status = layer.Load(json_layer_object); + if (status == LAYER_LOAD_INVALID || status == LAYER_LOAD_IGNORED) { + return status; } - // Make sure it's not empty - if (json_document.isNull() || json_document.isEmpty()) { - return LAYER_LOAD_INVALID; + Layer *duplicated_layer = this->Find(layer.GetId(), false); + if (duplicated_layer != nullptr) { + if (duplicated_layer->descriptor.removed) { + duplicated_layer->descriptor.removed = false; + duplicated_layer->descriptor.enabled = true; + } else if (duplicated_layer->descriptor.last_modified != layer.descriptor.last_modified) { + // Reload when the manifest was updated + LayerLoadStatus reloaded_status = duplicated_layer->Load(json_layer_object); + status = reloaded_status == LAYER_LOAD_ADDED ? LAYER_LOAD_RELOADED : reloaded_status; + } else { + status = LAYER_LOAD_UNMODIFIED; + } + } else { + this->available_layers.push_back(layer); } - Version file_format_version; - const QJsonObject &json_root_object = json_document.object(); - if (json_root_object.value("file_format_version") != QJsonValue::Undefined) { - file_format_version = Version(json_root_object.value("file_format_version").toString().toStdString().c_str()); - } + return status; +} +LayerLoadStatus LayerManager::ApplyParsedLayer(const LayerParseResult &parsed, ConfiguratorMode configurator_mode) { LayerLoadStatus status = LAYER_LOAD_ADDED; - const std::string &last_modified = layer_path.LastModified(); - if (json_root_object.value("layers") != QJsonValue::Undefined) { - const QJsonArray &json_layers_array = json_root_object.value("layers").toArray(); + if (parsed.has_layers_array) { + const QJsonArray &json_layers_array = parsed.json_root_object.value("layers").toArray(); for (int i = 0, n = json_layers_array.size(); i < n; ++i) { const QJsonObject &json_layer_object = json_layers_array[i].toObject(); - std::string key = ReadStringValue(json_layer_object, "name"); if (key == "VK_LAYER_LUNARG_override" || !(key.rfind("VK_", 0) == 0)) { @@ -604,33 +640,32 @@ LayerLoadStatus LayerManager::LoadLayers(const Path &layer_path, LayerType type, continue; } - LayerDescriptor descriptor = this->GetDescriptor(layer_path, key); + LayerDescriptor descriptor = this->GetDescriptor(parsed.layer_path, key); - if (this->validate_manifests && (descriptor.last_modified != last_modified) || !descriptor.validated) { - descriptor.validated = this->Validate(layer_path, json_text, configurator_mode); - descriptor.last_modified = last_modified; + if (this->validate_manifests && (descriptor.last_modified != parsed.last_modified) || !descriptor.validated) { + descriptor.validated = this->Validate(parsed.layer_path, parsed.json_text, configurator_mode); + descriptor.last_modified = parsed.last_modified; } - status = this->LoadLayer(json_layer_object, layer_path, type, file_format_version, descriptor); + status = this->LoadLayer(json_layer_object, parsed.layer_path, parsed.type, parsed.file_format_version, descriptor); } - } else if (json_root_object.value("layer") != QJsonValue::Undefined) { - const QJsonObject &json_layer_object = json_root_object.value("layer").toObject(); - + } else if (parsed.json_root_object.value("layer") != QJsonValue::Undefined) { + const QJsonObject &json_layer_object = parsed.json_root_object.value("layer").toObject(); std::string layer_key = ReadStringValue(json_layer_object, "name"); if (layer_key == "VK_LAYER_LUNARG_override" || !(layer_key.rfind("VK_", 0) == 0)) { return LAYER_LOAD_IGNORED; } - LayerDescriptor descriptor = this->GetDescriptor(layer_path, layer_key); + LayerDescriptor descriptor = this->GetDescriptor(parsed.layer_path, layer_key); if (this->validate_manifests && - (descriptor.last_modified != last_modified || descriptor.validated == LAYER_VALIDATE_NONE)) { - descriptor.validated = this->Validate(layer_path, json_text, configurator_mode); - descriptor.last_modified = last_modified; + (descriptor.last_modified != parsed.last_modified || descriptor.validated == LAYER_VALIDATE_NONE)) { + descriptor.validated = this->Validate(parsed.layer_path, parsed.json_text, configurator_mode); + descriptor.last_modified = parsed.last_modified; } - status = this->LoadLayer(json_layer_object, layer_path, type, file_format_version, descriptor); + status = this->LoadLayer(json_layer_object, parsed.layer_path, parsed.type, parsed.file_format_version, descriptor); } else { assert(0); } @@ -638,36 +673,38 @@ LayerLoadStatus LayerManager::LoadLayers(const Path &layer_path, LayerType type, return status; } -LayerLoadStatus LayerManager::LoadLayer(const QJsonObject &json_layer_object, const Path &layer_path, LayerType type, - Version file_format_version, LayerDescriptor descriptor) { - Layer layer; - layer.type = type; - layer.manifest_path = layer_path; - layer.file_format_version = file_format_version; - layer.descriptor = descriptor; +LayerParseResult LayerManager::ParseLayerFile(const Path &layer_path, LayerType type) { + LayerParseResult result; + result.layer_path = layer_path; + result.type = type; - LayerLoadStatus status = layer.Load(json_layer_object); - if (status == LAYER_LOAD_INVALID || status == LAYER_LOAD_IGNORED) { - return status; + QFile file(layer_path.AbsolutePath().c_str()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + result.status = LAYER_LOAD_INVALID; + return result; } - Layer *duplicated_layer = this->Find(layer.GetId(), false); - if (duplicated_layer != nullptr) { - if (duplicated_layer->descriptor.removed) { - duplicated_layer->descriptor.removed = false; - duplicated_layer->descriptor.enabled = true; - } else if (duplicated_layer->descriptor.last_modified != layer.descriptor.last_modified) { - // Reload when the manifest was updated - LayerLoadStatus reloaded_status = duplicated_layer->Load(json_layer_object); - status = reloaded_status == LAYER_LOAD_ADDED ? LAYER_LOAD_RELOADED : reloaded_status; - } else { - status = LAYER_LOAD_UNMODIFIED; - } - } else { - this->available_layers.push_back(layer); + QString json_text = file.readAll(); + file.close(); + + QJsonParseError json_parse_error; + const QJsonDocument &json_document = QJsonDocument::fromJson(json_text.toUtf8(), &json_parse_error); + if (json_parse_error.error != QJsonParseError::NoError || json_document.isNull() || json_document.isEmpty()) { + result.status = LAYER_LOAD_INVALID; + return result; } - return status; + result.json_text = json_text; + result.json_root_object = json_document.object(); + result.last_modified = layer_path.LastModified(); + + if (result.json_root_object.value("file_format_version") != QJsonValue::Undefined) { + result.file_format_version = Version(result.json_root_object.value("file_format_version").toString().toStdString().c_str()); + } + + result.has_layers_array = result.json_root_object.value("layers") != QJsonValue::Undefined; + result.status = LAYER_LOAD_ADDED; + return result; } void LayerManager::RemoveLayer(LayerId id) { diff --git a/vkconfig_core/layer_manager.h b/vkconfig_core/layer_manager.h index 22bf976237..6a9b9a30c3 100644 --- a/vkconfig_core/layer_manager.h +++ b/vkconfig_core/layer_manager.h @@ -35,6 +35,17 @@ struct LayerDisplay { LayerDescriptor descriptor; }; +struct LayerParseResult { + Path layer_path; + LayerType type; + LayerLoadStatus status = LAYER_LOAD_INVALID; + QJsonObject json_root_object; + QString json_text; + Version file_format_version; + std::string last_modified; + bool has_layers_array = false; +}; + bool operator<(const LayerDisplay& a, const LayerDisplay& b); class LayerManager : public Serialize { @@ -61,7 +72,6 @@ class LayerManager : public Serialize { Layer* FindFromManifest(const Path& manifest_path, bool find_disabled_layers = false); void LoadAllInstalledLayers(ConfiguratorMode configurator_mode); - LayerLoadStatus LoadLayers(const Path& layer_path, LayerType type, ConfiguratorMode configurator_mode); void RemoveLayer(LayerId id); void EnableLayer(LayerId id, bool enable); @@ -87,7 +97,11 @@ class LayerManager : public Serialize { LayerValidated Validate(const Path& layer_path, QString json_text, ConfiguratorMode configurator_mode) const; LayerLoadStatus LoadLayer(const QJsonObject& json_layer_object, const Path& layer_path, LayerType type, - Version file_format_version, LayerDescriptor descriptor); + Version file_format_version, LayerDescriptor descriptor); + + LayerLoadStatus ApplyParsedLayer(const LayerParseResult& parsed, ConfiguratorMode configurator_mode); + + static LayerParseResult ParseLayerFile(const Path& layer_path, LayerType type); void ApplyLayerDescriptor(); diff --git a/vkconfig_gui/tab_preferences.cpp b/vkconfig_gui/tab_preferences.cpp deleted file mode 100644 index e93316fcfb..0000000000 --- a/vkconfig_gui/tab_preferences.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2020-2026 Valve Corporation - * Copyright (c) 2020-2026 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Authors: - * - Christophe Riccio - */ - -#include "tab_preferences.h" -#include "style.h" -#include "mainwindow.h" - -#include "../vkconfig_core/configurator.h" - -#include -#include -#include -#include -#include - -TabPreferences::TabPreferences(MainWindow &window, std::shared_ptr ui) : Tab(TAB_DIAGNOSTIC, window, ui) { - Configurator &configurator = Configurator::Get(); - -#if QT_VERSION > QT_VERSION_CHECK(6, 5, 0) - window.app.setStyle("fusion"); -#endif - - this->connect(this->ui->preferences_keep_running, SIGNAL(toggled(bool)), this, SLOT(on_keep_running_toggled(bool))); - this->connect(this->ui->preferences_vk_home_text, SIGNAL(returnPressed()), this, SLOT(on_vk_home_text_pressed())); - this->connect(this->ui->preferences_vk_home_browse, SIGNAL(clicked()), this, SLOT(on_vk_home_browse_pressed())); - this->connect(this->ui->preferences_show_executable_scope, SIGNAL(toggled(bool)), this, - SLOT(on_show_executables_scope_toggled(bool))); - this->connect(this->ui->preferences_all_enabled_executables, SIGNAL(currentIndexChanged(int)), this, - SLOT(on_all_enabled_executables_changed(int))); - this->connect(this->ui->preferences_vk_download_browse, SIGNAL(clicked()), this, SLOT(on_vk_download_browse_pressed())); - this->connect(this->ui->preferences_vk_download_open, SIGNAL(clicked()), this, SLOT(on_vk_download_open_pressed())); - this->connect(this->ui->preferences_reset, SIGNAL(clicked()), this, SLOT(on_reset_hard_pressed())); - this->connect(this->ui->preferences_show_debug_settings, SIGNAL(toggled(bool)), this, SLOT(on_layer_debug_mode_toggled(bool))); - this->connect(this->ui->preferences_validate_layer, SIGNAL(toggled(bool)), this, SLOT(on_layer_validate_toggled(bool))); - this->connect(this->ui->preferences_open_page, SIGNAL(clicked()), this, SLOT(on_open_page_pressed())); - this->connect(this->ui->preferences_notify_releases, SIGNAL(toggled(bool)), this, SLOT(on_notify_releases_toggled(bool))); - this->connect(this->ui->preferences_download, SIGNAL(clicked()), this, SLOT(on_download_pressed())); - this->connect(this->ui->preferences_theme_mode, SIGNAL(currentIndexChanged(int)), this, SLOT(on_theme_mode_changed(int))); - this->connect(this->ui->preferences_theme_light_alternate_enabled, SIGNAL(toggled(bool)), this, - SLOT(on_theme_light_alternate_enabled(bool))); - this->connect(this->ui->preferences_theme_dark_alternate_enabled, SIGNAL(toggled(bool)), this, - SLOT(on_theme_dark_alternate_enabled(bool))); - this->connect(this->ui->preferences_theme_light_alternate_open, SIGNAL(clicked()), this, - SLOT(on_theme_light_alternate_pressed())); - this->connect(this->ui->preferences_theme_dark_alternate_open, SIGNAL(clicked()), this, - SLOT(on_theme_dark_alternate_pressed())); - this->connect(this->ui->preferences_app_log_max_blocks, SIGNAL(valueChanged(int)), this, - SLOT(on_app_text_max_blocks_changed(int))); - -#if QT_VERSION < QT_VERSION_CHECK(6, 8, 0) - this->ui->preferences_theme_mode->setToolTip( - "Control of the theme mode requires Vulkan Configurator to be build against Qt 6.8.0 or newer."); -#endif - - this->ui->preferences_keep_running->setEnabled(QSystemTrayIcon::isSystemTrayAvailable()); - if (!QSystemTrayIcon::isSystemTrayAvailable()) { - this->ui->preferences_keep_running->setToolTip("No system tray on this system."); - } - - this->ui->preferences_theme_mode->setEnabled(QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)); - this->ui->preferences_theme_mode->blockSignals(true); - this->ui->preferences_theme_mode->setCurrentIndex(configurator.current_theme_mode); - this->ui->preferences_theme_mode->blockSignals(false); - this->ui->preferences_theme_light_alternate_enabled->blockSignals(true); - this->ui->preferences_theme_light_alternate_enabled->setChecked(configurator.theme_light_alternate_enabled); - this->ui->preferences_theme_light_alternate_enabled->blockSignals(false); - this->ui->preferences_theme_dark_alternate_enabled->blockSignals(true); - this->ui->preferences_theme_dark_alternate_enabled->setChecked(configurator.theme_dark_alternate_enabled); - this->ui->preferences_theme_dark_alternate_enabled->blockSignals(false); - - this->ui->launch_log_text->document()->setMaximumBlockCount(configurator.app_log_max_blocks); - this->ui->preferences_app_log_max_blocks->blockSignals(true); - this->ui->preferences_app_log_max_blocks->setValue(configurator.app_log_max_blocks); - this->ui->preferences_app_log_max_blocks->blockSignals(false); - - this->ui->preferences_progress->setVisible(false); - this->ui->preferences_notify_releases->setChecked(configurator.GetUseNotifyReleases()); - this->ui->preferences_download->setText("Searching Latest Vulkan SDK..."); - this->ui->preferences_validate_layer->setChecked(configurator.layers.validate_manifests); - -#if WORKAROUND_WINARM_RELEASE_NOTIFICATION_BUG - // Windows ARM crash, it looks like a Qt bug in 6.8.2... - if (VKC_PLATFORM == PLATFORM_WINDOWS_ARM) { - this->ui->preferences_group_box_releases->setVisible(false); - } else { -#endif - QUrl url(GetLatestReleaseSDK(VKC_PLATFORM)); - QNetworkRequest request(url); - this->network_manager.get(request); - this->connect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), this, - SLOT(on_release_downloaded(QNetworkReply *))); -#if WORKAROUND_WINARM_RELEASE_NOTIFICATION_BUG - } -#endif - - this->UpdatePreferences(configurator.current_theme_mode); -} - -TabPreferences::~TabPreferences() {} - -void TabPreferences::UpdateUI(UpdateUIMode mode) { - (void)mode; - - Configurator &configurator = Configurator::Get(); - - this->ui->preferences_keep_running->blockSignals(true); - this->ui->preferences_keep_running->setChecked(configurator.GetUseSystemTray()); - this->ui->preferences_keep_running->blockSignals(false); - - this->ui->preferences_vk_home_text->blockSignals(true); - this->ui->preferences_vk_home_text->setText(::Path(Path::HOME).RelativePath().c_str()); - this->ui->preferences_vk_home_text->setToolTip(::Path(Path::HOME).AbsolutePath().c_str()); - this->ui->preferences_vk_home_text->blockSignals(false); - - this->ui->preferences_all_enabled_executables->blockSignals(true); - this->ui->preferences_all_enabled_executables->setEnabled(configurator.configuration_show_scope); - this->ui->preferences_all_enabled_executables->setCurrentIndex( - static_cast(configurator.GetAllEnabledExecutableBehavior())); - this->ui->preferences_all_enabled_executables->blockSignals(false); - - this->ui->preferences_show_debug_settings->blockSignals(true); - this->ui->preferences_show_debug_settings->setChecked(configurator.GetUseLayerDebugMode()); - this->ui->preferences_show_debug_settings->blockSignals(false); - - this->ui->preferences_vk_download_text->blockSignals(true); - this->ui->preferences_vk_download_text->setText(::Path(Path::DOWNLOAD).RelativePath().c_str()); - this->ui->preferences_vk_download_text->setToolTip(::Path(Path::DOWNLOAD).AbsolutePath().c_str()); - this->ui->preferences_vk_download_text->blockSignals(false); -} - -void TabPreferences::CleanUI() {} - -void TabPreferences::UpdatePreferences(ThemeMode new_theme_mode) { - Configurator &configurator = Configurator::Get(); - - // Configurations - this->ui->configurations_executable_append->setIcon(::Get(new_theme_mode, ::ICON_FILE_SEARCH)); - this->ui->configurations_executable_remove->setIcon(::Get(new_theme_mode, ::ICON_FILE_REMOVE)); - this->ui->configurations_settings_reset->setIcon(::Get(new_theme_mode, ::ICON_RELOAD)); - - // Drivers - this->ui->driver_browse->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_SEARCH)); - this->ui->driver_search_clear->setIcon(::Get(new_theme_mode, ::ICON_EXIT)); - - // Layers - this->ui->layers_browse_button->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_SEARCH)); - this->ui->layers_reload_button->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_RELOAD)); - this->ui->layers_search_clear->setIcon(::Get(new_theme_mode, ::ICON_EXIT)); - - // Applications - this->ui->launch_executable_search->setIcon(::Get(new_theme_mode, ::ICON_FILE_SEARCH)); - this->ui->launch_executable_append->setIcon(::Get(new_theme_mode, ::ICON_FILE_APPEND)); - this->ui->launch_executable_remove->setIcon(::Get(new_theme_mode, ::ICON_FILE_REMOVE)); - this->ui->launch_options_append->setIcon(::Get(new_theme_mode, ::ICON_OPTIONS_COPY)); - this->ui->launch_options_remove->setIcon(::Get(new_theme_mode, ::ICON_OPTIONS_REMOVE)); - this->ui->launch_options_dir_button->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_SEARCH)); - this->ui->launch_options_log_button->setIcon(::Get(new_theme_mode, ::ICON_FILE_SEARCH)); - this->ui->launch_options_log_open->setIcon(::Get(new_theme_mode, ::ICON_FILE_EXPORT)); - - this->ui->launch_search_clear->setIcon(::Get(new_theme_mode, ::ICON_EXIT)); - this->ui->launch_search_next->setIcon(::Get(new_theme_mode, ::ICON_NEXT)); - this->ui->launch_search_prev->setIcon(::Get(new_theme_mode, ::ICON_PREV)); - this->ui->launch_search_case->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_CASE)); - this->ui->launch_search_whole->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_WHOLE)); - this->ui->launch_search_regex->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_REGEX)); - - // Diagnostics - this->ui->diagnostic_export_folder->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_EXPORT)); - this->ui->diagnostic_export_file->setIcon(::Get(new_theme_mode, ::ICON_FILE_EXPORT)); - this->ui->diagnostic_refresh->setIcon(::Get(new_theme_mode, ::ICON_RELOAD)); - this->ui->diagnostic_search_clear->setIcon(::Get(new_theme_mode, ::ICON_EXIT)); - this->ui->diagnostic_search_next->setIcon(::Get(new_theme_mode, ::ICON_NEXT)); - this->ui->diagnostic_search_prev->setIcon(::Get(new_theme_mode, ::ICON_PREV)); - this->ui->diagnostic_search_case->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_CASE)); - this->ui->diagnostic_search_whole->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_WHOLE)); - this->ui->diagnostic_search_regex->setIcon(::Get(new_theme_mode, ::ICON_SEARCH_REGEX)); - this->ui->diagnostic_dir_sdk->setIcon(::Get(new_theme_mode, ::ICON_TOOLS)); - this->ui->diagnostic_dir_home->setIcon(::Get(new_theme_mode, ::ICON_HOME)); - this->ui->diagnostic_dir_system->setIcon(::Get(new_theme_mode, ::ICON_ADVANCED)); - this->ui->diagnostic_dir_info->setVisible(VKC_PLATFORM == PLATFORM_LINUX || VKC_ENV == VKC_ENV_WIN32); - - /* - QPalette palette = this->ui->configurations_list->palette(); - QColor background_color = palette.color(QPalette::Highlight); - palette.setColor(QPalette::Shadow, background_color); - this->ui->diagnostic_status_text->setPalette(palette); - */ - // Preferences - this->ui->preferences_reset->setIcon(::Get(new_theme_mode, ::ICON_RESET)); - this->ui->preferences_vk_home_browse->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_SEARCH)); - this->ui->preferences_vk_download_browse->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_SEARCH)); - this->ui->preferences_vk_download_open->setIcon(::Get(new_theme_mode, ::ICON_FOLDER_EXPORT)); - - { - QListWidget *dummy_widget = new QListWidget; - - QPalette palette = dummy_widget->palette(); - - switch (::GetActualThemeMode(new_theme_mode)) { - default: - case THEME_MODE_AUTO: - assert(0); - break; - case THEME_MODE_FORCE_LIGHT: { - if (configurator.theme_light_alternate_enabled) { - palette.setColor(QPalette::AlternateBase, configurator.theme_light_alternate_color); - } - break; - } - case THEME_MODE_FORCE_DARK: { - if (configurator.theme_dark_alternate_enabled) { - palette.setColor(QPalette::AlternateBase, configurator.theme_dark_alternate_color); - } - break; - } - } - - QString theme_light = QString("background-color: %1").arg(configurator.theme_light_alternate_color.name()); - this->ui->preferences_theme_light_alternate_open->setStyleSheet(theme_light); - QString theme_dark = QString("background-color: %1").arg(configurator.theme_dark_alternate_color.name()); - this->ui->preferences_theme_dark_alternate_open->setStyleSheet(theme_dark); - - this->ui->configurations_list->setPalette(palette); - this->ui->configurations_settings->setPalette(palette); - this->ui->configurations_layers_list->setPalette(palette); - this->ui->layers_list->setPalette(palette); - this->ui->driver_paths_list->setPalette(palette); - - delete dummy_widget; - } - - { - if (configurator.current_theme_mode == new_theme_mode && this->initialized) { - return; // Prevent Qt 6.8 crash - } - - configurator.current_theme_mode = new_theme_mode; - } - - this->initialized = true; -} - -bool TabPreferences::EventFilter(QObject *target, QEvent *event) { - (void)target; - (void)event; - - return false; -} - -void TabPreferences::on_show_executables_scope_toggled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.configuration_show_scope = checked; - - this->UpdateUI(UPDATE_REFRESH_UI); -} - -void TabPreferences::on_all_enabled_executables_changed(int index) { - Configurator &configurator = Configurator::Get(); - - configurator.Surrender(OVERRIDE_AREA_ALL); - - const ExecutableAllEnabledBehavior behavior = static_cast(index); - configurator.SetAllEnabledExecutableBehavior(behavior); - - configurator.Override(OVERRIDE_AREA_ALL); -} - -void TabPreferences::on_app_text_max_blocks_changed(int index) { - Configurator &configurator = Configurator::Get(); - configurator.app_log_max_blocks = index; -} - -void TabPreferences::on_theme_mode_changed(int index) { - static bool only_once = true; - - if (VKC_PLATFORM == PLATFORM_LINUX) { - Configurator &configurator = Configurator::Get(); - - if (only_once && !(configurator.Get(HIDE_MESSAGE_WARN_DARK_THEME_LINUX))) { - QMessageBox alert; - alert.setWindowTitle("Dark Mode on Linux system"); - alert.setText( - "The support of Dark Mode depends on the Linux desktop support so this option may have limited effects..."); - alert.setInformativeText("Only Vulkan Configurator icons may change color when dark mode is not supported."); - alert.setStandardButtons(QMessageBox::Ok); - alert.setDefaultButton(QMessageBox::Ok); - alert.setIcon(QMessageBox::Warning); - alert.setCheckBox(new QCheckBox("Do not show again.")); - alert.exec(); - if (alert.checkBox()->isChecked()) { - configurator.Set(HIDE_MESSAGE_WARN_DARK_THEME_LINUX); - } - - only_once = false; - } - } - - const ThemeMode new_theme_mode = static_cast(index); - - this->UpdatePreferences(new_theme_mode); -} - -void TabPreferences::on_theme_light_alternate_enabled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.theme_light_alternate_enabled = checked; - - this->UpdatePreferences(configurator.current_theme_mode); -} - -void TabPreferences::on_theme_dark_alternate_enabled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.theme_dark_alternate_enabled = checked; - - this->UpdatePreferences(configurator.current_theme_mode); -} - -void TabPreferences::on_theme_light_alternate_pressed() { - Configurator &configurator = Configurator::Get(); - - this->ui->preferences_theme_light_alternate_open->setStyleSheet(""); - - QColor color = - QColorDialog::getColor(configurator.theme_light_alternate_color, this->ui->preferences_theme_light_alternate_open, - tr("Select Light Alternate rows color")); - - if (color.isValid()) { - configurator.theme_light_alternate_color = color; - } - - this->UpdatePreferences(configurator.current_theme_mode); -} - -void TabPreferences::on_theme_dark_alternate_pressed() { - Configurator &configurator = Configurator::Get(); - - this->ui->preferences_theme_dark_alternate_open->setStyleSheet(""); - - QColor color = QColorDialog::getColor(configurator.theme_dark_alternate_color, this->ui->preferences_theme_dark_alternate_open, - tr("Select Dark Alternate rows color")); - - if (color.isValid()) { - configurator.theme_dark_alternate_color = color; - } - - this->UpdatePreferences(configurator.current_theme_mode); -} - -void TabPreferences::on_keep_running_toggled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.SetUseSystemTray(checked); -} - -void TabPreferences::on_vk_home_text_pressed() { - Path path(this->ui->preferences_vk_home_text->text().toStdString()); - if (path.Exists()) { - ::SetHomePath(this->ui->preferences_vk_home_text->text().toStdString()); - } else { - QMessageBox message; - message.setIcon(QMessageBox::Critical); - message.setWindowTitle("Invalid ${VULKAN_HOME} path..."); - message.setText( - format("'%s' is not a valid, it doesn't exist.", this->ui->preferences_vk_home_text->text().toStdString().c_str()) - .c_str()); - message.setInformativeText(format("Restoring the previous path '%s'.", ::Path(Path::HOME).AbsolutePath().c_str()).c_str()); - message.exec(); - - this->ui->preferences_vk_home_text->setText(::Path(Path::HOME).AbsolutePath().c_str()); - } -} - -void TabPreferences::on_vk_home_browse_pressed() { - const QString selected_path = QFileDialog::getExistingDirectory( - this->ui->preferences_vk_home_browse, "Select the Vulkan Home Default Working Folder (Set ${VULKAN_HOME} value)...", - ::Path(Path::HOME).AbsolutePath().c_str()); - - if (!selected_path.isEmpty()) { - this->ui->preferences_vk_home_text->setText(selected_path); - - ::SetHomePath(selected_path.toStdString()); - } -} - -void TabPreferences::on_vk_download_browse_pressed() { - const QString selected_path = QFileDialog::getExistingDirectory( - this->ui->preferences_vk_download_browse, - "Select the Vulkan Configurator Download Default Folder (Set ${VULKAN_DOWNLOAD} value)...", - ::Path(Path::DOWNLOAD).AbsolutePath().c_str()); - - if (!selected_path.isEmpty()) { - this->ui->preferences_vk_download_text->setText(selected_path); - - ::SetDownloadPath(selected_path.toStdString()); - } -} - -void TabPreferences::on_vk_download_open_pressed() { - const Path path_latest(Path::DOWNLOAD); - QDesktopServices::openUrl(QUrl::fromLocalFile(path_latest.AbsolutePath().c_str())); -} - -void TabPreferences::on_reset_hard_pressed() { - QMessageBox message; - message.setIcon(QMessageBox::Critical); - message.setWindowTitle(format("Restoring and Resetting %s to default...", VKCONFIG_NAME).c_str()); - message.setText( - "You are about to delete all the user-defined configurations and resetting all default configurations to their default " - "state."); - message.setInformativeText("Do you want to continue?"); - message.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - message.setDefaultButton(QMessageBox::No); - if (message.exec() == QMessageBox::Yes) { - this->disconnect(qApp, &QGuiApplication::commitDataRequest, nullptr, nullptr); - - Configurator::Get().Reset(true); - qApp->quit(); - } -} - -void TabPreferences::on_notify_releases_toggled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.SetUseNotifyReleases(checked); -} - -void TabPreferences::on_layer_validate_toggled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.layers.validate_manifests = checked; -} - -void TabPreferences::on_layer_debug_mode_toggled(bool checked) { - Configurator &configurator = Configurator::Get(); - configurator.SetUseLayerDebugMode(checked); -} - -void TabPreferences::on_open_page_pressed() { QDesktopServices::openUrl(QUrl("https://vulkan.lunarg.com/sdk/home")); } - -void TabPreferences::on_download_pressed() { - this->ui->preferences_download->setEnabled(false); - this->ui->preferences_progress->setVisible(true); - this->ui->preferences_vk_download_label->setVisible(false); - this->ui->preferences_vk_download_text->setVisible(false); - this->ui->preferences_vk_download_browse->setVisible(false); - - this->connect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(on_package_downloaded(QNetworkReply *))); - - QUrl url(GetLatestPackageSDK(VKC_PLATFORM)); - QNetworkRequest request(url); - QNetworkReply *reply = this->network_manager.get(request); - this->connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(on_download_progress(qint64, qint64))); - - this->ui->preferences_progress->setFormat((std::string(GetLatestPackageSDK(VKC_PLATFORM)) + " - %p%").c_str()); -} - -void TabPreferences::on_release_downloaded(QNetworkReply *pReply) { - this->disconnect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), 0, 0); - - Configurator &configurator = Configurator::Get(); - - if (pReply->error() == QNetworkReply::NoError) { - std::string data = pReply->readAll().toStdString(); - if (!data.empty()) { - configurator.online_sdk_version = Version(data); - } - } - - pReply->deleteLater(); - - if (configurator.online_sdk_version == Version::NONE) { - this->ui->preferences_download->setText("Couln't Download Latest Vulkan SDK version"); - this->ui->preferences_download->setEnabled(false); - return; - } else { - this->ui->preferences_download->setText( - format("Download Latest Vulkan SDK %s", configurator.online_sdk_version.str().c_str()).c_str()); - } - - if (configurator.ShouldNotify()) { - if (configurator.GetUseNotifyReleases()) { - QMessageBox alert; - alert.setWindowTitle("A new version of the Vulkan SDK is available"); - alert.setText(format("Do you want to download Vulkan SDK %s?", configurator.online_sdk_version.str().c_str()).c_str()); - alert.setIcon(QMessageBox::Question); - alert.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - alert.setDefaultButton(QMessageBox::Yes); - alert.setCheckBox(new QCheckBox("Do not show again for this version.")); - - int ret_val = alert.exec(); - if (alert.checkBox()->isChecked()) { - configurator.latest_sdk_version = configurator.online_sdk_version; - } - - if (ret_val == QMessageBox::Yes) { - this->ui->tab_widget->setCurrentIndex(TAB_PREFERENCES); - this->on_download_pressed(); - } - } - } -} - -void TabPreferences::on_package_downloaded(QNetworkReply *pReply) { - this->disconnect(&this->network_manager, SIGNAL(finished(QNetworkReply *)), 0, 0); - - this->ui->preferences_download->setEnabled(true); - this->ui->preferences_progress->setVisible(false); - this->ui->preferences_vk_download_label->setVisible(true); - this->ui->preferences_vk_download_text->setVisible(true); - this->ui->preferences_vk_download_browse->setVisible(true); - - Configurator &configurator = Configurator::Get(); - // configurator.latest_sdk_version = configurator.online_sdk_version; - - if (pReply->error() == QNetworkReply::NoError) { - this->downloaded_data = pReply->readAll(); - pReply->deleteLater(); - } else { - QMessageBox alert; - alert.setWindowTitle("Error while downloading the latest Vulkan SDK..."); - alert.setText( - format("Vulkan Configurator couldn't download Vulkan SDK %s package...", configurator.online_sdk_version.str().c_str()) - .c_str()); - alert.setIcon(QMessageBox::Critical); - alert.exec(); - - pReply->deleteLater(); - return; - } - - const Path &path_latest = ::AbsolutePath(Path::DOWNLOAD) + Path::Separator() + GetInstallerFilename(VKC_PLATFORM); - QFile file_latest(path_latest.AbsolutePath().c_str()); - - const bool result_latest = file_latest.open(QFile::WriteOnly); - if (result_latest) { - file_latest.write(this->downloaded_data); - file_latest.close(); - } - - const Path &path_version = ::AbsolutePath(Path::DOWNLOAD) + Path::Separator() + - format(GetVersionedFilename(VKC_PLATFORM), configurator.online_sdk_version.str().c_str()); - QFile file_version(path_version.AbsolutePath().c_str()); - - const bool result_version = file_version.open(QFile::WriteOnly); - if (result_latest) { - file_version.write(this->downloaded_data); - file_version.close(); - } - - if (!result_latest && !result_version) { - QMessageBox alert; - alert.setWindowTitle("Couldn't save downloaded Vulkan SDK installer..."); - alert.setIcon(QMessageBox::Critical); - alert.exec(); - } else { - configurator.latest_sdk_version = configurator.online_sdk_version; - } - - if (VKC_ENV == VKC_ENV_WIN32) { - QMessageBox alert; - alert.setWindowTitle("The new version of the Vulkan SDK is downloaded"); - alert.setText( - format("Do you want to Launch Vulkan SDK %s installer?", configurator.online_sdk_version.str().c_str()).c_str()); - alert.setIcon(QMessageBox::Question); - alert.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - alert.setDefaultButton(QMessageBox::Yes); - - int ret_val = alert.exec(); - if (ret_val == QMessageBox::Yes) { - QDesktopServices::openUrl(QUrl::fromLocalFile(path_latest.AbsolutePath().c_str())); - - qApp->quit(); - return; - } - } else if (VKC_PLATFORM == PLATFORM_LINUX) { - QDesktopServices::openUrl(QUrl("https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html")); - } else if (VKC_PLATFORM == PLATFORM_MACOS) { - QDesktopServices::openUrl(QUrl("https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html")); - } - - QDesktopServices::openUrl(QUrl::fromLocalFile(path_latest.AbsoluteDir().c_str())); -} - -void TabPreferences::on_download_progress(qint64 bytesReceived, qint64 bytesTotal) { - this->ui->preferences_progress->setMaximum(bytesTotal); - this->ui->preferences_progress->setValue(bytesReceived); -}