mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
parent
9a8a5a0006
commit
a5094dd3ea
@ -25,3 +25,9 @@ OSUtilsBase::OSUtilsBase(QObject* parent)
|
||||
OSUtilsBase::~OSUtilsBase()
|
||||
{
|
||||
}
|
||||
|
||||
bool OSUtilsBase::setPreventScreenCapture(QWindow*, bool) const
|
||||
{
|
||||
// Do nothing by default
|
||||
return false;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
class QWindow;
|
||||
|
||||
/**
|
||||
* Abstract base class for generic OS-specific functionality
|
||||
* which can be reasonably expected to be available on all platforms.
|
||||
@ -63,6 +65,9 @@ public:
|
||||
QString* error = nullptr) = 0;
|
||||
virtual bool unregisterGlobalShortcut(const QString& name) = 0;
|
||||
|
||||
virtual bool canPreventScreenCapture() const = 0;
|
||||
virtual bool setPreventScreenCapture(QWindow* window, bool allow) const;
|
||||
|
||||
signals:
|
||||
void globalShortcutTriggered(const QString& name);
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <QColor>
|
||||
#include <unistd.h>
|
||||
|
||||
class QWindow;
|
||||
|
||||
class AppKit : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -42,6 +44,7 @@ public:
|
||||
bool enableAccessibility();
|
||||
bool enableScreenRecording();
|
||||
void toggleForegroundApp(bool foreground);
|
||||
void setWindowSecurity(QWindow* window, bool state);
|
||||
|
||||
signals:
|
||||
void lockDatabases();
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/NSRunningApplication.h>
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
@interface AppKitImpl : NSObject
|
||||
{
|
||||
@ -40,5 +41,6 @@
|
||||
- (bool) enableAccessibility;
|
||||
- (bool) enableScreenRecording;
|
||||
- (void) toggleForegroundApp:(bool) foreground;
|
||||
- (void) setWindowSecurity:(NSWindow*) window state:(bool) state;
|
||||
|
||||
@end
|
||||
|
@ -18,11 +18,14 @@
|
||||
|
||||
#import "AppKitImpl.h"
|
||||
#include "AppKit.h"
|
||||
#include <QWindow>
|
||||
|
||||
#import <AppKit/NSStatusBar.h>
|
||||
#import <AppKit/NSStatusItem.h>
|
||||
#import <AppKit/NSStatusBarButton.h>
|
||||
#import <AppKit/NSWorkspace.h>
|
||||
#import <AppKit/NSWindow.h>
|
||||
#import <AppKit/NSView.h>
|
||||
#import <CoreVideo/CVPixelBuffer.h>
|
||||
|
||||
@implementation AppKitImpl
|
||||
@ -211,6 +214,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setWindowSecurity:(NSWindow*) window state:(bool) state
|
||||
{
|
||||
[window setSharingType: state ? NSWindowSharingNone : NSWindowSharingReadOnly];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
@ -285,3 +293,9 @@ void AppKit::toggleForegroundApp(bool foreground)
|
||||
{
|
||||
[static_cast<id>(self) toggleForegroundApp:foreground];
|
||||
}
|
||||
|
||||
void AppKit::setWindowSecurity(QWindow* window, bool state)
|
||||
{
|
||||
auto view = reinterpret_cast<NSView*>(window->winId());
|
||||
[static_cast<id>(self) setWindowSecurity:view.window state:state];
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <QSettings>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <CoreGraphics/CGEventSource.h>
|
||||
@ -40,9 +41,7 @@ MacUtils::MacUtils(QObject* parent)
|
||||
connect(m_appkit.data(), &AppKit::interfaceThemeChanged, this, [this]() {
|
||||
// Emit with delay, since isStatusBarDark() still returns the old value
|
||||
// if we call it too fast after a theme change.
|
||||
QTimer::singleShot(100, [this]() {
|
||||
emit statusbarThemeChanged();
|
||||
});
|
||||
QTimer::singleShot(100, [this]() { emit statusbarThemeChanged(); });
|
||||
});
|
||||
}
|
||||
|
||||
@ -152,6 +151,21 @@ void MacUtils::toggleForegroundApp(bool foreground)
|
||||
m_appkit->toggleForegroundApp(foreground);
|
||||
}
|
||||
|
||||
bool MacUtils::canPreventScreenCapture() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacUtils::setPreventScreenCapture(QWindow* window, bool prevent) const
|
||||
{
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_appkit->setWindowSecurity(window, prevent);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacUtils::registerNativeEventFilter()
|
||||
{
|
||||
EventTypeSpec eventSpec;
|
||||
|
@ -62,6 +62,9 @@ public:
|
||||
uint16 qtToNativeKeyCode(Qt::Key key);
|
||||
CGEventFlags qtToNativeModifiers(Qt::KeyboardModifiers modifiers, bool native);
|
||||
|
||||
bool canPreventScreenCapture() const override;
|
||||
bool setPreventScreenCapture(QWindow* window, bool prevent) const override;
|
||||
|
||||
signals:
|
||||
void lockDatabases();
|
||||
|
||||
|
@ -43,6 +43,11 @@ public:
|
||||
QString* error = nullptr) override;
|
||||
bool unregisterGlobalShortcut(const QString& name) override;
|
||||
|
||||
bool canPreventScreenCapture() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
signals:
|
||||
void keymapChanged();
|
||||
|
||||
|
@ -16,12 +16,14 @@
|
||||
*/
|
||||
|
||||
#include "WinUtils.h"
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QWindow>
|
||||
|
||||
#include <windows.h>
|
||||
#include <Windows.h>
|
||||
#undef MessageBox
|
||||
|
||||
QPointer<WinUtils> WinUtils::m_instance = nullptr;
|
||||
|
||||
@ -49,6 +51,20 @@ WinUtils::WinUtils(QObject* parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool WinUtils::canPreventScreenCapture() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinUtils::setPreventScreenCapture(QWindow* window, bool prevent) const
|
||||
{
|
||||
if (window) {
|
||||
HWND handle = reinterpret_cast<HWND>(window->winId());
|
||||
return SetWindowDisplayAffinity(handle, prevent ? WDA_EXCLUDEFROMCAPTURE : WDA_NONE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register event filters to handle native platform events such as global hotkeys
|
||||
*/
|
||||
|
@ -52,6 +52,9 @@ public:
|
||||
DWORD qtToNativeKeyCode(Qt::Key key);
|
||||
DWORD qtToNativeModifiers(Qt::KeyboardModifiers modifiers);
|
||||
|
||||
bool canPreventScreenCapture() const override;
|
||||
bool setPreventScreenCapture(QWindow* window, bool prevent) const override;
|
||||
|
||||
protected:
|
||||
explicit WinUtils(QObject* parent = nullptr);
|
||||
~WinUtils() override = default;
|
||||
|
24
src/main.cpp
24
src/main.cpp
@ -19,6 +19,7 @@
|
||||
#include <QCommandLineParser>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QWindow>
|
||||
|
||||
#include "cli/Utils.h"
|
||||
#include "config-keepassx.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "gui/Application.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/osutils/OSUtils.h"
|
||||
|
||||
#if defined(WITH_ASAN) && defined(WITH_LSAN)
|
||||
#include <sanitizer/lsan_interface.h>
|
||||
@ -65,6 +67,8 @@ int main(int argc, char** argv)
|
||||
"localconfig", QObject::tr("path to a custom local config file"), "localconfig");
|
||||
QCommandLineOption keyfileOption("keyfile", QObject::tr("key file of the database"), "keyfile");
|
||||
QCommandLineOption pwstdinOption("pw-stdin", QObject::tr("read password of the database from stdin"));
|
||||
QCommandLineOption allowScreenCaptureOption("allow-screencapture",
|
||||
QObject::tr("allow app screen recordering and screenshots"));
|
||||
|
||||
QCommandLineOption helpOption = parser.addHelpOption();
|
||||
QCommandLineOption versionOption = parser.addVersionOption();
|
||||
@ -75,6 +79,10 @@ int main(int argc, char** argv)
|
||||
parser.addOption(pwstdinOption);
|
||||
parser.addOption(debugInfoOption);
|
||||
|
||||
if (osUtils->canPreventScreenCapture()) {
|
||||
parser.addOption(allowScreenCaptureOption);
|
||||
}
|
||||
|
||||
Application app(argc, argv);
|
||||
// don't set organizationName as that changes the return value of
|
||||
// QStandardPaths::writableLocation(QDesktopServices::DataLocation)
|
||||
@ -132,6 +140,22 @@ int main(int argc, char** argv)
|
||||
|
||||
MainWindow mainWindow;
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
// Disable screen capture if capable and not explicitly allowed
|
||||
if (osUtils->canPreventScreenCapture() && !parser.isSet(allowScreenCaptureOption)) {
|
||||
// This ensures any top-level windows (Main Window, Modal Dialogs, etc.) are excluded from screenshots
|
||||
QObject::connect(&app, &QGuiApplication::focusWindowChanged, &mainWindow, [&](QWindow* window) {
|
||||
if (window) {
|
||||
if (!osUtils->setPreventScreenCapture(window, true)) {
|
||||
mainWindow.displayGlobalMessage(
|
||||
QObject::tr("Warning: Failed to prevent screenshots on a top level window!"),
|
||||
MessageWidget::Error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
const bool pwstdin = parser.isSet(pwstdinOption);
|
||||
for (const QString& filename : fileNames) {
|
||||
QString password;
|
||||
|
Loading…
Reference in New Issue
Block a user