mirror of https://github.com/keeweb/keeweb
fix #554: checking active window id during auto-type
parent
068e49c53c
commit
e0291b2d52
|
@ -1,7 +1,11 @@
|
|||
const Launcher = require('../../comp/launcher');
|
||||
|
||||
const ForeMostAppScript =
|
||||
'tell application "System Events" to set frontApp to name of first process whose frontmost is true';
|
||||
'tell application "System Events"\n' +
|
||||
' set frontAppName to name of first process whose frontmost is true\n' +
|
||||
' set frontAppId to id of first process whose frontmost is true\n' +
|
||||
'end tell\n' +
|
||||
'"" & frontAppId & " " & frontAppName';
|
||||
const ChromeScript =
|
||||
'tell application "{}" to set appUrl to URL of active tab of front window\n' +
|
||||
'tell application "{}" to set appTitle to title of active tab of front window\n' +
|
||||
|
@ -21,12 +25,19 @@ const OtherAppsScript =
|
|||
|
||||
const AutoTypeHelper = function() {};
|
||||
|
||||
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
||||
AutoTypeHelper.prototype.getActiveWindowInfo = function(callback) {
|
||||
AutoTypeHelper.exec(ForeMostAppScript, (err, out) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
const appName = out.trim();
|
||||
const output = out.trim();
|
||||
const spaceIx = output.indexOf(' ');
|
||||
let id = '',
|
||||
appName = '';
|
||||
if (spaceIx >= 0) {
|
||||
id = output.substr(0, spaceIx);
|
||||
appName = output.substr(spaceIx + 1).trim();
|
||||
}
|
||||
// getting urls and titles from Chrome or Safari:
|
||||
// - will suit in 90% cases
|
||||
// - does not require assistive access
|
||||
|
@ -34,26 +45,37 @@ AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
|||
if (['Google Chrome', 'Chromium', 'Google Chrome Canary'].indexOf(appName) >= 0) {
|
||||
AutoTypeHelper.exec(ChromeScript.replace(/\{}/g, appName), (err, out) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(err, { id });
|
||||
}
|
||||
const parts = out.split('\n');
|
||||
return callback(null, (parts[1] || '').trim(), parts[0].trim());
|
||||
return callback(null, {
|
||||
id,
|
||||
url: parts[0].trim(),
|
||||
title: (parts[1] || '').trim()
|
||||
});
|
||||
});
|
||||
} else if (['Safari', 'Webkit'].indexOf(appName) >= 0) {
|
||||
AutoTypeHelper.exec(SafariScript.replace(/\{}/g, appName), (err, out) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(err, { id });
|
||||
}
|
||||
const parts = out.split('\n');
|
||||
return callback(null, (parts[1] || '').trim(), parts[0].trim());
|
||||
return callback(null, {
|
||||
id,
|
||||
url: parts[0].trim(),
|
||||
title: (parts[1] || '').trim()
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// special cases are not available. this method may ask the user about assistive access
|
||||
AutoTypeHelper.exec(OtherAppsScript.replace(/\{}/g, appName), (err, out) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
return callback(err, { id });
|
||||
}
|
||||
return callback(null, out.trim());
|
||||
return callback(null, {
|
||||
id,
|
||||
title: out.trim()
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,12 +2,20 @@ const Launcher = require('../../comp/launcher');
|
|||
|
||||
const AutoTypeHelper = function() {};
|
||||
|
||||
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
||||
AutoTypeHelper.prototype.getActiveWindowInfo = function(callback) {
|
||||
Launcher.spawn({
|
||||
cmd: 'xdotool',
|
||||
args: ['getactivewindow', 'getwindowname'],
|
||||
complete(err, res) {
|
||||
return callback(err, res ? res.trim() : undefined);
|
||||
args: ['getactivewindow', 'getwindowname', 'getactivewindow'],
|
||||
complete(err, out) {
|
||||
let windowInfo;
|
||||
if (out) {
|
||||
const [id, title] = out.trim().split('\n');
|
||||
windowInfo = {
|
||||
id,
|
||||
title
|
||||
};
|
||||
}
|
||||
return callback(err, windowInfo);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ const AutoTypeNativeHelper = require('./auto-type-native-helper');
|
|||
|
||||
const AutoTypeHelper = function() {};
|
||||
|
||||
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
||||
AutoTypeHelper.prototype.getActiveWindowInfo = function(callback) {
|
||||
Launcher.spawn({
|
||||
cmd: AutoTypeNativeHelper.getHelperPath(),
|
||||
args: ['--window-info'],
|
||||
|
@ -11,8 +11,13 @@ AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
|
|||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
const parts = out.split('\n');
|
||||
return callback(null, (parts[0] || '').trim(), parts[1] ? parts[1].trim() : undefined);
|
||||
const [id, title, url] = out.trim().split('\n');
|
||||
const windowInfo = {
|
||||
id,
|
||||
title,
|
||||
url
|
||||
};
|
||||
return callback(null, windowInfo);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -152,30 +152,59 @@ const AutoType = {
|
|||
}
|
||||
},
|
||||
|
||||
getActiveWindowTitle(callback) {
|
||||
logger.debug('Get window title');
|
||||
return this.helper.getActiveWindowTitle((err, title, url) => {
|
||||
getActiveWindowInfo(callback) {
|
||||
logger.debug('Getting window info');
|
||||
return this.helper.getActiveWindowInfo((err, windowInfo) => {
|
||||
if (err) {
|
||||
logger.error('Error get window title', err);
|
||||
logger.error('Error getting window info', err);
|
||||
} else {
|
||||
if (!url) {
|
||||
if (!windowInfo.url) {
|
||||
// try to find a URL in the title
|
||||
const urlMatcher = new RegExp(
|
||||
'https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)'
|
||||
);
|
||||
const urlMatches = urlMatcher.exec(title);
|
||||
url = urlMatches && urlMatches.length > 0 ? urlMatches[0] : null;
|
||||
const urlMatches = urlMatcher.exec(windowInfo.title);
|
||||
windowInfo.url = urlMatches && urlMatches.length > 0 ? urlMatches[0] : null;
|
||||
}
|
||||
logger.debug('Window title', title, url);
|
||||
logger.debug('Window info', windowInfo.id, windowInfo.title, windowInfo.url);
|
||||
}
|
||||
return callback(err, title, url);
|
||||
return callback(err, windowInfo);
|
||||
});
|
||||
},
|
||||
|
||||
activeWindowMatches(windowInfo, callback) {
|
||||
if (!windowInfo || !windowInfo.id) {
|
||||
logger.debug('Skipped active window check because window id is unknown');
|
||||
return callback(true);
|
||||
}
|
||||
this.getActiveWindowInfo((err, activeWindowInfo) => {
|
||||
if (!activeWindowInfo) {
|
||||
logger.debug('Error during active window check, something is wrong', err);
|
||||
return callback(false);
|
||||
}
|
||||
if (activeWindowInfo.id !== windowInfo.id) {
|
||||
logger.info(
|
||||
`Active window doesn't match: ID is different. ` +
|
||||
`Expected ${windowInfo.id}, got ${activeWindowInfo.id}`
|
||||
);
|
||||
return callback(false, activeWindowInfo);
|
||||
}
|
||||
if (activeWindowInfo.url !== windowInfo.url) {
|
||||
logger.info(
|
||||
`Active window doesn't match: url is different. ` +
|
||||
`Expected "${windowInfo.url}", got "${activeWindowInfo.url}"`
|
||||
);
|
||||
return callback(false, activeWindowInfo);
|
||||
}
|
||||
logger.info('Active window matches');
|
||||
callback(true, activeWindowInfo);
|
||||
});
|
||||
},
|
||||
|
||||
selectEntryAndRun() {
|
||||
this.getActiveWindowTitle((e, title, url) => {
|
||||
const filter = new AutoTypeFilter({ title, url }, this.appModel);
|
||||
const evt = { filter };
|
||||
this.getActiveWindowInfo((e, windowInfo) => {
|
||||
const filter = new AutoTypeFilter(windowInfo, this.appModel);
|
||||
const evt = { filter, windowInfo };
|
||||
if (!this.appModel.files.hasOpenFiles()) {
|
||||
this.pendingEvent = evt;
|
||||
this.appModel.files.once('update', this.processPendingEvent, this);
|
||||
|
@ -211,7 +240,11 @@ const AutoType = {
|
|||
this.selectEntryView = null;
|
||||
this.hideWindow(() => {
|
||||
if (result) {
|
||||
this.runAndHandleResult(result);
|
||||
this.activeWindowMatches(evt.windowInfo, (matches, activeWindowInfo) => {
|
||||
if (matches) {
|
||||
this.runAndHandleResult(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ Release notes
|
|||
`+` #1243: auto-type any field
|
||||
`-` fix #764: multiple attachments display
|
||||
`-` fix multi-line fields display in history
|
||||
`-` fix #554: checking active window id during auto-type
|
||||
|
||||
##### v1.10.0 (2019-09-09)
|
||||
`+` macOS Dark theme
|
||||
|
|
Loading…
Reference in New Issue