Skip to content

Commit

Permalink
Implement Secure Input Field mode on macOS
Browse files Browse the repository at this point in the history
* Fixes #4738
* Also fixes flaky handling of caps lock detection events
  • Loading branch information
droidmonkey committed Jan 4, 2025
1 parent edab0fa commit 620abb9
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 10 deletions.
20 changes: 13 additions & 7 deletions src/gui/PasswordWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ PasswordWidget::PasswordWidget(QWidget* parent)
{
m_ui->setupUi(this);
setFocusProxy(m_ui->passwordEdit);
m_ui->passwordEdit->installEventFilter(this);

const QIcon errorIcon = icons()->icon("dialog-error");
m_errorAction = m_ui->passwordEdit->addAction(errorIcon, QLineEdit::TrailingPosition);
Expand Down Expand Up @@ -223,14 +224,19 @@ void PasswordWidget::updateRepeatStatus()
}
}

bool PasswordWidget::event(QEvent* event)
bool PasswordWidget::eventFilter(QObject* watched, QEvent* event)
{
if (isVisible()
&& (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease
|| event->type() == QEvent::FocusIn)) {
checkCapslockState();
if (watched == m_ui->passwordEdit) {
auto type = event->type();
if (isVisible() && (type == QEvent::KeyPress || type == QEvent::KeyRelease || type == QEvent::FocusIn)) {
checkCapslockState();
}
if (type == QEvent::FocusIn || type == QEvent::FocusOut) {
osUtils->setUserInputProtection(type == QEvent::FocusIn);
}
}
return QWidget::event(event);
// Continue with normal operations
return false;
}

void PasswordWidget::checkCapslockState()
Expand Down Expand Up @@ -306,4 +312,4 @@ void PasswordWidget::updatePasswordStrength(const QString& password)

break;
}
}
}
5 changes: 2 additions & 3 deletions src/gui/PasswordWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class PasswordWidget : public QWidget
bool isPasswordVisible() const;
QString text();

bool eventFilter(QObject* watched, QEvent* event) override;

signals:
void textChanged(QString text);

Expand All @@ -57,9 +59,6 @@ public slots:
void setEchoMode(QLineEdit::EchoMode mode);
void setClearButtonEnabled(bool enabled);

protected:
bool event(QEvent* event) override;

private slots:
void popupPasswordGenerator();
void updateRepeatStatus();
Expand Down
5 changes: 5 additions & 0 deletions src/gui/osutils/OSUtilsBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ class OSUtilsBase : public QObject
*/
virtual bool isCapslockEnabled() = 0;

/**
* @param enable Toggle protection on user input (if available).
*/
virtual void setUserInputProtection(bool enable) = 0;

virtual void registerNativeEventFilter() = 0;

virtual bool registerGlobalShortcut(const QString& name,
Expand Down
9 changes: 9 additions & 0 deletions src/gui/osutils/macutils/MacUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ bool MacUtils::isCapslockEnabled()
#endif
}

void MacUtils::setUserInputProtection(bool enable)
{
if (enable) {
EnableSecureEventInput();
} else {
DisableSecureEventInput();
}
}

/**
* Toggle application state between foreground app and UIElement app.
* Foreground apps have dock icons, UIElement apps do not.
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/macutils/MacUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MacUtils : public OSUtilsBase
bool isLaunchAtStartupEnabled() const override;
void setLaunchAtStartup(bool enable) override;
bool isCapslockEnabled() override;
void setUserInputProtection(bool enable) override;

WId activeWindow();
bool raiseWindow(WId pid);
Expand Down
6 changes: 6 additions & 0 deletions src/gui/osutils/nixutils/NixUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ bool NixUtils::isCapslockEnabled()
return false;
}

void NixUtils::setUserInputProtection(bool enable)
{
// Linux does not support this feature
Q_UNUSED(enable)
}

void NixUtils::registerNativeEventFilter()
{
qApp->installNativeEventFilter(this);
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/nixutils/NixUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
bool isLaunchAtStartupEnabled() const override;
void setLaunchAtStartup(bool enable) override;
bool isCapslockEnabled() override;
void setUserInputProtection(bool enable) override;

void registerNativeEventFilter() override;

Expand Down
6 changes: 6 additions & 0 deletions src/gui/osutils/winutils/WinUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ bool WinUtils::isCapslockEnabled()
return GetKeyState(VK_CAPITAL) == 1;
}

void WinUtils::setUserInputProtection(bool enable)
{
// Windows does not support this feature
Q_UNUSED(enable)
}

bool WinUtils::isHighContrastMode() const
{
QSettings settings(R"(HKEY_CURRENT_USER\Control Panel\Accessibility\HighContrast)", QSettings::NativeFormat);
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/winutils/WinUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class WinUtils : public OSUtilsBase, QAbstractNativeEventFilter
bool isLaunchAtStartupEnabled() const override;
void setLaunchAtStartup(bool enable) override;
bool isCapslockEnabled() override;
void setUserInputProtection(bool enable) override;
bool isHighContrastMode() const;

void registerNativeEventFilter() override;
Expand Down

0 comments on commit 620abb9

Please sign in to comment.