diff --git a/cmake/CLangFormat.cmake b/cmake/CLangFormat.cmake index 70169ed72..c1e9572c2 100644 --- a/cmake/CLangFormat.cmake +++ b/cmake/CLangFormat.cmake @@ -19,7 +19,7 @@ set(EXCLUDED_DIRS # objective-c directories src/touchid/ src/autotype/mac/ - src/gui/macutils/) + src/gui/osutils/macutils/) set(EXCLUDED_FILES # third-party files diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b3d9abfa..bc63b5ee9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -156,6 +156,7 @@ set(keepassx_SOURCES gui/reports/ReportsPageHealthcheck.cpp gui/reports/ReportsWidgetStatistics.cpp gui/reports/ReportsPageStatistics.cpp + gui/osutils/OSUtilsBase.cpp gui/settings/SettingsWidget.cpp gui/widgets/ElidedLabel.cpp gui/widgets/PopupHelpWidget.cpp @@ -181,20 +182,22 @@ if(APPLE) ${keepassx_SOURCES} core/ScreenLockListenerMac.cpp core/MacPasteboard.cpp - gui/macutils/MacUtils.cpp - gui/macutils/AppKitImpl.mm - gui/macutils/AppKit.h) + gui/osutils/macutils/MacUtils.cpp + gui/osutils/macutils/AppKitImpl.mm + gui/osutils/macutils/AppKit.h) endif() if(UNIX AND NOT APPLE) set(keepassx_SOURCES ${keepassx_SOURCES} core/ScreenLockListenerDBus.cpp - gui/MainWindowAdaptor.cpp) + gui/MainWindowAdaptor.cpp + gui/osutils/nixutils/NixUtils.cpp) endif() if(MINGW) set(keepassx_SOURCES ${keepassx_SOURCES} - core/ScreenLockListenerWin.cpp) + core/ScreenLockListenerWin.cpp + gui/osutils/winutils/WinUtils.cpp) endif() if(MINGW OR (UNIX AND NOT APPLE)) set(keepassx_SOURCES diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 80a2268ec..fa7537373 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -38,7 +38,7 @@ #include "gui/MessageBox.h" #ifdef Q_OS_MAC -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif AutoType* AutoType::m_instance = nullptr; diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index fadc70e1c..1e52f58fe 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -17,7 +17,7 @@ */ #include "AutoTypeMac.h" -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #include "gui/MessageBox.h" #include diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index e0c896eca..a09a4d564 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -39,7 +39,7 @@ #include "gui/MainWindow.h" #include "gui/MessageBox.h" #ifdef Q_OS_MACOS -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif const QString BrowserService::KEEPASSXCBROWSER_NAME = QStringLiteral("KeePassXC-Browser Settings"); diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 7e158406b..c867526ef 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -41,7 +41,7 @@ #include "gui/entry/EntryView.h" #include "gui/group/GroupView.h" #ifdef Q_OS_MACOS -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif #include "gui/wizard/NewDatabaseWizard.h" diff --git a/src/gui/IconDownloaderDialog.cpp b/src/gui/IconDownloaderDialog.cpp index ebe6980a2..b7c6567ff 100644 --- a/src/gui/IconDownloaderDialog.cpp +++ b/src/gui/IconDownloaderDialog.cpp @@ -28,7 +28,7 @@ #include "core/Tools.h" #include "gui/IconModels.h" #ifdef Q_OS_MACOS -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif #include diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 620a509bc..07649d244 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -43,7 +43,7 @@ #include "keys/PasswordKey.h" #ifdef Q_OS_MACOS -#include "macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif #ifdef WITH_XC_UPDATECHECK diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp index b4c5840cf..17347e337 100644 --- a/src/gui/entry/EntryModel.cpp +++ b/src/gui/entry/EntryModel.cpp @@ -31,7 +31,7 @@ #include "core/Group.h" #include "core/Metadata.h" #ifdef Q_OS_MACOS -#include "gui/macutils/MacUtils.h" +#include "gui/osutils/macutils/MacUtils.h" #endif EntryModel::EntryModel(QObject* parent) diff --git a/src/gui/osutils/OSUtils.h b/src/gui/osutils/OSUtils.h new file mode 100644 index 000000000..dd1bd8cd1 --- /dev/null +++ b/src/gui/osutils/OSUtils.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_OSUTILS_H +#define KEEPASSXC_OSUTILS_H + +#include "OSUtilsBase.h" +#include + +#if defined(Q_OS_WIN) + +#include "winutils/WinUtils.h" +#define osUtils static_cast(winUtils()) + +#elif defined(Q_OS_MACOS) + +#include "macutils/MacUtils.h" +#define osUtils static_cast(macUtils()) + +#elif defined(Q_OS_UNIX) + +#include "nixutils/NixUtils.h" +#define osUtils static_cast(nixUtils()) + +#endif + +#endif // KEEPASSXC_OSUTILS_H diff --git a/src/gui/osutils/OSUtilsBase.cpp b/src/gui/osutils/OSUtilsBase.cpp new file mode 100644 index 000000000..143cb72c1 --- /dev/null +++ b/src/gui/osutils/OSUtilsBase.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "OSUtilsBase.h" + +OSUtilsBase::OSUtilsBase(QObject* parent) + : QObject(parent) +{ +} + +OSUtilsBase::~OSUtilsBase() +{ +} diff --git a/src/gui/osutils/OSUtilsBase.h b/src/gui/osutils/OSUtilsBase.h new file mode 100644 index 000000000..9467fca09 --- /dev/null +++ b/src/gui/osutils/OSUtilsBase.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_OSUTILSBASE_H +#define KEEPASSXC_OSUTILSBASE_H + +#include +#include + +/** + * Abstract base class for generic OS-specific functionality + * which can be reasonably expected to be available on all platforms. + */ +class OSUtilsBase : public QObject +{ + Q_OBJECT + +public: + virtual bool isDarkMode() = 0; + +protected: + explicit OSUtilsBase(QObject* parent = nullptr); + virtual ~OSUtilsBase(); +}; + +#endif // KEEPASSXC_OSUTILSBASE_H diff --git a/src/gui/macutils/AppKit.h b/src/gui/osutils/macutils/AppKit.h similarity index 100% rename from src/gui/macutils/AppKit.h rename to src/gui/osutils/macutils/AppKit.h diff --git a/src/gui/macutils/AppKitImpl.h b/src/gui/osutils/macutils/AppKitImpl.h similarity index 100% rename from src/gui/macutils/AppKitImpl.h rename to src/gui/osutils/macutils/AppKitImpl.h diff --git a/src/gui/macutils/AppKitImpl.mm b/src/gui/osutils/macutils/AppKitImpl.mm similarity index 100% rename from src/gui/macutils/AppKitImpl.mm rename to src/gui/osutils/macutils/AppKitImpl.mm diff --git a/src/gui/macutils/MacUtils.cpp b/src/gui/osutils/macutils/MacUtils.cpp similarity index 96% rename from src/gui/macutils/MacUtils.cpp rename to src/gui/osutils/macutils/MacUtils.cpp index 211aaa7eb..498325868 100644 --- a/src/gui/macutils/MacUtils.cpp +++ b/src/gui/osutils/macutils/MacUtils.cpp @@ -19,10 +19,10 @@ #include "MacUtils.h" #include -MacUtils* MacUtils::m_instance = nullptr; +QPointer MacUtils::m_instance = nullptr; MacUtils::MacUtils(QObject* parent) - : QObject(parent) + : OSUtils(parent) , m_appkit(new AppKit()) { connect(m_appkit.data(), SIGNAL(lockDatabases()), SIGNAL(lockDatabases())); diff --git a/src/gui/macutils/MacUtils.h b/src/gui/osutils/macutils/MacUtils.h similarity index 87% rename from src/gui/macutils/MacUtils.h rename to src/gui/osutils/macutils/MacUtils.h index 3e35994b1..427c7230a 100644 --- a/src/gui/macutils/MacUtils.h +++ b/src/gui/osutils/macutils/MacUtils.h @@ -19,17 +19,16 @@ #ifndef KEEPASSXC_MACUTILS_H #define KEEPASSXC_MACUTILS_H +#include "gui/osutils/OSUtilsBase.h" #include "AppKit.h" -#include -#include +#include -class MacUtils : public QObject +class MacUtils : public OSUtils { Q_OBJECT public: static MacUtils* instance(); - static void createTestInstance(); WId activeWindow(); bool raiseWindow(WId pid); @@ -37,20 +36,20 @@ public: bool raiseOwnWindow(); bool hideOwnWindow(); bool isHidden(); - bool isDarkMode(); + bool isDarkMode() override; bool enableAccessibility(); bool enableScreenRecording(); signals: void lockDatabases(); -private: +protected: explicit MacUtils(QObject* parent = nullptr); - ~MacUtils(); + ~MacUtils() override; private: QScopedPointer m_appkit; - static MacUtils* m_instance; + static QPointer m_instance; Q_DISABLE_COPY(MacUtils) }; diff --git a/src/gui/osutils/nixutils/NixUtils.cpp b/src/gui/osutils/nixutils/NixUtils.cpp new file mode 100644 index 000000000..229d6b519 --- /dev/null +++ b/src/gui/osutils/nixutils/NixUtils.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "NixUtils.h" +#include +#include +#include +#include + +QPointer NixUtils::m_instance = nullptr; + +NixUtils* NixUtils::instance() +{ + if (!m_instance) { + m_instance = new NixUtils(qApp); + } + + return m_instance; +} + +NixUtils::NixUtils(QObject* parent) + : OSUtilsBase(parent) +{ +} + +NixUtils::~NixUtils() +{ +} + +bool NixUtils::isDarkMode() +{ + if (!qApp || !qApp->style()) { + return false; + } + return qApp->style()->standardPalette().color(QPalette::Window).toHsl().lightness() < 110; +} diff --git a/src/gui/osutils/nixutils/NixUtils.h b/src/gui/osutils/nixutils/NixUtils.h new file mode 100644 index 000000000..bf236cdc3 --- /dev/null +++ b/src/gui/osutils/nixutils/NixUtils.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_NIXUTILS_H +#define KEEPASSXC_NIXUTILS_H + +#include "gui/osutils/OSUtilsBase.h" +#include + +class NixUtils : public OSUtilsBase +{ + Q_OBJECT + +public: + static NixUtils* instance(); + + bool isDarkMode() override; + +private: + explicit NixUtils(QObject* parent = nullptr); + ~NixUtils() override; + +private: + static QPointer m_instance; + + Q_DISABLE_COPY(NixUtils) +}; + +inline NixUtils* nixUtils() +{ + return NixUtils::instance(); +} + +#endif // KEEPASSXC_NIXUTILS_H diff --git a/src/gui/osutils/winutils/WinUtils.cpp b/src/gui/osutils/winutils/WinUtils.cpp new file mode 100644 index 000000000..f92192f18 --- /dev/null +++ b/src/gui/osutils/winutils/WinUtils.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "WinUtils.h" +#include +#include +#include + +#include + +QPointer WinUtils::m_instance = nullptr; +QScopedPointer WinUtils::m_eventFilter; + +WinUtils* WinUtils::instance() +{ + if (!m_instance) { + m_instance = new WinUtils(qApp); + } + + return m_instance; +} + +WinUtils::WinUtils(QObject* parent) + : OSUtilsBase(parent) +{ +} + +WinUtils::~WinUtils() +{ +} + +/** + * Register event filters to handle native platform events such as theme changes. + */ +void WinUtils::registerEventFilters() +{ + if (!m_eventFilter) { + m_eventFilter.reset(new DWMEventFilter); + qApp->installNativeEventFilter(m_eventFilter.data()); + } +} + +bool WinUtils::DWMEventFilter::nativeEventFilter(const QByteArray& eventType, void* message, long*) +{ + if (eventType != "windows_generic_MSG") { + return false; + } + + auto* msg = static_cast(message); + if (!msg->hwnd) { + return false; + } + switch (msg->message) { + case WM_CREATE: + case WM_INITDIALOG: { + if (winUtils()->isDarkMode()) { + // TODO: indicate dark mode support for black title bar + } + break; + } + } + + return false; +} + +bool WinUtils::isDarkMode() +{ + QSettings settings(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)", + QSettings::NativeFormat); + return settings.value("AppsUseLightTheme", 1).toInt() == 0; +} diff --git a/src/gui/osutils/winutils/WinUtils.h b/src/gui/osutils/winutils/WinUtils.h new file mode 100644 index 000000000..1a95716e1 --- /dev/null +++ b/src/gui/osutils/winutils/WinUtils.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_WINUTILS_H +#define KEEPASSXC_WINUTILS_H + +#include "gui/osutils/OSUtilsBase.h" + +#include +#include +#include + +class WinUtils : public OSUtilsBase +{ + Q_OBJECT + +public: + static WinUtils* instance(); + static void registerEventFilters(); + + bool isDarkMode() override; + +protected: + explicit WinUtils(QObject* parent = nullptr); + ~WinUtils() override; + +private: + class DWMEventFilter : public QAbstractNativeEventFilter + { + public: + bool nativeEventFilter(const QByteArray& eventType, void* message, long*) override; + }; + + static QPointer m_instance; + static QScopedPointer m_eventFilter; + + Q_DISABLE_COPY(WinUtils) +}; + +inline WinUtils* winUtils() +{ + return WinUtils::instance(); +} + +#endif // KEEPASSXC_WINUTILS_H