[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-bugs-dist
Subject: [Bug 113057] kwallet popup window does not grab focus anymore
From: Lubos Lunak <l.lunak () kde ! org>
Date: 2006-08-29 15:09:56
Message-ID: 20060829150956.14231.qmail () ktown ! kde ! org
[Download RAW message or body]
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
http://bugs.kde.org/show_bug.cgi?id=113057
l.lunak kde org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
------- Additional Comments From l.lunak kde org 2006-08-29 17:09 -------
SVN commit 578532 by lunakl:
Replace the wallet dialog hacks that were supposed to work around #91940
and caused #113057 with slightly better hacks. If somebody notices
some problems with kwallet dialogs after this change please yell.
CCMAIL: kde-core-devel kde org
BUG: 113057
M +50 -26 kwalletd.cpp
M +7 -2 kwalletd.h
--- branches/KDE/3.5/kdelibs/kio/misc/kwalletd/kwalletd.cpp #578531:578532
@ -50,10 +50,6 @
#include <assert.h>
-#ifdef Q_WS_X11
-#include <X11/Xlib.h>
-#endif
-
extern "C" {
KDE_EXPORT KDEDModule *create_kwalletd(const QCString &name) {
return new KWalletD(name);
@ -67,6 +63,7 @
tType = Unknown;
transaction = 0L;
client = 0L;
+ modal = false;
}
~KWalletTransaction() {
@ -83,6 +80,7 @
QCString appid;
uint wId;
QString wallet;
+ bool modal;
};
@ -149,7 +147,7 @
switch (xact->tType) {
case KWalletTransaction::Open:
- res = doTransactionOpen(xact->appid, xact->wallet, xact->wId);
+ res = doTransactionOpen(xact->appid, xact->wallet, xact->wId, xact->modal);
replyType = "int";
if (!xact->returnObject.isEmpty()) {
DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res);
@ -232,6 +230,7 @
DCOPRef(appid, returnObject).send("walletOpenResult", 0);
QTimer::singleShot(0, this, SLOT(processTransactions()));
+ checkActiveDialog();
}
@ -266,18 +265,53 @
xact->wallet = wallet;
xact->wId = wId;
xact->tType = KWalletTransaction::Open;
+ xact->modal = true; // mark dialogs as modal, the app has blocking wait
QTimer::singleShot(0, this, SLOT(processTransactions()));
+ checkActiveDialog();
return 0; // process later
}
-int KWalletD::doTransactionOpen(const QCString& appid, const QString& wallet, uint \
wId) { +// Sets up a dialog that will be shown by kwallet.
+void KWalletD::setupDialog( QWidget* dialog, WId wId, const QCString& appid, bool \
modal ) { + if( wId != 0 )
+ KWin::setMainWindow( dialog, wId ); // correct, set dialog parent
+ else {
+ if( appid.isEmpty())
+ kdWarning() << "Using kwallet without parent window!" << endl;
+ else
+ kdWarning() << "Application '" << appid << "' using kwallet without parent \
window!" << endl; + // allow dialog activation even if it interrupts, better than \
trying hacks + // with keeping the dialog on top or on all desktops
+ kapp->updateUserTimestamp();
+ }
+ if( modal )
+ KWin::setState( dialog->winId(), NET::Modal );
+ else
+ KWin::clearState( dialog->winId(), NET::Modal );
+ activeDialog = dialog;
+}
+
+// If there's a dialog already open and another application tries some operation \
that'd lead to +// opening a dialog, that application will be blocked by this dialog. \
A proper solution would +// be to set the second application's window also as a \
parent for the active dialog, so that +// KWin properly handles focus changes and so \
on, but there's currently no support for multiple +// dialog parents. Hopefully to be \
done in KDE4, for now just use all kinds of bad hacks to make +// sure the user \
doesn't overlook the active dialog. +void KWalletD::checkActiveDialog() {
+ if( !activeDialog || !activeDialog->isShown())
+ return;
+ kapp->updateUserTimestamp();
+ KWin::setState( activeDialog->winId(), NET::KeepAbove );
+ KWin::setOnAllDesktops( activeDialog->winId(), true );
+ KWin::forceActiveWindow( activeDialog->winId());
+}
+
+int KWalletD::doTransactionOpen(const QCString& appid, const QString& wallet, uint \
wId, bool modal) { if (_firstUse && \
!wallets().contains(KWallet::Wallet::LocalWallet())) { // First use wizard
KWalletWizard *wiz = new KWalletWizard(0);
-#ifdef Q_WS_X11
- XSetTransientForHint(qt_xdisplay(), wiz->winId(), wId);
-#endif
+ setupDialog( wiz, wId, appid, modal );
int rc = wiz->exec();
if (rc == QDialog::Accepted) {
KConfig cfg("kwalletrc");
@ -317,12 +351,12 @
cfg.sync();
}
- int rc = internalOpen(appid, wallet, false, wId);
+ int rc = internalOpen(appid, wallet, false, wId, modal);
return rc;
}
-int KWalletD::internalOpen(const QCString& appid, const QString& wallet, bool \
isPath, WId w) { +int KWalletD::internalOpen(const QCString& appid, const QString& \
wallet, bool isPath, WId w, bool modal) { int rc = -1;
bool brandNew = false;
@ -402,11 +436,7 @
const char *p = 0L;
while (!b->isOpen()) {
assert(kpd); // kpd can't be null if isOpen() is false
-#ifdef Q_WS_X11
- XSetTransientForHint(qt_xdisplay(), kpd->winId(), w);
-#endif
- KWin::setState( kpd->winId(), NET::KeepAbove );
- KWin::setOnAllDesktops(kpd->winId(), true);
+ setupDialog( kpd, w, appid, modal );
if (kpd->exec() == KDialog::Accepted) {
p = kpd->password();
int rc = b->open(QByteArray().duplicate(p, strlen(p)));
@ -489,12 +519,7 @
} else {
dialog->setLabel(i18n("<qt>The application '<b>%1</b>' has requested access to \
the open wallet '<b>%2</b>'.").arg(QStyleSheet::escape(QString(appid))).arg(QStyleSheet::escape(wallet)));
}
-#ifdef Q_WS_X11
- XSetTransientForHint(qt_xdisplay(), dialog->winId(), w);
-#endif
- KWin::setState(dialog->winId(), NET::KeepAbove);
- KWin::setOnAllDesktops(dialog->winId(), true);
-
+ setupDialog( dialog, w, appid, false );
response = dialog->exec();
delete dialog;
}
@ -560,6 +585,7 @
_transactions.append(xact);
QTimer::singleShot(0, this, SLOT(processTransactions()));
+ checkActiveDialog();
}
@ -576,7 +602,7 @
}
if (!it.current()) {
- handle = doTransactionOpen(appid, wallet, wId);
+ handle = doTransactionOpen(appid, wallet, wId,false);
if (-1 == handle) {
KMessageBox::sorryWId(wId, i18n("Unable to open wallet. The wallet must be opened \
in order to change the password."), i18n("KDE Wallet Service")); return;
@ -596,9 +622,7 @
kpd->setPrompt(i18n("<qt>Please choose a new password for the wallet \
'<b>%1</b>'.").arg(QStyleSheet::escape(wallet))); kpd->setCaption(i18n("KDE Wallet \
Service")); kpd->setAllowEmptyPasswords(true);
-#ifdef Q_WS_X11
- XSetTransientForHint(qt_xdisplay(), kpd->winId(), wId);
-#endif
+ setupDialog( kpd, wId, appid, false );
if (kpd->exec() == KDialog::Accepted) {
const char *p = kpd->password();
if (p) {
--- branches/KDE/3.5/kdelibs/kio/misc/kwalletd/kwalletd.h #578531:578532
@ -26,6 +26,7 @
#include <qintdict.h>
#include <qstring.h>
#include <qwidget.h>
+#include <qguardedptr.h>
#include "kwalletbackend.h"
#include <time.h>
@ -150,7 +151,7 @
void processTransactions();
private:
- int internalOpen(const QCString& appid, const QString& wallet, bool isPath = \
false, WId w = 0); + int internalOpen(const QCString& appid, const QString& wallet, \
bool isPath = false, WId w = 0, bool modal = false); bool isAuthorizedApp(const \
QCString& appid, const QString& wallet, WId w); // This also validates the handle. \
May return NULL. KWallet::Backend* getWallet(const QCString& appid, int handle);
@ -169,8 +170,11 @
QCString friendlyDCOPPeerName();
void doTransactionChangePassword(const QCString& appid, const QString& wallet, \
uint wId);
- int doTransactionOpen(const QCString& appid, const QString& wallet, uint wId);
+ int doTransactionOpen(const QCString& appid, const QString& wallet, uint wId, bool \
modal);
+ void setupDialog( QWidget* dialog, WId wId, const QCString& appid, bool modal );
+ void checkActiveDialog();
+
QIntDict<KWallet::Backend> _wallets;
QMap<QCString,QValueList<int> > _handles;
QMap<QString,QCString> _passwords;
@ -184,6 +188,7 @
KTimeout *_timeouts;
QPtrList<KWalletTransaction> _transactions;
+ QGuardedPtr< QWidget > activeDialog;
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic