refactor(ui): add WinUI stylesheet for Windows

- Introduced WinToolWidget for custom window management on Windows.
- Implemented backdrop type settings for Windows in SettingsManager.
- Enhanced SettingsWidget to allow selection of backdrop type.
- Improved status balloon and toolbox widget styles for Windows.
- Refined tab widget animations and styles for better visual feedback.
- Fixed issues with loading and error widgets in ZLoadingWidget.
- Updated welcome widget to support custom hyperlink colors.
- General code cleanup and style adjustments across multiple files.
This commit is contained in:
uncor3
2026-02-22 11:59:57 +03:00
parent bc3998cefb
commit 43d804991e
121 changed files with 3745 additions and 479 deletions
+38 -84
View File
@@ -6,7 +6,6 @@ if(WIN32)
endif() endif()
# Feature options # Feature options
option(ENABLE_RECOVERY_DEVICE_SUPPORT "Enable recovery device support (requires libirecovery)" ON)
set(PACKAGE_MANAGER_HINT "" CACHE STRING "Name of package manager(s) used to manage this build (e.g. paru, yay, pamac)") set(PACKAGE_MANAGER_HINT "" CACHE STRING "Name of package manager(s) used to manage this build (e.g. paru, yay, pamac)")
option(PACKAGE_MANAGER_MANAGED "Build as package manager managed version (auto updates will be handled by the package manager)" OFF) option(PACKAGE_MANAGER_MANAGED "Build as package manager managed version (auto updates will be handled by the package manager)" OFF)
option(DEPLOY "Deploy the application (WIN32 only)" ON) option(DEPLOY "Deploy the application (WIN32 only)" ON)
@@ -26,39 +25,27 @@ if (APPLE)
endif() endif()
# Platform-specific paths for libraries built from source # Platform-specific paths for libraries built from source
# if(WIN32) if(WIN32)
# include_directories("C:/msys64/mingw64/include") include_directories("C:/msys64/mingw64/include")
# link_directories("C:/msys64/mingw64/lib") link_directories("C:/msys64/mingw64/lib")
# set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe") set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
# list(APPEND CMAKE_PREFIX_PATH "C:/lxqt") list(APPEND CMAKE_PREFIX_PATH "C:/lxqt")
# set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib") set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib")
# set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include") set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include")
# set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig") set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig")
# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}") set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}")
# elseif(APPLE) elseif(APPLE)
# set(CUSTOM_LIB_PATH "/usr/local/lib") set(CUSTOM_LIB_PATH "/usr/local/lib")
# # Remove the problematic include path that's causing conflicts # Remove the problematic include path that's causing conflicts
# # set(CUSTOM_INCLUDE_PATH "/usr/local/include") # set(CUSTOM_INCLUDE_PATH "/usr/local/include")
# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig") set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}") set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
# else () else ()
# set(CUSTOM_LIB_PATH "/usr/local/lib") set(CUSTOM_LIB_PATH "/usr/local/lib")
# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig") set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
# set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}") set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}")
# endif() endif()
# foreach(_ IN LISTS CMAKE_PREFIX_PATH)
# list(APPEND _qt_pkg_dirs
# "${_}/lib/pkgconfig"
# "${_}/lib64/pkgconfig"
# "${_}/lib64/qt/pkgconfig"
# "${_}/lib/qt/pkgconfig"
# )
# endforeach()
# list(APPEND _qt_pkg_dirs ${CUSTOM_PKGCONFIG_PATH})
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets Network QuickControls2 SerialPort Positioning Location QuickWidgets) find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets Network QuickControls2 SerialPort Positioning Location QuickWidgets)
find_package(SQLite3 REQUIRED) find_package(SQLite3 REQUIRED)
@@ -110,6 +97,14 @@ add_custom_command(
COMMENT "Building idevice-rs FFI libraryy" COMMENT "Building idevice-rs FFI libraryy"
VERBATIM VERBATIM
) )
elseif(WIN32)
add_custom_command(
OUTPUT ${IDEVICE_RS_LIB_PATH}
COMMAND ${CARGO_EXECUTABLE} +stable-x86_64-pc-windows-gnu build --manifest-path ${IDEVICE_RS_SOURCE_DIR}/Cargo.toml
WORKING_DIRECTORY ${IDEVICE_RS_SOURCE_DIR}
COMMENT "Building idevice-rs FFI libraryy"
VERBATIM
)
else() else()
add_custom_command( add_custom_command(
OUTPUT ${IDEVICE_RS_LIB_PATH} OUTPUT ${IDEVICE_RS_LIB_PATH}
@@ -150,6 +145,11 @@ file(GLOB PLIST_CPP_SOURCES
add_library(idevice_cpp STATIC ${IDEVICE_CPP_SOURCES} ${PLIST_CPP_SOURCES}) add_library(idevice_cpp STATIC ${IDEVICE_CPP_SOURCES} ${PLIST_CPP_SOURCES})
add_dependencies(idevice_cpp idevice_rs_build) add_dependencies(idevice_cpp idevice_rs_build)
if(WIN32)
# Define LIBPLIST_STATIC to prevent functions from being marked as DLL imports
target_compile_definitions(idevice_cpp PUBLIC LIBPLIST_STATIC)
endif()
target_include_directories(idevice_cpp PUBLIC target_include_directories(idevice_cpp PUBLIC
${IDEVICE_CPP_INCLUDE_DIR} ${IDEVICE_CPP_INCLUDE_DIR}
${PLIST_CPP_INCLUDE_DIR} ${PLIST_CPP_INCLUDE_DIR}
@@ -201,21 +201,6 @@ pkg_check_modules(AVCODEC REQUIRED IMPORTED_TARGET libavcodec)
pkg_check_modules(AVUTIL REQUIRED IMPORTED_TARGET libavutil) pkg_check_modules(AVUTIL REQUIRED IMPORTED_TARGET libavutil)
pkg_check_modules(SWSCALE REQUIRED IMPORTED_TARGET libswscale) pkg_check_modules(SWSCALE REQUIRED IMPORTED_TARGET libswscale)
# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
# find_library(IRECOVERY_LIBRARY
# NAMES irecovery-1.0
# PATHS ${CUSTOM_LIB_PATH}
# NO_DEFAULT_PATH
# )
# if(IRECOVERY_LIBRARY)
# message(STATUS "Building with recovery device support enabled")
# else()
# message(WARNING "libirecovery not found. Recovery device support will be disabled. This is to be expected if you are installing from Arch AUR.")
# set(ENABLE_RECOVERY_DEVICE_SUPPORT OFF)
# endif()
# else()
# message(STATUS "Recovery device support disabled")
# endif()
# Add libssh for SSH connections # Add libssh for SSH connections
pkg_check_modules(SSH REQUIRED IMPORTED_TARGET libssh) pkg_check_modules(SSH REQUIRED IMPORTED_TARGET libssh)
@@ -252,8 +237,10 @@ elseif (WIN32)
src/core/services/dnssd/dnssd_service.h src/core/services/dnssd/dnssd_service.h
) )
file(GLOB WINDOWS_PLATFORM_SOURCES src/platform/windows/*.cpp src/platform/windows/*.h) file(GLOB WINDOWS_PLATFORM_SOURCES src/platform/windows/*.cpp src/platform/windows/*.h src/platform/windows/widgets/*.cpp src/platform/windows/widgets/*.h)
list(APPEND PROJECT_SOURCES ${WINDOWS_PLATFORM_SOURCES}) list(APPEND PROJECT_SOURCES ${WINDOWS_PLATFORM_SOURCES})
list(APPEND PROJECT_SOURCES
resources.win.qrc)
else() else()
list(APPEND PROJECT_SOURCES list(APPEND PROJECT_SOURCES
src/core/services/avahi/avahi_service.cpp src/core/services/avahi/avahi_service.cpp
@@ -261,17 +248,6 @@ else()
) )
endif() endif()
if (NOT ENABLE_RECOVERY_DEVICE_SUPPORT)
list(REMOVE_ITEM PROJECT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.h
${CMAKE_CURRENT_SOURCE_DIR}/src/core/helpers/parse_recovery_mode.cpp
src/recoverydeviceinfowidget.cpp
src/recoverydeviceinfowidget.h
src/core/helpers/parse_recovery_mode.cpp
)
endif()
add_subdirectory(lib/uxplay) add_subdirectory(lib/uxplay)
add_subdirectory(lib/ipatool-go) add_subdirectory(lib/ipatool-go)
add_subdirectory(lib/zupdater) add_subdirectory(lib/zupdater)
@@ -323,14 +299,8 @@ target_link_libraries(iDescriptor PRIVATE
Qt6::Positioning Qt6::Positioning
Qt6::QuickWidgets Qt6::QuickWidgets
Qt6::QuickControls2 Qt6::QuickControls2
# ${IMOBILEDEVICE_LIBRARY}
# ${IMOBILEDEVICE_GLUE_LIBRARY}
# ${TATSU_LIBRARY}
# ${SSL_LIBRARY}
# ${CRYPTO_LIBRARY}
PkgConfig::SSH PkgConfig::SSH
${SSH_LIBRARY} ${SSH_LIBRARY}
# ${USBMUXD_LIBRARY}
PkgConfig::PUGIXML PkgConfig::PUGIXML
# PkgConfig::USB # PkgConfig::USB
# PkgConfig::PLIST # PkgConfig::PLIST
@@ -350,11 +320,6 @@ target_link_libraries(iDescriptor PRIVATE
SQLite::SQLite3 SQLite::SQLite3
) )
# # Conditionally link libirecovery
# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
# target_link_libraries(iDescriptor PRIVATE ${IRECOVERY_LIBRARY})
# endif()
target_include_directories(iDescriptor PRIVATE target_include_directories(iDescriptor PRIVATE
# Put idevice-rs includes FIRST # Put idevice-rs includes FIRST
${IDEVICE_CPP_INCLUDE_DIR} ${IDEVICE_CPP_INCLUDE_DIR}
@@ -376,7 +341,7 @@ if(APPLE)
${CORE_SERVICES_FRAMEWORK}) ${CORE_SERVICES_FRAMEWORK})
message(STATUS "Using macOS Bonjour framework for network service discovery") message(STATUS "Using macOS Bonjour framework for network service discovery")
elseif (WIN32) elseif (WIN32)
target_link_libraries(iDescriptor PRIVATE PkgConfig::LIBARCHIVE) target_link_libraries(iDescriptor PRIVATE PkgConfig::LIBARCHIVE dwmapi ntdll)
find_path(DNSSD_INCLUDE_DIR dns_sd.h HINTS ${BONJOUR_SDK}/Include ) find_path(DNSSD_INCLUDE_DIR dns_sd.h HINTS ${BONJOUR_SDK}/Include )
# $<$<COMPILE_LANGUAGE:CXX> fixes winres compiler errors # $<$<COMPILE_LANGUAGE:CXX> fixes winres compiler errors
target_include_directories(iDescriptor PRIVATE target_include_directories(iDescriptor PRIVATE
@@ -406,11 +371,6 @@ target_compile_definitions(iDescriptor PRIVATE
SOURCE_DIR="${CMAKE_SOURCE_DIR}" SOURCE_DIR="${CMAKE_SOURCE_DIR}"
) )
# Add compile definition for recovery device support
if(ENABLE_RECOVERY_DEVICE_SUPPORT)
target_compile_definitions(iDescriptor PRIVATE ENABLE_RECOVERY_DEVICE_SUPPORT)
endif()
if(PACKAGE_MANAGER_MANAGED) if(PACKAGE_MANAGER_MANAGED)
target_compile_definitions(iDescriptor PRIVATE PACKAGE_MANAGER_MANAGED) target_compile_definitions(iDescriptor PRIVATE PACKAGE_MANAGER_MANAGED)
message(STATUS "Building as package manager managed version, updates will be handled by the package manager") message(STATUS "Building as package manager managed version, updates will be handled by the package manager")
@@ -435,14 +395,8 @@ set_target_properties(iDescriptor PROPERTIES
WIN32_EXECUTABLE TRUE WIN32_EXECUTABLE TRUE
BUILD_WITH_INSTALL_RPATH TRUE BUILD_WITH_INSTALL_RPATH TRUE
) )
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
# Required on Linux to find libirecovery-1.0.so.5 at runtime
if (ENABLE_RECOVERY_DEVICE_SUPPORT)
set_target_properties(iDescriptor PROPERTIES
# Control library search order - system libs first, then /usr/local/lib
INSTALL_RPATH "/usr/lib/x86_64-linux-gnu:/usr/lib:/usr/local/lib:$ORIGIN"
)
endif()
# Add install rules for the project # Add install rules for the project
# include(GNUInstallDirs) # include(GNUInstallDirs)
+82
View File
@@ -0,0 +1,82 @@
<RCC>
<qresource prefix="/">
<file>resources/win.dark.qcss</file>
<file>resources/win.light.qcss</file>
</qresource>
<qresource prefix="/">
<file>resources/win/dark/CheckBox.png</file>
<file>resources/win/dark/CheckBoxPressed.png</file>
<file>resources/win/dark/ComboBox.png</file>
<file>resources/win/dark/ComboBoxDisabled.png</file>
<file>resources/win/dark/NextMonth.png</file>
<file>resources/win/dark/NextMonthDisabled.png</file>
<file>resources/win/dark/PrevMonth.png</file>
<file>resources/win/dark/PrevMonthDisabled.png</file>
<file>resources/win/dark/RadioButton.png</file>
<file>resources/win/dark/RadioButtonHover.png</file>
<file>resources/win/dark/RadioButtonPressed.png</file>
<file>resources/win/dark/ScrollBottom.png</file>
<file>resources/win/dark/ScrollBottomHover.png</file>
<file>resources/win/dark/ScrollBottomPressed.png</file>
<file>resources/win/dark/ScrollLeft.png</file>
<file>resources/win/dark/ScrollLeftHover.png</file>
<file>resources/win/dark/ScrollLeftPressed.png</file>
<file>resources/win/dark/ScrollRight.png</file>
<file>resources/win/dark/ScrollRightHover.png</file>
<file>resources/win/dark/ScrollRightPressed.png</file>
<file>resources/win/dark/ScrollTop.png</file>
<file>resources/win/dark/ScrollTopHover.png</file>
<file>resources/win/dark/ScrollTopPressed.png</file>
<file>resources/win/dark/SpinBoxDown.png</file>
<file>resources/win/dark/SpinBoxDownDisabled.png</file>
<file>resources/win/dark/SpinBoxUp.png</file>
<file>resources/win/dark/SpinBoxUpDisabled.png</file>
<file>resources/win/dark/ToggleSwitchDisabled.png</file>
<file>resources/win/dark/ToggleSwitchOff.png</file>
<file>resources/win/dark/ToggleSwitchOffHover.png</file>
<file>resources/win/dark/ToggleSwitchOffPressed.png</file>
<file>resources/win/dark/ToggleSwitchOn.png</file>
<file>resources/win/dark/ToggleSwitchOnHover.png</file>
<file>resources/win/dark/ToggleSwitchOnPressed.png</file>
<file>resources/win/dark/TreeViewClose.png</file>
<file>resources/win/dark/TreeViewOpen.png</file>
</qresource>
<qresource prefix="/">
<file>resources/win/light/CheckBox.png</file>
<file>resources/win/light/CheckBoxPressed.png</file>
<file>resources/win/light/ComboBox.png</file>
<file>resources/win/light/ComboBoxDisabled.png</file>
<file>resources/win/light/NextMonth.png</file>
<file>resources/win/light/NextMonthDisabled.png</file>
<file>resources/win/light/PrevMonth.png</file>
<file>resources/win/light/PrevMonthDisabled.png</file>
<file>resources/win/light/RadioButton.png</file>
<file>resources/win/light/RadioButtonHover.png</file>
<file>resources/win/light/RadioButtonPressed.png</file>
<file>resources/win/light/ScrollBottom.png</file>
<file>resources/win/light/ScrollBottomHover.png</file>
<file>resources/win/light/ScrollBottomPressed.png</file>
<file>resources/win/light/ScrollLeft.png</file>
<file>resources/win/light/ScrollLeftHover.png</file>
<file>resources/win/light/ScrollLeftPressed.png</file>
<file>resources/win/light/ScrollRight.png</file>
<file>resources/win/light/ScrollRightHover.png</file>
<file>resources/win/light/ScrollRightPressed.png</file>
<file>resources/win/light/ScrollTop.png</file>
<file>resources/win/light/ScrollTopHover.png</file>
<file>resources/win/light/ScrollTopPressed.png</file>
<file>resources/win/light/SpinBoxDown.png</file>
<file>resources/win/light/SpinBoxDownDisabled.png</file>
<file>resources/win/light/SpinBoxUp.png</file>
<file>resources/win/light/SpinBoxUpDisabled.png</file>
<file>resources/win/light/ToggleSwitchDisabled.png</file>
<file>resources/win/light/ToggleSwitchOff.png</file>
<file>resources/win/light/ToggleSwitchOffHover.png</file>
<file>resources/win/light/ToggleSwitchOffPressed.png</file>
<file>resources/win/light/ToggleSwitchOn.png</file>
<file>resources/win/light/ToggleSwitchOnHover.png</file>
<file>resources/win/light/ToggleSwitchOnPressed.png</file>
<file>resources/win/light/TreeViewClose.png</file>
<file>resources/win/light/TreeViewOpen.png</file>
</qresource>
</RCC>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

+1 -1
View File
@@ -57,7 +57,7 @@
#include "diagnosedialog.h" #include "diagnosedialog.h"
#ifdef WIN32 #ifdef WIN32
#include "platform/windows/check_deps.h" #include "platform/windows/win_common.h"
#endif #endif
#include "toolboxwidget.h" #include "toolboxwidget.h"
+14 -6
View File
@@ -87,18 +87,23 @@ void AppsWidget::setupUI()
QWidget *headerWidget = new QWidget(); QWidget *headerWidget = new QWidget();
headerWidget->setFixedHeight(60); headerWidget->setFixedHeight(60);
headerWidget->setStyleSheet("border-bottom: 1px solid #363d32;"); headerWidget->setStyleSheet(
"border-bottom: 1px solid #363d32; border-radius: 0px;");
QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget); QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget);
headerLayout->setContentsMargins(20, 10, 20, 10); headerLayout->setContentsMargins(20, 10, 20, 10);
// Create status label first // Create status label first
m_statusLabel = new QLabel("Not signed in"); m_statusLabel = new QLabel("Not signed in");
m_statusLabel->setStyleSheet("margin-right: 20px;"); m_statusLabel->setStyleSheet("margin-right: 20px; border: none;");
m_loginButton = new QPushButton(); m_loginButton = new QPushButton();
m_searchEdit = new ZLineEdit(); m_searchEdit = new QLineEdit();
#ifndef WIN32
m_searchEdit->setMaximumWidth(350); m_searchEdit->setMaximumWidth(350);
#else
m_searchEdit->setMaximumWidth(200);
#endif
// --- Status and Login Button --- // --- Status and Login Button ---
m_manager = AppStoreManager::sharedInstance(); m_manager = AppStoreManager::sharedInstance();
@@ -214,7 +219,7 @@ void AppsWidget::handleInit()
} }
/* /*
FIXME: ipatoolinitialze still uses the secure backends FIXME: ipatoolinitialze still uses the secure backends
when if the user rejects it, the moment he/she tries to sign in even if the user rejects it, the moment he/she tries to sign in
prompt(keychain or secret-service whatever the backend is) will be seen prompt(keychain or secret-service whatever the backend is) will be seen
again again
*/ */
@@ -262,10 +267,12 @@ void AppsWidget::onAppStoreInitialized(const QJsonObject &accountInfo)
} }
m_loginButton->setText(m_isLoggedIn ? "Sign Out" : "Sign In"); m_loginButton->setText(m_isLoggedIn ? "Sign Out" : "Sign In");
#ifndef WIN32
m_loginButton->setStyleSheet( m_loginButton->setStyleSheet(
"background-color: #007AFF; color: white; border: none; " "background-color: #007AFF; color: white; border: none; "
"border-radius: " "border-radius: "
"4px; padding: 8px 16px; font-size: 14px;"); "4px; padding: 8px 16px; font-size: 14px;");
#endif
m_searchEdit->setPlaceholderText(m_isLoggedIn ? "Search for apps..." m_searchEdit->setPlaceholderText(m_isLoggedIn ? "Search for apps..."
: "Sign in to search"); : "Sign in to search");
} }
@@ -638,8 +645,9 @@ void AppsWidget::createAppCard(
ZLabel *installLabel = new ZLabel("Install"); ZLabel *installLabel = new ZLabel("Install");
installLabel->setAlignment(Qt::AlignCenter); installLabel->setAlignment(Qt::AlignCenter);
installLabel->setStyleSheet( installLabel->setStyleSheet(
"font-size: 12px; color: #007AFF; font-weight: " QString("font-size: 12px; color: %1; font-weight: "
"bold; background-color: transparent;"); "bold; background-color: transparent;")
.arg(COLOR_ACCENT_BLUE.name()));
installLabel->setCursor(Qt::PointingHandCursor); installLabel->setCursor(Qt::PointingHandCursor);
installLabel->setFixedHeight(30); installLabel->setFixedHeight(30);
+8
View File
@@ -18,8 +18,16 @@
*/ */
#include "tool.h" #include "tool.h"
#ifdef WIN32
#include "../platform/windows/widgets/wintoolwidget.h"
#include "../platform/windows/win_common.h"
#endif
#ifdef WIN32
Tool::Tool(QWidget *parent) : WinToolWidget(parent)
#else
Tool::Tool(QWidget *parent) : QWidget(parent) Tool::Tool(QWidget *parent) : QWidget(parent)
#endif
{ {
#ifdef __APPLE__ #ifdef __APPLE__
setupToolFrame(this); setupToolFrame(this);
+9
View File
@@ -26,7 +26,16 @@
#include "../platform/macos/macos.h" #include "../platform/macos/macos.h"
#endif #endif
#ifdef WIN32
#include "../platform/windows/widgets/wintoolwidget.h"
#endif
#ifdef WIN32
class Tool : public WinToolWidget
#else
class Tool : public QWidget class Tool : public QWidget
#endif
{ {
public: public:
explicit Tool(QWidget *parent = nullptr); explicit Tool(QWidget *parent = nullptr);
+4 -4
View File
@@ -81,7 +81,7 @@ void CableInfoWidget::setupUI()
m_loadingWidget = new ZLoadingWidget(true, this); m_loadingWidget = new ZLoadingWidget(true, this);
m_loadingWidget->setupContentWidget(m_mainLayout); m_loadingWidget->setupContentWidget(m_mainLayout);
QVBoxLayout *layout = new QVBoxLayout(this); QVBoxLayout *layout = new QVBoxLayout(contentWidget());
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_loadingWidget); layout->addWidget(m_loadingWidget);
@@ -230,7 +230,7 @@ void CableInfoWidget::updateUI()
if (!m_cableInfo.isConnected) { if (!m_cableInfo.isConnected) {
m_errorLabel->setText( m_errorLabel->setText(
QString("%1 does not seem to be connected to any cable.") QString("%1 does not seem to be connected to any cable.")
.arg(m_device->deviceInfo.productType)); .arg(QString::fromStdString(m_device->deviceInfo.productType)));
m_loadingWidget->showError(); m_loadingWidget->showError();
return; return;
} }
@@ -243,13 +243,13 @@ void CableInfoWidget::updateUI()
"absolute guarantee of authenticity."); "absolute guarantee of authenticity.");
if (m_cableInfo.isGenuine) { if (m_cableInfo.isGenuine) {
// todo: type-c to type-c // todo: type-c to type-c
statusText = QString("Genuine %1") statusText = QString("Genuine %1")
.arg(m_cableInfo.isTypeC ? "USB-C to Lightning Cable" .arg(m_cableInfo.isTypeC ? "USB-C to Lightning Cable"
: "Lightning Cable"); : "Lightning Cable");
statusStyle = statusStyle =
"QLabel { color: #28a745; font-size: 18px; font-weight: bold; }"; "QLabel { color: #28a745; font-size: 18px; font-weight: bold; }";
} else { } else {
statusText = "⚠️ Third-party Cable"; statusText = "Third-party Cable";
statusStyle = statusStyle =
"QLabel { color: #dc3545; font-size: 18px; font-weight: bold; }"; "QLabel { color: #dc3545; font-size: 18px; font-weight: bold; }";
+2 -1
View File
@@ -126,6 +126,7 @@ void get_device_info_xml(const char *udid, LockdowndClientHandle *client,
if (xml_string) { if (xml_string) {
infoXml.load_string(xml_string); infoXml.load_string(xml_string);
free(xml_string); // FIXME: crashes on Windows
// free(xml_string);
} }
} }
+9 -3
View File
@@ -26,12 +26,18 @@
#endif #endif
#include "../../heartbeat.h" #include "../../heartbeat.h"
#include <QDebug> #include <QDebug>
#ifdef _WIN32
#include "../../platform/windows/win_common.h"
#else
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sstream>
#include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#endif
#include <sstream>
#include <string.h>
std::string safeGetXML(const char *key, pugi::xml_node dict) std::string safeGetXML(const char *key, pugi::xml_node dict)
{ {
@@ -453,7 +459,7 @@ void init_idescriptor_device(const iDescriptor::Uniq &uniq,
heartbeatThread->start(); heartbeatThread->start();
while (!heartbeatThread->initialCompleted()) { while (!heartbeatThread->initialCompleted()) {
sleep(1); // sleep(1);
} }
} else { } else {
+17 -11
View File
@@ -25,7 +25,6 @@
#include "iDescriptor.h" #include "iDescriptor.h"
#include "infolabel.h" #include "infolabel.h"
#include "privateinfolabel.h" #include "privateinfolabel.h"
// #include "toolboxwidget.h"
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QGraphicsDropShadowEffect> #include <QGraphicsDropShadowEffect>
@@ -146,13 +145,14 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
m_chargingStatusLabel = m_chargingStatusLabel =
new QLabel(device->deviceInfo.batteryInfo.isCharging ? "Charging" new QLabel(device->deviceInfo.batteryInfo.isCharging ? "Charging"
: "Not Charging"); : "Not Charging");
m_chargingStatusLabel->setObjectName("ChargingStatusLabel");
m_chargingStatusLabel->setStyleSheet( m_chargingStatusLabel->setStyleSheet(mergeStyles(
device->deviceInfo.batteryInfo.isCharging m_chargingStatusLabel,
? QString("color: %1;").arg(COLOR_GREEN.name()) (device->deviceInfo.batteryInfo.isCharging
: QString("color: %1;") ? QString("QLabel#ChargingStatusLabel { color: %1; }")
.arg(qApp->palette().color(QPalette::WindowText).name())); .arg(COLOR_GREEN.name())
: QString("QLabel#ChargingStatusLabel { color: %1; }")
.arg(qApp->palette().color(QPalette::WindowText).name()))));
// Create the layout without a parent widget // Create the layout without a parent widget
QHBoxLayout *chargingLayout = new QHBoxLayout(); QHBoxLayout *chargingLayout = new QHBoxLayout();
chargingLayout->setContentsMargins(0, 0, 0, 0); chargingLayout->setContentsMargins(0, 0, 0, 0);
@@ -314,7 +314,11 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
for (int i = 0; i < numRows; ++i) { for (int i = 0; i < numRows; ++i) {
// Left column item // Left column item
QLabel *keyLabelLeft = new QLabel(infoItems[i].first); QLabel *keyLabelLeft = new QLabel(infoItems[i].first);
#ifndef WIN32
keyLabelLeft->setStyleSheet("font-weight: bold;"); keyLabelLeft->setStyleSheet("font-weight: bold;");
#else
keyLabelLeft->setStyleSheet("font-size: 15px; font-weight: 500;");
#endif
gridLayout->addWidget(keyLabelLeft, i, 0); gridLayout->addWidget(keyLabelLeft, i, 0);
gridLayout->addWidget(infoItems[i].second, i, 1); gridLayout->addWidget(infoItems[i].second, i, 1);
@@ -322,7 +326,11 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
int rightIndex = i + numRows; int rightIndex = i + numRows;
if (rightIndex < infoItems.size()) { if (rightIndex < infoItems.size()) {
QLabel *keyLabelRight = new QLabel(infoItems[rightIndex].first); QLabel *keyLabelRight = new QLabel(infoItems[rightIndex].first);
#ifndef WIN32
keyLabelRight->setStyleSheet("font-weight: bold;"); keyLabelRight->setStyleSheet("font-weight: bold;");
#else
keyLabelRight->setStyleSheet("font-size: 15px; font-weight: 500;");
#endif
gridLayout->addWidget(keyLabelRight, i, 2); gridLayout->addWidget(keyLabelRight, i, 2);
gridLayout->addWidget(infoItems[rightIndex].second, i, 3); gridLayout->addWidget(infoItems[rightIndex].second, i, 3);
} }
@@ -348,8 +356,6 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
rightSideLayout->addWidget(new DiskUsageWidget(device, this)); rightSideLayout->addWidget(new DiskUsageWidget(device, this));
rightSideLayout->addStretch(); rightSideLayout->addStretch();
// // TODO: layout shift cause ?
// // rightSideLayout->setAlignment(Qt::AlignCenter);
mainLayout->addLayout(rightSideLayout); mainLayout->addLayout(rightSideLayout);
mainLayout->addStretch(); mainLayout->addStretch();
@@ -420,4 +426,4 @@ void DeviceInfoWidget::updateChargingStatusIcon()
// m_chargingStatusLabel->setStyleSheet(""); // m_chargingStatusLabel->setStyleSheet("");
// m_lightningIconLabel->hide(); // m_lightningIconLabel->hide();
// } // }
} }
+76 -52
View File
@@ -39,6 +39,7 @@ DeviceSidebarItem::DeviceSidebarItem(const QString &deviceName,
setFrameStyle(QFrame::StyledPanel); setFrameStyle(QFrame::StyledPanel);
setLineWidth(1); setLineWidth(1);
updateToggleButton(); updateToggleButton();
setObjectName("DeviceSidebarItem");
} }
void DeviceSidebarItem::setupUI() void DeviceSidebarItem::setupUI()
@@ -59,7 +60,9 @@ void DeviceSidebarItem::setupUI()
QHBoxLayout *nameLayout = new QHBoxLayout(); QHBoxLayout *nameLayout = new QHBoxLayout();
nameLayout->setContentsMargins(0, 0, 0, 0); nameLayout->setContentsMargins(0, 0, 0, 0);
m_deviceLabel = new QLabel(m_deviceName); m_deviceLabel = new QLabel(m_deviceName);
#ifndef WIN32
m_deviceLabel->setStyleSheet("QLabel { font-weight: bold; }"); m_deviceLabel->setStyleSheet("QLabel { font-weight: bold; }");
#endif
m_deviceLabel->setWordWrap(true); m_deviceLabel->setWordWrap(true);
nameLayout->addWidget(m_deviceLabel); nameLayout->addWidget(m_deviceLabel);
if (m_wireless) { if (m_wireless) {
@@ -78,6 +81,9 @@ void DeviceSidebarItem::setupUI()
m_toggleButton->setStyleSheet("QPushButton { " m_toggleButton->setStyleSheet("QPushButton { "
" text-align: left; " " text-align: left; "
" padding: 2px 5px; " " padding: 2px 5px; "
#ifdef WIN32
" min-height: 0; "
#endif
" border: none; " " border: none; "
" color: #666; " " color: #666; "
" font-size: 11px; " " font-size: 11px; "
@@ -121,6 +127,9 @@ void DeviceSidebarItem::setupUI()
QString("QPushButton { " QString("QPushButton { "
" background-color: rgba(255, 255, 255, 120); " " background-color: rgba(255, 255, 255, 120); "
" border: 1px solid rgba(255, 255, 255, 200); " " border: 1px solid rgba(255, 255, 255, 200); "
#ifdef WIN32
" min-height: 0; "
#endif
" padding: 4px 8px; " " padding: 4px 8px; "
" text-align: center; " " text-align: center; "
" border-radius: 6px; " " border-radius: 6px; "
@@ -159,7 +168,20 @@ void DeviceSidebarItem::setupUI()
setSelected(false); setSelected(false);
} }
void DeviceSidebarItem::setSelected(bool selected) { m_selected = selected; } void DeviceSidebarItem::setSelected(bool selected)
{
m_selected = selected;
if (selected) {
setStyleSheet(
"QFrame#DeviceSidebarItem { background-color: rgba(255, "
"255, 255, 45); }");
} else {
setStyleSheet(
"QFrame#DeviceSidebarItem { background-color: rgba(255, "
"255, 255, 16); }");
}
}
void DeviceSidebarItem::setCollapsed(bool collapsed) void DeviceSidebarItem::setCollapsed(bool collapsed)
{ {
@@ -452,68 +474,70 @@ void DevicePendingSidebarItem::mousePressEvent(QMouseEvent *event)
} }
// FIXME: better move this to a separate file // FIXME: better move this to a separate file
void DeviceSidebarItem::paintEvent(QPaintEvent *event) // void DeviceSidebarItem::paintEvent(QPaintEvent *event)
{ // {
Q_UNUSED(event); // Q_UNUSED(event);
QPainter p(this); // QPainter p(this);
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); // p.setRenderHints(QPainter::Antialiasing |
// QPainter::SmoothPixmapTransform);
const qreal dpr = devicePixelRatioF(); // const qreal dpr = devicePixelRatioF();
const int w = width(); // const int w = width();
const int h = height(); // const int h = height();
const int sw = int(w * dpr); // const int sw = int(w * dpr);
const int sh = int(h * dpr); // const int sh = int(h * dpr);
constexpr int kCornerRadius = 10; // constexpr int kCornerRadius = 10;
constexpr int kBlurRadius = 2; // constexpr int kBlurRadius = 2;
// Cache the blurred background per size // // Cache the blurred background per size
static QPixmap cachedBg; // static QPixmap cachedBg;
static QSize cachedSize; // static QSize cachedSize;
const QSize cacheSize(sw, sh); // const QSize cacheSize(sw, sh);
if (cachedSize != cacheSize) { // if (cachedSize != cacheSize) {
cachedSize = cacheSize; // cachedSize = cacheSize;
QPixmap gradPm(sw, sh); // QPixmap gradPm(sw, sh);
gradPm.fill(Qt::transparent); // gradPm.fill(Qt::transparent);
{ // {
QPainter gp(&gradPm); // QPainter gp(&gradPm);
gp.setRenderHints(QPainter::Antialiasing | // gp.setRenderHints(QPainter::Antialiasing |
QPainter::SmoothPixmapTransform); // QPainter::SmoothPixmapTransform);
QLinearGradient grad(0, 0, 1, 1); // QLinearGradient grad(0, 0, 1, 1);
grad.setCoordinateMode(QGradient::ObjectMode); // grad.setCoordinateMode(QGradient::ObjectMode);
grad.setStops({{0.0, QColor(255, 255, 255, 255)}, // grad.setStops({{0.0, QColor(255, 255, 255, 255)},
{0.35, QColor(255, 255, 255, 125)}, // {0.35, QColor(255, 255, 255, 125)},
{0.65, QColor(255, 255, 255, 125)}, // {0.65, QColor(255, 255, 255, 125)},
{1.0, QColor(255, 255, 255, 255)}}); // {1.0, QColor(255, 255, 255, 255)}});
gp.fillRect(QRectF(0, 0, sw, sh), grad); // gp.fillRect(QRectF(0, 0, sw, sh), grad);
} // }
QPixmap blurred = BackDrop::blurPixmap(gradPm, kBlurRadius); // QPixmap blurred = BackDrop::blurPixmap(gradPm, kBlurRadius);
QPixmap mask = BackDrop::getColoredPixmap( // QPixmap mask = BackDrop::getColoredPixmap(
QBrush(Qt::white), Qt::white, 1, sw, sh, int(kCornerRadius * dpr)); // QBrush(Qt::white), Qt::white, 1, sw, sh, int(kCornerRadius *
// dpr));
BackDrop::cutPixmap(blurred, mask, sw, sh); // BackDrop::cutPixmap(blurred, mask, sw, sh);
blurred.setDevicePixelRatio(dpr); // blurred.setDevicePixelRatio(dpr);
cachedBg = blurred; // cachedBg = blurred;
} // }
QPainterPath clipPath; // QPainterPath clipPath;
QRectF r = rect().adjusted(0.5, 0.5, -0.5, -0.5); // QRectF r = rect().adjusted(0.5, 0.5, -0.5, -0.5);
clipPath.addRoundedRect(r, kCornerRadius, kCornerRadius); // clipPath.addRoundedRect(r, kCornerRadius, kCornerRadius);
p.setClipPath(clipPath); // p.setClipPath(clipPath);
p.drawPixmap(r.toRect(), cachedBg); // p.drawPixmap(r.toRect(), cachedBg);
p.setClipping(false); // p.setClipping(false);
QColor borderColor = m_selected ? COLOR_BLUE : QColor("#FFFFFF"); // QColor borderColor = m_selected ? COLOR_BLUE : QColor("#FFFFFF");
QPen pen(borderColor, m_selected ? 2.0 : 1.0); // QPen pen(borderColor, m_selected ? 2.0 : 1.0);
p.setPen(pen); // p.setPen(pen);
p.setBrush(Qt::NoBrush); // p.setBrush(Qt::NoBrush);
p.drawRoundedRect(r, kCornerRadius, kCornerRadius); // p.drawRoundedRect(r, kCornerRadius, kCornerRadius);
} // }
+2 -2
View File
@@ -45,8 +45,8 @@ public:
void setCollapsed(bool collapsed); void setCollapsed(bool collapsed);
bool isCollapsed() const { return m_collapsed; } bool isCollapsed() const { return m_collapsed; }
protected: // protected:
void paintEvent(QPaintEvent *event) override; // void paintEvent(QPaintEvent *event) override;
signals: signals:
void deviceSelected(const std::string &uuid); void deviceSelected(const std::string &uuid);
void navigationRequested(const std::string &uuid, const QString &section); void navigationRequested(const std::string &uuid, const QString &section);
+24 -7
View File
@@ -19,10 +19,11 @@
#include "diagnosewidget.h" #include "diagnosewidget.h"
#ifdef WIN32 #ifdef WIN32
#include "platform/windows/check_deps.h" #include "platform/windows/win_common.h"
#include <archive.h> #include <archive.h>
#include <archive_entry.h> #include <archive_entry.h>
#endif #endif
#include "iDescriptor-ui.h"
#include <QApplication> #include <QApplication>
#include <QCoreApplication> #include <QCoreApplication>
#include <QCryptographicHash> #include <QCryptographicHash>
@@ -97,21 +98,37 @@ void DependencyItem::setInstalled(bool installed)
if (installed) { if (installed) {
if (m_name == "Avahi Daemon") { if (m_name == "Avahi Daemon") {
m_statusLabel->setText("✓ Activated"); m_statusLabel->setText("Activated");
} else { } else {
m_statusLabel->setText("✓ Installed"); m_statusLabel->setText("Installed");
} }
m_statusLabel->setStyleSheet("color: green; font-weight: bold;"); #ifndef WIN32
m_statusLabel->setStyleSheet("color: green;");
#else
// FIXME: if we call this multiple times, the styles will keep stacking
// and become a mess, need a better way to handle this
m_statusLabel->setStyleSheet(mergeStyles(
m_statusLabel,
QString("QLabel { color: %1; }").arg(COLOR_GREEN.name())));
#endif
m_installButton->setVisible(false); m_installButton->setVisible(false);
} else { } else {
if (m_name == "Avahi Daemon") { if (m_name == "Avahi Daemon") {
m_statusLabel->setText("Not activated"); m_statusLabel->setText("Not activated");
m_installButton->setText("Enable"); m_installButton->setText("Enable");
} else { } else {
m_statusLabel->setText("Not Installed"); m_statusLabel->setText("Not Installed");
m_installButton->setText("Install"); m_installButton->setText("Install");
} }
m_statusLabel->setStyleSheet("color: red; font-weight: bold;"); #ifndef WIN32
m_statusLabel->setStyleSheet("color: red;");
#else
// FIXME: if we call this multiple times, the styles will keep stacking
// and become a mess, need a better way to handle this
m_statusLabel->setStyleSheet(mergeStyles(
m_statusLabel,
QString("QLabel { color: %1; }").arg(COLOR_RED.name())));
#endif
m_installButton->setVisible(true); m_installButton->setVisible(true);
} }
} }
+9 -6
View File
@@ -143,22 +143,25 @@ void DiskUsageWidget::setupUI()
// Set colors // Set colors
m_systemBar->setStyleSheet( m_systemBar->setStyleSheet(
"QWidget#systemBar { background-color: #a1384d; border: 1px solid" "QWidget#systemBar { background-color: #a1384d; border: 1px solid"
"#e64a5b; padding: 0; margin: 0; border-top-left-radius: 3px; " "#e64a5b; padding: 0; margin: 0; border-radius:0px; "
"border-top-left-radius: 3px; "
"border-bottom-left-radius: 3px; }"); "border-bottom-left-radius: 3px; }");
m_appsBar->setStyleSheet( m_appsBar->setStyleSheet(
"QWidget#appsBar { background-color: #4f869f; border: 1px solid " "QWidget#appsBar { background-color: #4f869f; border: 1px solid "
"#63b4da; padding: 0; margin: 0; }"); "#63b4da; border-radius:0px; padding: 0; margin: 0; }");
m_mediaBar->setStyleSheet("QWidget#mediaBar { background-color: #2ECC71; " m_mediaBar->setStyleSheet("QWidget#mediaBar { background-color: #2ECC71; "
"border: none; padding: 0; margin: 0; }"); "border: none; padding: 0; margin: 0; }");
m_galleryBar->setStyleSheet( m_galleryBar->setStyleSheet(
"QWidget#galleryBar { background-color: #9b59b6; border: 1px solid " "QWidget#galleryBar { background-color: #9b59b6; border: 1px solid "
"#8e44ad; padding: 0; margin: 0; }"); "#8e44ad; border-radius:0px; padding: 0; margin: 0; }");
m_othersBar->setStyleSheet( m_othersBar->setStyleSheet(
"QWidget#othersBar { background-color: #a28729; border: 1px solid " "QWidget#othersBar { background-color: #a28729; border: 1px solid "
"#c4a32d; padding: 0; margin: 0; }"); "#c4a32d; border-radius:0px; padding: 0; margin: 0; }");
m_freeBar->setStyleSheet( m_freeBar->setStyleSheet(
"QWidget#freeBar { background-color: #474747; border: 1px solid " "QWidget#freeBar { background-color: rgba(255, 255, 255, 10); border: "
"#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; " "1px solid "
"#4f4f4f4f; padding: 0; margin: 0; border-radius:0px; "
"border-top-right-radius: 3px; "
"border-bottom-right-radius: 3px; }"); "border-bottom-right-radius: 3px; }");
// remove padding margin from layout // remove padding margin from layout
+4 -4
View File
@@ -239,12 +239,12 @@ QString HttpServer::generateJsonManifest() const
QString HttpServer::getLocalIP() const QString HttpServer::getLocalIP() const
{ {
foreach (const QNetworkInterface &interface, foreach (const QNetworkInterface &netIf,
QNetworkInterface::allInterfaces()) { QNetworkInterface::allInterfaces()) {
if (interface.flags().testFlag(QNetworkInterface::IsUp) && if (netIf.flags().testFlag(QNetworkInterface::IsUp) &&
!interface.flags().testFlag(QNetworkInterface::IsLoopBack)) { !netIf.flags().testFlag(QNetworkInterface::IsLoopBack)) {
foreach (const QNetworkAddressEntry &entry, foreach (const QNetworkAddressEntry &entry,
interface.addressEntries()) { netIf.addressEntries()) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
return entry.ip().toString(); return entry.ip().toString();
} }
+22
View File
@@ -40,13 +40,35 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include "./platform/macos/macos.h" #include "./platform/macos/macos.h"
#elif defined(WIN32)
#include "./platform/windows/win_common.h"
#endif #endif
#define COLOR_GREEN QColor(0, 180, 0) // Green #define COLOR_GREEN QColor(0, 180, 0) // Green
#define COLOR_ORANGE QColor(255, 140, 0) // Orange #define COLOR_ORANGE QColor(255, 140, 0) // Orange
#define COLOR_RED QColor(255, 0, 0) // Red #define COLOR_RED QColor(255, 0, 0) // Red
#define COLOR_BLUE QColor("#2b5693") #define COLOR_BLUE QColor("#2b5693")
#ifndef WIN32
#define COLOR_ACCENT_BLUE QColor("#0b5ed7") #define COLOR_ACCENT_BLUE QColor("#0b5ed7")
#define COLOR_HYPERLINK QColor(0, 122, 255)
#else
#define COLOR_ACCENT_BLUE QColor(getWindowsAccentColor())
#define COLOR_HYPERLINK QColor("#FF7FFFD4")
#endif
inline QString mergeStyles(QWidget *widget, const QString &newStyles)
{
if (!widget) {
return newStyles;
}
QString existing = widget->styleSheet();
if (existing.isEmpty())
return newStyles;
return existing + "\n" + newStyles;
}
#define MIN_MAIN_WINDOW_SIZE QSize(900, 600) #define MIN_MAIN_WINDOW_SIZE QSize(900, 600)
class ResponsiveGraphicsView : public QGraphicsView class ResponsiveGraphicsView : public QGraphicsView
+5 -3
View File
@@ -355,7 +355,7 @@ public:
plist_get_string_val(current_node, &value); plist_get_string_val(current_node, &value);
std::string result = value ? value : ""; std::string result = value ? value : "";
if (value) if (value)
free(value); plist_mem_free(value);
return result; return result;
} }
plist_t getNode() const { return current_node; } plist_t getNode() const { return current_node; }
@@ -605,10 +605,12 @@ inline void free_directory_listing(char **entries, size_t count)
return; return;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
if (entries[i]) { if (entries[i]) {
free(entries[i]); // FIXME: crashes on Windows
// free(entries[i]);
} }
} }
free(entries); // FIXME: crashes on Windows
// free(entries);
} }
inline int read_file(const char *filename, uint8_t **data, size_t *length) inline int read_file(const char *filename, uint8_t **data, size_t *length)
+1 -1
View File
@@ -30,7 +30,7 @@
#include <QStatusBar> #include <QStatusBar>
#include <QTimer> #include <QTimer>
#ifdef WIN32 #ifdef WIN32
#include "platform/windows/check_deps.h" #include "platform/windows/win_common.h"
#endif #endif
iFuseWidget::iFuseWidget(iDescriptorDevice *device, QWidget *parent) iFuseWidget::iFuseWidget(iDescriptorDevice *device, QWidget *parent)
+9 -24
View File
@@ -29,9 +29,7 @@ InfoLabel::InfoLabel(const QString &text, const QString &textToCopy,
m_textToCopy(!textToCopy.isEmpty() ? textToCopy : text) m_textToCopy(!textToCopy.isEmpty() ? textToCopy : text)
{ {
setCursor(Qt::PointingHandCursor); setCursor(Qt::PointingHandCursor);
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); " setStyleSheet(m_style);
"border-radius: 2px; }");
m_restoreTimer = new QTimer(this); m_restoreTimer = new QTimer(this);
m_restoreTimer->setSingleShot(true); m_restoreTimer->setSingleShot(true);
connect(m_restoreTimer, &QTimer::timeout, this, connect(m_restoreTimer, &QTimer::timeout, this,
@@ -49,39 +47,26 @@ void InfoLabel::mousePressEvent(QMouseEvent *event)
// prevent layout shifts // prevent layout shifts
setMinimumWidth(originalWidth); setMinimumWidth(originalWidth);
setText("Copied!"); setText("Copied!");
#ifdef WIN32
setStyleSheet(QStringLiteral(
"QLabel { color: #4CAF50; font-weight: bold; font-size: 14px; }"
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
"border-radius: 2px; }"));
#else
setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; } " setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; } "
"QLabel:hover { background-color: rgba(255, 255, 255, " "QLabel:hover { background-color: rgba(255, 255, 255, "
"0.1); border-radius: 2px; }"); "0.1); border-radius: 2px; }");
#endif
m_restoreTimer->start(1000); // Show "Copied!" for 1 second m_restoreTimer->start(1000); // Show "Copied!" for 1 second
} }
QLabel::mousePressEvent(event); QLabel::mousePressEvent(event);
} }
void InfoLabel::enterEvent(QEnterEvent *event)
{
if (!m_restoreTimer->isActive()) {
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, "
"0.1); border-radius: 2px; }");
}
QLabel::enterEvent(event);
}
void InfoLabel::leaveEvent(QEvent *event)
{
if (!m_restoreTimer->isActive()) {
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, "
"0.1); border-radius: 2px; }");
}
QLabel::leaveEvent(event);
}
void InfoLabel::restoreOriginalText() void InfoLabel::restoreOriginalText()
{ {
setText(m_originalText); setText(m_originalText);
setMinimumWidth(0); setMinimumWidth(0);
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); " setStyleSheet(m_style);
"border-radius: 2px; }");
} }
void InfoLabel::setOriginalText(const QString &text) { m_originalText = text; } void InfoLabel::setOriginalText(const QString &text) { m_originalText = text; }
+13 -2
View File
@@ -21,6 +21,7 @@
#define INFOLABEL_H #define INFOLABEL_H
#include <QLabel> #include <QLabel>
#include <QString>
#include <QTimer> #include <QTimer>
class InfoLabel : public QLabel class InfoLabel : public QLabel
@@ -37,8 +38,6 @@ public:
protected: protected:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
private slots: private slots:
void restoreOriginalText(); void restoreOriginalText();
@@ -47,6 +46,18 @@ private:
QString m_originalText; QString m_originalText;
QString m_textToCopy; QString m_textToCopy;
QTimer *m_restoreTimer; QTimer *m_restoreTimer;
QString m_style =
#ifdef WIN32
QStringLiteral(
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
"border-radius: 2px; }"
"QLabel { "
"font-size: 14px;}");
#else
QStringLiteral(
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
"border-radius: 2px; }");
#endif
}; };
#endif // INFOLABEL_H #endif // INFOLABEL_H
+3 -3
View File
@@ -322,7 +322,7 @@ void InstalledAppsWidget::fetchInstalledApps()
plist_get_string_val(bundle_id, &bundle_id_str); plist_get_string_val(bundle_id, &bundle_id_str);
if (bundle_id_str) { if (bundle_id_str) {
appData["bundleId"] = QString(bundle_id_str); appData["bundleId"] = QString(bundle_id_str);
free(bundle_id_str); plist_mem_free(bundle_id_str);
} }
} }
@@ -337,7 +337,7 @@ void InstalledAppsWidget::fetchInstalledApps()
if (display_name_str) { if (display_name_str) {
appData["displayName"] = appData["displayName"] =
QString(display_name_str); QString(display_name_str);
free(display_name_str); plist_mem_free(display_name_str);
} }
} }
@@ -350,7 +350,7 @@ void InstalledAppsWidget::fetchInstalledApps()
plist_get_string_val(version, &version_str); plist_get_string_val(version, &version_str);
if (version_str) { if (version_str) {
appData["version"] = QString(version_str); appData["version"] = QString(version_str);
free(version_str); plist_mem_free(version_str);
} }
} }
+22 -9
View File
@@ -30,12 +30,20 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#ifdef WIN32
#include "platform/windows/win_common.h"
#endif
LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent) LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
{ {
setWindowTitle("Login to App Store - iDescriptor"); setWindowTitle("Login to App Store - iDescriptor");
setModal(true); setModal(true);
setFixedWidth(400); setFixedWidth(400);
#ifdef WIN32
setupWinWindow(this);
#endif
QVBoxLayout *layout = new QVBoxLayout(this); QVBoxLayout *layout = new QVBoxLayout(this);
layout->setSpacing(15); layout->setSpacing(15);
layout->setContentsMargins(20, 20, 20, 20); layout->setContentsMargins(20, 20, 20, 20);
@@ -47,8 +55,11 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
m_emailEdit = new QLineEdit(); m_emailEdit = new QLineEdit();
m_emailEdit->setPlaceholderText("Enter your email"); m_emailEdit->setPlaceholderText("Enter your email");
#ifndef WIN32
m_emailEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; " m_emailEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; "
"border-radius: 4px; font-size: 14px;"); "border-radius: 4px; font-size: 14px;");
#endif
layout->addWidget(m_emailEdit); layout->addWidget(m_emailEdit);
// Password // Password
@@ -59,33 +70,35 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
m_passwordEdit = new QLineEdit(); m_passwordEdit = new QLineEdit();
m_passwordEdit->setPlaceholderText("Enter your password"); m_passwordEdit->setPlaceholderText("Enter your password");
m_passwordEdit->setEchoMode(QLineEdit::Password); m_passwordEdit->setEchoMode(QLineEdit::Password);
#ifndef WIN32
m_passwordEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; " m_passwordEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; "
"border-radius: 4px; font-size: 14px;"); "border-radius: 4px; font-size: 14px;");
#endif
layout->addWidget(m_passwordEdit); layout->addWidget(m_passwordEdit);
// Description // Description
QLabel *descriptionLabel = QLabel *descriptionLabel = new QLabel(
new QLabel("Don't worry, your credentials won't be " "You shouldn't be using your main account here and don't worry, "
"stored or shared anywhere. This App is open-source."); "your credentials won't be "
"stored or shared anywhere. This App is open-source.");
descriptionLabel->setStyleSheet("font-size: 10px; font-weight: thin;"); descriptionLabel->setStyleSheet("font-size: 10px; font-weight: thin;");
descriptionLabel->setAlignment(Qt::AlignLeft); descriptionLabel->setAlignment(Qt::AlignLeft);
descriptionLabel->setWordWrap(true); // Add this line descriptionLabel->setWordWrap(true);
layout->addWidget(descriptionLabel); layout->addWidget(descriptionLabel);
// --- Buttons and Indicator ---
// Create a container widget for the sign-in button and the indicator
QWidget *signInContainer = new QWidget(this); QWidget *signInContainer = new QWidget(this);
m_signInStackedLayout = new QStackedLayout(signInContainer); m_signInStackedLayout = new QStackedLayout(signInContainer);
m_signInStackedLayout->setContentsMargins(0, 0, 0, 0); m_signInStackedLayout->setContentsMargins(0, 0, 0, 0);
// Create the actual "Sign In" button // Create the actual "Sign In" button
m_signInButton = new QPushButton("Sign In"); m_signInButton = new QPushButton("Sign In");
#ifndef WIN32
m_signInButton->setStyleSheet( m_signInButton->setStyleSheet(
"QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; " "QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; "
"background-color: #007AFF; color: white; border: none; min-width: " "background-color: #007AFF; color: white; border: none; min-width: "
"80px; }" "80px; }"
"QPushButton:hover { background-color: #0056CC; }"); "QPushButton:hover { background-color: #0056CC; }");
#endif
// Create the indicator // Create the indicator
QWidget *indicatorWidget = new QWidget(); QWidget *indicatorWidget = new QWidget();
QVBoxLayout *indicatorLayout = new QVBoxLayout(indicatorWidget); QVBoxLayout *indicatorLayout = new QVBoxLayout(indicatorWidget);
@@ -103,15 +116,15 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
// Ensure the container has the same size as the button // Ensure the container has the same size as the button
signInContainer->setFixedSize(m_signInButton->sizeHint()); signInContainer->setFixedSize(m_signInButton->sizeHint());
// Create the "Cancel" button
m_cancelButton = new QPushButton("Cancel"); m_cancelButton = new QPushButton("Cancel");
// add disabled style to cancel button #ifndef WIN32
m_cancelButton->setStyleSheet( m_cancelButton->setStyleSheet(
"QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; " "QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; "
"background-color: #f0f0f0; color: #333; border: 1px solid #ddd; " "background-color: #f0f0f0; color: #333; border: 1px solid #ddd; "
"min-width: 80px; }" "min-width: 80px; }"
"QPushButton:disabled { background-color: #eee; color: #aaa; border: " "QPushButton:disabled { background-color: #eee; color: #aaa; border: "
"1px solid #ddd; }"); "1px solid #ddd; }");
#endif
// Layout for the buttons // Layout for the buttons
QHBoxLayout *buttonLayout = new QHBoxLayout(); QHBoxLayout *buttonLayout = new QHBoxLayout();
+12 -2
View File
@@ -23,14 +23,15 @@
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFile>
#include <QMessageBox> #include <QMessageBox>
#include <QStyleFactory> #include <QStyleFactory>
#include <QtGlobal> #include <QtGlobal>
#include <stdlib.h> #include <stdlib.h>
#ifdef WIN32 #ifdef WIN32
#include "platform/windows/check_deps.h" #include "platform/windows/win_common.h"
#endif #endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
@@ -45,6 +46,15 @@ int main(int argc, char *argv[])
// " "their default values."); // " "their default values.");
// } // }
#ifdef WIN32 #ifdef WIN32
QFile styleFile(detectDarkModeWindows() ? ":/resources/win.dark.qcss"
: ":/resources/win.light.qcss");
if (styleFile.open(QFile::ReadOnly | QFile::Text)) {
const QString style = QString::fromUtf8(styleFile.readAll())
.arg(COLOR_ACCENT_BLUE.name());
qDebug() << "Loaded Windows style sheet successfully.";
a.setStyleSheet(style);
}
QString appPath = QCoreApplication::applicationDirPath(); QString appPath = QCoreApplication::applicationDirPath();
QString gstPluginPath = QString gstPluginPath =
QDir::toNativeSeparators(appPath + "/gstreamer-1.0"); QDir::toNativeSeparators(appPath + "/gstreamer-1.0");
+35 -104
View File
@@ -18,7 +18,6 @@
*/ */
#include "mainwindow.h" #include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "appswidget.h" #include "appswidget.h"
#include "devicemanagerwidget.h" #include "devicemanagerwidget.h"
#include "iDescriptor-ui.h" #include "iDescriptor-ui.h"
@@ -26,9 +25,6 @@
#include "ifusediskunmountbutton.h" #include "ifusediskunmountbutton.h"
#include "ifusemanager.h" #include "ifusemanager.h"
#include "jailbrokenwidget.h" #include "jailbrokenwidget.h"
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
// #include "libirecovery.h"
// #endif
#include "toolboxwidget.h" #include "toolboxwidget.h"
#include "welcomewidget.h" #include "welcomewidget.h"
#include <QHBoxLayout> #include <QHBoxLayout>
@@ -51,112 +47,38 @@
#include <QMenu> #include <QMenu>
#include <QMenuBar> #include <QMenuBar>
#include <QMessageBox> #include <QMessageBox>
#ifdef WIN32 #ifdef WIN32
#include "platform/windows/check_deps.h" #include "platform/windows/win_common.h"
#endif #endif
using namespace IdeviceFFI; using namespace IdeviceFFI;
// void handleCallback(const idevice_event_t *event, void *userData)
// {
// printf("Device event received: ");
// switch (event->event) {
// case IDEVICE_DEVICE_ADD: {
// /* this should never happen iDescriptor does not support network
// devices but for some reason even though we are only listening for USB
// devices, we still get network devices on macOS*/ if (event->conn_type
// == CONNECTION_NETWORK) {
// return;
// }
// qDebug() << "Device added: " << QString::fromUtf8(event->udid);
// QMetaObject::invokeMethod(
// AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
// Q_ARG(QString, QString::fromUtf8(event->udid)),
// Q_ARG(idevice_connection_type, event->conn_type),
// Q_ARG(AddType, AddType::Regular));
// break;
// }
// case IDEVICE_DEVICE_REMOVE: {
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
// "removeDevice",
// Qt::QueuedConnection,
// Q_ARG(QString, QString(event->udid)));
// break;
// }
// case IDEVICE_DEVICE_PAIRED: {
// if (event->conn_type == CONNECTION_NETWORK) {
// qDebug()
// << "Network devices are not supported but a network device
// was "
// "received in event listener. Please report this issue.";
// return;
// }
// qDebug() << "Device paired: " << QString::fromUtf8(event->udid);
// QMetaObject::invokeMethod(
// AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
// Q_ARG(QString, QString::fromUtf8(event->udid)),
// Q_ARG(idevice_connection_type, event->conn_type),
// Q_ARG(AddType, AddType::Pairing));
// break;
// }
// default:
// qDebug() << "Unhandled event: " << event->event;
// }
// }
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
// void handleCallbackRecovery(const irecv_device_event_t *event, void
// *userData)
// {
// switch (event->type) {
// case IRECV_DEVICE_ADD:
// qDebug() << "Recovery device added: ";
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
// "addRecoveryDevice", Qt::QueuedConnection,
// Q_ARG(uint64_t, event->device_info->ecid));
// break;
// case IRECV_DEVICE_REMOVE:
// qDebug() << "Recovery device removed: ";
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
// "removeRecoveryDevice",
// Qt::QueuedConnection, Q_ARG(uint64_t,
// event->device_info->ecid));
// break;
// default:
// printf("Unhandled recovery event: %d\n", event->type);
// }
// }
// irecv_device_event_context_t context;
// #endif
MainWindow *MainWindow::sharedInstance() MainWindow *MainWindow::sharedInstance()
{ {
static MainWindow instance; static MainWindow instance;
return &instance; return &instance;
} }
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{ {
ui->setupUi(this);
setMinimumSize(MIN_MAIN_WINDOW_SIZE); setMinimumSize(MIN_MAIN_WINDOW_SIZE);
resize(MIN_MAIN_WINDOW_SIZE); resize(MIN_MAIN_WINDOW_SIZE);
m_ZTabWidget = new ZTabWidget(this);
m_ZTabWidget->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
setContentsMargins(0, 0, 0, 0); setContentsMargins(0, 0, 0, 0);
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
auto mainLayout = new QVBoxLayout(centralWidget);
mainLayout->setContentsMargins(0, 0, 0, 0);
m_ZTabWidget = new ZTabWidget(this);
#ifdef __APPLE__ #ifdef __APPLE__
setupMacOSWindow(this); setupMacOSWindow(this);
setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false); setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
#endif #endif
setCentralWidget(m_ZTabWidget); mainLayout->addWidget(m_ZTabWidget);
#ifdef WIN32
setupWinWindow(this);
#endif
m_mainStackedWidget = new QStackedWidget(); m_mainStackedWidget = new QStackedWidget();
WelcomeWidget *welcomePage = new WelcomeWidget(this); WelcomeWidget *welcomePage = new WelcomeWidget(this);
@@ -200,25 +122,35 @@ MainWindow::MainWindow(QWidget *parent)
m_connectedDeviceCountLabel->setStyleSheet( m_connectedDeviceCountLabel->setStyleSheet(
"QLabel:hover { background-color : #13131319; }"); "QLabel:hover { background-color : #13131319; }");
ui->statusbar->addWidget(m_connectedDeviceCountLabel); QWidget *statusbar = new QWidget();
QHBoxLayout *statusLayout = new QHBoxLayout(statusbar);
statusLayout->setContentsMargins(0, 0, 0, 0);
statusbar->setObjectName("StatusBar");
statusbar->setStyleSheet(
"QWidget#StatusBar { background-color: transparent; }");
statusLayout->addWidget(m_connectedDeviceCountLabel);
// TODO: implement downloads/uploads progress stuff // TODO: implement downloads/uploads progress stuff
StatusBalloon *statusBalloon = StatusBalloon::sharedInstance(); StatusBalloon *statusBalloon = StatusBalloon::sharedInstance();
ui->statusbar->addWidget(statusBalloon->getButton()); statusLayout->addWidget(statusBalloon->getButton());
statusLayout->addStretch(1);
ui->statusbar->setContentsMargins(0, 0, 0, 0); statusLayout->setContentsMargins(0, 0, 0, 0);
QLabel *appVersionLabel = new QLabel(QString("v%1").arg(APP_VERSION)); QLabel *appVersionLabel = new QLabel(QString("v%1").arg(APP_VERSION));
appVersionLabel->setContentsMargins(5, 0, 5, 0); appVersionLabel->setContentsMargins(5, 0, 5, 0);
appVersionLabel->setStyleSheet( appVersionLabel->setStyleSheet(
"QLabel:hover { background-color : #13131319; }"); "QLabel:hover { background-color : #13131319; }");
ui->statusbar->addPermanentWidget(appVersionLabel); statusLayout->addWidget(appVersionLabel);
ui->statusbar->addPermanentWidget(githubButton); statusLayout->addWidget(githubButton);
ui->statusbar->addPermanentWidget(settingsButton); statusLayout->addWidget(settingsButton);
#ifdef WIN32 // #ifdef WIN32
ui->statusbar->setStyleSheet( // statusLayout->setStyleSheet("QStatusBar { border-top: 1px solid
"QStatusBar { border-top: 1px solid #dcdcdc; }"); // #dcdcdc;
#endif // }");
// #endif
mainLayout->addWidget(statusbar);
#ifdef __linux__ #ifdef __linux__
QList<QString> mounted_iFusePaths = iFuseManager::getMountPoints(); QList<QString> mounted_iFusePaths = iFuseManager::getMountPoints();
@@ -226,7 +158,7 @@ MainWindow::MainWindow(QWidget *parent)
for (const QString &path : mounted_iFusePaths) { for (const QString &path : mounted_iFusePaths) {
auto *p = new iFuseDiskUnmountButton(path); auto *p = new iFuseDiskUnmountButton(path);
ui->statusbar->addPermanentWidget(p); statusbar->addWidget(p);
connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p, path]() { connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p, path]() {
bool ok = iFuseManager::linuxUnmount(path); bool ok = iFuseManager::linuxUnmount(path);
if (!ok) { if (!ok) {
@@ -235,7 +167,7 @@ MainWindow::MainWindow(QWidget *parent)
". Please try again."); ". Please try again.");
return; return;
} }
ui->statusbar->removeWidget(p); statusbar->removeWidget(p);
p->deleteLater(); p->deleteLater();
}); });
} }
@@ -521,7 +453,6 @@ MainWindow::~MainWindow()
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT // #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
// irecv_device_event_unsubscribe(context); // irecv_device_event_unsubscribe(context);
// #endif // #endif
delete ui;
m_deviceMonitor->requestInterruption(); m_deviceMonitor->requestInterruption();
// FIXME:QThread: Destroyed while thread '' is still running // FIXME:QThread: Destroyed while thread '' is still running
// m_deviceMonitor->wait(); // m_deviceMonitor->wait();
+9 -13
View File
@@ -22,23 +22,13 @@
#include "ZDownloader.h" #include "ZDownloader.h"
#include "ZUpdater.h" #include "ZUpdater.h"
#include "devicemanagerwidget.h" #include "devicemanagerwidget.h"
#include "iDescriptor.h"
#include <QMainWindow>
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
// #include "libirecovery.h"
// #endif
#include "devicemonitor.h" #include "devicemonitor.h"
#include "iDescriptor.h"
#include "ztabwidget.h" #include "ztabwidget.h"
#include <QLabel> #include <QLabel>
#include <QMainWindow>
#include <QStackedWidget> #include <QStackedWidget>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@@ -54,11 +44,17 @@ public slots:
private: private:
void createMenus(); void createMenus();
Ui::MainWindow *ui;
ZTabWidget *m_ZTabWidget; ZTabWidget *m_ZTabWidget;
DeviceManagerWidget *m_deviceManager; DeviceManagerWidget *m_deviceManager;
QStackedWidget *m_mainStackedWidget; QStackedWidget *m_mainStackedWidget;
QLabel *m_connectedDeviceCountLabel; QLabel *m_connectedDeviceCountLabel;
DeviceMonitorThread *m_deviceMonitor; DeviceMonitorThread *m_deviceMonitor;
QLabel *m_titleLabel;
QPushButton *m_minBtn;
QPushButton *m_maxBtn;
QPushButton *m_closeBtn;
QWidget *m_titleBar;
QWidget *m_contentArea;
QHBoxLayout *m_titleBarLayout;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H
+101
View File
@@ -0,0 +1,101 @@
/*
* iDescriptor: A free and open-source idevice management tool.
*
* Copyright (C) 2025 Uncore <https://github.com/uncor3>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../../settingsmanager.h"
#include "win_common.h"
void enableAcrylic(HWND hwnd)
{
const HINSTANCE hModule = LoadLibraryA("user32.dll");
if (hModule) {
struct ACCENTPOLICY {
int nAccentState;
int nFlags;
DWORD nColor;
int nAnimationId;
};
struct WINCOMPATTRDATA {
int nAttribute;
PVOID pData;
ULONG ulDataSize;
};
typedef BOOL(WINAPI *
pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA *);
const auto SetWindowCompositionAttribute =
(pSetWindowCompositionAttribute)GetProcAddress(
hModule, "SetWindowCompositionAttribute");
if (SetWindowCompositionAttribute) {
ACCENTPOLICY policy{};
policy.nAccentState = 4; // ACCENT_ENABLE_ACRYLICBLURBEHIND
policy.nFlags = 2;
policy.nColor = 0xD0202020;
WINCOMPATTRDATA data{};
data.nAttribute = 19;
data.pData = &policy;
data.ulDataSize = sizeof(policy);
SetWindowCompositionAttribute(hwnd, &data);
}
FreeLibrary(hModule);
}
}
#ifndef DWMWA_SYSTEMBACKDROP_TYPE
#define DWMWA_SYSTEMBACKDROP_TYPE 38
#endif
#ifndef DWMWA_MICA_EFFECT
#define DWMWA_MICA_EFFECT 1029
#endif
void enableMica(HWND hwnd)
{
if (!hwnd)
return;
SettingsManager *sm = SettingsManager::sharedInstance();
WIN_BACKDROP type = sm->winBackdropType();
MARGINS margins = {-1};
DwmExtendFrameIntoClientArea(hwnd, &margins);
DWORD build = 0;
RTL_OSVERSIONINFOW rovi = {0};
rovi.dwOSVersionInfoSize = sizeof(rovi);
using RtlGetVersionPtr = LONG(WINAPI *)(PRTL_OSVERSIONINFOW);
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll) {
auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(
GetProcAddress(ntdll, "RtlGetVersion"));
if (pRtlGetVersion && pRtlGetVersion(&rovi) == 0) {
build = rovi.dwBuildNumber;
}
}
if (build >= 22523) {
DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, &type,
sizeof(type));
} else if (build >= 22000) {
// Undocumented old method
BOOL mica = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &mica, sizeof(mica));
}
}

Some files were not shown because too many files have changed in this diff Show More