From 21e83f422667e431c1283b9ae3356fded3523e50 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Date: Wed, 13 May 2015 16:36:26 -0400
Subject: [PATCH] Avoid implicit declaration of function addnwstr.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

* pinentry/pinentry-curses.c [HAVE_NCURSESW]: Include <ncursesw/curses.h>.
[! HAVE_NCURSESW]: Only include <curses.h> in this case.

--

When built with libncursesw, we see this problem:

pinentry-curses.c:440:8: warning: implicit declaration of function ‘addnwstr’ [-Wimplicit-function-declaration]
        ADDCH (start[i]);
        ^
---
 pinentry/pinentry-curses.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/pinentry/pinentry-curses.c b/pinentry/pinentry-curses.c
index 60fd9da..65a5a67 100644
--- a/pinentry/pinentry-curses.c
+++ b/pinentry/pinentry-curses.c
@@ -22,7 +22,11 @@
 #include <config.h>
 #endif
 #include <assert.h>
+#ifdef HAVE_NCURSESW
+#include <ncursesw/curses.h>
+#else
 #include <curses.h>
+#endif
 #include <signal.h>
 #include <fcntl.h>
 #include <unistd.h>
-- 
2.11.0

diff -ruN pinentry-1.1.0-orig/pinentry/pinentry-curses.c pinentry-1.1.0/pinentry/pinentry-curses.c
--- pinentry-1.1.0-orig/pinentry/pinentry-curses.c	2017-12-03 10:13:05.000000000 -0600
+++ pinentry-1.1.0/pinentry/pinentry-curses.c	2020-10-09 05:27:21.000000000 -0500
@@ -55,6 +55,9 @@
 # define GPG_ERR_MISSING_ENVVAR   303
 #endif
 
+/* Get rid of implict warning */
+int addnwstr();
+
 
 /* FIXME: We should allow configuration of these button labels and in
    any case use the default_ok, default_cancel values if available.
diff --git a/qt/main.cpp b/qt/main.cpp
index b0bcddd..bbcf226 100644
--- a/qt/main.cpp
+++ b/qt/main.cpp
@@ -1,397 +1,401 @@
 /* main.cpp - A Qt dialog for PIN entry.
  * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
  * Copyright (C) 2003 g10 Code GmbH
  * Copyright 2007 Ingo Klöcker
  *
  * Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
  * Modified by Marcus Brinkmann <marcus@g10code.de>.
  * Modified by Marc Mutz <marc@kdab.com>
  *
  * 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 of the
  * License, or (at your option) any later version.
  *
  * 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 <https://www.gnu.org/licenses/>.
  * SPDX-License-Identifier: GPL-2.0+
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "pinentryconfirm.h"
 #include "pinentrydialog.h"
 #include "pinentry.h"
 
 #include <QApplication>
 #include <QDebug>
 #include <QIcon>
 #include <QMessageBox>
 #include <QPushButton>
 #include <QString>
 #include <QWidget>
+#if QT_VERSION >= 0x050000
 #include <QWindow>
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 
 #include <stdexcept>
 #include <gpg-error.h>
 
 #ifdef FALLBACK_CURSES
 #include <pinentry-curses.h>
 #endif
 
 #if QT_VERSION >= 0x050000 && defined(QT_STATIC)
   #include <QtPlugin>
   #ifdef Q_OS_WIN
     #include <windows.h>
     #include <shlobj.h>
     Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
   #elif defined(Q_OS_MAC)
     Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
   #else
     Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
   #endif
 #endif
 
 #ifdef Q_OS_WIN
 #include <windows.h>
 #endif
 
 static QString escape_accel(const QString &s)
 {
 
     QString result;
     result.reserve(s.size());
 
     bool afterUnderscore = false;
 
     for (unsigned int i = 0, end = s.size() ; i != end ; ++i) {
         const QChar ch = s[i];
         if (ch == QLatin1Char('_')) {
             if (afterUnderscore) { // escaped _
                 result += QLatin1Char('_');
                 afterUnderscore = false;
             } else { // accel
                 afterUnderscore = true;
             }
         } else {
             if (afterUnderscore ||  // accel
                     ch == QLatin1Char('&')) {  // escape & from being interpreted by Qt
                 result += QLatin1Char('&');
             }
             result += ch;
             afterUnderscore = false;
         }
     }
 
     if (afterUnderscore)
         // trailing single underscore: shouldn't happen, but deal with it robustly:
     {
         result += QLatin1Char('_');
     }
 
     return result;
 }
 
 namespace
 {
 class InvalidUtf8 : public std::invalid_argument
 {
 public:
     InvalidUtf8() : std::invalid_argument("invalid utf8") {}
     ~InvalidUtf8() throw() {}
 };
 }
 
 static const bool GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8 = false;
 
 static QString from_utf8(const char *s)
 {
     const QString result = QString::fromUtf8(s);
     if (result.contains(QChar::ReplacementCharacter)) {
         if (GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8) {
             throw InvalidUtf8();
         } else {
             return QString::fromLocal8Bit(s);
         }
     }
 
     return result;
 }
 
 static void
 setup_foreground_window(QWidget *widget, WId parentWid)
 {
+#if QT_VERSION >= 0x050000
     /* For windows set the desktop window as the transient parent */
     QWindow *parentWindow = nullptr;
     if (parentWid) {
         parentWindow = QWindow::fromWinId(parentWid);
     }
 #ifdef Q_OS_WIN
     if (!parentWindow) {
         HWND desktop = GetDesktopWindow();
         if (desktop) {
             parentWindow = QWindow::fromWinId((WId) desktop);
         }
     }
 #endif
     if (parentWindow) {
         // Ensure that we have a native wid
         widget->winId();
         QWindow *wndHandle = widget->windowHandle();
 
         if (wndHandle) {
             wndHandle->setTransientParent(parentWindow);
         }
     }
+#endif
     widget->setWindowFlags(Qt::Window |
                            Qt::CustomizeWindowHint |
                            Qt::WindowTitleHint |
                            Qt::WindowCloseButtonHint |
                            Qt::WindowStaysOnTopHint |
                            Qt::WindowMinimizeButtonHint);
 }
 
 static int
 qt_cmd_handler(pinentry_t pe)
 {
     char *str;
 
     int want_pass = !!pe->pin;
 
     const QString ok =
         pe->ok             ? escape_accel(from_utf8(pe->ok)) :
         pe->default_ok     ? escape_accel(from_utf8(pe->default_ok)) :
         /* else */           QLatin1String("&OK") ;
     const QString cancel =
         pe->cancel         ? escape_accel(from_utf8(pe->cancel)) :
         pe->default_cancel ? escape_accel(from_utf8(pe->default_cancel)) :
         /* else */           QLatin1String("&Cancel") ;
 
     str = pinentry_get_title (pe);
     const QString title =
         str       ? from_utf8(str) :
         /* else */  QLatin1String("pinentry-qt") ;
     free (str);
 
     const QString repeatError =
         pe->repeat_error_string ? from_utf8(pe->repeat_error_string) :
                                   QLatin1String("Passphrases do not match");
     const QString repeatString =
         pe->repeat_passphrase ? from_utf8(pe->repeat_passphrase) :
                                 QString();
     const QString visibilityTT =
         pe->default_tt_visi ? from_utf8(pe->default_tt_visi) :
                               QLatin1String("Show passphrase");
     const QString hideTT =
         pe->default_tt_hide ? from_utf8(pe->default_tt_hide) :
                               QLatin1String("Hide passphrase");
 
     const QString generateLbl = pe->genpin_label ? from_utf8(pe->genpin_label) :
                                 QString();
     const QString generateTT = pe->genpin_tt ? from_utf8(pe->genpin_tt) :
                                QString();
 
 
     if (want_pass) {
         char *str;
 
         PinEntryDialog pinentry(nullptr, 0, pe->timeout, true, !!pe->quality_bar,
                                 repeatString, visibilityTT, hideTT);
         setup_foreground_window(&pinentry, pe->parent_wid);
         pinentry.setPinentryInfo(pe);
         pinentry.setPrompt(escape_accel(from_utf8(pe->prompt)));
         pinentry.setDescription(from_utf8(pe->description));
         pinentry.setRepeatErrorText(repeatError);
         pinentry.setGenpinLabel(generateLbl);
         pinentry.setGenpinTT(generateTT);
 
         str = pinentry_get_title (pe);
         if (str) {
             pinentry.setWindowTitle(from_utf8(str));
             free (str);
         }
 
         /* If we reuse the same dialog window.  */
         pinentry.setPin(QString());
 
         pinentry.setOkText(ok);
         pinentry.setCancelText(cancel);
         if (pe->error) {
             pinentry.setError(from_utf8(pe->error));
         }
         if (pe->quality_bar) {
             pinentry.setQualityBar(from_utf8(pe->quality_bar));
         }
         if (pe->quality_bar_tt) {
             pinentry.setQualityBarTT(from_utf8(pe->quality_bar_tt));
         }
         bool ret = pinentry.exec();
         if (!ret) {
             if (pinentry.timedOut())
                 pe->specific_err = gpg_error (GPG_ERR_TIMEOUT);
             return -1;
         }
 
         const QString pinStr = pinentry.pin();
         QByteArray pin = pinStr.toUtf8();
 
         if (!!pe->repeat_passphrase) {
             /* Should not have been possible to accept
                the dialog in that case but we do a safety
                check here */
             pe->repeat_okay = (pinStr == pinentry.repeatedPin());
         }
 
         int len = strlen(pin.constData());
         if (len >= 0) {
             pinentry_setbufferlen(pe, len + 1);
             if (pe->pin) {
                 strcpy(pe->pin, pin.constData());
                 return len;
             }
         }
         return -1;
     } else {
         const QString desc  = pe->description ? from_utf8(pe->description) : QString();
         const QString notok = pe->notok       ? escape_accel(from_utf8(pe->notok)) : QString();
 
         const QMessageBox::StandardButtons buttons =
             pe->one_button ? QMessageBox::Ok :
             pe->notok      ? QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel :
             /* else */       QMessageBox::Ok | QMessageBox::Cancel ;
 
         PinentryConfirm box(QMessageBox::Information, pe->timeout, title, desc, buttons, nullptr);
         setup_foreground_window(&box, pe->parent_wid);
 
         const struct {
             QMessageBox::StandardButton button;
             QString label;
         } buttonLabels[] = {
             { QMessageBox::Ok,     ok     },
             { QMessageBox::Yes,    ok     },
             { QMessageBox::No,     notok  },
             { QMessageBox::Cancel, cancel },
         };
 
         for (size_t i = 0 ; i < sizeof buttonLabels / sizeof * buttonLabels ; ++i)
             if ((buttons & buttonLabels[i].button) && !buttonLabels[i].label.isEmpty()) {
                 box.button(buttonLabels[i].button)->setText(buttonLabels[i].label);
 #ifndef QT_NO_ACCESSIBILITY
                 box.button(buttonLabels[i].button)->setAccessibleDescription(buttonLabels[i].label);
 #endif
             }
 
         box.setIconPixmap(icon());
 
         if (!pe->one_button) {
             box.setDefaultButton(QMessageBox::Cancel);
         }
 
         box.show();
         raiseWindow(&box);
 
         const int rc = box.exec();
 
         if (rc == QMessageBox::Cancel) {
             pe->canceled = true;
         }
         if (box.timedOut()) {
           pe->specific_err = gpg_error (GPG_ERR_TIMEOUT);
         }
 
         return rc == QMessageBox::Ok || rc == QMessageBox::Yes ;
 
     }
 }
 
 static int
 qt_cmd_handler_ex(pinentry_t pe)
 {
     try {
         return qt_cmd_handler(pe);
     } catch (const InvalidUtf8 &) {
         pe->locale_err = true;
         return pe->pin ? -1 : false ;
     } catch (...) {
         pe->canceled = true;
         return pe->pin ? -1 : false ;
     }
 }
 
 pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler_ex;
 
 int
 main(int argc, char *argv[])
 {
     pinentry_init("pinentry-qt");
 
     QApplication *app = NULL;
     int new_argc = 0;
 
 #ifdef FALLBACK_CURSES
     if (!pinentry_have_display(argc, argv)) {
         pinentry_cmd_handler = curses_cmd_handler;
         pinentry_set_flavor_flag ("curses");
     } else
 #endif
     {
         /* Qt does only understand -display but not --display; thus we
            are fixing that here.  The code is pretty simply and may get
            confused if an argument is called "--display". */
         char **new_argv, *p;
         size_t n;
         int i, done;
 
         for (n = 0, i = 0; i < argc; i++) {
             n += strlen(argv[i]) + 1;
         }
         n++;
         new_argv = (char **)calloc(argc + 1, sizeof * new_argv);
         if (new_argv) {
             *new_argv = (char *)malloc(n);
         }
         if (!new_argv || !*new_argv) {
             fprintf(stderr, "pinentry-qt: can't fixup argument list: %s\n",
                     strerror(errno));
             exit(EXIT_FAILURE);
 
         }
         for (done = 0, p = *new_argv, i = 0; i < argc; i++)
             if (!done && !strcmp(argv[i], "--display")) {
                 new_argv[i] = strcpy(p, argv[i] + 1);
                 p += strlen(argv[i] + 1) + 1;
                 done = 1;
             } else {
                 new_argv[i] = strcpy(p, argv[i]);
                 p += strlen(argv[i]) + 1;
             }
 
         /* Note: QApplication uses int &argc so argc has to be valid
          * for the full lifetime of the application.
          *
          * As Qt might modify argc / argv we use copies here so that
          * we do not loose options that are handled in both. e.g. display.
          */
         new_argc = argc;
         Q_ASSERT (new_argc);
         app = new QApplication(new_argc, new_argv);
         app->setWindowIcon(QIcon(QLatin1String(":/document-encrypt.png")));
     }
 
     pinentry_parse_opts(argc, argv);
 
     int rc = pinentry_loop();
     delete app;
     return rc ? EXIT_FAILURE : EXIT_SUCCESS ;
 }
diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp
index 684e465..1b2be36 100644
--- a/qt/pinentrydialog.cpp
+++ b/qt/pinentrydialog.cpp
@@ -1,499 +1,511 @@
 /* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry.
  * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
  * Copyright 2007 Ingo Klöcker
  * Copyright 2016 Intevation GmbH
  *
  * Written by Steffen Hansen <steffen@klaralvdalens-datakonsult.se>.
  * Modified by Andre Heinecke <aheinecke@intevation.de>
  *
  * 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 of the
  * License, or (at your option) any later version.
  *
  * 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 <https://www.gnu.org/licenses/>.
  * SPDX-License-Identifier: GPL-2.0+
  */
 
 #include "pinentrydialog.h"
 #include <QGridLayout>
 
 #include <QProgressBar>
 #include <QApplication>
 #include <QFontMetrics>
 #include <QStyle>
 #include <QPainter>
 #include <QPushButton>
 #include <QDialogButtonBox>
 #include <QKeyEvent>
 #include <QLabel>
 #include <QPalette>
 #include <QLineEdit>
 #include <QAction>
 #include <QCheckBox>
 #include "pinlineedit.h"
 
 #include <QDebug>
 
 #ifdef Q_OS_WIN
 #include <windows.h>
 #if QT_VERSION >= 0x050700
 #include <QtPlatformHeaders/QWindowsWindowFunctions>
 #endif
 #endif
 
 void raiseWindow(QWidget *w)
 {
 #ifdef Q_OS_WIN
 #if QT_VERSION >= 0x050700
     QWindowsWindowFunctions::setWindowActivationBehavior(
             QWindowsWindowFunctions::AlwaysActivateWindow);
 #endif
 #endif
     w->setWindowState((w->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
     w->activateWindow();
     w->raise();
 }
 
 QPixmap icon(QStyle::StandardPixmap which)
 {
     QPixmap pm = qApp->windowIcon().pixmap(48, 48);
 
     if (which != QStyle::SP_CustomBase) {
         const QIcon ic = qApp->style()->standardIcon(which);
         QPainter painter(&pm);
         const int emblemSize = 22;
         painter.drawPixmap(pm.width() - emblemSize, 0,
                            ic.pixmap(emblemSize, emblemSize));
     }
 
     return pm;
 }
 
 void PinEntryDialog::slotTimeout()
 {
     _timed_out = true;
     reject();
 }
 
 PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name,
                                int timeout, bool modal, bool enable_quality_bar,
                                const QString &repeatString,
                                const QString &visibilityTT,
                                const QString &hideTT)
     : QDialog(parent),
       mRepeat(NULL),
       _grabbed(false),
       _disable_echo_allowed(true),
       mVisibilityTT(visibilityTT),
       mHideTT(hideTT),
       mVisiActionEdit(NULL),
       mGenerateActionEdit(NULL),
       mVisiCB(NULL)
 {
     _timed_out = false;
 
     if (modal) {
         setWindowModality(Qt::ApplicationModal);
     }
 
     _icon = new QLabel(this);
     _icon->setPixmap(icon());
 
     _error = new QLabel(this);
     QPalette pal;
     pal.setColor(QPalette::WindowText, Qt::red);
     _error->setPalette(pal);
     _error->hide();
 
     _desc = new QLabel(this);
     _desc->hide();
 
     _prompt = new QLabel(this);
     _prompt->hide();
 
     _edit = new PinLineEdit(this);
     _edit->setMaxLength(256);
     _edit->setMinimumWidth(_edit->fontMetrics().averageCharWidth()*20 + 48);
     _edit->setEchoMode(QLineEdit::Password);
 
     _prompt->setBuddy(_edit);
 
     if (enable_quality_bar) {
         _quality_bar_label = new QLabel(this);
         _quality_bar_label->setAlignment(Qt::AlignVCenter);
         _quality_bar = new QProgressBar(this);
         _quality_bar->setAlignment(Qt::AlignCenter);
         _have_quality_bar = true;
     } else {
         _have_quality_bar = false;
     }
 
     QDialogButtonBox *const buttons = new QDialogButtonBox(this);
     buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
     _ok = buttons->button(QDialogButtonBox::Ok);
     _cancel = buttons->button(QDialogButtonBox::Cancel);
 
     _ok->setDefault(true);
 
     if (style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons)) {
         _ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton));
         _cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));
     }
 
     if (timeout > 0) {
         _timer = new QTimer(this);
         connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
         _timer->start(timeout * 1000);
     } else {
         _timer = NULL;
     }
 
     connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
     connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
     connect(_edit, SIGNAL(textChanged(QString)),
             this, SLOT(updateQuality(QString)));
     connect(_edit, SIGNAL(textChanged(QString)),
             this, SLOT(textChanged(QString)));
     connect(_edit, SIGNAL(backspacePressed()),
             this, SLOT(onBackspace()));
 
     QGridLayout *const grid = new QGridLayout(this);
     int row = 1;
     grid->addWidget(_error, row++, 1, 1, 2);
     grid->addWidget(_desc,  row++, 1, 1, 2);
     //grid->addItem( new QSpacerItem( 0, _edit->height() / 10, QSizePolicy::Minimum, QSizePolicy::Fixed ), 1, 1 );
     grid->addWidget(_prompt, row, 1);
     grid->addWidget(_edit, row++, 2);
     if (!repeatString.isNull()) {
         mRepeat = new QLineEdit;
         mRepeat->setMaxLength(256);
         mRepeat->setEchoMode(QLineEdit::Password);
         connect(mRepeat, SIGNAL(textChanged(QString)),
                 this, SLOT(textChanged(QString)));
         QLabel *repeatLabel = new QLabel(repeatString);
         repeatLabel->setBuddy(mRepeat);
         grid->addWidget(repeatLabel, row, 1);
         grid->addWidget(mRepeat, row++, 2);
         setTabOrder(_edit, mRepeat);
         setTabOrder(mRepeat, _ok);
     }
     if (enable_quality_bar) {
         grid->addWidget(_quality_bar_label, row, 1);
         grid->addWidget(_quality_bar, row++, 2);
     }
     /* Set up the show password action */
     const QIcon visibilityIcon = QIcon::fromTheme(QLatin1String("visibility"));
     const QIcon hideIcon = QIcon::fromTheme(QLatin1String("hint"));
     const QIcon generateIcon = QIcon(); /* Disabled for now
                                          QIcon::fromTheme(QLatin1String("password-generate")); */
 #if QT_VERSION >= 0x050200
     if (!generateIcon.isNull()) {
         mGenerateActionEdit = _edit->addAction(generateIcon,
                                                QLineEdit::LeadingPosition);
         mGenerateActionEdit->setToolTip(mGenerateTT);
         connect(mGenerateActionEdit, SIGNAL(triggered()), this, SLOT(generatePin()));
     }
     if (!visibilityIcon.isNull() && !hideIcon.isNull()) {
         mVisiActionEdit = _edit->addAction(visibilityIcon, QLineEdit::TrailingPosition);
         mVisiActionEdit->setVisible(false);
         mVisiActionEdit->setToolTip(mVisibilityTT);
         connect(mVisiActionEdit, SIGNAL(triggered()), this, SLOT(toggleVisibility()));
     } else
 #endif
     {
         if (!mVisibilityTT.isNull()) {
             mVisiCB = new QCheckBox(mVisibilityTT);
             connect(mVisiCB, SIGNAL(toggled(bool)), this, SLOT(toggleVisibility()));
             grid->addWidget(mVisiCB, row++, 1, 1, 2, Qt::AlignLeft);
         }
     }
     grid->addWidget(buttons, ++row, 0, 1, 3);
 
     grid->addWidget(_icon, 0, 0, row - 1, 1, Qt::AlignVCenter | Qt::AlignLeft);
 
     grid->setSizeConstraint(QLayout::SetFixedSize);
 
 
     connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
             this, SLOT(focusChanged(QWidget *, QWidget *)));
 
+#if QT_VERSION >= 0x050000
+    /* This is mostly an issue on Windows where this results
+       in the pinentry popping up nicely with an animation and
+       comes to front. It is not ifdefed for Windows only since
+       window managers on Linux like KWin can also have this
+       result in an animation when the pinentry is shown and
+       not just popping it up.
+    */
     setWindowState(Qt::WindowMinimized);
     QTimer::singleShot(0, this, [this] () {
         raiseWindow (this);
     });
+#else
+    activateWindow();
+    raise();
+#endif
 }
 
 void PinEntryDialog::showEvent(QShowEvent *event)
 {
     QDialog::showEvent(event);
     _edit->setFocus();
 }
 
 void PinEntryDialog::setDescription(const QString &txt)
 {
     _desc->setVisible(!txt.isEmpty());
     _desc->setText(txt);
 #ifndef QT_NO_ACCESSIBILITY
     _desc->setAccessibleDescription(txt);
 #endif
     _icon->setPixmap(icon());
     setError(QString());
 }
 
 QString PinEntryDialog::description() const
 {
     return _desc->text();
 }
 
 void PinEntryDialog::setError(const QString &txt)
 {
     if (!txt.isNull()) {
         _icon->setPixmap(icon(QStyle::SP_MessageBoxCritical));
     }
     _error->setText(txt);
 #ifndef QT_NO_ACCESSIBILITY
     _error->setAccessibleDescription(txt);
 #endif
     _error->setVisible(!txt.isEmpty());
 }
 
 QString PinEntryDialog::error() const
 {
     return _error->text();
 }
 
 void PinEntryDialog::setPin(const QString &txt)
 {
     _edit->setText(txt);
 }
 
 QString PinEntryDialog::pin() const
 {
     return _edit->text();
 }
 
 void PinEntryDialog::setPrompt(const QString &txt)
 {
     _prompt->setText(txt);
     _prompt->setVisible(!txt.isEmpty());
     if (txt.contains("PIN"))
       _disable_echo_allowed = false;
 }
 
 QString PinEntryDialog::prompt() const
 {
     return _prompt->text();
 }
 
 void PinEntryDialog::setOkText(const QString &txt)
 {
     _ok->setText(txt);
 #ifndef QT_NO_ACCESSIBILITY
     _ok->setAccessibleDescription(txt);
 #endif
     _ok->setVisible(!txt.isEmpty());
 }
 
 void PinEntryDialog::setCancelText(const QString &txt)
 {
     _cancel->setText(txt);
 #ifndef QT_NO_ACCESSIBILITY
     _cancel->setAccessibleDescription(txt);
 #endif
     _cancel->setVisible(!txt.isEmpty());
 }
 
 void PinEntryDialog::setQualityBar(const QString &txt)
 {
     if (_have_quality_bar) {
         _quality_bar_label->setText(txt);
 #ifndef QT_NO_ACCESSIBILITY
         _quality_bar_label->setAccessibleDescription(txt);
 #endif
     }
 }
 
 void PinEntryDialog::setQualityBarTT(const QString &txt)
 {
     if (_have_quality_bar) {
         _quality_bar->setToolTip(txt);
     }
 }
 
 void PinEntryDialog::setGenpinLabel(const QString &txt)
 {
     if (!mGenerateActionEdit) {
         return;
     }
     if (txt.isEmpty()) {
         mGenerateActionEdit->setVisible(false);
     } else {
         mGenerateActionEdit->setText(txt);
         mGenerateActionEdit->setVisible(true);
     }
 }
 
 void PinEntryDialog::setGenpinTT(const QString &txt)
 {
     if (mGenerateActionEdit) {
         mGenerateActionEdit->setToolTip(txt);
     }
 }
 
 void PinEntryDialog::onBackspace()
 {
     if (_disable_echo_allowed) {
         _edit->setEchoMode(QLineEdit::NoEcho);
         if (mRepeat) {
             mRepeat->setEchoMode(QLineEdit::NoEcho);
         }
     }
 }
 
 void PinEntryDialog::updateQuality(const QString &txt)
 {
     int length;
     int percent;
     QPalette pal;
 
     if (_timer) {
         _timer->stop();
     }
 
     _disable_echo_allowed = false;
 
     if (!_have_quality_bar || !_pinentry_info) {
         return;
     }
     const QByteArray utf8_pin = txt.toUtf8();
     const char *pin = utf8_pin.constData();
     length = strlen(pin);
     percent = length ? pinentry_inq_quality(_pinentry_info, pin, length) : 0;
     if (!length) {
         _quality_bar->reset();
     } else {
         pal = _quality_bar->palette();
         if (percent < 0) {
             pal.setColor(QPalette::Highlight, QColor("red"));
             percent = -percent;
         } else {
             pal.setColor(QPalette::Highlight, QColor("green"));
         }
         _quality_bar->setPalette(pal);
         _quality_bar->setValue(percent);
     }
 }
 
 void PinEntryDialog::setPinentryInfo(pinentry_t peinfo)
 {
     _pinentry_info = peinfo;
 }
 
 void PinEntryDialog::focusChanged(QWidget *old, QWidget *now)
 {
     // Grab keyboard. It might be a little weird to do it here, but it works!
     // Previously this code was in showEvent, but that did not work in Qt4.
     if (!_pinentry_info || _pinentry_info->grab) {
         if (_grabbed && old && (old == _edit || old == mRepeat)) {
             old->releaseKeyboard();
             _grabbed = false;
         }
         if (!_grabbed && now && (now == _edit || now == mRepeat)) {
             now->grabKeyboard();
             _grabbed = true;
         }
     }
 
 }
 
 void PinEntryDialog::textChanged(const QString &text)
 {
     Q_UNUSED(text);
     if (mRepeat && mRepeat->text() == _edit->text()) {
         _ok->setEnabled(true);
         _ok->setToolTip(QString());
     } else if (mRepeat) {
         _ok->setEnabled(false);
         _ok->setToolTip(mRepeatError);
     }
 
     if (mVisiActionEdit && sender() == _edit) {
         mVisiActionEdit->setVisible(!_edit->text().isEmpty());
     }
     if (mGenerateActionEdit) {
         mGenerateActionEdit->setVisible(_edit->text().isEmpty() &&
                                         _pinentry_info->genpin_label);
     }
 }
 
 void PinEntryDialog::generatePin()
 {
     const char *pin = pinentry_inq_genpin(_pinentry_info);
     if (pin) {
         if (_edit->echoMode() == QLineEdit::Password) {
             toggleVisibility();
         }
         const auto pinStr = QString::fromUtf8(pin);
         _edit->setText(pinStr);
         mRepeat->setText(pinStr);
     }
 }
 
 void PinEntryDialog::toggleVisibility()
 {
     if (sender() != mVisiCB) {
         if (_edit->echoMode() == QLineEdit::Password) {
             mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("hint")));
             mVisiActionEdit->setToolTip(mHideTT);
             _edit->setEchoMode(QLineEdit::Normal);
             if (mRepeat) {
                 mRepeat->setEchoMode(QLineEdit::Normal);
             }
         } else {
             mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("visibility")));
             mVisiActionEdit->setToolTip(mVisibilityTT);
             _edit->setEchoMode(QLineEdit::Password);
             if (mRepeat) {
                 mRepeat->setEchoMode(QLineEdit::Password);
             }
         }
     } else {
         if (mVisiCB->isChecked()) {
             if (mRepeat) {
                 mRepeat->setEchoMode(QLineEdit::Normal);
             }
             _edit->setEchoMode(QLineEdit::Normal);
         } else {
             if (mRepeat) {
                 mRepeat->setEchoMode(QLineEdit::Password);
             }
             _edit->setEchoMode(QLineEdit::Password);
         }
     }
 }
 
 QString PinEntryDialog::repeatedPin() const
 {
     if (mRepeat) {
         return mRepeat->text();
     }
     return QString();
 }
 
 bool PinEntryDialog::timedOut() const
 {
     return _timed_out;
 }
 
 void PinEntryDialog::setRepeatErrorText(const QString &err)
 {
     mRepeatError = err;
 }
 #include "pinentrydialog.moc"