The current dark mode detection implementation is prone to a race
between an asynchronous D-Bus method call in NixUtils::NixUtils() and
bootstrap logic in Bootstrap::bootstrap(). This race condition causes
dark mode detection to fail intermittently during application startup.
The sequence of events in the failing case is as follows:
1. In the Application constructor, osUtils is instantiated, causing
the NixUtils constructor to run.
2. An asynchronous D-Bus method call is issued to query the value of
the org.freedesktop.appearance.color-scheme key.
3. Bootstrap code runs. In particular, a prctl() system call is
issued to set the keepassxc process "dumpable" attribute to 0.
4. xdg-desktop-portal begins handling the D-Bus method call initiated
in step 2. Flatpak detection logic is invoked, triggering an
attempt to access /proc/<pid>/root, where <pid> is the PID of the
keepassxc process.
5. Since the keepassxc process had its "dumpable" attribute set to 0
in step 3, its /proc/<pid>/root entry becomes owned by root. This
causes the access attempt from xdg-desktop-portal to fail, which in
turn causes the D-Bus method call to fail as well. As a result, the
registered callback (NixUtils::handleColorSchemeRead()) is never
invoked, effectively breaking dark mode detection.
If xdg-desktop-portal completes its permission checks before the
prctl() system call is issued (that is, if the order of steps 3 and 4
is reversed), everything works correctly.
Fix by replacing the asynchronous D-Bus method call with a synchronous
one, preventing bootstrap code from executing while the D-Bus call is
still pending.
* Use ReadOne D-Bus method instead of Read
The org.freedesktop.portal.Settings.Read method is deprecated. Replace
its use with org.freedesktop.portal.Settings.ReadOne and adjust reply
handling accordingly.
Remove NixUtils::handleColorSchemeRead(), which is no longer needed.
* Fixes#13351
* This unfortunately breaks backwards compatibility with the _original_ KeeAgent plugin for KeePass2. Qt6 refuses to write XML in UTF-16 format, so we have to use UTF-8. This should not be a big deal at all since our SSH agent integration has surpassed the original KeeAgent with features at this point.
* Remove individual feature flags in favor of a single `KPXC_MINIMAL` flag that removes advanced features from the build. Basic features are no longer guarded by feature flags.
* Basic features: Auto-Type, Yubikey, KeeShare
* Advanced features include: Browser (and passkeys), SSH Agent, and Secret Service
* Networking, Documentation, and Update Checking remain as feature flags to accommodate various distro requirements.
This change also cleans up the main CMakeLists.txt by re-arranging some content and placing macros into a dedicated include file. The minimum CMake version was bumped to 3.16.0 to conform to our minimum Ubuntu support of Focal (20.04). This also allows us to default to C++20, we fall back to C++17 for Qt versions less than 5.15.0 due to lack of support.
Lastly this change removes the KEEPASSXC_BUILD_TYPE="PreRelease" which is never used. We only support "Snapshot" and "Release" now.
Additional cleanup of CMakeLists:
1. Removed always-true CMake version guard if(CMAKE_VERSION >= 3.14.0)
2. Removed dead GCC 4.8 stack protector fallback; C++20 requires GCC 10+, and -fstack-protector-strong has been available since GCC 4.9.
3. Removed dead ASan LSan version guard for the same reason.
4. Converted set_target_properties( COMPILE_DEFINITIONS) to target_compile_definitions() on both keepassxc_core and keepassxc_gui. Both are now PRIVATE since the symbol is an internal build detail.
5. Scoped Qt5Gui_PRIVATE_INCLUDE_DIRS to keepassxc_gui preventing Qt-internal headers from leaking into every target in the build.
6. Use cmake_parse_arguments to cleanup test case definition macros. Remove test output formats as they are never used and can be controlled when tests are run.
* moved /fsanitize=address to compile options instead of definitions for MSVC builds
---------
Co-authored-by: varjolintu <sami.vanttinen@ahmala.org>
* Refactor: avoid naming lambda expressions and use STL algorithm
Lambda expressions in C++ are designed to be anonymous, lightweight, and local,
intended to encapsulate concise logic without the need for formal declarations.
Explicitly naming them (e.g., assigning to a variable or using a named `auto`)
contradicts their purpose: it introduces redundancy, adds unnecessary weight,
and blurs the line between lambdas and regular functions.
This change removes unnecessary lambda names and replaces the custom logic with
a standard STL algorithm, making the code more idiomatic, maintainable, and
aligned with the STL's philosophy of generic, reusable components.
* Refactor: Use std::any_of and lambda for deleted object checks
Replace manual for-loop iteration with std::any_of and a lambda expression
to check for the presence of a deleted object by UUID. This improves code
clarity, conciseness, and aligns with modern C++ best practices by leveraging
STL algorithms and functional-style expressions.
The second overload of containsDeletedObject() is now implemented by reusing
the first, avoiding code duplication and ensuring consistency.
* Run code format
* refactor(config): replace manual loop with `std::any_of` for roaming settings validation
- Remove the local lambda function `isValidSetting` and replace it with a direct use of `std::any_of` in the loop.
- Improve code readability and maintainability by leveraging the C++ Standard Library.
- Reduce redundancy and make the logic more concise and idiomatic.
This change ensures the code is more aligned with modern C++ practices while maintaining the same functionality.
* refactor(icons): simplify image format validation using `std::all_of`
- Replace manual loop and flag-based validation with `std::all_of` to check for non-alphanumeric characters in image formats.
- Improve code clarity and reduce boilerplate by leveraging the C++ Standard Library.
- Maintain the same filtering logic while making the code more concise and idiomatic.
---------
Co-authored-by: Jonathan White <support@dmapps.us>
* Fix ghost window on Windows by using proper dialog window flags
Replace Qt::Window with Qt::Dialog | Qt::WindowTitleHint | Qt::WindowCloseButtonHint
in UpdateCheckDialog to prevent an orphaned DWM window frame on Windows 11.
Using bare Qt::Window on a QDialog causes Windows DWM to create an independently
managed top-level composition surface. If the dialog's native handle is not
cleanly destroyed (e.g., during process exit while the dialog exists), DWM can
leave behind a transparent, non-interactive ghost window frame that persists
even after the process is gone and can only be cleared by rebooting.
Using Qt::Dialog keeps the dialog properly associated with its parent window
in DWM's composition tree, preventing the orphaned frame.
Fixes#9493
Replace "Chinese (China)" with "Chinese (Simplified)" and "Chinese (Taiwan)" with "Chinese (Traditional)". This keeps both items adjacent in the language dropdown, uses script-accurate naming, and avoids any geographic misinterpretation.
* Security: Prevent loading of openssl.cnf
Prevent loading openssl.cnf from the originating vcpkg folder tree to avoid DLL injections. This patch force sets the OPENSSL_CONF and OPENSSL_MODULES env vars to an invalid directory. This prevents openssl from attempting to load a cnf file which can contain settings to load arbitrary DLL files into KeePassXC memory space.
Thank you to zdi-disclosures for reporting this finding!
After building KeePassXC, it is impossible to run the program successfully from a user-writable location. This will prevent us from releasing the portable version.
* Fix test failure introduced by ab31a748fa (#10993)
* Fix tray hiding test failure
Introduced by 43904d87b7 (#10928), but somehow hasn't posed an issue until now.
* Try to make attachment GUI test more robust
---------
Co-authored-by: Jonathan White <support@dmapps.us>
* Fix font size for all platforms
* Fix font size for TOTP in preview panel
* Styles: drop Windows-specific palette overrides
* Fix encoding of EditEntryWidgetMain.ui
* Fix tab width
The 'openHelpButton' in the Auto-Type configuration widget is now
enabled whenever the main 'Enable Auto-Type for this entry' checkbox is
checked, regardless of whether a custom sequence is defined.
Previously, the help button's state depended on the custom sequence
being enabled, which was inconsistent and confusing. The help is now
available whenever the main Auto-Type feature is enabled, providing
assistance for both default and window-specific sequences.