mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Merge branch 'master' of https://github.com/keepassx/keepassx
This commit is contained in:
commit
e20968bdfe
@ -148,6 +148,8 @@ void AutoType::performAutoType(const Entry* entry, QWidget* hideWindow, const QS
|
|||||||
window = m_plugin->activeWindow();
|
window = m_plugin->activeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
|
||||||
|
|
||||||
Q_FOREACH (AutoTypeAction* action, actions) {
|
Q_FOREACH (AutoTypeAction* action, actions) {
|
||||||
if (m_plugin->activeWindow() != window) {
|
if (m_plugin->activeWindow() != window) {
|
||||||
qWarning("Active window changed, interrupting auto-type.");
|
qWarning("Active window changed, interrupting auto-type.");
|
||||||
@ -475,9 +477,17 @@ QList<AutoTypeAction*> AutoType::createActionFromTemplate(const QString& tmpl, c
|
|||||||
QString resolved = entry->resolvePlaceholders(placeholder);
|
QString resolved = entry->resolvePlaceholders(placeholder);
|
||||||
if (placeholder != resolved) {
|
if (placeholder != resolved) {
|
||||||
Q_FOREACH (const QChar& ch, resolved) {
|
Q_FOREACH (const QChar& ch, resolved) {
|
||||||
|
if (ch == '\n') {
|
||||||
|
list.append(new AutoTypeKey(Qt::Key_Enter));
|
||||||
|
}
|
||||||
|
else if (ch == '\t') {
|
||||||
|
list.append(new AutoTypeKey(Qt::Key_Tab));
|
||||||
|
}
|
||||||
|
else {
|
||||||
list.append(new AutoTypeChar(ch));
|
list.append(new AutoTypeChar(ch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ AutoTypePlatformX11::AutoTypePlatformX11()
|
|||||||
m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome
|
m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome
|
||||||
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3
|
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3
|
||||||
m_classBlacklist << "Plasma"; // KDE 4
|
m_classBlacklist << "Plasma"; // KDE 4
|
||||||
|
m_classBlacklist << "plasmashell"; // KDE 5
|
||||||
m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4
|
m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4
|
||||||
|
|
||||||
m_currentGlobalKey = static_cast<Qt::Key>(0);
|
m_currentGlobalKey = static_cast<Qt::Key>(0);
|
||||||
@ -58,7 +59,9 @@ AutoTypePlatformX11::AutoTypePlatformX11()
|
|||||||
void AutoTypePlatformX11::unload()
|
void AutoTypePlatformX11::unload()
|
||||||
{
|
{
|
||||||
// Restore the KeyboardMapping to its original state.
|
// Restore the KeyboardMapping to its original state.
|
||||||
|
if (m_currentRemapKeysym != NoSymbol) {
|
||||||
AddKeysym(NoSymbol);
|
AddKeysym(NoSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_keysymTable) {
|
if (m_keysymTable) {
|
||||||
XFree(m_keysymTable);
|
XFree(m_keysymTable);
|
||||||
@ -433,9 +436,21 @@ void AutoTypePlatformX11::updateKeymap()
|
|||||||
int mod_index, mod_key;
|
int mod_index, mod_key;
|
||||||
XModifierKeymap *modifiers;
|
XModifierKeymap *modifiers;
|
||||||
|
|
||||||
/* read keyboard map */
|
|
||||||
if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
|
if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True);
|
||||||
m_xkb = XkbGetKeyboard (m_dpy, XkbCompatMapMask | XkbGeometryMask, XkbUseCoreKbd);
|
|
||||||
|
XDeviceInfo* devices;
|
||||||
|
int num_devices;
|
||||||
|
XID keyboard_id = XkbUseCoreKbd;
|
||||||
|
devices = XListInputDevices(m_dpy, &num_devices);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_devices; i++) {
|
||||||
|
if (QString(devices[i].name) == "Virtual core XTEST keyboard") {
|
||||||
|
keyboard_id = devices[i].id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_xkb = XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id);
|
||||||
|
|
||||||
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
|
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
|
||||||
if (m_keysymTable != NULL) XFree(m_keysymTable);
|
if (m_keysymTable != NULL) XFree(m_keysymTable);
|
||||||
@ -469,6 +484,14 @@ void AutoTypePlatformX11::updateKeymap()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFreeModifiermap(modifiers);
|
XFreeModifiermap(modifiers);
|
||||||
|
|
||||||
|
/* Xlib needs some time until the mapping is distributed to
|
||||||
|
all clients */
|
||||||
|
// TODO: we should probably only sleep while in the middle of typing something
|
||||||
|
timespec ts;
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 30 * 1000 * 1000;
|
||||||
|
nanosleep(&ts, Q_NULLPTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoTypePlatformX11::isRemapKeycodeValid()
|
bool AutoTypePlatformX11::isRemapKeycodeValid()
|
||||||
@ -535,13 +558,6 @@ int AutoTypePlatformX11::AddKeysym(KeySym keysym)
|
|||||||
XFlush(m_dpy);
|
XFlush(m_dpy);
|
||||||
updateKeymap();
|
updateKeymap();
|
||||||
|
|
||||||
/* Xlib needs some time until the mapping is distributed to
|
|
||||||
all clients */
|
|
||||||
timespec ts;
|
|
||||||
ts.tv_sec = 0;
|
|
||||||
ts.tv_nsec = 10 * 1000 * 1000;
|
|
||||||
nanosleep(&ts, Q_NULLPTR);
|
|
||||||
|
|
||||||
return m_remapKeycode;
|
return m_remapKeycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,23 +674,56 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
|
|||||||
|
|
||||||
Window root, child;
|
Window root, child;
|
||||||
int root_x, root_y, x, y;
|
int root_x, root_y, x, y;
|
||||||
unsigned int mask;
|
unsigned int wanted_mask = 0;
|
||||||
unsigned int saved_mask;
|
unsigned int original_mask;
|
||||||
|
|
||||||
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
|
XQueryPointer(m_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &original_mask);
|
||||||
saved_mask = mask;
|
|
||||||
|
|
||||||
/* determine keycode and mask for the given keysym */
|
/* determine keycode and mask for the given keysym */
|
||||||
keycode = GetKeycode(keysym, &mask);
|
keycode = GetKeycode(keysym, &wanted_mask);
|
||||||
if (keycode < 8 || keycode > 255) {
|
if (keycode < 8 || keycode > 255) {
|
||||||
qWarning("Unable to get valid keycode for key: keysym=0x%lX", static_cast<long>(keysym));
|
qWarning("Unable to get valid keycode for key: keysym=0x%lX", static_cast<long>(keysym));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release all modifiers */
|
event.state = original_mask;
|
||||||
SendModifier(&event, mask, KeyRelease);
|
|
||||||
|
|
||||||
SendModifier(&event, mask, KeyPress);
|
// modifiers that need to be pressed but aren't
|
||||||
|
unsigned int press_mask = wanted_mask & ~original_mask;
|
||||||
|
|
||||||
|
// modifiers that are pressed but maybe shouldn't
|
||||||
|
unsigned int release_check_mask = original_mask & ~wanted_mask;
|
||||||
|
|
||||||
|
// modifiers we need to release before sending the keycode
|
||||||
|
unsigned int release_mask = 0;
|
||||||
|
|
||||||
|
// check every release_check_mask individually if it affects the keysym we would generate
|
||||||
|
// if it doesn't we probably don't need to release it
|
||||||
|
for (int mod_index = ShiftMapIndex; mod_index <= Mod5MapIndex; mod_index ++) {
|
||||||
|
if (release_check_mask & (1 << mod_index)) {
|
||||||
|
unsigned int mods_rtrn;
|
||||||
|
KeySym keysym_rtrn;
|
||||||
|
XkbTranslateKeyCode(m_xkb, keycode, wanted_mask | (1 << mod_index), &mods_rtrn, &keysym_rtrn);
|
||||||
|
|
||||||
|
if (keysym_rtrn != keysym) {
|
||||||
|
release_mask |= (1 << mod_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally check if the combination of pressed modifiers that we chose to ignore affects the keysym
|
||||||
|
unsigned int mods_rtrn;
|
||||||
|
KeySym keysym_rtrn;
|
||||||
|
XkbTranslateKeyCode(m_xkb, keycode, wanted_mask | (release_check_mask & ~release_mask), &mods_rtrn, &keysym_rtrn);
|
||||||
|
if (keysym_rtrn != keysym) {
|
||||||
|
// oh well, release all the modifiers we don't want
|
||||||
|
release_mask = release_check_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release all modifiers */
|
||||||
|
SendModifier(&event, release_mask, KeyRelease);
|
||||||
|
|
||||||
|
SendModifier(&event, press_mask, KeyPress);
|
||||||
|
|
||||||
/* press and release key */
|
/* press and release key */
|
||||||
event.keycode = keycode;
|
event.keycode = keycode;
|
||||||
@ -682,10 +731,10 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym)
|
|||||||
SendEvent(&event, KeyRelease);
|
SendEvent(&event, KeyRelease);
|
||||||
|
|
||||||
/* release the modifiers */
|
/* release the modifiers */
|
||||||
SendModifier(&event, mask, KeyRelease);
|
SendModifier(&event, press_mask, KeyRelease);
|
||||||
|
|
||||||
/* restore the old keyboard mask */
|
/* restore the old keyboard mask */
|
||||||
SendModifier(&event, saved_mask, KeyPress);
|
SendModifier(&event, release_mask, KeyPress);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
|
int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event)
|
||||||
|
@ -343,6 +343,22 @@ void Metadata::addCustomIcon(const Uuid& uuid, const QImage& icon)
|
|||||||
Q_EMIT modified();
|
Q_EMIT modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
|
||||||
|
{
|
||||||
|
QImage iconScaled;
|
||||||
|
|
||||||
|
// scale down to 64x64 if icon is larger
|
||||||
|
if (icon.width() > 64 || icon.height() > 64) {
|
||||||
|
iconScaled = icon.scaled(QSize(64, 64), Qt::KeepAspectRatio,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iconScaled = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
addCustomIcon(uuid, iconScaled);
|
||||||
|
}
|
||||||
|
|
||||||
void Metadata::removeCustomIcon(const Uuid& uuid)
|
void Metadata::removeCustomIcon(const Uuid& uuid)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!uuid.isNull());
|
Q_ASSERT(!uuid.isNull());
|
||||||
|
@ -115,6 +115,7 @@ public:
|
|||||||
void setProtectNotes(bool value);
|
void setProtectNotes(bool value);
|
||||||
// void setAutoEnableVisualHiding(bool value);
|
// void setAutoEnableVisualHiding(bool value);
|
||||||
void addCustomIcon(const Uuid& uuid, const QImage& icon);
|
void addCustomIcon(const Uuid& uuid, const QImage& icon);
|
||||||
|
void addCustomIconScaled(const Uuid& uuid, const QImage& icon);
|
||||||
void removeCustomIcon(const Uuid& uuid);
|
void removeCustomIcon(const Uuid& uuid);
|
||||||
void copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata);
|
void copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata);
|
||||||
void setRecycleBinEnabled(bool value);
|
void setRecycleBinEnabled(bool value);
|
||||||
|
@ -132,7 +132,7 @@ void EditWidgetIcons::addCustomIcon()
|
|||||||
QImage image(filename);
|
QImage image(filename);
|
||||||
if (!image.isNull()) {
|
if (!image.isNull()) {
|
||||||
Uuid uuid = Uuid::random();
|
Uuid uuid = Uuid::random();
|
||||||
m_database->metadata()->addCustomIcon(uuid, image.scaled(16, 16));
|
m_database->metadata()->addCustomIconScaled(uuid, image);
|
||||||
m_customIconModel->setIcons(m_database->metadata()->customIcons(),
|
m_customIconModel->setIcons(m_database->metadata()->customIcons(),
|
||||||
m_database->metadata()->customIconsOrder());
|
m_database->metadata()->customIconsOrder());
|
||||||
QModelIndex index = m_customIconModel->indexFromUuid(uuid);
|
QModelIndex index = m_customIconModel->indexFromUuid(uuid);
|
||||||
|
Loading…
Reference in New Issue
Block a user