mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
Automatically Update shadPS4 on OS Startup (#2700)
Created a separate .exe for updating. Added a checkbox in the settings to enable the option to update on Windows startup. When the option is enabled, a PowerShell script adds the new updater exe to the Windows Task Scheduler and sets it to run at startup. If there are updates available at startup, the update windows pops up. Disabling the option runs another script to remove the updater from the Task Scheduler. Co-authored-by: Joao Ribeiro <joao.viegas.ribeiro@tecnico.ulisboa.pt>
This commit is contained in:
parent
64bbedeb82
commit
bbfb799802
129
CMakeLists.txt
129
CMakeLists.txt
@ -34,6 +34,7 @@ endif()
|
||||
option(ENABLE_QT_GUI "Enable the Qt GUI. If not selected then the emulator uses a minimal SDL-based UI instead" OFF)
|
||||
option(ENABLE_DISCORD_RPC "Enable the Discord RPC integration" ON)
|
||||
option(ENABLE_UPDATER "Enables the options to updater" ON)
|
||||
option(ENABLE_UPDATER_EXE "Enables the new executable for updates" ON)
|
||||
|
||||
# First, determine whether to use CMAKE_OSX_ARCHITECTURES or CMAKE_SYSTEM_PROCESSOR.
|
||||
if (APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
@ -1074,6 +1075,26 @@ if (ENABLE_QT_GUI)
|
||||
${EMULATOR}
|
||||
src/images/shadPS4.icns
|
||||
)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
qt_add_executable(shadps4_updater
|
||||
${AUDIO_CORE}
|
||||
${IMGUI}
|
||||
${INPUT}
|
||||
${COMMON}
|
||||
${CORE}
|
||||
${SHADER_RECOMPILER}
|
||||
${VIDEO_CORE}
|
||||
${EMULATOR}
|
||||
${UPDATER}
|
||||
${RESOURCE_FILES}
|
||||
src/qt_gui/main_window_themes.cpp
|
||||
src/qt_gui/main_window_themes.h
|
||||
src/qt_gui/background_music_player.cpp
|
||||
src/qt_gui/background_music_player.h
|
||||
src/updater/main.cpp
|
||||
src/images/shadPS4.icns
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
add_executable(shadps4
|
||||
${AUDIO_CORE}
|
||||
@ -1097,20 +1118,55 @@ create_target_directory_groups(shadps4)
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb)
|
||||
|
||||
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
create_target_directory_groups(shadps4_updater)
|
||||
|
||||
target_link_libraries(shadps4_updater PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4_updater PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb)
|
||||
endif()
|
||||
|
||||
#Hide console for shadps4_updater
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
if (WIN32)
|
||||
set_target_properties(shadps4_updater PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(shadps4 PRIVATE shell32)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE shell32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_compile_definitions(shadps4_updater PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
endif()
|
||||
|
||||
if (ENABLE_DISCORD_RPC)
|
||||
target_compile_definitions(shadps4 PRIVATE ENABLE_DISCORD_RPC)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_compile_definitions(shadps4_updater PRIVATE ENABLE_DISCORD_RPC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
# Optional due to https://github.com/shadps4-emu/shadPS4/issues/1704
|
||||
if (ENABLE_USERFAULTFD)
|
||||
target_compile_definitions(shadps4 PRIVATE ENABLE_USERFAULTFD)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_compile_definitions(shadps4_updater PRIVATE ENABLE_USERFAULTFD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE uuid)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE uuid)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
@ -1118,9 +1174,15 @@ if (APPLE)
|
||||
if (ENABLE_QT_GUI)
|
||||
set(MVK_BUNDLE_PATH "Resources/vulkan/icd.d")
|
||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLE_PATH}")
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
set_property(TARGET shadps4_updater APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLE_PATH}")
|
||||
endif()
|
||||
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/${MVK_BUNDLE_PATH})
|
||||
else()
|
||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path")
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
set_property(TARGET shadps4_updater APPEND PROPERTY BUILD_RPATH "@executable_path")
|
||||
endif()
|
||||
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
@ -1143,14 +1205,23 @@ if (APPLE)
|
||||
add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST})
|
||||
add_dependencies(CopyMoltenVK MoltenVK)
|
||||
add_dependencies(shadps4 CopyMoltenVK)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
add_dependencies(shadps4_updater CopyMoltenVK)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
# Reserve system-managed memory space.
|
||||
target_link_options(shadps4 PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x4000,-segaddr,TCB_SPACE,0x4000,-segaddr,SYSTEM_MANAGED,0x400000,-segaddr,SYSTEM_RESERVED,0x7FFFFC000,-image_base,0x20000000000)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_options(shadps4_updater PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x4000,-segaddr,TCB_SPACE,0x4000,-segaddr,SYSTEM_MANAGED,0x400000,-segaddr,SYSTEM_RESERVED,0x7FFFFC000,-image_base,0x20000000000)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Replacement for std::chrono::time_zone
|
||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE date::date-tz)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT ENABLE_QT_GUI)
|
||||
@ -1159,6 +1230,9 @@ endif()
|
||||
|
||||
if (ENABLE_QT_GUI)
|
||||
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network Qt6::Multimedia)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network Qt6::Multimedia)
|
||||
endif()
|
||||
add_definitions(-DENABLE_QT_GUI)
|
||||
if (ENABLE_UPDATER)
|
||||
add_definitions(-DENABLE_UPDATER)
|
||||
@ -1167,6 +1241,9 @@ endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(shadps4 PRIVATE mincore)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE mincore)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# MSVC likes putting opinions on what people can use, disable:
|
||||
@ -1185,37 +1262,64 @@ if (WIN32)
|
||||
|
||||
if (MSVC)
|
||||
target_link_libraries(shadps4 PRIVATE clang_rt.builtins-x86_64.lib)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE clang_rt.builtins-x86_64.lib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Disable ASLR so we can reserve the user area
|
||||
if (MSVC)
|
||||
target_link_options(shadps4 PRIVATE /DYNAMICBASE:NO)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_options(shadps4_updater PRIVATE /DYNAMICBASE:NO)
|
||||
endif()
|
||||
else()
|
||||
target_link_options(shadps4 PRIVATE -Wl,--disable-dynamicbase)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_options(shadps4_updater PRIVATE -Wl,--disable-dynamicbase)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Increase stack commit area (Needed, otherwise there are crashes)
|
||||
if (MSVC)
|
||||
target_link_options(shadps4 PRIVATE /STACK:0x200000,0x200000)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_options(shadps4_updater PRIVATE /STACK:0x200000,0x200000)
|
||||
endif()
|
||||
else()
|
||||
target_link_options(shadps4 PRIVATE -Wl,--stack,2097152)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_options(shadps4_updater PRIVATE -Wl,--stack,2097152)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_sources(shadps4 PRIVATE src/shadps4.rc)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_sources(shadps4_updater PRIVATE src/shadps4.rc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(-DBOOST_ASIO_STANDALONE)
|
||||
|
||||
target_include_directories(shadps4 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_include_directories(shadps4_updater PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
# Shaders sources
|
||||
set(HOST_SHADERS_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/src/video_core/host_shaders)
|
||||
|
||||
add_subdirectory(${HOST_SHADERS_INCLUDE})
|
||||
add_dependencies(shadps4 host_shaders)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
add_dependencies(shadps4_updater host_shaders)
|
||||
endif()
|
||||
target_include_directories(shadps4 PRIVATE ${HOST_SHADERS_INCLUDE})
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_include_directories(shadps4_updater PRIVATE ${HOST_SHADERS_INCLUDE})
|
||||
endif()
|
||||
|
||||
# embed resources
|
||||
|
||||
@ -1228,11 +1332,20 @@ cmrc_add_resource_library(embedded-resources
|
||||
src/images/platinum.png
|
||||
src/images/silver.png)
|
||||
target_link_libraries(shadps4 PRIVATE res::embedded)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE res::embedded)
|
||||
endif()
|
||||
|
||||
# ImGui resources
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/imgui/renderer)
|
||||
add_dependencies(shadps4 ImGui_Resources)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
add_dependencies(shadps4_updater ImGui_Resources)
|
||||
endif()
|
||||
target_include_directories(shadps4 PRIVATE ${IMGUI_RESOURCES_INCLUDE})
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_include_directories(shadps4_updater PRIVATE ${IMGUI_RESOURCES_INCLUDE})
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT_GUI)
|
||||
set_target_properties(shadps4 PROPERTIES
|
||||
@ -1242,7 +1355,15 @@ if (ENABLE_QT_GUI)
|
||||
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APP_VERSION}"
|
||||
)
|
||||
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
set_target_properties(shadps4 PROPERTIES
|
||||
# WIN32_EXECUTABLE ON
|
||||
MACOSX_BUNDLE ON
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in"
|
||||
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APP_VERSION}"
|
||||
)
|
||||
endif()
|
||||
set_source_files_properties(src/images/shadPS4.icns PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
endif()
|
||||
@ -1251,12 +1372,18 @@ if (UNIX AND NOT APPLE)
|
||||
if (ENABLE_QT_GUI)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(shadps4 PRIVATE ${OPENSSL_LIBRARIES})
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE ${OPENSSL_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Discord RPC
|
||||
if (ENABLE_DISCORD_RPC)
|
||||
target_link_libraries(shadps4 PRIVATE discord-rpc)
|
||||
if (ENABLE_UPDATER_EXE)
|
||||
target_link_libraries(shadps4_updater PRIVATE discord-rpc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install rules
|
||||
|
@ -53,6 +53,7 @@ static bool isDebugDump = false;
|
||||
static bool isShaderDebug = false;
|
||||
static bool isShowSplash = false;
|
||||
static bool isAutoUpdate = false;
|
||||
static bool isStartupUpdate = false;
|
||||
static bool isAlwaysShowChangelog = false;
|
||||
static std::string isSideTrophy = "right";
|
||||
static bool isNullGpu = false;
|
||||
@ -280,6 +281,10 @@ bool autoUpdate() {
|
||||
return isAutoUpdate;
|
||||
}
|
||||
|
||||
bool startupUpdate() {
|
||||
return isStartupUpdate;
|
||||
}
|
||||
|
||||
bool alwaysShowChangelog() {
|
||||
return isAlwaysShowChangelog;
|
||||
}
|
||||
@ -388,6 +393,10 @@ void setAutoUpdate(bool enable) {
|
||||
isAutoUpdate = enable;
|
||||
}
|
||||
|
||||
void setStartupUpdate(bool enable) {
|
||||
isStartupUpdate = enable;
|
||||
}
|
||||
|
||||
void setAlwaysShowChangelog(bool enable) {
|
||||
isAlwaysShowChangelog = enable;
|
||||
}
|
||||
@ -780,6 +789,7 @@ void load(const std::filesystem::path& path) {
|
||||
}
|
||||
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
||||
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
||||
isStartupUpdate = toml::find_or<bool>(general, "startupUpdate", false);
|
||||
isAlwaysShowChangelog = toml::find_or<bool>(general, "alwaysShowChangelog", false);
|
||||
isSideTrophy = toml::find_or<std::string>(general, "sideTrophy", "right");
|
||||
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
|
||||
@ -976,6 +986,7 @@ void save(const std::filesystem::path& path) {
|
||||
data["General"]["chooseHomeTab"] = chooseHomeTab;
|
||||
data["General"]["showSplash"] = isShowSplash;
|
||||
data["General"]["autoUpdate"] = isAutoUpdate;
|
||||
data["General"]["startupUpdate"] = isStartupUpdate;
|
||||
data["General"]["alwaysShowChangelog"] = isAlwaysShowChangelog;
|
||||
data["General"]["sideTrophy"] = isSideTrophy;
|
||||
data["General"]["compatibilityEnabled"] = compatibilityData;
|
||||
@ -1136,6 +1147,7 @@ void setDefaultValues() {
|
||||
isShaderDebug = false;
|
||||
isShowSplash = false;
|
||||
isAutoUpdate = false;
|
||||
isStartupUpdate = false;
|
||||
isAlwaysShowChangelog = false;
|
||||
isSideTrophy = "right";
|
||||
isNullGpu = false;
|
||||
|
@ -70,6 +70,7 @@ bool debugDump();
|
||||
bool collectShadersForDebug();
|
||||
bool showSplash();
|
||||
bool autoUpdate();
|
||||
bool startupUpdate();
|
||||
bool alwaysShowChangelog();
|
||||
std::string sideTrophy();
|
||||
bool nullGpu();
|
||||
@ -84,6 +85,7 @@ void setDebugDump(bool enable);
|
||||
void setCollectShaderForDebug(bool enable);
|
||||
void setShowSplash(bool enable);
|
||||
void setAutoUpdate(bool enable);
|
||||
void setStartupUpdate(bool enable);
|
||||
void setAlwaysShowChangelog(bool enable);
|
||||
void setSideTrophy(std::string side);
|
||||
void setNullGpu(bool enable);
|
||||
|
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <filesystem>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@ -444,8 +445,7 @@ void CheckUpdate::Install() {
|
||||
QString userPath;
|
||||
Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir));
|
||||
|
||||
QString rootPath;
|
||||
Common::FS::PathToQString(rootPath, std::filesystem::current_path());
|
||||
QString rootPath = QCoreApplication::applicationDirPath();
|
||||
|
||||
QString tempDirPath = userPath + "/temp_download_update";
|
||||
QString startingUpdate = tr("Starting Update...");
|
||||
|
@ -9,12 +9,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setStyleSheet("");
|
||||
switch (theme) {
|
||||
case Theme::Dark:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1e1e1e; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1e1e1e; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(50, 50, 50));
|
||||
themePalette.setColor(QPalette::WindowText, Qt::white);
|
||||
themePalette.setColor(QPalette::Base, QColor(20, 20, 20));
|
||||
@ -31,12 +33,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Light:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #ffffff; color: #000000; border: 1px solid #000000; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #ffffff; color: #000000; border: 1px solid #000000; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(240, 240, 240)); // Light gray
|
||||
themePalette.setColor(QPalette::WindowText, Qt::black); // Black
|
||||
themePalette.setColor(QPalette::Base, QColor(230, 230, 230, 80)); // Grayish
|
||||
@ -52,12 +56,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Green:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #192819; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #192819; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(53, 69, 53)); // Dark green background
|
||||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(25, 40, 25)); // Darker green base
|
||||
@ -76,12 +82,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Blue:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #14283c; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #14283c; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(40, 60, 90)); // Dark blue background
|
||||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(20, 40, 60)); // Darker blue base
|
||||
@ -101,12 +109,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Violet:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #501e5a; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #501e5a; color: #ffffff; border: 1px solid #ffffff; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(100, 50, 120)); // Violet background
|
||||
themePalette.setColor(QPalette::WindowText, Qt::white); // White text
|
||||
themePalette.setColor(QPalette::Base, QColor(80, 30, 90)); // Darker violet base
|
||||
@ -126,12 +136,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Gruvbox:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1d2021; color: #f9f5d7; border: 1px solid #f9f5d7; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #83A598; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1d2021; color: #f9f5d7; border: 1px solid #f9f5d7; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #83A598; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(29, 32, 33));
|
||||
themePalette.setColor(QPalette::WindowText, QColor(249, 245, 215));
|
||||
themePalette.setColor(QPalette::Base, QColor(29, 32, 33));
|
||||
@ -148,12 +160,14 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::TokyoNight:
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1a1b26; color: #9d7cd8; border: 1px solid #9d7cd8; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #7aa2f7; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet(
|
||||
"QLineEdit {"
|
||||
"background-color: #1a1b26; color: #9d7cd8; border: 1px solid #9d7cd8; "
|
||||
"border-radius: 4px; padding: 5px; }"
|
||||
"QLineEdit:focus {"
|
||||
"border: 1px solid #7aa2f7; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, QColor(31, 35, 53));
|
||||
themePalette.setColor(QPalette::WindowText, QColor(192, 202, 245));
|
||||
themePalette.setColor(QPalette::Base, QColor(25, 28, 39));
|
||||
@ -170,8 +184,10 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) {
|
||||
qApp->setPalette(themePalette);
|
||||
break;
|
||||
case Theme::Oled:
|
||||
mw_searchbar->setStyleSheet("QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
if (mw_searchbar) {
|
||||
mw_searchbar->setStyleSheet("QLineEdit:focus {"
|
||||
"border: 1px solid #2A82DA; }");
|
||||
}
|
||||
themePalette.setColor(QPalette::Window, Qt::black);
|
||||
themePalette.setColor(QPalette::WindowText, Qt::white);
|
||||
themePalette.setColor(QPalette::Base, Qt::black);
|
||||
|
@ -3,11 +3,21 @@
|
||||
|
||||
#include <vector>
|
||||
#include <QCompleter>
|
||||
#include <QCoreApplication>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QHoverEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
#include <QUuid>
|
||||
#include <fmt/format.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/scm_rev.h"
|
||||
@ -178,12 +188,29 @@ SettingsDialog::SettingsDialog(std::shared_ptr<CompatibilityInfoClass> m_compat_
|
||||
connect(ui->updateCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int state) { Config::setAutoUpdate(state == Qt::Checked); });
|
||||
|
||||
connect(ui->startupUpdateCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
Config::setStartupUpdate(state == Qt::Checked);
|
||||
if (state == Qt::Checked)
|
||||
AddUpdaterToStartup();
|
||||
else
|
||||
RemoveUpdaterFromStartup();
|
||||
});
|
||||
|
||||
connect(ui->changelogCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int state) { Config::setAlwaysShowChangelog(state == Qt::Checked); });
|
||||
#else
|
||||
connect(ui->updateCheckBox, &QCheckBox::checkStateChanged, this,
|
||||
[](Qt::CheckState state) { Config::setAutoUpdate(state == Qt::Checked); });
|
||||
|
||||
connect(ui->startupUpdateCheckBox, &QCheckBox::checkStateChanged, this,
|
||||
[this](Qt::CheckState state) {
|
||||
Config::setStartupUpdate(state == Qt::Checked);
|
||||
if (state == Qt::Checked)
|
||||
AddUpdaterToStartup();
|
||||
else
|
||||
RemoveUpdaterFromStartup();
|
||||
});
|
||||
|
||||
connect(ui->changelogCheckBox, &QCheckBox::checkStateChanged, this,
|
||||
[](Qt::CheckState state) { Config::setAlwaysShowChangelog(state == Qt::Checked); });
|
||||
#endif
|
||||
@ -502,6 +529,8 @@ void SettingsDialog::LoadValuesFromConfig() {
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
ui->updateCheckBox->setChecked(toml::find_or<bool>(data, "General", "autoUpdate", false));
|
||||
ui->startupUpdateCheckBox->setChecked(
|
||||
toml::find_or<bool>(data, "General", "startupUpdate", false));
|
||||
ui->changelogCheckBox->setChecked(
|
||||
toml::find_or<bool>(data, "General", "alwaysShowChangelog", false));
|
||||
|
||||
@ -785,6 +814,7 @@ void SettingsDialog::UpdateSettings() {
|
||||
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked());
|
||||
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked());
|
||||
Config::setAutoUpdate(ui->updateCheckBox->isChecked());
|
||||
Config::setStartupUpdate(ui->startupUpdateCheckBox->isChecked());
|
||||
Config::setAlwaysShowChangelog(ui->changelogCheckBox->isChecked());
|
||||
Config::setUpdateChannel(channelMap.value(ui->updateComboBox->currentText()).toStdString());
|
||||
Config::setChooseHomeTab(
|
||||
@ -862,3 +892,89 @@ void SettingsDialog::ResetInstallFolders() {
|
||||
Config::setAllGameInstallDirs(settings_install_dirs_config);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::AddUpdaterToStartup() {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
QString tempDirPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||
"/Temp/temp_download_update";
|
||||
QDir().mkpath(tempDirPath);
|
||||
|
||||
QString scriptFileName =
|
||||
tempDirPath + "/create_task_" + QUuid::createUuid().toString(QUuid::WithoutBraces) + ".ps1";
|
||||
|
||||
QString taskName = "ShadPS4Updater";
|
||||
QString exePath = QCoreApplication::applicationFilePath()
|
||||
.replace("shadps4.exe", "shadps4_updater.exe")
|
||||
.replace("/", "\\");
|
||||
|
||||
QString scriptContent =
|
||||
QStringLiteral("$Action = New-ScheduledTaskAction -Execute '%1'\n"
|
||||
"$Trigger = New-ScheduledTaskTrigger -AtLogOn\n"
|
||||
"$Principal = New-ScheduledTaskPrincipal -UserId \"$env:USERNAME\" "
|
||||
"-LogonType Interactive -RunLevel Highest\n"
|
||||
"$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries "
|
||||
"-DontStopIfGoingOnBatteries\n"
|
||||
"Register-ScheduledTask -TaskName '%2' -Action $Action -Trigger $Trigger "
|
||||
"-Principal $Principal -Settings $Settings -Force\n")
|
||||
.arg(exePath, taskName);
|
||||
|
||||
QFile scriptFile(scriptFileName);
|
||||
if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&scriptFile);
|
||||
out << scriptContent;
|
||||
scriptFile.close();
|
||||
|
||||
// Elevate PowerShell to run the script
|
||||
ShellExecuteW(
|
||||
nullptr,
|
||||
L"runas", // Triggers UAC prompt
|
||||
L"powershell.exe",
|
||||
(L"-ExecutionPolicy Bypass -File \"" + scriptFileName.toStdWString() + L"\"").c_str(),
|
||||
nullptr, SW_HIDE);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SettingsDialog::RemoveUpdaterFromStartup() {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
QString tempDirPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||
"/Temp/temp_download_update";
|
||||
QDir().mkpath(tempDirPath);
|
||||
|
||||
QString scriptFileName =
|
||||
tempDirPath + "/remove_task_" + QUuid::createUuid().toString(QUuid::WithoutBraces) + ".ps1";
|
||||
|
||||
QString taskName = "ShadPS4Updater";
|
||||
|
||||
QString scriptContent =
|
||||
QStringLiteral(
|
||||
"$taskName = '%1'\n"
|
||||
"if (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue) {\n"
|
||||
" Unregister-ScheduledTask -TaskName $taskName -Confirm:$false\n"
|
||||
"}\n"
|
||||
"Remove-Item -LiteralPath $MyInvocation.MyCommand.Path -Force\n" // Optional:
|
||||
// self-delete the
|
||||
// script
|
||||
)
|
||||
.arg(taskName);
|
||||
|
||||
QFile scriptFile(scriptFileName);
|
||||
if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&scriptFile);
|
||||
out << scriptContent;
|
||||
scriptFile.close();
|
||||
|
||||
// Run PowerShell script with admin privileges
|
||||
ShellExecuteW(
|
||||
nullptr, L"runas", L"powershell.exe",
|
||||
(L"-ExecutionPolicy Bypass -File \"" + scriptFileName.toStdWString() + L"\"").c_str(),
|
||||
nullptr, SW_HIDE);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ private:
|
||||
void OnLanguageChanged(int index);
|
||||
void OnCursorStateChanged(s16 index);
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
void AddUpdaterToStartup();
|
||||
void RemoveUpdaterFromStartup();
|
||||
|
||||
std::unique_ptr<Ui::SettingsDialog> ui;
|
||||
|
||||
|
@ -415,6 +415,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="startupUpdateCheckBox">
|
||||
<property name="text">
|
||||
<string>Check for Updates at OS Startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="changelogCheckBox">
|
||||
<property name="text">
|
||||
|
46
src/updater/main.cpp
Normal file
46
src/updater/main.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QApplication>
|
||||
#include "common/config.h"
|
||||
#include "common/path_util.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "qt_gui/check_update.h"
|
||||
#include "qt_gui/main_window_themes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Custom message handler to ignore Qt logs
|
||||
void customMessageHandler(QtMsgType, const QMessageLogContext&, const QString&) {}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
QApplication u(argc, argv);
|
||||
|
||||
QApplication::setDesktopFileName("net.shadps4.shadPS4_updater");
|
||||
QApplication::setStyle("Fusion");
|
||||
|
||||
// Load configurations
|
||||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::load(user_dir / "config.toml");
|
||||
|
||||
WindowThemes m_window_themes;
|
||||
|
||||
Theme lastTheme = static_cast<Theme>(Config::getMainWindowTheme());
|
||||
m_window_themes.SetWindowTheme(lastTheme, nullptr);
|
||||
|
||||
if (Config::startupUpdate()) {
|
||||
auto checkUpdate = new CheckUpdate(false);
|
||||
checkUpdate->exec();
|
||||
}
|
||||
|
||||
// Ignore Qt logs
|
||||
qInstallMessageHandler(customMessageHandler);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user