From 653e0b5af2dc176e80eb617df89f32bf8a00427e Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Sun, 12 Jun 2016 23:57:10 +0200 Subject: [PATCH 01/10] fix(capslockindicator): fix altering the line edit height Fix altering the Line Edit widget height when the indicator is on (e.g. when caps lock is active). To avoid messing with the style and all the complex issues that arise from it, use an action to display the icon inside the line edit, as it is a built-in feature that work just fine. Fixes #3379. --- src/widget/capslockindicator.cpp | 40 +++++--------------------------- src/widget/capslockindicator.h | 15 ++++-------- src/widget/loginscreen.cpp | 2 -- 3 files changed, 11 insertions(+), 46 deletions(-) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index 0028acd07..6fe4ec917 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -3,40 +3,12 @@ #include "src/platform/capslock.h" #endif -CapsLockIndicator::CapsLockIndicator(QWidget *parent) : QToolButton(parent) +CapsLockIndicator::CapsLockIndicator(QLineEdit *parent) : + QAction(parent), + parent(parent) { - cleanInputStyle = parentWidget()->styleSheet(); - - QIcon icon = QIcon(":img/caps_lock.svg"); - setIcon(icon); - setCursor(Qt::ArrowCursor); - setStyleSheet("border: none; padding: 0; color: white"); + setIcon(QIcon(":img/caps_lock.svg")); setToolTip(tr("CAPS-LOCK ENABLED")); - updateSize(); -} - -void CapsLockIndicator::updateSize() -{ - inputSize = parentWidget()->size(); - move(inputSize.width() - inputSize.height(), 0); - - int side = inputSize.height() - 5; - QSize iconSize(side, side); - setIconSize(iconSize); -} - -void CapsLockIndicator::show() -{ - QToolButton::show(); - - QString style = QString("padding: -3px %1px -3px -6px; color: white").arg(iconSize().width() - 3); - parentWidget()->setStyleSheet(style); -} - -void CapsLockIndicator::hide() -{ - QToolButton::hide(); - parentWidget()->setStyleSheet(cleanInputStyle); } void CapsLockIndicator::updateIndicator() @@ -48,7 +20,7 @@ void CapsLockIndicator::updateIndicator() #endif if (caps) - show(); + parent->addAction(this, QLineEdit::TrailingPosition); else - hide(); + parent->removeAction(this); } diff --git a/src/widget/capslockindicator.h b/src/widget/capslockindicator.h index a01874fa9..d7566464d 100644 --- a/src/widget/capslockindicator.h +++ b/src/widget/capslockindicator.h @@ -1,21 +1,16 @@ #ifndef CAPSLOCKINDICATOR_H #define CAPSLOCKINDICATOR_H -#include +#include +#include -class CapsLockIndicator : QToolButton +class CapsLockIndicator : QAction { public: - CapsLockIndicator(QWidget *widget); + CapsLockIndicator(QLineEdit *widget); void updateIndicator(); - void updateSize(); private: - void show(); - void hide(); - -private: - QString cleanInputStyle; - QSize inputSize; + QLineEdit *parent; }; #endif // CAPSLOCKINDICATOR_H diff --git a/src/widget/loginscreen.cpp b/src/widget/loginscreen.cpp index 61b10d6d4..706f32ac5 100644 --- a/src/widget/loginscreen.cpp +++ b/src/widget/loginscreen.cpp @@ -136,8 +136,6 @@ bool LoginScreen::event(QEvent* event) void LoginScreen::onNewProfilePageClicked() { ui->stackedWidget->setCurrentIndex(0); - capsIndicator->updateSize(); - confimCapsIndicator->updateSize(); } void LoginScreen::onLoginPageClicked() From f9190734d727a2a1cb424629caf0fb3a77f3f7e9 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 15 Jun 2016 18:43:32 +0200 Subject: [PATCH 02/10] fix(capslock_x11): properly release the X display handle This fixes caps lock detection after a while, and removes the "Maximum number of clients reached" message on stdout. --- src/platform/capslock_x11.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/capslock_x11.cpp b/src/platform/capslock_x11.cpp index 141ddb429..62b455bf1 100644 --- a/src/platform/capslock_x11.cpp +++ b/src/platform/capslock_x11.cpp @@ -35,6 +35,7 @@ bool Platform::capsLockEnabled() unsigned n; XkbGetIndicatorState(d, XkbUseCoreKbd, &n); caps_state = (n & 0x01) == 1; + XCloseDisplay(d); } return caps_state; } From 5fc67284cd9c8c86eccd359247e4b6f8bcc7c42c Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 15 Jun 2016 20:21:23 +0200 Subject: [PATCH 03/10] refactor(capslockindicator): encapsulate event handling Use an event filter on QCoreApplication instead of requiring the caller to manually call updateIndicator() when the caps lock state changed. --- src/widget/capslockindicator.cpp | 21 +++++++++++++++++++++ src/widget/capslockindicator.h | 5 +++++ src/widget/loginscreen.cpp | 5 ----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index 6fe4ec917..1ca4608b6 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -2,6 +2,7 @@ #ifdef QTOX_PLATFORM_EXT #include "src/platform/capslock.h" #endif +#include CapsLockIndicator::CapsLockIndicator(QLineEdit *parent) : QAction(parent), @@ -9,6 +10,8 @@ CapsLockIndicator::CapsLockIndicator(QLineEdit *parent) : { setIcon(QIcon(":img/caps_lock.svg")); setToolTip(tr("CAPS-LOCK ENABLED")); + + QCoreApplication::instance()->installEventFilter(this); } void CapsLockIndicator::updateIndicator() @@ -24,3 +27,21 @@ void CapsLockIndicator::updateIndicator() else parent->removeAction(this); } + +bool CapsLockIndicator::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) + { + case QEvent::Show: + if (obj == this) + updateIndicator(); + break; + case QEvent::KeyRelease: + updateIndicator(); + break; + default: + break; + } + + return QAction::eventFilter(obj, event); +} diff --git a/src/widget/capslockindicator.h b/src/widget/capslockindicator.h index d7566464d..01bd974f8 100644 --- a/src/widget/capslockindicator.h +++ b/src/widget/capslockindicator.h @@ -8,6 +8,11 @@ class CapsLockIndicator : QAction { public: CapsLockIndicator(QLineEdit *widget); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: void updateIndicator(); private: diff --git a/src/widget/loginscreen.cpp b/src/widget/loginscreen.cpp index 706f32ac5..b9fd5fec8 100644 --- a/src/widget/loginscreen.cpp +++ b/src/widget/loginscreen.cpp @@ -120,11 +120,6 @@ bool LoginScreen::event(QEvent* event) emit windowStateChanged(windowState()); break; #endif - case QEvent::Show: - case QEvent::KeyRelease: - capsIndicator->updateIndicator(); - confimCapsIndicator->updateIndicator(); - break; default: break; } From 2fe41071bedb689ba1776affe97e50138b9d6984 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 15 Jun 2016 20:27:35 +0200 Subject: [PATCH 04/10] fix(capslockindicator): also update indicator when the app gets focus This allows to have an up-to-date indicator when the caps lock state changed outside of the application and the user comes back to it, even if it doesn't trigger a Show event (e.g. the window was visible all the time). --- src/widget/capslockindicator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index 1ca4608b6..bf5fc2e97 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -36,6 +36,7 @@ bool CapsLockIndicator::eventFilter(QObject *obj, QEvent *event) if (obj == this) updateIndicator(); break; + case QEvent::WindowActivate: case QEvent::KeyRelease: updateIndicator(); break; From 6a40ca0b559ccac3862eb2f0f8bb5b768eedba3a Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 15 Jun 2016 23:10:11 +0200 Subject: [PATCH 05/10] refactor(capslockindicator): expose as a QAction to simplify API --- src/widget/capslockindicator.cpp | 15 ++++++++------- src/widget/capslockindicator.h | 8 +++----- src/widget/loginscreen.cpp | 6 ++---- src/widget/loginscreen.h | 2 -- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index bf5fc2e97..521ac8bcc 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -4,9 +4,8 @@ #endif #include -CapsLockIndicator::CapsLockIndicator(QLineEdit *parent) : - QAction(parent), - parent(parent) +CapsLockIndicator::CapsLockIndicator(QObject* parent) : + QAction(parent) { setIcon(QIcon(":img/caps_lock.svg")); setToolTip(tr("CAPS-LOCK ENABLED")); @@ -14,6 +13,11 @@ CapsLockIndicator::CapsLockIndicator(QLineEdit *parent) : QCoreApplication::instance()->installEventFilter(this); } +CapsLockIndicator::~CapsLockIndicator() +{ + QCoreApplication::instance()->removeEventFilter(this); +} + void CapsLockIndicator::updateIndicator() { bool caps = false; @@ -22,10 +26,7 @@ void CapsLockIndicator::updateIndicator() caps = Platform::capsLockEnabled(); #endif - if (caps) - parent->addAction(this, QLineEdit::TrailingPosition); - else - parent->removeAction(this); + setVisible(caps); } bool CapsLockIndicator::eventFilter(QObject *obj, QEvent *event) diff --git a/src/widget/capslockindicator.h b/src/widget/capslockindicator.h index 01bd974f8..e5477ac42 100644 --- a/src/widget/capslockindicator.h +++ b/src/widget/capslockindicator.h @@ -4,18 +4,16 @@ #include #include -class CapsLockIndicator : QAction +class CapsLockIndicator : public QAction { public: - CapsLockIndicator(QLineEdit *widget); + CapsLockIndicator(QObject *parent); + ~CapsLockIndicator(); protected: bool eventFilter(QObject *obj, QEvent *event); private: void updateIndicator(); - -private: - QLineEdit *parent; }; #endif // CAPSLOCKINDICATOR_H diff --git a/src/widget/loginscreen.cpp b/src/widget/loginscreen.cpp index b9fd5fec8..7fbe18f71 100644 --- a/src/widget/loginscreen.cpp +++ b/src/widget/loginscreen.cpp @@ -58,8 +58,8 @@ LoginScreen::LoginScreen(QWidget *parent) : connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginToggled); connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile); - capsIndicator = new CapsLockIndicator(ui->newPass); - confimCapsIndicator = new CapsLockIndicator(ui->newPassConfirm); + ui->newPass->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition); + ui->newPassConfirm->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition); reset(); this->setStyleSheet(Style::getStylesheet(":/ui/loginScreen/loginScreen.css")); @@ -72,8 +72,6 @@ LoginScreen::~LoginScreen() { Translator::unregister(this); delete ui; - delete capsIndicator; - delete confimCapsIndicator; } void LoginScreen::reset() diff --git a/src/widget/loginscreen.h b/src/widget/loginscreen.h index 2f958583d..f1548d4fa 100644 --- a/src/widget/loginscreen.h +++ b/src/widget/loginscreen.h @@ -67,8 +67,6 @@ private: private: Ui::LoginScreen *ui; QShortcut quitShortcut; - CapsLockIndicator *capsIndicator; - CapsLockIndicator *confimCapsIndicator; }; #endif // LOGINSCREEN_H From 61892d0c18ccb5de7acab67066c237d53dc9f1b3 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Wed, 15 Jun 2016 23:14:21 +0200 Subject: [PATCH 06/10] refactor(capslockindicator): use a single shared event handler Optimize the implementation by using a single shared event handler, managing the caps lock state check and propagating it appropriately to all instances at once. --- src/widget/capslockindicator.cpp | 38 +++++++++++++++++++++++++------- src/widget/capslockindicator.h | 15 ++++++++++--- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index 521ac8bcc..16c8173c8 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -4,21 +4,40 @@ #endif #include +CapsLockIndicator::EventHandler* CapsLockIndicator::eventHandler{nullptr}; + CapsLockIndicator::CapsLockIndicator(QObject* parent) : QAction(parent) { setIcon(QIcon(":img/caps_lock.svg")); setToolTip(tr("CAPS-LOCK ENABLED")); - QCoreApplication::instance()->installEventFilter(this); + if (!eventHandler) + eventHandler = new EventHandler(); + eventHandler->actions.append(this); } CapsLockIndicator::~CapsLockIndicator() +{ + eventHandler->actions.removeOne(this); + if (eventHandler->actions.isEmpty()) + { + delete eventHandler; + eventHandler = nullptr; + } +} + +CapsLockIndicator::EventHandler::EventHandler() +{ + QCoreApplication::instance()->installEventFilter(this); +} + +CapsLockIndicator::EventHandler::~EventHandler() { QCoreApplication::instance()->removeEventFilter(this); } -void CapsLockIndicator::updateIndicator() +void CapsLockIndicator::EventHandler::updateActions(const QObject* object) { bool caps = false; // It doesn't needed for OSX, because it shows indicator by default @@ -26,24 +45,27 @@ void CapsLockIndicator::updateIndicator() caps = Platform::capsLockEnabled(); #endif - setVisible(caps); + for (QAction* action : actions) + { + if (! object || object == action) + action->setVisible(caps); + } } -bool CapsLockIndicator::eventFilter(QObject *obj, QEvent *event) +bool CapsLockIndicator::EventHandler::eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { case QEvent::Show: - if (obj == this) - updateIndicator(); + updateActions(obj); break; case QEvent::WindowActivate: case QEvent::KeyRelease: - updateIndicator(); + updateActions(); break; default: break; } - return QAction::eventFilter(obj, event); + return QObject::eventFilter(obj, event); } diff --git a/src/widget/capslockindicator.h b/src/widget/capslockindicator.h index e5477ac42..eea595719 100644 --- a/src/widget/capslockindicator.h +++ b/src/widget/capslockindicator.h @@ -10,10 +10,19 @@ public: CapsLockIndicator(QObject *parent); ~CapsLockIndicator(); -protected: - bool eventFilter(QObject *obj, QEvent *event); +private: + class EventHandler : QObject + { + public: + QVector actions; + + EventHandler(); + ~EventHandler(); + void updateActions(const QObject* object = nullptr); + bool eventFilter(QObject *obj, QEvent *event); + }; private: - void updateIndicator(); + static EventHandler* eventHandler; }; #endif // CAPSLOCKINDICATOR_H From 3454f96d4c1038487122c8a6b369e159b562f996 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Thu, 16 Jun 2016 18:57:35 +0200 Subject: [PATCH 07/10] refactor(capslockindicator): avoid overhead on OSX On OSX the indicator is disabled, so avoid most of the overhead by not listening to any events that wouldn't lead to any change anyway. --- src/widget/capslockindicator.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp index 16c8173c8..c7860e720 100644 --- a/src/widget/capslockindicator.cpp +++ b/src/widget/capslockindicator.cpp @@ -4,29 +4,41 @@ #endif #include +// It isn't needed for OSX, because it shows indicator by default +#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX) +#define ENABLE_CAPSLOCK_INDICATOR +#endif + CapsLockIndicator::EventHandler* CapsLockIndicator::eventHandler{nullptr}; CapsLockIndicator::CapsLockIndicator(QObject* parent) : QAction(parent) { +#ifndef ENABLE_CAPSLOCK_INDICATOR + setVisible(false); +#else setIcon(QIcon(":img/caps_lock.svg")); setToolTip(tr("CAPS-LOCK ENABLED")); if (!eventHandler) eventHandler = new EventHandler(); eventHandler->actions.append(this); +#endif } CapsLockIndicator::~CapsLockIndicator() { +#ifdef ENABLE_CAPSLOCK_INDICATOR eventHandler->actions.removeOne(this); if (eventHandler->actions.isEmpty()) { delete eventHandler; eventHandler = nullptr; } +#endif } +#ifdef ENABLE_CAPSLOCK_INDICATOR CapsLockIndicator::EventHandler::EventHandler() { QCoreApplication::instance()->installEventFilter(this); @@ -39,11 +51,7 @@ CapsLockIndicator::EventHandler::~EventHandler() void CapsLockIndicator::EventHandler::updateActions(const QObject* object) { - bool caps = false; - // It doesn't needed for OSX, because it shows indicator by default -#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX) - caps = Platform::capsLockEnabled(); -#endif + bool caps = Platform::capsLockEnabled(); for (QAction* action : actions) { @@ -69,3 +77,4 @@ bool CapsLockIndicator::EventHandler::eventFilter(QObject *obj, QEvent *event) return QObject::eventFilter(obj, event); } +#endif // ENABLE_CAPSLOCK_INDICATOR From 5f34a959fc32583b4d037d70f027287ee39b1f27 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Fri, 17 Jun 2016 20:41:13 +0200 Subject: [PATCH 08/10] refactor: replace CapsLockIndicator with new PasswordEdit widget Introduce a new PasswordEdit widget extending QLineEdit that takes care of all the specifics of a QLineEntry when it is used to input a password, including echo mode and caps lock indicator. Also optimize the event handling to only listen to global events when it is actually needed, e.g. when a password field is actually visible. --- qtox.pro | 4 +- src/loginscreen.ui | 19 +++--- src/widget/capslockindicator.cpp | 80 ----------------------- src/widget/capslockindicator.h | 28 -------- src/widget/loginscreen.cpp | 3 - src/widget/loginscreen.h | 1 - src/widget/passwordedit.cpp | 106 +++++++++++++++++++++++++++++++ src/widget/passwordedit.h | 37 +++++++++++ 8 files changed, 154 insertions(+), 124 deletions(-) delete mode 100644 src/widget/capslockindicator.cpp delete mode 100644 src/widget/capslockindicator.h create mode 100644 src/widget/passwordedit.cpp create mode 100644 src/widget/passwordedit.h diff --git a/qtox.pro b/qtox.pro index 111b7019b..95fcc5d4e 100644 --- a/qtox.pro +++ b/qtox.pro @@ -354,7 +354,7 @@ HEADERS += \ src/widget/about/aboutuser.h \ src/widget/form/groupinviteform.h \ src/widget/tool/profileimporter.h \ - src/widget/capslockindicator.h + src/widget/passwordedit.h SOURCES += \ src/ipc.cpp \ @@ -471,4 +471,4 @@ SOURCES += \ src/widget/about/aboutuser.cpp \ src/widget/form/groupinviteform.cpp \ src/widget/tool/profileimporter.cpp \ - src/widget/capslockindicator.cpp + src/widget/passwordedit.cpp diff --git a/src/loginscreen.ui b/src/loginscreen.ui index 37f4850bf..bccc77645 100644 --- a/src/loginscreen.ui +++ b/src/loginscreen.ui @@ -130,11 +130,7 @@ - - - QLineEdit::Password - - + @@ -147,11 +143,7 @@ - - - QLineEdit::Password - - + @@ -431,6 +423,13 @@ + + + PasswordEdit + QLineEdit +
src/widget/passwordedit.h
+
+
diff --git a/src/widget/capslockindicator.cpp b/src/widget/capslockindicator.cpp deleted file mode 100644 index c7860e720..000000000 --- a/src/widget/capslockindicator.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "capslockindicator.h" -#ifdef QTOX_PLATFORM_EXT -#include "src/platform/capslock.h" -#endif -#include - -// It isn't needed for OSX, because it shows indicator by default -#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX) -#define ENABLE_CAPSLOCK_INDICATOR -#endif - -CapsLockIndicator::EventHandler* CapsLockIndicator::eventHandler{nullptr}; - -CapsLockIndicator::CapsLockIndicator(QObject* parent) : - QAction(parent) -{ -#ifndef ENABLE_CAPSLOCK_INDICATOR - setVisible(false); -#else - setIcon(QIcon(":img/caps_lock.svg")); - setToolTip(tr("CAPS-LOCK ENABLED")); - - if (!eventHandler) - eventHandler = new EventHandler(); - eventHandler->actions.append(this); -#endif -} - -CapsLockIndicator::~CapsLockIndicator() -{ -#ifdef ENABLE_CAPSLOCK_INDICATOR - eventHandler->actions.removeOne(this); - if (eventHandler->actions.isEmpty()) - { - delete eventHandler; - eventHandler = nullptr; - } -#endif -} - -#ifdef ENABLE_CAPSLOCK_INDICATOR -CapsLockIndicator::EventHandler::EventHandler() -{ - QCoreApplication::instance()->installEventFilter(this); -} - -CapsLockIndicator::EventHandler::~EventHandler() -{ - QCoreApplication::instance()->removeEventFilter(this); -} - -void CapsLockIndicator::EventHandler::updateActions(const QObject* object) -{ - bool caps = Platform::capsLockEnabled(); - - for (QAction* action : actions) - { - if (! object || object == action) - action->setVisible(caps); - } -} - -bool CapsLockIndicator::EventHandler::eventFilter(QObject *obj, QEvent *event) -{ - switch (event->type()) - { - case QEvent::Show: - updateActions(obj); - break; - case QEvent::WindowActivate: - case QEvent::KeyRelease: - updateActions(); - break; - default: - break; - } - - return QObject::eventFilter(obj, event); -} -#endif // ENABLE_CAPSLOCK_INDICATOR diff --git a/src/widget/capslockindicator.h b/src/widget/capslockindicator.h deleted file mode 100644 index eea595719..000000000 --- a/src/widget/capslockindicator.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef CAPSLOCKINDICATOR_H -#define CAPSLOCKINDICATOR_H - -#include -#include - -class CapsLockIndicator : public QAction -{ -public: - CapsLockIndicator(QObject *parent); - ~CapsLockIndicator(); - -private: - class EventHandler : QObject - { - public: - QVector actions; - - EventHandler(); - ~EventHandler(); - void updateActions(const QObject* object = nullptr); - bool eventFilter(QObject *obj, QEvent *event); - }; - -private: - static EventHandler* eventHandler; -}; -#endif // CAPSLOCKINDICATOR_H diff --git a/src/widget/loginscreen.cpp b/src/widget/loginscreen.cpp index 7fbe18f71..133205ad3 100644 --- a/src/widget/loginscreen.cpp +++ b/src/widget/loginscreen.cpp @@ -58,9 +58,6 @@ LoginScreen::LoginScreen(QWidget *parent) : connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginToggled); connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile); - ui->newPass->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition); - ui->newPassConfirm->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition); - reset(); this->setStyleSheet(Style::getStylesheet(":/ui/loginScreen/loginScreen.css")); diff --git a/src/widget/loginscreen.h b/src/widget/loginscreen.h index f1548d4fa..7978f03bd 100644 --- a/src/widget/loginscreen.h +++ b/src/widget/loginscreen.h @@ -21,7 +21,6 @@ #ifndef LOGINSCREEN_H #define LOGINSCREEN_H -#include "capslockindicator.h" #include #include #include diff --git a/src/widget/passwordedit.cpp b/src/widget/passwordedit.cpp new file mode 100644 index 000000000..65882b3f0 --- /dev/null +++ b/src/widget/passwordedit.cpp @@ -0,0 +1,106 @@ +#include "passwordedit.h" +#ifdef QTOX_PLATFORM_EXT +#include "src/platform/capslock.h" +#endif +#include + +// It isn't needed for OSX, because it shows indicator by default +#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX) +#define ENABLE_CAPSLOCK_INDICATOR +#endif + +PasswordEdit::EventHandler* PasswordEdit::eventHandler{nullptr}; + +PasswordEdit::PasswordEdit(QWidget* parent) : + QLineEdit(parent), + action(new QAction(this)) +{ + setEchoMode(QLineEdit::Password); + +#ifndef ENABLE_CAPSLOCK_INDICATOR + action->setVisible(false); +#else + action->setIcon(QIcon(":img/caps_lock.svg")); + action->setToolTip(tr("CAPS-LOCK ENABLED")); +#endif + + addAction(action, QLineEdit::TrailingPosition); +} + +PasswordEdit::~PasswordEdit() +{ + unregisterHandler(); +} + +void PasswordEdit::registerHandler() +{ +#ifdef ENABLE_CAPSLOCK_INDICATOR + if (!eventHandler) + eventHandler = new EventHandler(); + if (!eventHandler->actions.contains(action)) + eventHandler->actions.append(action); +#endif +} + +void PasswordEdit::unregisterHandler() +{ +#ifdef ENABLE_CAPSLOCK_INDICATOR + if (eventHandler && eventHandler->actions.contains(action)) + { + eventHandler->actions.removeOne(action); + if (eventHandler->actions.isEmpty()) + { + delete eventHandler; + eventHandler = nullptr; + } + } +#endif +} + +void PasswordEdit::showEvent(QShowEvent*) +{ +#ifdef ENABLE_CAPSLOCK_INDICATOR + action->setVisible(Platform::capsLockEnabled()); +#endif + registerHandler(); +} + +void PasswordEdit::hideEvent(QHideEvent*) +{ + unregisterHandler(); +} + +#ifdef ENABLE_CAPSLOCK_INDICATOR +PasswordEdit::EventHandler::EventHandler() +{ + QCoreApplication::instance()->installEventFilter(this); +} + +PasswordEdit::EventHandler::~EventHandler() +{ + QCoreApplication::instance()->removeEventFilter(this); +} + +void PasswordEdit::EventHandler::updateActions() +{ + bool caps = Platform::capsLockEnabled(); + + for (QAction* action : actions) + action->setVisible(caps); +} + +bool PasswordEdit::EventHandler::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) + { + case QEvent::WindowActivate: + case QEvent::KeyRelease: + updateActions(); + break; + default: + break; + } + + return QObject::eventFilter(obj, event); +} +#endif // ENABLE_CAPSLOCK_INDICATOR diff --git a/src/widget/passwordedit.h b/src/widget/passwordedit.h new file mode 100644 index 000000000..724506e99 --- /dev/null +++ b/src/widget/passwordedit.h @@ -0,0 +1,37 @@ +#ifndef PASSWORDEDIT_H +#define PASSWORDEDIT_H + +#include +#include + +class PasswordEdit : public QLineEdit +{ +public: + PasswordEdit(QWidget *parent); + ~PasswordEdit(); + +protected: + virtual void showEvent(QShowEvent* event); + virtual void hideEvent(QHideEvent* event); + +private: + class EventHandler : QObject + { + public: + QVector actions; + + EventHandler(); + ~EventHandler(); + void updateActions(); + bool eventFilter(QObject *obj, QEvent *event); + }; + + void registerHandler(); + void unregisterHandler(); + +private: + QAction* action; + + static EventHandler* eventHandler; +}; +#endif // PASSWORDEDIT_H From e3d0cc0e55ee91d85942b3beddac716435b78bee Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Fri, 17 Jun 2016 20:48:48 +0200 Subject: [PATCH 09/10] fix(passwordfields): use PasswordEdit widget for all password fields Fixes #3378. --- src/loginscreen.ui | 6 +----- src/widget/form/setpassworddialog.ui | 19 +++++++++---------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/loginscreen.ui b/src/loginscreen.ui index bccc77645..29dc92637 100644 --- a/src/loginscreen.ui +++ b/src/loginscreen.ui @@ -294,11 +294,7 @@
- - - QLineEdit::Password - - + diff --git a/src/widget/form/setpassworddialog.ui b/src/widget/form/setpassworddialog.ui index fcba47df7..62aff9a4c 100644 --- a/src/widget/form/setpassworddialog.ui +++ b/src/widget/form/setpassworddialog.ui @@ -43,18 +43,10 @@ - - - QLineEdit::Password - - + - - - QLineEdit::Password - - + @@ -96,6 +88,13 @@ + + + PasswordEdit + QLineEdit +
src/widget/passwordedit.h
+
+
passwordlineEdit repasswordlineEdit From 473b29b2a7c9476fa0c88f0eff5ae7c29c1e2576 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Sat, 18 Jun 2016 00:45:31 +0200 Subject: [PATCH 10/10] refactor(passwordedit): don't add the caps indicator at all if disabled --- src/widget/passwordedit.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/widget/passwordedit.cpp b/src/widget/passwordedit.cpp index 65882b3f0..4ab6cdda3 100644 --- a/src/widget/passwordedit.cpp +++ b/src/widget/passwordedit.cpp @@ -17,14 +17,11 @@ PasswordEdit::PasswordEdit(QWidget* parent) : { setEchoMode(QLineEdit::Password); -#ifndef ENABLE_CAPSLOCK_INDICATOR - action->setVisible(false); -#else +#ifdef ENABLE_CAPSLOCK_INDICATOR action->setIcon(QIcon(":img/caps_lock.svg")); action->setToolTip(tr("CAPS-LOCK ENABLED")); -#endif - addAction(action, QLineEdit::TrailingPosition); +#endif } PasswordEdit::~PasswordEdit()