Adds auto-type and global auto-type functionality for OS X. Also fixes a small bug (2992282).

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@383 b624d157-de02-0410-bad0-e51aec6abb33
master
bdmayes 15 years ago
parent 4bee0601d6
commit c5c10b6220
  1. 1
      src/Kdb3Database.cpp
  2. 13
      src/dialogs/AutoTypeDlg.cpp
  3. 1
      src/dialogs/AutoTypeDlg.h
  4. 3
      src/dialogs/TargetWindowDlg.cpp
  5. 54
      src/lib/ShortcutWidget.cpp
  6. 5
      src/lib/ShortcutWidget.h
  7. 21
      src/mainwindow.cpp
  8. 4
      src/res/docs/faq.html
  9. 19
      src/res/docs/quickstart.html
  10. 17
      src/src.pro

@ -976,6 +976,7 @@ bool Kdb3Database::setFileKey(const QString& filename){
RawMasterKey.lock();
return true;
}
file.seek(0);
}
SHA256 sha;
unsigned char* buffer[2048];

@ -18,6 +18,10 @@
#include <QDesktopWidget>
#include "AutoTypeDlg.h"
#ifdef Q_WS_MAC
#include "lib/AutoTypeGlobalMacX.h"
#include "lib/HelperMacX.h"
#endif
bool AutoTypeDlg::dialogVisible = false;
@ -67,7 +71,7 @@ AutoTypeDlg::AutoTypeDlg(QList<IEntryHandle*> entries, QList<int> numbers, bool
if (!hideUsernames)
entryList->setColumnWidth(1, entryList->columnWidth(1)+10);
connect(ButtonBox, SIGNAL(rejected()), SLOT(close()));
connect(ButtonBox, SIGNAL(rejected()), SLOT(cancelled()));
connect(entryList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SLOT(itemSelected(QTreeWidgetItem*)));
connect(entryList, SIGNAL(returnPressed(QTreeWidgetItem*)), SLOT(itemSelected(QTreeWidgetItem*)));
}
@ -113,3 +117,10 @@ void AutoTypeDlg::itemSelected(QTreeWidgetItem* item){
close();
autoType->perform(itemToEntry[item].dbHandle, pWasLocked, itemToEntry[item].nr, pWasLocked);
}
void AutoTypeDlg::cancelled(){
close();
#ifdef Q_WS_MAC
static_cast<AutoTypeGlobalMacX*>(autoType)->cancelled();
#endif
}

@ -35,6 +35,7 @@ class AutoTypeDlg : public QWidget, private Ui::AutoTypeDlg
private slots:
void itemSelected(QTreeWidgetItem* item);
void cancelled();
private:
struct AutoTypeEntry {

@ -23,7 +23,10 @@
TargetWindowDlg::TargetWindowDlg(QWidget* parent) : QDialog(parent){
setupUi(this);
QStringList windowTitles = autoType->getAllWindowTitles();
#ifndef Q_WS_MAC
// on MacX, titles are in top to bottom order which is better than alpha order so no sort
windowTitles.sort();
#endif
for (QStringList::const_iterator i = windowTitles.constBegin(); i != windowTitles.constEnd(); ++i)
comboWindow->addItem(*i);

@ -1,10 +1,10 @@
/***************************************************************************
* Copyright (C) 2009 by Jeff Gibbons *
* Copyright (C) 2005-2008 by Felix Geyer *
* *
* 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; version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
@ -19,13 +19,19 @@
#include "ShortcutWidget.h"
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_X11)
#if defined(GLOBAL_AUTOTYPE) && (defined(Q_WS_X11) || defined(Q_WS_MAC))
#include <QKeyEvent>
#include <QX11Info>
#include <QPalette>
#ifdef Q_WS_X11
#include <QX11Info>
#include "HelperX11.h"
#include "AutoTypeGlobalX11.h"
#endif
#ifdef Q_WS_MAC
#include "lib/HelperMacX.h"
#include "lib/AutoTypeGlobalMacX.h"
#endif
ShortcutWidget::ShortcutWidget(QWidget* parent) : QLineEdit(parent), lock(false), failed(false){
}
@ -56,17 +62,35 @@ void ShortcutWidget::keyEvent(QKeyEvent* event, bool release){
if (release && lock)
return;
#ifdef Q_WS_X11
AutoTypeGlobalX11* autoTypeGlobal = static_cast<AutoTypeGlobalX11*>(autoType);
unsigned int mods = HelperX11::keyboardModifiers(QX11Info::display());
displayShortcut(event->nativeVirtualKey(), release, mods & ControlMask,
mods & ShiftMask, mods & autoTypeGlobal->maskAlt(),
mods & autoTypeGlobal->maskAltGr(), mods & autoTypeGlobal->maskMeta());
#endif
#ifdef Q_WS_MAC
AutoTypeGlobalMacX* autoTypeGlobal = static_cast<AutoTypeGlobalMacX*>(autoType);
quint32 mods = event->nativeModifiers();
// mods >> 16 bits denote outside main keyboard eg keypad, arrow keys, home, end, etc
if ((0 != (mods >> 16)) || (0 == mods)) return;
quint32 key = event->nativeVirtualKey();
// prohibited keys
switch (key) {
case kVK_Delete: case kVK_Escape: case kVK_Return: case kVK_Tab: case kVK_ANSI_KeypadEnter: return;
}
displayShortcut(HelperMacX::keycodeToKeysym(key), release,
mods & autoTypeGlobal->maskCtrl(), mods & autoTypeGlobal->maskShift(),
mods & autoTypeGlobal->maskAlt(), mods & autoTypeGlobal->maskAltGr(),
mods & autoTypeGlobal->maskMeta());
#endif
}
void ShortcutWidget::displayShortcut(quint32 key, bool release, bool ctrl, bool shift, bool alt, bool altgr, bool win){
QString text;
#ifdef Q_WS_X11
if (ctrl)
text.append(tr("Ctrl")).append(" + ");
if (shift)
@ -87,6 +111,20 @@ void ShortcutWidget::displayShortcut(quint32 key, bool release, bool ctrl, bool
else{
text.append(static_cast<quint32>(keysym));
}
#endif
#ifdef Q_WS_MAC
if (ctrl)
text.append(kControlUnicode);
if (shift)
text.append(kShiftUnicode);
if (alt)
text.append(kOptionUnicode);
if (win)
text.append(kCommandUnicode);
KeySym keysym = key;
if (!release && (NoSymbol != keysym)){
text.append(QChar(keysym).toUpper());
#endif
lock = ctrl || shift || alt || altgr || win;
if (lock){
@ -96,11 +134,13 @@ void ShortcutWidget::displayShortcut(quint32 key, bool release, bool ctrl, bool
pShortcut.alt = alt;
pShortcut.altgr = altgr;
pShortcut.win = win;
failed = autoType->registerGlobalShortcut(pShortcut);
if (!failed)
failed = !autoType->registerGlobalShortcut(pShortcut);
if (failed)
setBackgroundColor(QColor(255, 150, 150));
else
else {
setBackgroundColor(Qt::white);
setText(text);
}
}
}
else {
@ -108,8 +148,6 @@ void ShortcutWidget::displayShortcut(quint32 key, bool release, bool ctrl, bool
if (failed)
setBackgroundColor(Qt::white);
}
setText(text);
}
void ShortcutWidget::setBackgroundColor(const QColor& c){

@ -4,7 +4,6 @@
* 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; version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
@ -21,7 +20,7 @@
#define SHORTCUT_WIDGET_H
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_X11)
#if defined(GLOBAL_AUTOTYPE) && (defined(Q_WS_X11) || defined(Q_WS_MAC))
#include "lib/AutoType.h"
#endif
@ -30,7 +29,7 @@ class ShortcutWidget : public QLineEdit{
public:
ShortcutWidget(QWidget* parent = 0);
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_X11)
#if defined(GLOBAL_AUTOTYPE) && (defined(Q_WS_X11) || defined(Q_WS_MAC))
Shortcut shortcut();
void setShortcut(const Shortcut& s);

@ -43,6 +43,10 @@
#include "dialogs/ManageBookmarksDlg.h"
#include "dialogs/HelpDlg.h"
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
#include "lib/HelperMacX.h"
#endif
Import_KeePassX_Xml import_KeePassX_Xml;
Import_PwManager import_PwManager;
Import_KWalletXml import_KWalletXml;
@ -433,6 +437,10 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
QPushButton* readOnlyButton = new QPushButton(tr("Open read-only"), &msgBox);
msgBox.addButton(readOnlyButton, QMessageBox::AcceptRole);
msgBox.setDefaultButton(readOnlyButton);
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
// On MacX, QMessageBox is not brought to foreground on exec() when app not already there
HelperMacX::processToFront(HelperMacX::getKeepassxPID());
#endif
msgBox.exec();
if (!msgBox.clickedButton() || msgBox.clickedButton() == msgBox.button(QMessageBox::No))
@ -454,6 +462,10 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
dlg.setWindowModality(Qt::WindowModal);
unlockDlg = &dlg;
}
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
// On MacX, QMessageBox is not brought to foreground on exec() when app not already there
HelperMacX::processToFront(HelperMacX::getKeepassxPID());
#endif
bool rejected = (dlg.exec()==PasswordDialog::Exit_Cancel);
if (InUnLock)
unlockDlg = NULL;
@ -578,6 +590,10 @@ void KeepassMainWindow::OnFileNewKdb(){
IDatabase* db_new=dynamic_cast<IDatabase*>(new Kdb3Database());
db_new->create();
PasswordDialog dlg(this,PasswordDialog::Mode_Set,PasswordDialog::Flag_None,"New Database");
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
// On MacX, QMessageBox is not brought to foreground on exec()
HelperMacX::processToFront(HelperMacX::getKeepassxPID());
#endif
if(dlg.exec()==PasswordDialog::Exit_Ok){
if(FileOpen)
if(!closeDatabase())return;
@ -1323,6 +1339,11 @@ void KeepassMainWindow::OnUnLockWorkspace(){
if(IsLocked){
if (InUnLock) return;
InUnLock = true;
#if defined(GLOBAL_AUTOTYPE) && defined(Q_WS_MAC)
// show in case minimized, especially in another Space
// only needed if invoked from global autotype
show();
#endif
if ( openDatabase(currentFilePath,true) ){
QTreeWidgetItem* item = GroupView->invisibleRootItem();
if (lockGroup.size()>0){

@ -9,9 +9,9 @@
<h1>KeePassX Frequently Asked Questions</h1>
<a name="faq_autotype_support" />
<h3 class="question">Q: Is Auto-Type supported on Mac OS X or Windows?</h3>
<h3 class="question">Q: On what platforms is Auto-Type supported?</h3>
<p class="answer">
A: No, Auto-Type is currently supported on Linux only.
A: Auto-Type is currently supported on Linux and Mac OS X. It is not supported on Windows.
</p>
<a name="faq_database_formats" />

@ -147,7 +147,7 @@
</p>
<a name="autotype" />
<h2>Setup Auto-Type (currently Linux only)</h2>
<h2>Setup Auto-Type (currently Linux and OS X only)</h2>
<p>
<b>Auto-Type</b> is a feature that allows you to e.g. log in
to web page by hitting only one key combination.
@ -158,7 +158,7 @@
database, it executes a predefined key sequence
(by default your username, <tt>TAB</tt>, password, <tt>ENTER</tt>) in
the active window. This feature is currently available
in the Linux version only.
in the Linux and OS X versions only.
</p>
<p>
To enable Auto-Type, first go to
@ -221,6 +221,21 @@
By modifing the Auto-Type key sequence you can tailor
Auto-Type to suit almost every web login page you'll enter.
</p>
<p>
For OS X, there are two additional Auto-Type elements: <tt>{CLEARFIELD}</tt> and
<tt>{MACSENDKEYCODES}</tt>. <tt>{CLEARFIELD}</tt> clears the typing target to ensure
it is empty before typing into it. <tt>{MACSENDKEYCODES}</tt> should be put at the
beginning of and Auto-Type string to force the use of a more primitive typing
mechanism when the normal mechanism fails. A known case where this is required
is a web site where the login dialog is implemented in flash. The following
is an example:<br><br>
<tt>{MACSENDKEYCODES}{USERNAME}{TAB}{PASSWORD}{ENTER}</tt>
</p>
<p>
Also note that the use of <tt>{CLEARFIELD}</tt> may require the user to define
a somewhat larger Key Stroke Delay in Preferences.
</p>
<!--
<a name="" />

@ -80,12 +80,19 @@ unix : !macx : !isEqual(QMAKE_WIN32,1){
#-------------------------------------------------------------------------------
macx {
isEmpty(PREFIX): PREFIX = /Applications
!isEqual(AUTOTYPE,0){
DEFINES += AUTOTYPE
!isEqual(GLOBAL_AUTOTYPE,0){
DEFINES += GLOBAL_AUTOTYPE
}
}
TARGET = ../bin/KeePassX
target.path = $${PREFIX}
data.files += ../share/keepassx
data.path = Contents/Resources
INSTALLS += data
LIBS += -framework CoreFoundation
LIBS += -framework Carbon
isEqual(LINK,DYNAMIC){
isEmpty(QT_FRAMEWORK_DIR): QT_FRAMEWORK_DIR = /Library/Frameworks
private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtCore.framework
@ -95,7 +102,7 @@ macx {
QMAKE_BUNDLE_DATA += private_frameworks
}
isEqual(LINK,STATIC){
LIBS += -framework Carbon -framework AppKit -lz
LIBS += -framework AppKit -lz
}
QMAKE_BUNDLE_DATA += data
QMAKE_INFO_PLIST= ../share/macx_bundle/Info.plist
@ -106,6 +113,14 @@ macx {
}
isEqual(ARCH,INTEL): CONFIG += x86
isEqual(ARCH,PPC): CONFIG += ppc
contains(DEFINES,AUTOTYPE){
SOURCES += lib/HelperMacX.cpp lib/AutoTypeMacX.cpp
HEADERS += lib/HelperMacX.h lib/AutoTypeMacX.h
}
contains(DEFINES,GLOBAL_AUTOTYPE){
SOURCES += lib/AutoTypeGlobalMacX.cpp
HEADERS += lib/AutoTypeGlobalMacX.h
}
# SOURCES += main_macx.cpp
}