cleaned up legacy auto-type

pull/1777/head
antelle 2 years ago
parent 6ba3d44fa1
commit 4e84121553
No known key found for this signature in database
GPG Key ID: 63C9777AAB7C563C

@ -144,18 +144,6 @@ module.exports = function (grunt) {
expand: true,
nonull: true
},
'desktop-darwin-helper-x64': {
src: 'helper/darwin/KeeWebHelper',
dest: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Resources/',
nonull: true,
options: { mode: '0755' }
},
'desktop-darwin-helper-arm64': {
src: 'helper/darwin/KeeWebHelper',
dest: 'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app/Contents/Resources/',
nonull: true,
options: { mode: '0755' }
},
'desktop-darwin-installer-helper-x64': {
cwd: 'tmp/desktop/KeeWeb Installer.app',
src: '**',
@ -174,21 +162,6 @@ module.exports = function (grunt) {
nonull: true,
options: { mode: true }
},
'desktop-windows-helper-x64': {
src: 'helper/win32/KeeWebHelper.exe',
dest: 'tmp/desktop/KeeWeb-win32-x64/Resources/',
nonull: true
},
'desktop-windows-helper-ia32': {
src: 'helper/win32/KeeWebHelper.exe',
dest: 'tmp/desktop/KeeWeb-win32-ia32/Resources/',
nonull: true
},
'desktop-windows-helper-arm64': {
src: 'helper/win32/KeeWebHelper.exe',
dest: 'tmp/desktop/KeeWeb-win32-arm64/Resources/',
nonull: true
},
'desktop-win32-dist-x64': {
src: 'tmp/desktop/KeeWeb.win.x64.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.x64.exe`,

@ -1,19 +0,0 @@
import { Launcher } from 'comp/launcher';
import { AppSettingsModel } from 'models/app-settings-model';
import { AutoTypeEmitter } from 'auto-type/auto-type-emitter';
const AutoTypeEmitterFactory = {
create(callback, windowId) {
if (Launcher && Launcher.autoTypeSupported) {
if (AppSettingsModel.useLegacyAutoType) {
const { AutoTypeEmitter } = require('./emitter/auto-type-emitter-' +
Launcher.platform());
return new AutoTypeEmitter(callback, windowId);
}
return new AutoTypeEmitter(callback, windowId);
}
return null;
}
};
export { AutoTypeEmitterFactory };

@ -1,19 +0,0 @@
import { Launcher } from 'comp/launcher';
import { AppSettingsModel } from 'models/app-settings-model';
import { AutoTypeHelper } from 'auto-type/auto-type-helper';
const AutoTypeHelperFactory = {
create() {
if (Launcher && Launcher.autoTypeSupported) {
if (AppSettingsModel.useLegacyAutoType) {
const { AutoTypeHelper } = require('./helper/auto-type-helper-' +
Launcher.platform());
return new AutoTypeHelper();
}
return new AutoTypeHelper();
}
return null;
}
};
export { AutoTypeHelperFactory };

@ -1,8 +1,7 @@
import { AutoTypeEmitterFactory } from 'auto-type/auto-type-emitter-factory';
import { AutoTypeEmitter } from 'auto-type/auto-type-emitter';
import { AutoTypeObfuscator } from 'auto-type/auto-type-obfuscator';
import { StringFormat } from 'util/formatting/string-format';
import { Logger } from 'util/logger';
import { AppSettingsModel } from 'models/app-settings-model';
const emitterLogger = new Logger(
'auto-type-emitter',
@ -433,9 +432,7 @@ AutoTypeRunner.prototype.obfuscateOp = function (op) {
};
AutoTypeRunner.prototype.run = function (callback, windowId) {
const emitterType = AppSettingsModel.useLegacyAutoType ? 'legacy' : 'native';
emitterLogger.info(`Using ${emitterType} auto-type emitter`);
this.emitter = AutoTypeEmitterFactory.create(this.emitNext.bind(this), windowId);
this.emitter = new AutoTypeEmitter(this.emitNext.bind(this), windowId);
this.emitterState = {
callback,
stack: [],

@ -1,133 +0,0 @@
import { AutoTypeNativeHelper } from 'auto-type/helper/auto-type-native-helper';
import { Launcher } from 'comp/launcher';
// http://eastmanreference.com/complete-list-of-applescript-key-codes/
const KeyMap = {
tab: 48,
enter: 36,
space: 49,
up: 126,
down: 125,
left: 123,
right: 124,
home: 115,
end: 119,
pgup: 116,
pgdn: 121,
ins: 114,
del: 117,
bs: 51,
esc: 53,
win: 55,
rwin: 55,
f1: 122,
f2: 120,
f3: 99,
f4: 118,
f5: 96,
f6: 97,
f7: 98,
f8: 100,
f9: 101,
f10: 109,
f11: 103,
f12: 111,
f13: 105,
f14: 107,
f15: 113,
f16: 106,
add: 69,
subtract: 78,
multiply: 67,
divide: 75,
n0: 82,
n1: 83,
n2: 84,
n3: 85,
n4: 86,
n5: 87,
n6: 88,
n7: 89,
n8: 91,
n9: 92
};
const ModMap = {
'^': '@',
'+': '+',
'%': '%',
'^^': '^'
};
const AutoTypeEmitter = function (callback) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
};
AutoTypeEmitter.prototype.begin = function () {
this.callback();
};
AutoTypeEmitter.prototype.setMod = function (mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function (text) {
this.pendingScript.push('text ' + this.modString() + ' ' + text);
this.callback();
};
AutoTypeEmitter.prototype.key = function (key) {
if (typeof key !== 'number') {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key];
}
this.pendingScript.push('key ' + this.modString() + key);
this.callback();
};
AutoTypeEmitter.prototype.copyPaste = function (text) {
this.pendingScript.push('copypaste ' + text);
this.callback();
};
AutoTypeEmitter.prototype.wait = function (time) {
this.pendingScript.push('wait ' + time);
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function () {
if (this.pendingScript.length) {
const script = this.pendingScript.join('\n');
this.pendingScript.length = 0;
this.runScript(script);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.setDelay = function (delay) {
this.delay = delay || 0;
this.callback('Not implemented');
};
AutoTypeEmitter.prototype.modString = function () {
return Object.keys(this.mod).join('');
};
AutoTypeEmitter.prototype.runScript = function (script) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
data: script,
complete: this.callback
});
};
export { AutoTypeEmitter };

@ -1,162 +0,0 @@
import { Launcher } from 'comp/launcher';
import { Locale } from 'util/locale';
// https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
const KeyMap = {
tab: 'Tab',
enter: 'KP_Enter',
space: 'KP_Space',
up: 'Up',
down: 'Down',
left: 'Left',
right: 'Right',
home: 'Home',
end: 'End',
pgup: 'Page_Up',
pgdn: 'Page_Down',
ins: 'Insert',
del: 'Delete',
bs: 'BackSpace',
esc: 'Escape',
win: 'Meta_L',
rwin: 'Meta_R',
f1: 'F1',
f2: 'F2',
f3: 'F3',
f4: 'F4',
f5: 'F5',
f6: 'F6',
f7: 'F7',
f8: 'F8',
f9: 'F9',
f10: 'F10',
f11: 'F11',
f12: 'F12',
f13: 'F13',
f14: 'F14',
f15: 'F15',
f16: 'F16',
add: 'KP_Add',
subtract: 'KP_Subtract',
multiply: 'KP_Multiply',
divide: 'KP_Divide',
n0: 'KP_0',
n1: 'KP_1',
n2: 'KP_2',
n3: 'KP_3',
n4: 'KP_4',
n5: 'KP_5',
n6: 'KP_6',
n7: 'KP_7',
n8: 'KP_8',
n9: 'KP_9'
};
const ModMap = {
'^': 'ctrl',
'+': 'shift',
'%': 'alt',
'^^': 'ctrl'
};
const AutoTypeEmitter = function (callback, windowId) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
if (typeof windowId !== 'undefined' && windowId) {
this.pendingScript.push('windowactivate --sync ' + windowId);
}
};
AutoTypeEmitter.prototype.begin = function () {
this.callback();
};
AutoTypeEmitter.prototype.setMod = function (mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function (text) {
this.pendingScript.push('keyup ctrl alt shift t');
Object.keys(this.mod).forEach((mod) => {
this.pendingScript.push('keydown ' + ModMap[mod]);
});
text.split('').forEach((char) => {
this.pendingScript.push('key ' + 'U' + char.charCodeAt(0).toString(16));
});
Object.keys(this.mod).forEach((mod) => {
this.pendingScript.push('keyup ' + ModMap[mod]);
});
this.waitComplete();
};
AutoTypeEmitter.prototype.key = function (key) {
const isSpecialKey = typeof key !== 'number';
if (isSpecialKey) {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key].toString();
}
this.pendingScript.push('key --clearmodifiers ' + this.modString() + key);
if (isSpecialKey) {
this.waitComplete();
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.copyPaste = function (text) {
this.pendingScript.push('sleep 0.5');
Launcher.setClipboardText(text);
this.pendingScript.push('key --clearmodifiers ' + 'shift+Insert');
this.pendingScript.push('sleep 0.5');
this.waitComplete();
};
AutoTypeEmitter.prototype.wait = function (time) {
this.pendingScript.push('sleep ' + time / 1000);
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function (callback) {
if (this.pendingScript.length) {
const script = this.pendingScript.join(' ');
this.pendingScript.length = 0;
this.runScript(script, callback);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.modString = function () {
let mod = '';
Object.keys(this.mod).forEach((key) => {
mod += key + '+';
});
return mod;
};
AutoTypeEmitter.prototype.runScript = function (script, callback) {
// xdotool doesn't like it when stdin doesn't end with a linebreak
// see https://github.com/keeweb/keeweb/issues/1409
const data = script + '\n';
Launcher.spawn({
cmd: 'xdotool',
args: ['-'],
data,
complete: (err, stdout, code) => {
if (err && err.code === 'ENOENT') {
err = Locale.autoTypeErrorNotInstalled.replace('{}', 'xdotool');
}
const cb = callback || this.callback;
cb(err, stdout, code);
}
});
};
export { AutoTypeEmitter };

@ -1,135 +0,0 @@
import { AutoTypeNativeHelper } from 'auto-type/helper/auto-type-native-helper';
import { Launcher } from 'comp/launcher';
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
const KeyMap = {
tab: 0x09,
enter: 0x0d,
space: 0x20,
up: 0x26,
down: 0x28,
left: 0x25,
right: 0x27,
home: 0x24,
end: 0x23,
pgup: 0x21,
pgdn: 0x22,
ins: 0x2d,
del: 0x2e,
bs: 0x08,
esc: 0x1b,
win: 0x5b,
rwin: 0x5c,
f1: 0x70,
f2: 0x71,
f3: 0x72,
f4: 0x73,
f5: 0x74,
f6: 0x75,
f7: 0x76,
f8: 0x77,
f9: 0x78,
f10: 0x79,
f11: 0x7a,
f12: 0x7b,
f13: 0x7c,
f14: 0x7d,
f15: 0x7e,
f16: 0x7f,
add: 0x6b,
subtract: 0x6d,
multiply: 0x6a,
divide: 0x6f,
n0: 0x30,
n1: 0x31,
n2: 0x32,
n3: 0x33,
n4: 0x34,
n5: 0x35,
n6: 0x36,
n7: 0x37,
n8: 0x38,
n9: 0x39
};
const ModMap = {
'^': '^',
'+': '+',
'%': '%',
'^^': '^'
};
const AutoTypeEmitter = function (callback) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
};
AutoTypeEmitter.prototype.begin = function () {
this.callback();
};
AutoTypeEmitter.prototype.setMod = function (mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function (text) {
if (text) {
this.pendingScript.push('text ' + this.modStr() + ' ' + text);
}
this.callback();
};
AutoTypeEmitter.prototype.key = function (key) {
if (typeof key !== 'number') {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key];
}
this.pendingScript.push('key ' + this.modStr() + key);
this.callback();
};
AutoTypeEmitter.prototype.copyPaste = function (text) {
this.pendingScript.push('copypaste ' + text);
this.callback();
};
AutoTypeEmitter.prototype.wait = function (time) {
this.pendingScript.push('wait ' + time);
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function () {
if (this.pendingScript.length) {
const script = this.pendingScript.join('\n');
this.pendingScript.length = 0;
this.runScript(script);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.setDelay = function (delay) {
this.delay = delay || 0;
this.callback('Not implemented');
};
AutoTypeEmitter.prototype.modStr = function () {
return Object.keys(this.mod).join('');
};
AutoTypeEmitter.prototype.runScript = function (script) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
data: script,
complete: this.callback
});
};
export { AutoTypeEmitter };

@ -1,92 +0,0 @@
import { Launcher } from 'comp/launcher';
const ForeMostAppScript =
'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' +
'return appUrl & "\n" & appTitle';
const SafariScript =
'tell application "{}" to set appUrl to URL of front document\n' +
'tell application "{}" to set appTitle to name of front document\n' +
'return appUrl & "\n" & appTitle';
const OtherAppsScript =
'tell application "System Events"\n' +
' tell process "{}"\n' +
' tell (1st window whose value of attribute "AXMain" is true)\n' +
' set windowTitle to value of attribute "AXTitle"\n' +
' end tell\n' +
' end tell\n' +
'end tell';
const AutoTypeHelper = function () {};
AutoTypeHelper.prototype.getActiveWindowInfo = function (callback) {
AutoTypeHelper.exec(ForeMostAppScript, (err, out) => {
if (err) {
return callback(err);
}
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
// - allows to get url
if (['Google Chrome', 'Chromium', 'Google Chrome Canary'].indexOf(appName) >= 0) {
AutoTypeHelper.exec(ChromeScript.replace(/\{}/g, appName), (err, out) => {
if (err) {
return callback(err, { id });
}
const parts = out.split('\n');
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, { id });
}
const parts = out.split('\n');
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, { id });
}
return callback(null, {
id,
title: out.trim()
});
});
}
});
};
AutoTypeHelper.exec = function (script, callback) {
Launcher.spawn({
cmd: 'osascript',
args: ['-e', script],
complete: callback
});
};
export { AutoTypeHelper };

@ -1,23 +0,0 @@
import { Launcher } from 'comp/launcher';
const AutoTypeHelper = function () {};
AutoTypeHelper.prototype.getActiveWindowInfo = function (callback) {
Launcher.spawn({
cmd: 'xdotool',
args: ['getactivewindow', 'getwindowname', 'getactivewindow'],
complete(err, out) {
let windowInfo;
if (out) {
const [title, id] = out.trim().split('\n');
windowInfo = {
id,
title
};
}
return callback(err, windowInfo);
}
});
};
export { AutoTypeHelper };

@ -1,25 +0,0 @@
import { AutoTypeNativeHelper } from 'auto-type/helper/auto-type-native-helper';
import { Launcher } from 'comp/launcher';
const AutoTypeHelper = function () {};
AutoTypeHelper.prototype.getActiveWindowInfo = function (callback) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
args: ['--window-info'],
complete(err, out) {
if (err) {
return callback(err);
}
const [id, title, url] = out.trim().split('\n');
const windowInfo = {
id,
title,
url
};
return callback(null, windowInfo);
}
});
};
export { AutoTypeHelper };

@ -1,21 +0,0 @@
import { Launcher } from 'comp/launcher';
import { Logger } from 'util/logger';
const logger = new Logger('auto-type');
const AutoTypeNativeHelper = {
getHelperPath() {
if (this._helperPath) {
return this._helperPath;
}
const ext = process.platform === 'win32' ? '.exe' : '';
const helperRelPath = `helper/${process.platform}/KeeWebHelper${ext}`;
const helperPath = Launcher.getAppPath(helperRelPath);
Launcher.ensureRunnable(helperPath);
logger.debug('Using auto-type helper', helperPath);
this._helperPath = helperPath;
return helperPath;
}
};
export { AutoTypeNativeHelper };

@ -1,6 +1,6 @@
import { Events } from 'framework/events';
import { AutoTypeFilter } from 'auto-type/auto-type-filter';
import { AutoTypeHelperFactory } from 'auto-type/auto-type-helper-factory';
import { AutoTypeHelper } from 'auto-type/auto-type-helper';
import { AutoTypeParser } from 'auto-type/auto-type-parser';
import { Launcher } from 'comp/launcher';
import { Features } from 'util/features';
@ -168,9 +168,8 @@ const AutoType = {
},
getActiveWindowInfo(callback) {
const helperType = AppSettingsModel.useLegacyAutoType ? 'legacy' : 'native';
logger.debug(`Getting window info using ${helperType} helper`);
const helper = AutoTypeHelperFactory.create();
logger.debug('Getting window info');
const helper = new AutoTypeHelper();
return helper.getActiveWindowInfo((err, windowInfo) => {
if (err) {
logger.error('Error getting window info', err);

@ -43,7 +43,6 @@ const DefaultAppSettings = {
excludePinsFromAudit: true, // exclude PIN codes from audit
checkPasswordsOnHIBP: false, // check passwords on Have I Been Pwned
auditPasswordAge: 0, // show warnings about old passwords, number of years, 0 = disabled
useLegacyAutoType: false, // use legacy auto-type engine (will be removed in future versions)
deviceOwnerAuth: null, // Touch ID: null / 'memory' / 'file'
deviceOwnerAuthTimeoutMinutes: 0, // how often master password is required with Touch ID
disableOfflineStorage: false, // don't cache loaded files in offline storage

@ -464,7 +464,6 @@
"setGenShowAppLogs": "Show app logs",
"setGenReloadApp": "Reload the app",
"setGenFieldLabelDblClickAutoType": "Auto-type on double-clicking field labels",
"setGenUseLegacyAutoType": "Use legacy auto-type (if you have issues)",
"setGenTouchId": "Touch ID",
"setGenTouchIdDisabled": "Don't use Touch ID",
"setGenTouchIdMemory": "Unlock with Touch ID only while KeeWeb is running",

@ -54,7 +54,6 @@ class SettingsGeneralView extends View {
'change .settings__general-direct-autotype': 'changeDirectAutotype',
'change .settings__general-field-label-dblclick-autotype':
'changeFieldLabelDblClickAutoType',
'change .settings__general-use-legacy-autotype': 'changeUseLegacyAutoType',
'change .settings__general-device-owner-auth': 'changeDeviceOwnerAuth',
'change .settings__general-device-owner-auth-timeout': 'changeDeviceOwnerAuthTimeout',
'change .settings__general-titlebar-style': 'changeTitlebarStyle',
@ -135,7 +134,6 @@ class SettingsGeneralView extends View {
useGroupIconForEntries: AppSettingsModel.useGroupIconForEntries,
directAutotype: AppSettingsModel.directAutotype,
fieldLabelDblClickAutoType: AppSettingsModel.fieldLabelDblClickAutoType,
useLegacyAutoType: AppSettingsModel.useLegacyAutoType,
supportsTitleBarStyles: Features.supportsTitleBarStyles(),
supportsCustomTitleBarAndDraggableWindow: Features.supportsCustomTitleBarAndDraggableWindow(),
titlebarStyle: AppSettingsModel.titlebarStyle,
@ -435,12 +433,6 @@ class SettingsGeneralView extends View {
Events.emit('refresh');
}
changeUseLegacyAutoType(e) {
const useLegacyAutoType = e.target.checked || false;
AppSettingsModel.useLegacyAutoType = useLegacyAutoType;
Events.emit('refresh');
}
changeDeviceOwnerAuth(e) {
const deviceOwnerAuth = e.target.value || null;

@ -326,13 +326,6 @@
<h2 id="advanced">{{res 'advanced'}}</h2>
<a class="settings__general-show-advanced">{{res 'setGenShowAdvanced'}}</a>
<div class="settings__general-advanced hide">
{{#if canAutoType}}
<div>
<input type="checkbox" class="settings__input input-base settings__general-use-legacy-autotype"
id="settings__general-use-legacy-autotype" {{#if useLegacyAutoType}}checked{{/if}} />
<label for="settings__general-use-legacy-autotype">{{res 'setGenUseLegacyAutoType'}}</label>
</div>
{{/if}}
{{#if devTools}}
<button class="btn-silent settings__general-dev-tools-link">{{res 'setGenDevTools'}}</button>
<button class="btn-silent settings__general-try-beta-link">{{res 'setGenTryBeta'}}</button>

@ -53,7 +53,6 @@ module.exports = function(grunt) {
'electron:darwin-x64',
'electron-patch:darwin-x64',
'build-darwin-installer',
'copy:desktop-darwin-helper-x64',
'copy:desktop-darwin-installer-helper-x64',
'copy:native-modules-darwin-x64'
]);
@ -67,7 +66,6 @@ module.exports = function(grunt) {
'default',
'build-desktop-app-content',
'electron:win32-x64',
'copy:desktop-windows-helper-x64',
'copy:native-modules-win32-x64'
]);

@ -37,8 +37,6 @@ module.exports = function (grunt) {
'electron-patch:darwin-x64',
'electron-patch:darwin-arm64',
'build-darwin-installer',
'copy:desktop-darwin-helper-x64',
'copy:desktop-darwin-helper-arm64',
'copy:desktop-darwin-installer-helper-x64',
'copy:desktop-darwin-installer-helper-arm64',
'copy:native-modules-darwin-x64',
@ -65,9 +63,6 @@ module.exports = function (grunt) {
sign ? 'sign-exe:win32-build-x64' : 'noop',
sign ? 'sign-exe:win32-build-ia32' : 'noop',
sign ? 'sign-exe:win32-build-arm64' : 'noop',
'copy:desktop-windows-helper-x64',
'copy:desktop-windows-helper-ia32',
'copy:desktop-windows-helper-arm64',
'copy:native-modules-win32-x64',
'copy:native-modules-win32-ia32',
'copy:native-modules-win32-arm64'

Binary file not shown.

@ -1,308 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
48035AAD1D5724FF00EB44C4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AAC1D5724FF00EB44C4 /* main.m */; };
48035AB41D57263A00EB44C4 /* InputParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AB31D57263A00EB44C4 /* InputParser.m */; };
48035ABF1D57286F00EB44C4 /* NoOpCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035ABE1D57286F00EB44C4 /* NoOpCommand.m */; };
48035AC11D57393200EB44C4 /* libreadline.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 48035AC01D57393200EB44C4 /* libreadline.tbd */; };
48035AC41D573A8F00EB44C4 /* UnknownCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AC31D573A8F00EB44C4 /* UnknownCommand.m */; };
48035AC61D573C1200EB44C4 /* WaitCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AC51D573C1200EB44C4 /* WaitCommand.m */; };
48035ACA1D573E0D00EB44C4 /* CopyPasteCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AC91D573E0D00EB44C4 /* CopyPasteCommand.m */; };
48035ACD1D573F0600EB44C4 /* SendTextCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035ACC1D573F0600EB44C4 /* SendTextCommand.m */; };
48035AD01D573FD900EB44C4 /* KeyRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035ACF1D573FD900EB44C4 /* KeyRunner.m */; };
48035AD51D57410600EB44C4 /* SendKeyCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 48035AD41D57410600EB44C4 /* SendKeyCommand.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
48035AA71D5724FF00EB44C4 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
48035AA91D5724FF00EB44C4 /* KeeWebHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KeeWebHelper; sourceTree = BUILT_PRODUCTS_DIR; };
48035AAC1D5724FF00EB44C4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
48035AB31D57263A00EB44C4 /* InputParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InputParser.m; sourceTree = "<group>"; };
48035AB51D57267600EB44C4 /* InputParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InputParser.h; sourceTree = "<group>"; };
48035AB71D57275600EB44C4 /* InputCommandBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InputCommandBase.h; path = InputCommands/InputCommandBase.h; sourceTree = "<group>"; };
48035ABD1D57286F00EB44C4 /* NoOpCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NoOpCommand.h; path = InputCommands/NoOpCommand.h; sourceTree = "<group>"; };
48035ABE1D57286F00EB44C4 /* NoOpCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NoOpCommand.m; path = InputCommands/NoOpCommand.m; sourceTree = "<group>"; };
48035AC01D57393200EB44C4 /* libreadline.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libreadline.tbd; path = usr/lib/libreadline.tbd; sourceTree = SDKROOT; };
48035AC21D573A8300EB44C4 /* UnknownCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UnknownCommand.h; path = InputCommands/UnknownCommand.h; sourceTree = "<group>"; };
48035AC31D573A8F00EB44C4 /* UnknownCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UnknownCommand.m; path = InputCommands/UnknownCommand.m; sourceTree = "<group>"; };
48035AC51D573C1200EB44C4 /* WaitCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WaitCommand.m; path = InputCommands/WaitCommand.m; sourceTree = "<group>"; };
48035AC71D573C2200EB44C4 /* WaitCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WaitCommand.h; path = InputCommands/WaitCommand.h; sourceTree = "<group>"; };
48035AC81D573DE800EB44C4 /* CopyPasteCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CopyPasteCommand.h; path = InputCommands/CopyPasteCommand.h; sourceTree = "<group>"; };
48035AC91D573E0D00EB44C4 /* CopyPasteCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CopyPasteCommand.m; path = InputCommands/CopyPasteCommand.m; sourceTree = "<group>"; };
48035ACB1D573EE800EB44C4 /* SendTextCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SendTextCommand.h; path = InputCommands/SendTextCommand.h; sourceTree = "<group>"; };
48035ACC1D573F0600EB44C4 /* SendTextCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SendTextCommand.m; path = InputCommands/SendTextCommand.m; sourceTree = "<group>"; };
48035ACE1D573F8100EB44C4 /* KeyRunner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyRunner.h; sourceTree = "<group>"; };
48035ACF1D573FD900EB44C4 /* KeyRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyRunner.m; sourceTree = "<group>"; };
48035AD11D57406700EB44C4 /* SendKeyCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SendKeyCommand.h; path = InputCommands/SendKeyCommand.h; sourceTree = "<group>"; };
48035AD41D57410600EB44C4 /* SendKeyCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SendKeyCommand.m; path = InputCommands/SendKeyCommand.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
48035AA61D5724FF00EB44C4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
48035AC11D57393200EB44C4 /* libreadline.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
48035AA01D5724FF00EB44C4 = {
isa = PBXGroup;
children = (
48035AC01D57393200EB44C4 /* libreadline.tbd */,
48035AAB1D5724FF00EB44C4 /* KeeWebHelper */,
48035AAA1D5724FF00EB44C4 /* Products */,
);
sourceTree = "<group>";
};
48035AAA1D5724FF00EB44C4 /* Products */ = {
isa = PBXGroup;
children = (
48035AA91D5724FF00EB44C4 /* KeeWebHelper */,
);
name = Products;
sourceTree = "<group>";
};
48035AAB1D5724FF00EB44C4 /* KeeWebHelper */ = {
isa = PBXGroup;
children = (
48035AB61D57273300EB44C4 /* InputCommands */,
48035AAC1D5724FF00EB44C4 /* main.m */,
48035AB31D57263A00EB44C4 /* InputParser.m */,
48035AB51D57267600EB44C4 /* InputParser.h */,
48035ACE1D573F8100EB44C4 /* KeyRunner.h */,
48035ACF1D573FD900EB44C4 /* KeyRunner.m */,
);
path = KeeWebHelper;
sourceTree = "<group>";
};
48035AB61D57273300EB44C4 /* InputCommands */ = {
isa = PBXGroup;
children = (
48035AB71D57275600EB44C4 /* InputCommandBase.h */,
48035ABD1D57286F00EB44C4 /* NoOpCommand.h */,
48035ABE1D57286F00EB44C4 /* NoOpCommand.m */,
48035AC21D573A8300EB44C4 /* UnknownCommand.h */,
48035AC31D573A8F00EB44C4 /* UnknownCommand.m */,
48035AC51D573C1200EB44C4 /* WaitCommand.m */,
48035AC71D573C2200EB44C4 /* WaitCommand.h */,
48035AC81D573DE800EB44C4 /* CopyPasteCommand.h */,
48035AC91D573E0D00EB44C4 /* CopyPasteCommand.m */,
48035ACB1D573EE800EB44C4 /* SendTextCommand.h */,
48035ACC1D573F0600EB44C4 /* SendTextCommand.m */,
48035AD11D57406700EB44C4 /* SendKeyCommand.h */,
48035AD41D57410600EB44C4 /* SendKeyCommand.m */,
);
name = InputCommands;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
48035AA81D5724FF00EB44C4 /* KeeWebHelper */ = {
isa = PBXNativeTarget;
buildConfigurationList = 48035AB01D5724FF00EB44C4 /* Build configuration list for PBXNativeTarget "KeeWebHelper" */;
buildPhases = (
48035AA51D5724FF00EB44C4 /* Sources */,
48035AA61D5724FF00EB44C4 /* Frameworks */,
48035AA71D5724FF00EB44C4 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = KeeWebHelper;
productName = KeeWebHelper;
productReference = 48035AA91D5724FF00EB44C4 /* KeeWebHelper */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
48035AA11D5724FF00EB44C4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = KeeWeb;
TargetAttributes = {
48035AA81D5724FF00EB44C4 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 48035AA41D5724FF00EB44C4 /* Build configuration list for PBXProject "KeeWebHelper" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 48035AA01D5724FF00EB44C4;
productRefGroup = 48035AAA1D5724FF00EB44C4 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
48035AA81D5724FF00EB44C4 /* KeeWebHelper */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
48035AA51D5724FF00EB44C4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
48035ACA1D573E0D00EB44C4 /* CopyPasteCommand.m in Sources */,
48035AD51D57410600EB44C4 /* SendKeyCommand.m in Sources */,
48035AD01D573FD900EB44C4 /* KeyRunner.m in Sources */,
48035AAD1D5724FF00EB44C4 /* main.m in Sources */,
48035AB41D57263A00EB44C4 /* InputParser.m in Sources */,
48035AC61D573C1200EB44C4 /* WaitCommand.m in Sources */,
48035ACD1D573F0600EB44C4 /* SendTextCommand.m in Sources */,
48035AC41D573A8F00EB44C4 /* UnknownCommand.m in Sources */,
48035ABF1D57286F00EB44C4 /* NoOpCommand.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
48035AAE1D5724FF00EB44C4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
48035AAF1D5724FF00EB44C4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.9;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
48035AB11D5724FF00EB44C4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
48035AB21D5724FF00EB44C4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
48035AA41D5724FF00EB44C4 /* Build configuration list for PBXProject "KeeWebHelper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
48035AAE1D5724FF00EB44C4 /* Debug */,
48035AAF1D5724FF00EB44C4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
48035AB01D5724FF00EB44C4 /* Build configuration list for PBXNativeTarget "KeeWebHelper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
48035AB11D5724FF00EB44C4 /* Debug */,
48035AB21D5724FF00EB44C4 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 48035AA11D5724FF00EB44C4 /* Project object */;
}

@ -1,11 +0,0 @@
#import <Foundation/Foundation.h>
#import "InputCommandBase.h"
@interface CopyPasteCommand : NSObject<InputCommandBase> {
NSString *text;
}
- (id)initWithText:(NSString *)aText;
@end

@ -1,29 +0,0 @@
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
#import "CopyPasteCommand.h"
#import "../KeyRunner.h"
@implementation CopyPasteCommand
- (id)initWithText:(NSString *)aText {
self = [super init];
if (self) {
text = aText;
}
return self;
}
- (void)execute {
usleep(500000);
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents];
[pasteboard setString:text forType:NSStringPboardType];
usleep(500000);
[KeyRunner keyModUpDown:kCGEventFlagMaskCommand down:true];
[KeyRunner keyPress:0 code:kVK_ANSI_V flags:kCGEventFlagMaskCommand];
[KeyRunner keyModUpDown:kCGEventFlagMaskCommand down:false];
usleep(500000);
}
@end

@ -1,5 +0,0 @@
@protocol InputCommandBase
- (void)execute;
@end

@ -1,12 +0,0 @@
#import <Foundation/Foundation.h>
#import "InputCommandBase.h"
@interface NoOpCommand : NSObject<InputCommandBase> {
NSString *message;
}
- (id)init;
- (id)initWithMessage:(NSString *)aMessage;
@end

@ -1,24 +0,0 @@
#import "NoOpCommand.h"
@implementation NoOpCommand
- (id)init {
self = [super init];
return self;
}
- (id)initWithMessage:(NSString *)aMessage {
self = [super init];
if (self) {
message = aMessage;
}
return self;
}
- (void)execute {
if (message) {
NSLog(@"Error: %@", message);
}
}
@end

@ -1,14 +0,0 @@
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
#import "InputCommandBase.h"
@interface SendKeyCommand : NSObject<InputCommandBase> {
CGKeyCode key;
CGEventFlags modifier;
}
- (id)initWithKey:(CGKeyCode)aKey andModifier:(CGEventFlags)aModifier;
@end

@ -1,25 +0,0 @@
#import "SendKeyCommand.h"
#import "../KeyRunner.h"
@implementation SendKeyCommand
- (id)initWithKey:(CGKeyCode)aKey andModifier:(CGEventFlags)aModifier {
self = [super init];
if (self) {
key = aKey;
modifier = aModifier;
}
return self;
}
- (void)execute {
if (modifier) {
[KeyRunner keyModUpDown:modifier down:true];
}
[KeyRunner keyPress:0 code:key flags:modifier];
if (modifier) {
[KeyRunner keyModUpDown:modifier down:false];
}
}
@end

@ -1,13 +0,0 @@
#import <Foundation/Foundation.h>
#import "InputCommandBase.h"
@interface SendTextCommand : NSObject<InputCommandBase> {
NSString *text;
CGEventFlags modifier;
}
- (id)initWithText:(NSString *)aText andModifier:(CGEventFlags)aModifier;
+ (void)initialize;
@end

@ -1,112 +0,0 @@
#import "SendTextCommand.h"
#import "../KeyRunner.h"
@implementation SendTextCommand
NSDictionary *knownKeyCodes;
- (id)initWithText:(NSString *)aText andModifier:(CGEventFlags)aModifier {
self = [super init];
if (self) {
text = aText;
modifier = aModifier;
}
return self;
}
- (void)execute {
if (modifier) {
[KeyRunner keyModUpDown:modifier down:true];
}
NSString *textLower = [text lowercaseString];
for (int i = 0; i < text.length; i++) {
unichar ch = [text characterAtIndex:i];
unichar chLower = [textLower characterAtIndex:i];
id knownKeyCode = [knownKeyCodes objectForKey:@(chLower)];
CGKeyCode keyCode = knownKeyCode == nil ? 0 : (CGKeyCode)[knownKeyCode unsignedShortValue];
if (modifier && modifier != kCGEventFlagMaskShift) {
ch = 0;
}
[KeyRunner keyPress:ch code:keyCode flags:modifier];
}
if (modifier) {
[KeyRunner keyModUpDown:modifier down:false];
}
}
+ (void)initialize {
knownKeyCodes = @{
@'0': @(kVK_ANSI_0),
@'1': @(kVK_ANSI_1),
@'2': @(kVK_ANSI_2),
@'3': @(kVK_ANSI_3),
@'4': @(kVK_ANSI_4),
@'5': @(kVK_ANSI_5),
@'6': @(kVK_ANSI_6),
@'7': @(kVK_ANSI_7),
@'8': @(kVK_ANSI_8),
@'9': @(kVK_ANSI_9),
@'0': @(kVK_ANSI_0),
@'a': @(kVK_ANSI_A),
@'b': @(kVK_ANSI_B),
@'c': @(kVK_ANSI_C),
@'d': @(kVK_ANSI_D),
@'e': @(kVK_ANSI_E),
@'f': @(kVK_ANSI_F),
@'g': @(kVK_ANSI_G),
@'h': @(kVK_ANSI_H),
@'i': @(kVK_ANSI_I),
@'j': @(kVK_ANSI_J),
@'k': @(kVK_ANSI_K),
@'l': @(kVK_ANSI_L),
@'m': @(kVK_ANSI_M),
@'n': @(kVK_ANSI_N),
@'o': @(kVK_ANSI_O),
@'p': @(kVK_ANSI_P),
@'q': @(kVK_ANSI_Q),
@'r': @(kVK_ANSI_R),
@'s': @(kVK_ANSI_S),
@'t': @(kVK_ANSI_T),
@'u': @(kVK_ANSI_U),
@'v': @(kVK_ANSI_V),
@'w': @(kVK_ANSI_W),
@'x': @(kVK_ANSI_X),
@'y': @(kVK_ANSI_Y),
@'z': @(kVK_ANSI_Z),
@'!': @(kVK_ANSI_1),
@'@': @(kVK_ANSI_2),
@'#': @(kVK_ANSI_3),
@'$': @(kVK_ANSI_4),
@'%': @(kVK_ANSI_5),
@'^': @(kVK_ANSI_6),
@'&': @(kVK_ANSI_7),
@'*': @(kVK_ANSI_8),
@'(': @(kVK_ANSI_9),
@')': @(kVK_ANSI_0),
@'-': @(kVK_ANSI_Minus),
@'_': @(kVK_ANSI_Minus),
@'=': @(kVK_ANSI_Equal),
@'+': @(kVK_ANSI_Equal),
@'`': @(kVK_ANSI_Grave),
@'~': @(kVK_ANSI_Grave),
@',': @(kVK_ANSI_Comma),
@'<': @(kVK_ANSI_Comma),
@'.': @(kVK_ANSI_Period),
@'>': @(kVK_ANSI_Period),
@'/': @(kVK_ANSI_Slash),
@'?': @(kVK_ANSI_Slash),
@'\\': @(kVK_ANSI_Backslash),
@'|': @(kVK_ANSI_Backslash),
@';': @(kVK_ANSI_Semicolon),
@':': @(kVK_ANSI_Semicolon),
@'\'': @(kVK_ANSI_Quote),
@'"': @(kVK_ANSI_Quote),
@'[': @(kVK_ANSI_LeftBracket),
@'{': @(kVK_ANSI_LeftBracket),
@']': @(kVK_ANSI_RightBracket),
@'}': @(kVK_ANSI_RightBracket),
@'\t': @(kVK_Tab)
};
}
@end

@ -1,11 +0,0 @@
#import <Foundation/Foundation.h>
#import "InputCommandBase.h"
@interface UnknownCommand : NSObject<InputCommandBase> {
NSString *name;
}
- (id)initWithName:(NSString *)aName;
@end

@ -1,17 +0,0 @@
#import "UnknownCommand.h"
@implementation UnknownCommand
- (id)initWithName:(NSString *)aName {
self = [super init];
if (self) {
name = aName;
}
return self;
}
- (void)execute {
NSLog(@"Unknown command: %@", name);
}
@end

@ -1,11 +0,0 @@
#import <Foundation/Foundation.h>
#import "InputCommandBase.h"
@interfa