Skip to content

Instantly share code, notes, and snippets.

@Samasaur1
Created November 18, 2023 22:33
Show Gist options
  • Save Samasaur1/71f246cd8797da05385f927220f6ef43 to your computer and use it in GitHub Desktop.
Save Samasaur1/71f246cd8797da05385f927220f6ef43 to your computer and use it in GitHub Desktop.
import Cocoa
let src = CGEventSource(stateID: .hidSystemState)
let down = CGEvent(keyboardEventSource: src, virtualKey: 0x12, keyDown: true)!
let up = CGEvent(keyboardEventSource: src, virtualKey: 0x12, keyDown: false)!
sleep(5)
////down?.post(tap: .cghidEventTap)
////up?.post(tap: .cghidEventTap)
////down?.flags = .maskCommand
//
//let cmd_d = CGEvent(keyboardEventSource: src, virtualKey: 0x37, keyDown: true)!
//let cmd_u = CGEvent(keyboardEventSource: src, virtualKey: 0x37, keyDown: false)!
//let a_d = CGEvent(keyboardEventSource: src, virtualKey: 0x00, keyDown: true)!
//let a_u = CGEvent(keyboardEventSource: src, virtualKey: 0x00, keyDown: false)!
//let delete_d = CGEvent(keyboardEventSource: src, virtualKey: 0x33, keyDown: true)!
//let delete_u = CGEvent(keyboardEventSource: src, virtualKey: 0x33, keyDown: false)!
//
//down.post(tap: .cghidEventTap)
//up.post(tap: .cghidEventTap)
//sleep(1)
////cmd_d.post(tap: .cghidEventTap)
//a_d.flags = .maskCommand
//a_u.flags = .maskCommand
//a_d.post(tap: .cghidEventTap)
//a_u.post(tap: .cghidEventTap)
////cmd_u.post(tap: .cghidEventTap)
//sleep(1)
//delete_d.post(tap: .cghidEventTap)
//delete_u.post(tap: .cghidEventTap)
enum KeyCode: UInt16 {
// https://gist.github.com/swillits/df648e87016772c7f7e5dbed2b345066
// Layout-independent Keys
// eg.These key codes are always the same key on all layouts.
case returnKey = 0x24
// case enter = 0x4C //0x24
case tab = 0x30
case space = 0x31
case delete = 0x33
case escape = 0x35
case command = 0x37
case shift = 0x38
case capsLock = 0x39
case option = 0x3A
case control = 0x3B
case rightShift = 0x3C
case rightOption = 0x3D
case rightControl = 0x3E
case leftArrow = 0x7B
case rightArrow = 0x7C
case downArrow = 0x7D
case upArrow = 0x7E
case volumeUp = 0x48
case volumeDown = 0x49
case mute = 0x4A
case help = 0x72
case home = 0x73
case pageUp = 0x74
case forwardDelete = 0x75
case end = 0x77
case pageDown = 0x79
case function = 0x3F
case f1 = 0x7A
case f2 = 0x78
case f4 = 0x76
case f5 = 0x60
case f6 = 0x61
case f7 = 0x62
case f3 = 0x63
case f8 = 0x64
case f9 = 0x65
case f10 = 0x6D
case f11 = 0x67
case f12 = 0x6F
case f13 = 0x69
case f14 = 0x6B
case f15 = 0x71
case f16 = 0x6A
case f17 = 0x40
case f18 = 0x4F
case f19 = 0x50
case f20 = 0x5A
// US-ANSI Keyboard Positions
// eg. These key codes are for the physical key (in any keyboard layout)
// at the location of the named key in the US-ANSI layout.
case a = 0x00
case b = 0x0B
case c = 0x08
case d = 0x02
case e = 0x0E
case f = 0x03
case g = 0x05
case h = 0x04
case i = 0x22
case j = 0x26
case k = 0x28
case l = 0x25
case m = 0x2E
case n = 0x2D
case o = 0x1F
case p = 0x23
case q = 0x0C
case r = 0x0F
case s = 0x01
case t = 0x11
case u = 0x20
case v = 0x09
case w = 0x0D
case x = 0x07
case y = 0x10
case z = 0x06
case zero = 0x1D
case one = 0x12
case two = 0x13
case three = 0x14
case four = 0x15
case five = 0x17
case six = 0x16
case seven = 0x1A
case eight = 0x1C
case nine = 0x19
case equals = 0x18
case minus = 0x1B
case semicolon = 0x29
case apostrophe = 0x27
case comma = 0x2B
case period = 0x2F
case forwardSlash = 0x2C
case backslash = 0x2A
case grave = 0x32
case leftBracket = 0x21
case rightBracket = 0x1E
case keypadDecimal = 0x41
case keypadMultiply = 0x43
case keypadPlus = 0x45
case keypadClear = 0x47
case keypadDivide = 0x4B
case keypadEnter = 0x4C
case keypadMinus = 0x4E
case keypadEquals = 0x51
case keypad0 = 0x52
case keypad1 = 0x53
case keypad2 = 0x54
case keypad3 = 0x55
case keypad4 = 0x56
case keypad5 = 0x57
case keypad6 = 0x58
case keypad7 = 0x59
case keypad8 = 0x5B
case keypad9 = 0x5C
}
func press(_ key: KeyCode, withModifiers modifiers: CGEventFlags = .init()) {
let down = CGEvent(keyboardEventSource: src, virtualKey: key.rawValue, keyDown: true)!
let up = CGEvent(keyboardEventSource: src, virtualKey: key.rawValue, keyDown: false)!
down.flags = modifiers
up.flags = modifiers
down.post(tap: .cghidEventTap)
up.post(tap: .cghidEventTap)
}
struct KeyPress {
let key: KeyCode
let modifiers: CGEventFlags
}
func press(_ key: KeyPress) {
press(key.key, withModifiers: key.modifiers)
}
/// An enum representing possible typing rates.
///
/// - allAtOnce: All the text should be typed at once.
/// - consistent: The text should be typed at a reasonable speed, but with no variance in delay.
/// - natural: The text should be typed so that it appears natural.
/// - customConsistent: The text should be typed at a consistent speed, specified by the associated value.
/// - customVarying: The text should be typed around a given speed, with 5 possible ranges of variation. Both the base speed and the maximum variance are specified by associated values.
public enum Rate {
/// All the text should be typed at once.
case allAtOnce
/// The text should be typed at a reasonable speed, but with no variance in delay.
case consistent
/// The text should be typed so that it appears natural.
case natural
/// The text should be typed at a specified consistent speed.
/// - µsecondDelay: The delay between each key typed.
case customConsistent(µsecondDelay: UInt32)
/// The text should be typed around a specified given speed, with specified variation. The base delay should be the average delay time, and the max variance is the maximum distance from the average to the fastest/slowest possible delay.
/// - µsecondBaseDelay: The base delay between each key typed.
/// - maxVariance: The delay between each key typed.
case customVarying(µsecondBaseDelay: UInt32, maxVariance: UInt32)
}
func type(_ text: [KeyPress], typing: Rate = .natural) {
for character in text {
press(character)
switch typing {
case .allAtOnce:
usleep(0001000)
case .consistent:
usleep(0100000)
case .natural:
var sleepTime = UInt32.random(in: 0...4)
sleepTime *= 10000
usleep(0080000 + sleepTime)
case .customConsistent(let µsecondDelay):
usleep(µsecondDelay)
case let .customVarying(µsecondBaseDelay, maxVariance):
var sleepTime = UInt32.random(in: 0...4)
let base = µsecondBaseDelay - maxVariance
sleepTime *= (maxVariance / 2)
let µsecondDelay = base + sleepTime
usleep(µsecondDelay)
}
}
}
let lowercaseCharMap: [Character: KeyCode] = [
"a": .a,
"b": .b,
"c": .c,
"d": .d,
"e": .e,
"f": .f,
"g": .g,
"h": .h,
"i": .i,
"j": .j,
"k": .k,
"l": .l,
"m": .m,
"n": .n,
"o": .o,
"p": .p,
"q": .q,
"r": .r,
"s": .s,
"t": .t,
"u": .u,
"v": .v,
"w": .w,
"x": .x,
"y": .y,
"z": .z,
"0": .zero,
"1": .one,
"2": .two,
"3": .three,
"4": .four,
"5": .five,
"6": .six,
"7": .seven,
"8": .eight,
"9": .nine,
"=": .equals,
"-": .minus,
";": .semicolon,
"'": .apostrophe,
",": .comma,
".": .period,
"/": .forwardSlash,
"\\": .backslash,
"`": .grave,
"[": .leftBracket,
"]": .rightBracket,
" ": .space
]
let uppercaseCharMap: [Character: KeyCode] = [
"A": .a,
"B": .b,
"C": .c,
"D": .d,
"E": .e,
"F": .f,
"G": .g,
"H": .h,
"I": .i,
"J": .j,
"K": .k,
"L": .l,
"M": .m,
"N": .n,
"O": .o,
"P": .p,
"Q": .q,
"R": .r,
"S": .s,
"T": .t,
"U": .u,
"V": .v,
"W": .w,
"X": .x,
"Y": .y,
"Z": .z,
")": .zero,
"!": .one,
"@": .two,
"#": .three,
"$": .four,
"%": .five,
"^": .six,
"&": .seven,
"*": .eight,
"(": .nine,
"+": .equals,
"_": .minus,
":": .semicolon,
"\"": .apostrophe,
"<": .comma,
">": .period,
"?": .forwardSlash,
"|": .backslash,
"~": .grave,
"{": .leftBracket,
"}": .rightBracket,
]
func type(_ text: String, typing: Rate = .natural) {
type(str_to_kparr(text), typing: typing)
}
type("Hello, there")
func str_to_kparr(_ str: String) -> [KeyPress] {
str.map { char -> KeyPress in
if let kc = lowercaseCharMap[char] {
return KeyPress(key: kc, modifiers: .init())
}
if let kc = uppercaseCharMap[char] {
return KeyPress(key: kc, modifiers: .maskShift)
}
return KeyPress(key: .three, modifiers: .maskShift)
}
}
func +(lhs: String, rhs: [KeyPress]) -> [KeyPress] {
return str_to_kparr(lhs) + rhs
}
func +(lhs: [KeyPress], rhs: String) -> [KeyPress] {
return lhs + str_to_kparr(rhs)
}
type("! General Kenobi" + [.init(key: .a, modifiers: .maskCommand), .init(key: .delete, modifiers: .init()), .init(key: .space, modifiers: [.maskCommand])])
extension KeyPress {
static let returnKey = KeyPress(key: .returnKey, modifiers: .init())
static let enter = Self.returnKey
static let tab = KeyPress(key: .tab, modifiers: .init())
static let space = KeyPress(key: .space, modifiers: .init())
static let delete = KeyPress(key: .delete, modifiers: .init())
static let escape = KeyPress(key: .escape, modifiers: .init())
static let command = KeyPress(key: .command, modifiers: .init())
static let shift = KeyPress(key: .shift, modifiers: .init())
static let capsLock = KeyPress(key: .capsLock, modifiers: .init())
static let option = KeyPress(key: .option, modifiers: .init())
static let control = KeyPress(key: .control, modifiers: .init())
static let rightShift = KeyPress(key: .rightShift, modifiers: .init())
static let rightOption = KeyPress(key: .rightOption, modifiers: .init())
static let rightControl = KeyPress(key: .rightControl, modifiers: .init())
static let leftArrow = KeyPress(key: .leftArrow, modifiers: .init())
static let rightArrow = KeyPress(key: .rightArrow, modifiers: .init())
static let downArrow = KeyPress(key: .downArrow, modifiers: .init())
static let upArrow = KeyPress(key: .upArrow, modifiers: .init())
static let volumeUp = KeyPress(key: .volumeUp, modifiers: .init())
static let volumeDown = KeyPress(key: .volumeDown, modifiers: .init())
static let mute = KeyPress(key: .mute, modifiers: .init())
static let help = KeyPress(key: .help, modifiers: .init())
static let home = KeyPress(key: .home, modifiers: .init())
static let pageUp = KeyPress(key: .pageUp, modifiers: .init())
static let forwardDelete = KeyPress(key: .forwardDelete, modifiers: .init())
static let end = KeyPress(key: .end, modifiers: .init())
static let pageDown = KeyPress(key: .pageDown, modifiers: .init())
static let function = KeyPress(key: .function, modifiers: .init())
static let f1 = KeyPress(key: .f1, modifiers: .init())
static let f2 = KeyPress(key: .f2, modifiers: .init())
static let f4 = KeyPress(key: .f4, modifiers: .init())
static let f5 = KeyPress(key: .f5, modifiers: .init())
static let f6 = KeyPress(key: .f6, modifiers: .init())
static let f7 = KeyPress(key: .f7, modifiers: .init())
static let f3 = KeyPress(key: .f3, modifiers: .init())
static let f8 = KeyPress(key: .f8, modifiers: .init())
static let f9 = KeyPress(key: .f9, modifiers: .init())
static let f10 = KeyPress(key: .f10, modifiers: .init())
static let f11 = KeyPress(key: .f11, modifiers: .init())
static let f12 = KeyPress(key: .f12, modifiers: .init())
static let f13 = KeyPress(key: .f13, modifiers: .init())
static let f14 = KeyPress(key: .f14, modifiers: .init())
static let f15 = KeyPress(key: .f15, modifiers: .init())
static let f16 = KeyPress(key: .f16, modifiers: .init())
static let f17 = KeyPress(key: .f17, modifiers: .init())
static let f18 = KeyPress(key: .f18, modifiers: .init())
static let f19 = KeyPress(key: .f19, modifiers: .init())
static let f20 = KeyPress(key: .f20, modifiers: .init())
// US-ANSI Keyboard Positions
// eg. These key codes are for the physical key (in any keyboard layout)
// at the location of the named key in the US-ANSI layout.
static let a = KeyPress(key: .a, modifiers: .init())
static let b = KeyPress(key: .b, modifiers: .init())
static let c = KeyPress(key: .c, modifiers: .init())
static let d = KeyPress(key: .d, modifiers: .init())
static let e = KeyPress(key: .e, modifiers: .init())
static let f = KeyPress(key: .f, modifiers: .init())
static let g = KeyPress(key: .g, modifiers: .init())
static let h = KeyPress(key: .h, modifiers: .init())
static let i = KeyPress(key: .i, modifiers: .init())
static let j = KeyPress(key: .j, modifiers: .init())
static let k = KeyPress(key: .k, modifiers: .init())
static let l = KeyPress(key: .l, modifiers: .init())
static let m = KeyPress(key: .m, modifiers: .init())
static let n = KeyPress(key: .n, modifiers: .init())
static let o = KeyPress(key: .o, modifiers: .init())
static let p = KeyPress(key: .p, modifiers: .init())
static let q = KeyPress(key: .q, modifiers: .init())
static let r = KeyPress(key: .r, modifiers: .init())
static let s = KeyPress(key: .s, modifiers: .init())
static let t = KeyPress(key: .t, modifiers: .init())
static let u = KeyPress(key: .u, modifiers: .init())
static let v = KeyPress(key: .v, modifiers: .init())
static let w = KeyPress(key: .w, modifiers: .init())
static let x = KeyPress(key: .x, modifiers: .init())
static let y = KeyPress(key: .y, modifiers: .init())
static let z = KeyPress(key: .z, modifiers: .init())
static let A = KeyPress(key: .a, modifiers: .maskShift)
static let B = KeyPress(key: .b, modifiers: .maskShift)
static let C = KeyPress(key: .c, modifiers: .maskShift)
static let D = KeyPress(key: .d, modifiers: .maskShift)
static let E = KeyPress(key: .e, modifiers: .maskShift)
static let F = KeyPress(key: .f, modifiers: .maskShift)
static let G = KeyPress(key: .g, modifiers: .maskShift)
static let H = KeyPress(key: .h, modifiers: .maskShift)
static let I = KeyPress(key: .i, modifiers: .maskShift)
static let J = KeyPress(key: .j, modifiers: .maskShift)
static let K = KeyPress(key: .k, modifiers: .maskShift)
static let L = KeyPress(key: .l, modifiers: .maskShift)
static let M = KeyPress(key: .m, modifiers: .maskShift)
static let N = KeyPress(key: .n, modifiers: .maskShift)
static let O = KeyPress(key: .o, modifiers: .maskShift)
static let P = KeyPress(key: .p, modifiers: .maskShift)
static let Q = KeyPress(key: .q, modifiers: .maskShift)
static let R = KeyPress(key: .r, modifiers: .maskShift)
static let S = KeyPress(key: .s, modifiers: .maskShift)
static let T = KeyPress(key: .t, modifiers: .maskShift)
static let U = KeyPress(key: .u, modifiers: .maskShift)
static let V = KeyPress(key: .v, modifiers: .maskShift)
static let W = KeyPress(key: .w, modifiers: .maskShift)
static let X = KeyPress(key: .x, modifiers: .maskShift)
static let Y = KeyPress(key: .y, modifiers: .maskShift)
static let Z = KeyPress(key: .z, modifiers: .maskShift)
static let zero = KeyPress(key: .zero, modifiers: .init())
static let one = KeyPress(key: .one, modifiers: .init())
static let two = KeyPress(key: .two, modifiers: .init())
static let three = KeyPress(key: .three, modifiers: .init())
static let four = KeyPress(key: .four, modifiers: .init())
static let five = KeyPress(key: .five, modifiers: .init())
static let six = KeyPress(key: .six, modifiers: .init())
static let seven = KeyPress(key: .seven, modifiers: .init())
static let eight = KeyPress(key: .eight, modifiers: .init())
static let nine = KeyPress(key: .nine, modifiers: .init())
static let leftParenthesis = KeyPress(key: .zero, modifiers: .maskShift)
static let exclamationPoint = KeyPress(key: .one, modifiers: .maskShift)
static let atSign = KeyPress(key: .two, modifiers: .maskShift)
static let numberSign = KeyPress(key: .three, modifiers: .maskShift)
static let dollarSign = KeyPress(key: .four, modifiers: .maskShift)
static let percent = KeyPress(key: .five, modifiers: .maskShift)
static let caret = KeyPress(key: .six, modifiers: .maskShift)
static let ampersand = KeyPress(key: .seven, modifiers: .maskShift)
static let asterisk = KeyPress(key: .eight, modifiers: .maskShift)
static let rightParenthesis = KeyPress(key: .nine, modifiers: .maskShift)
static let equals = KeyPress(key: .equals, modifiers: .init())
static let minus = KeyPress(key: .minus, modifiers: .init())
static let semicolon = KeyPress(key: .semicolon, modifiers: .init())
static let apostrophe = KeyPress(key: .apostrophe, modifiers: .init())
static let comma = KeyPress(key: .comma, modifiers: .init())
static let period = KeyPress(key: .period, modifiers: .init())
static let forwardSlash = KeyPress(key: .forwardSlash, modifiers: .init())
static let backslash = KeyPress(key: .backslash, modifiers: .init())
static let grave = KeyPress(key: .grave, modifiers: .init())
static let leftBracket = KeyPress(key: .leftBracket, modifiers: .init())
static let rightBracket = KeyPress(key: .rightBracket, modifiers: .init())
static let plus = KeyPress(key: .equals, modifiers: .maskShift)
static let underscore = KeyPress(key: .minus, modifiers: .maskShift)
static let colon = KeyPress(key: .semicolon, modifiers: .maskShift)
static let quotationMark = KeyPress(key: .apostrophe, modifiers: .maskShift)
static let lessThan = KeyPress(key: .comma, modifiers: .maskShift)
static let greaterThan = KeyPress(key: .period, modifiers: .maskShift)
static let questionMark = KeyPress(key: .forwardSlash, modifiers: .maskShift)
static let pipe = KeyPress(key: .backslash, modifiers: .maskShift)
static let tilde = KeyPress(key: .grave, modifiers: .maskShift)
static let leftBrace = KeyPress(key: .leftBracket, modifiers: .maskShift)
static let rightBrace = KeyPress(key: .rightBracket, modifiers: .maskShift)
static let keypadDecimal = KeyPress(key: .keypadDecimal, modifiers: .init())
static let keypadMultiply = KeyPress(key: .keypadMultiply, modifiers: .init())
static let keypadPlus = KeyPress(key: .keypadPlus, modifiers: .init())
static let keypadClear = KeyPress(key: .keypadClear, modifiers: .init())
static let keypadDivide = KeyPress(key: .keypadDivide, modifiers: .init())
static let keypadEnter = KeyPress(key: .keypadEnter, modifiers: .init())
static let keypadMinus = KeyPress(key: .keypadMinus, modifiers: .init())
static let keypadEquals = KeyPress(key: .keypadEquals, modifiers: .init())
static let keypad0 = KeyPress(key: .keypad0, modifiers: .init())
static let keypad1 = KeyPress(key: .keypad1, modifiers: .init())
static let keypad2 = KeyPress(key: .keypad2, modifiers: .init())
static let keypad3 = KeyPress(key: .keypad3, modifiers: .init())
static let keypad4 = KeyPress(key: .keypad4, modifiers: .init())
static let keypad5 = KeyPress(key: .keypad5, modifiers: .init())
static let keypad6 = KeyPress(key: .keypad6, modifiers: .init())
static let keypad7 = KeyPress(key: .keypad7, modifiers: .init())
static let keypad8 = KeyPress(key: .keypad8, modifiers: .init())
static let keypad9 = KeyPress(key: .keypad9, modifiers: .init())
}
extension KeyPress {
func withModifiers(_ modifiers: CGEventFlags) -> KeyPress {
return KeyPress(key: self.key, modifiers: modifiers)
}
func appendingModifiers(_ modifiers: CGEventFlags) -> KeyPress {
return self.withModifiers(self.modifiers.union(modifiers))
}
}
sleep(2)
type([KeyPress.space.withModifiers([.maskCommand])] + "My name is Inigo Montoya. You killed my father. Prepare to die" + [KeyPress.space.withModifiers([.maskCommand]), KeyPress.tab.withModifiers(.maskCommand), .command])
func +(lhs: String, rhs: KeyPress) -> [KeyPress] {
return lhs + [rhs]
}
func +(lhs: KeyPress, rhs: String) -> [KeyPress] {
return [lhs] + rhs
}
type([KeyPress.tab.withModifiers(.maskCommand), .command, KeyPress.space.withModifiers([.maskCommand])] + "")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment