Require Qt >= 5.12

Bump the minimum required Qt version up to 5.12, as per
https://github.com/keepassxreboot/keepassxc/issues/10859#issuecomment-2148477826.
Previously, the minimum version was 5.2.0 based on the CMakeLists.txt
check, though it's unclear if such old versions would actually work.

With this, we are able to remove a whole bunch of #ifdef'd code.
This commit is contained in:
Carlo Teubner 2024-06-14 19:45:26 +01:00 committed by Jonathan White
parent e6db2ce3b9
commit 07f565aa49
20 changed files with 7 additions and 156 deletions

View File

@ -512,14 +512,8 @@ else()
find_package(Qt5 COMPONENTS ${QT_COMPONENTS} REQUIRED)
endif()
if(Qt5Core_VERSION VERSION_LESS "5.2.0")
message(FATAL_ERROR "Qt version 5.2.0 or higher is required")
endif()
# CBOR for Passkeys requires Qt 5.12
if(Qt5Core_VERSION VERSION_LESS "5.12.0")
message(STATUS "Qt version 5.12.0 or higher is required for Passkeys support")
set(WITH_XC_BROWSER_PASSKEYS OFF)
message(FATAL_ERROR "Qt version 5.12.0 or higher is required")
endif()
get_filename_component(Qt5_PREFIX ${Qt5_DIR}/../../.. REALPATH)

View File

@ -5701,11 +5701,6 @@ This version is not meant for production use.</source>
Expect some bugs and minor issues, this version is meant for testing purposes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard.
We recommend you use the AppImage available on our downloads page.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No Tags</source>
<translation type="unfinished"></translation>

View File

@ -21,12 +21,8 @@
#include <QCloseEvent>
#include <QMenu>
#include <QShortcut>
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
#include <QScreen>
#else
#include <QDesktopWidget>
#endif
#include <QShortcut>
#include "core/Config.h"
#include "core/Database.h"
@ -334,7 +330,6 @@ void AutoTypeSelectDialog::buildActionMenu()
});
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Qt 5.10 introduced a new "feature" to hide shortcuts in context menus
// Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them
typeUsernameAction->setShortcutVisibleInContextMenu(true);
@ -342,7 +337,6 @@ void AutoTypeSelectDialog::buildActionMenu()
typeTotpAction->setShortcutVisibleInContextMenu(true);
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
typeVirtualAction->setShortcutVisibleInContextMenu(true);
#endif
#endif
copyUsernameAction->setProperty(MENU_FIELD_PROP_NAME, MENU_FIELD::USERNAME);
@ -377,16 +371,12 @@ void AutoTypeSelectDialog::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto screen = QApplication::screenAt(QCursor::pos());
if (!screen) {
// screenAt can return a nullptr, default to the primary screen
screen = QApplication::primaryScreen();
}
QRect screenGeometry = screen->availableGeometry();
#else
QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos());
#endif
// Resize to last used size
QSize size = config()->get(Config::GUI_AutoTypeSelectDialogSize).toSize();

View File

@ -21,12 +21,8 @@
#include "gui/Icons.h"
#include <QPushButton>
#include <QShortcut>
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
#include <QScreen>
#else
#include <QDesktopWidget>
#endif
#include <QShortcut>
PickcharsDialog::PickcharsDialog(const QString& string, QWidget* parent)
: QDialog(parent)
@ -157,15 +153,11 @@ void PickcharsDialog::showEvent(QShowEvent* event)
QDialog::showEvent(event);
// Center on active screen
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto screen = QApplication::screenAt(QCursor::pos());
if (!screen) {
// screenAt can return a nullptr, default to the primary screen
screen = QApplication::primaryScreen();
}
QRect screenGeometry = screen->availableGeometry();
#else
QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos());
#endif
move(screenGeometry.center().x() - (size().width() / 2), screenGeometry.center().y() - (size().height() / 2));
}

View File

@ -219,7 +219,6 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
// Messages
{Config::Messages_NoLegacyKeyFileWarning, {QS("Messages/NoLegacyKeyFileWarning"), Roaming, false}},
{Config::Messages_Qt55CompatibilityWarning, {QS("Messages/Qt55CompatibilityWarning"), Local, false}},
{Config::Messages_HidePreReleaseWarning, {QS("Messages/HidePreReleaseWarning"), Local, {}}}};
// clang-format on
@ -360,7 +359,7 @@ static const QHash<QString, Config::ConfigKey> deprecationMap = {
{QS("generator/WordList"), Config::PasswordGenerator_WordList},
{QS("generator/WordCase"), Config::PasswordGenerator_WordCase},
{QS("generator/Type"), Config::PasswordGenerator_Type},
{QS("QtErrorMessageShown"), Config::Messages_Qt55CompatibilityWarning},
{QS("QtErrorMessageShown"), Config::Deleted},
{QS("GUI/HidePasswords"), Config::Deleted},
{QS("GUI/DarkTrayIcon"), Config::Deleted},

View File

@ -194,7 +194,6 @@ public:
PasswordGenerator_Type,
Messages_NoLegacyKeyFileWarning,
Messages_Qt55CompatibilityWarning,
Messages_HidePreReleaseWarning,
// Special internal value

View File

@ -318,10 +318,8 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt
backupDatabase(filePath, backupFilePath);
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
QFileInfo info(filePath);
auto createTime = info.exists() ? info.birthTime() : QDateTime::currentDateTime();
#endif
switch (action) {
case Atomic: {
@ -332,10 +330,8 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt
return false;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Retain original creation time
saveFile.setFileTime(createTime, QFile::FileBirthTime);
#endif
if (saveFile.commit()) {
// successfully saved database file
@ -368,10 +364,8 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt
// successfully saved the database
tempFile.setAutoRemove(false);
QFile::setPermissions(filePath, perms);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Retain original creation time
tempFile.setFileTime(createTime, QFile::FileBirthTime);
#endif
return true;
} else if (backupFilePath.isEmpty() || !restoreDatabase(filePath, backupFilePath)) {
// Failed to copy new database in place, and

View File

@ -77,7 +77,6 @@ namespace Tools
#endif
debugInfo.append("\n");
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
debugInfo.append(QObject::tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4")
.arg(QSysInfo::prettyProductName(),
QSysInfo::currentCpuArchitecture(),
@ -85,7 +84,6 @@ namespace Tools
QSysInfo::kernelVersion()));
debugInfo.append("\n\n");
#endif
QString extensions;
#ifdef WITH_XC_AUTOTYPE

View File

@ -88,20 +88,6 @@ namespace Tools
}
}
inline int qtRuntimeVersion()
{
// Cache the result since the Qt version can't change during
// the execution, computing it once will be enough
const static int version = []() {
const auto sq = QString::fromLatin1(qVersion());
return (sq.section(QChar::fromLatin1('.'), 0, 0).toInt() << 16)
+ (sq.section(QChar::fromLatin1('.'), 1, 1).toInt() << 8)
+ (sq.section(QChar::fromLatin1('.'), 2, 2).toInt());
}();
return version;
}
// Checks if all values are found inside the list. Returns a list of values not found.
template <typename T> QList<T> getMissingValuesFromList(const QList<T>& list, const QList<T>& required)
{

View File

@ -101,13 +101,11 @@ QIcon Icons::trayIcon(bool unlocked)
#else
i = icon(QString("%1-%2%3").arg(applicationIconName(), iconApperance, suffix), false);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
// Set as mask to allow the operating system to recolour the tray icon. This may look weird
// if we failed to detect the status bar background colour correctly, but it is certainly
// better than a barely visible icon and even if we did guess correctly, it allows for better
// integration should the system's preferred colours not be 100% black or white.
i.setIsMask(true);
#endif
return i;
}
@ -121,11 +119,7 @@ AdaptiveIconEngine::AdaptiveIconEngine(QIcon baseIcon, QColor overrideColor)
void AdaptiveIconEngine::paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state)
{
// Temporary image canvas to ensure that the background is transparent and alpha blending works.
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
auto scale = painter->device()->devicePixelRatioF();
#else
auto scale = painter->device()->devicePixelRatio();
#endif
QImage img(rect.size() * scale, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter p(&img);
@ -191,9 +185,7 @@ QIcon Icons::icon(const QString& name, bool recolor, const QColor& overrideColor
icon = QIcon::fromTheme(name);
if (recolor) {
icon = QIcon(new AdaptiveIconEngine(icon, overrideColor));
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
icon.setIsMask(true);
#endif
}
m_iconCache.insert(cacheName, icon);

View File

@ -38,7 +38,6 @@
#include "autotype/AutoType.h"
#include "core/InactivityTimer.h"
#include "core/Resources.h"
#include "core/Tools.h"
#include "gui/AboutDialog.h"
#include "gui/ActionCollection.h"
#include "gui/Icons.h"
@ -293,7 +292,6 @@ MainWindow::MainWindow()
connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity()));
applySettingsChanges();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// Qt 5.10 introduced a new "feature" to hide shortcuts in context menus
// Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them
m_ui->actionEntryNew->setShortcutVisibleInContextMenu(true);
@ -315,7 +313,6 @@ MainWindow::MainWindow()
m_ui->actionEntryCopyTitle->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryAddToAgent->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryRemoveFromAgent->setShortcutVisibleInContextMenu(true);
#endif
connect(m_ui->menuEntries, SIGNAL(aboutToShow()), SLOT(obtainContextFocusLock()));
connect(m_ui->menuEntries, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
@ -666,15 +663,6 @@ MainWindow::MainWindow()
MessageWidget::Information,
-1);
}
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
if (!config()->get(Config::Messages_Qt55CompatibilityWarning).toBool()) {
m_ui->globalMessageWidget->showMessage(
tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard.\n"
"We recommend you use the AppImage available on our downloads page."),
MessageWidget::Warning,
-1);
config()->set(Config::Messages_Qt55CompatibilityWarning, true);
}
#endif
connect(qApp, SIGNAL(anotherInstanceStarted()), this, SLOT(bringToFront()));
@ -1864,27 +1852,6 @@ void MainWindow::toggleWindow()
hideWindow();
} else {
bringToFront();
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && !defined(QT_NO_DBUS) && (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
// re-register global D-Bus menu (needed on Ubuntu with Unity)
// see https://github.com/keepassxreboot/keepassxc/issues/271
// and https://bugreports.qt.io/browse/QTBUG-58723
// check for !isVisible(), because isNativeMenuBar() does not work with appmenu-qt5
static const auto isDesktopSessionUnity = qgetenv("XDG_CURRENT_DESKTOP") == "Unity";
if (isDesktopSessionUnity && Tools::qtRuntimeVersion() < QT_VERSION_CHECK(5, 9, 0)
&& !m_ui->menubar->isVisible()) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("com.canonical.AppMenu.Registrar"),
QStringLiteral("/com/canonical/AppMenu/Registrar"),
QStringLiteral("com.canonical.AppMenu.Registrar"),
QStringLiteral("RegisterWindow"));
QList<QVariant> args;
args << QVariant::fromValue(static_cast<uint32_t>(winId()))
<< QVariant::fromValue(QDBusObjectPath("/MenuBar/1"));
msg.setArguments(args);
QDBusConnection::sessionBus().send(msg);
}
#endif
}
}
@ -2019,11 +1986,7 @@ void MainWindow::displayDesktopNotification(const QString& msg, QString title, i
title = BaseWindowTitle;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
m_trayIcon->showMessage(title, msg, icons()->applicationIcon(), msTimeoutHint);
#else
m_trayIcon->showMessage(title, msg, QSystemTrayIcon::Information, msTimeoutHint);
#endif
}
void MainWindow::restartApp(const QString& message)

View File

@ -570,17 +570,10 @@ void EntryView::startDrag(Qt::DropActions supportedActions)
// Grab the screen pixel ratio where the window resides
// TODO: Use direct call to screen() when moving to Qt 6
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto screen = QGuiApplication::screenAt(window()->geometry().center());
if (!screen) {
screen = QGuiApplication::primaryScreen();
}
#else
auto screen = QGuiApplication::primaryScreen();
if (windowHandle()) {
screen = windowHandle()->screen();
}
#endif
auto pixelRatio = screen->devicePixelRatio();

View File

@ -41,10 +41,8 @@
#ifdef Q_OS_MACOS
#include <QMainWindow>
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
#include <QOperatingSystemVersion>
#endif
#endif
#include "gui/Icons.h"
@ -52,15 +50,6 @@ QT_BEGIN_NAMESPACE
Q_GUI_EXPORT int qt_defaultDpiX();
QT_END_NAMESPACE
// Redefine Q_FALLTHROUGH for older Qt versions
#ifndef Q_FALLTHROUGH
#if (defined(Q_CC_GNU) && Q_CC_GNU >= 700) && !defined(Q_CC_INTEL)
#define Q_FALLTHROUGH() __attribute__((fallthrough))
#else
#define Q_FALLTHROUGH() (void)0
#endif
#endif
namespace Phantom
{
namespace
@ -1033,15 +1022,6 @@ namespace Phantom
painter->restore();
}
int fontMetricsWidth(const QFontMetrics& fontMetrics, const QString& text)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
return fontMetrics.width(text, text.size(), Qt::TextBypassShaping);
#else
return fontMetrics.horizontalAdvance(text);
#endif
}
// This always draws the arrow with the correct aspect ratio, even if the
// provided bounding rect is non-square. The base edge of the triangle is
// snapped to a whole pixel to avoid anti-aliasing making it look soft.
@ -3886,11 +3866,9 @@ int BaseStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const
case PM_DockWidgetTitleBarButtonMargin:
val = 2;
break;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
case PM_TitleBarButtonSize:
val = 19;
break;
#endif
case PM_MaximumDragDistance:
return -1; // Do not dpi-scale because the value is magic
case PM_TabCloseIndicatorWidth:
@ -4381,7 +4359,7 @@ QRect BaseStyle::subControlRect(ComplexControl control,
int textHeight = option->fontMetrics.height();
// width()/horizontalAdvance() is faster than size() and good enough for
// us, since we only support a single line of text here anyway.
int textWidth = Phantom::fontMetricsWidth(option->fontMetrics, groupBox->text);
int textWidth = option->fontMetrics.horizontalAdvance(groupBox->text);
int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
int margin = 0;
@ -4624,10 +4602,8 @@ int BaseStyle::styleHint(StyleHint hint,
return Phantom::ShowItemViewDecorationSelected;
case SH_ItemView_MovementWithoutUpdatingSelection:
return 1;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
case SH_ItemView_ScrollMode:
return QAbstractItemView::ScrollPerPixel;
#endif
case SH_ScrollBar_ContextMenu:
#ifdef Q_OS_MAC
return 0;

View File

@ -51,11 +51,9 @@ QPalette DarkStyle::standardPalette() const
palette.setColor(QPalette::Inactive, QPalette::Text, QRgb(0xC8C8C6));
palette.setColor(QPalette::Disabled, QPalette::Text, QRgb(0x707070));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
palette.setColor(QPalette::Active, QPalette::PlaceholderText, QRgb(0x7D7D82));
palette.setColor(QPalette::Inactive, QPalette::PlaceholderText, QRgb(0x87888C));
palette.setColor(QPalette::Disabled, QPalette::PlaceholderText, QRgb(0x737373));
#endif
palette.setColor(QPalette::Active, QPalette::BrightText, QRgb(0x252627));
palette.setColor(QPalette::Inactive, QPalette::BrightText, QRgb(0x2D2D2F));

View File

@ -51,11 +51,9 @@ QPalette LightStyle::standardPalette() const
palette.setColor(QPalette::Inactive, QPalette::Text, QRgb(0x252528));
palette.setColor(QPalette::Disabled, QPalette::Text, QRgb(0x8C8C92));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
palette.setColor(QPalette::Active, QPalette::PlaceholderText, QRgb(0x71727D));
palette.setColor(QPalette::Inactive, QPalette::PlaceholderText, QRgb(0x878893));
palette.setColor(QPalette::Disabled, QPalette::PlaceholderText, QRgb(0xA3A4AC));
#endif
palette.setColor(QPalette::Active, QPalette::BrightText, QRgb(0xF3F3F4));
palette.setColor(QPalette::Inactive, QPalette::BrightText, QRgb(0xEAEAEB));

View File

@ -39,12 +39,6 @@
#include <cassert>
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
#define FONT_METRICS_WIDTH(fmt, ...) fmt.width(__VA_ARGS__)
#else
#define FONT_METRICS_WIDTH(fmt, ...) fmt.horizontalAdvance(__VA_ARGS__)
#endif
namespace
{
@ -255,7 +249,7 @@ struct TagsEdit::Impl
{
for (auto it = range.first; it != range.second; ++it) {
// calc text rect
const auto text_w = FONT_METRICS_WIDTH(fm, it->text);
const auto text_w = fm.horizontalAdvance(it->text);
auto const text_h = fm.height() + fm.leading();
auto const w = cross_deleter
? tag_inner.left() + tag_inner.right() + tag_cross_padding * 2 + tag_cross_width
@ -280,7 +274,7 @@ struct TagsEdit::Impl
template <class It> void calcEditorRect(QPoint& lt, size_t& row, QRect r, QFontMetrics const& fm, It it) const
{
auto const text_w = FONT_METRICS_WIDTH(fm, text_layout.text());
auto const text_w = fm.horizontalAdvance(text_layout.text());
auto const text_h = fm.height() + fm.leading();
auto const w = tag_inner.left() + tag_inner.right();
auto const h = tag_inner.top() + tag_inner.bottom();

View File

@ -52,10 +52,8 @@ int main(int argc, char** argv)
{
QT_REQUIRE_VERSION(argc, argv, QT_VERSION_STR)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && defined(Q_OS_WIN)
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
@ -172,9 +170,7 @@ int main(int argc, char** argv)
// Apply the configured theme before creating any GUI elements
app.applyTheme();
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QGuiApplication::setDesktopFileName(app.property("KPXC_QUALIFIED_APPNAME").toString() + QStringLiteral(".desktop"));
#endif
Application::bootstrap(config()->get(Config::GUI_Language).toString());

View File

@ -75,10 +75,8 @@
int main(int argc, char* argv[])
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
Application app(argc, argv);
app.setApplicationName("KeePassXC");
app.setApplicationVersion(KEEPASSXC_VERSION);

View File

@ -41,10 +41,8 @@
int main(int argc, char* argv[])
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
Application app(argc, argv);
app.setApplicationName("KeePassXC");
app.setApplicationVersion(KEEPASSXC_VERSION);

View File

@ -46,10 +46,8 @@
int main(int argc, char* argv[])
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
Application app(argc, argv);
app.setApplicationName("KeePassXC");
app.setApplicationVersion(KEEPASSXC_VERSION);