aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2018-10-18Update TODOTeddy Wing
2018-10-18lib/dome-key-map: Update to get special media keysoTeddy Wing
Key actions like `<VolumeDown>`, `<Play>`, etc.
2018-10-18Revert "Test code to press the "play" media key"Teddy Wing
This reverts commit d1954a7d49d010929f0444d4127dfe130a890a8e. This code has been moved to the `dome_key_event_source_simulator` repository to be included as a static library in our Rust static library.
2018-10-13Test code to press the "play" media keyTeddy Wing
Based on code from Albert https://stackoverflow.com/users/133374/albert and Nick Sweeting https://stackoverflow.com/users/2156113/nick-sweeting on Stack Overflow: - https://stackoverflow.com/questions/11045814/emulate-media-key-press-on-mac/11048135#11048135 - https://stackoverflow.com/questions/10459085/cocoa-simulate-macbook-upper-keys-multimedia-keys/50574159#50574159 Proof of concept code that simulates a key press of the "play" media key. Worked basically on the first try here, after the Rust version of the code giving me so much segfault hell. Going to adapt this to a generic function that I can pass as a pointer to the Rust code to call to send a media key event.
2018-10-10Update TODOTeddy Wing
2018-10-09Try moving MPRemoteCommandCenter to AppDelegateTeddy Wing
Wanted to see if moving this closer to the launch point of the application and also storing a reference to the command center in an ivar would change anything. It didn't, still doesn't appear to work for listening to Bluetooth button events.
2018-10-07HeadphoneKey: Try using `MPRemoteCommandCenter` to listen for media keysTeddy Wing
Try to use `MPRemoteCommandCenter` to get Bluetooth button input. Doesn't appear to work.
2018-10-07Try listening to Bluetooth headphone buttonsTeddy Wing
Second attempt at getting events from Bluetooth headphone buttons. This time with some code from KillerDeMouches and Josh Guice. The magic numbers make no sense to me. Would have loved to have constants, but hypothesizing that maybe they were gathered from direct input and event monitoring using Karabiner's event monitor. Unfortunately, this code didn't work for me. I still have to try it on a < 10.12 machine, as maybe it'll work there (_hopefully_, as there was very scarce material online about how to do this). My next attempt is going to be using `MPRemoteCommandCenter`. Hoping that will work, but it's only going to be a solution for >= 10.12.
2018-10-07main: Switch back to `NSApplication`Teddy Wing
Since media keys didn't work for Bluetooth button interception, revert back to `NSApplication` instead of our subclass.
2018-10-07Try listening to media keysTeddy Wing
Use Peter Maurer's mechanism for getting media key events. Code taken from a Rogue Amoeba article. My hope was that this would allow us to intercept Bluetooth headphone key presses. It didn't. I'll likely be reverting this code.
2018-10-06Add DKApplicationTeddy Wing
Will be used to override the `sendEvent:` method to try to intercept media key events as described in https://weblog.rogueamoeba.com/2007/09/29/. Trying to find out if intercepting these events will enable the program to work with Bluetooth headphones.
2018-10-06Update TODOTeddy Wing
2018-10-06Update TODOTeddy Wing
2018-10-06HeadphoneKey: Free `_state` when deallocatingTeddy Wing
2018-10-06main: Free the config objectTeddy Wing
2018-10-06Update TODOTeddy Wing
2018-10-06Makefile(run): Add the `--daemon` flag to the executableTeddy Wing
Now that the `--daemon` flag is required to go into daemon mode instead of it happening automatically, add this flag to the `run` target to give us the same behaviour we had before.
2018-10-06Mappings(dispatchReload): Return result of `notify_post()`Teddy Wing
Return this as the exit code so we can pass the information back to the client.
2018-10-06main: Run main NSApp code when the `--daemon` flag is passedTeddy Wing
2018-10-06Parse command line arguments with the `dome-key-map` libraryTeddy Wing
2018-10-05Set up IPC to enable reloading the mappings fileTeddy Wing
My original plan was to use an `NSXPCConnection` to handle the IPC for reloading mappings. For some background, this is what I'm envisioning: 1. DomeKey is running in the background 2. User wants to make a change to their config. Update `mappings.dkmap`. 3. The new mappings file needs to be re-parsed and reloaded into memory. The simplest thing we could do is just quit and relaunch DomeKey. but that's kind of a pain. So instead, we run something like this from the command line: $ dome-key --reload-mappings This will tell the running DomeKey process to update its mappings by reloading the mappings file. As I said, I was going to use `NSXPCConnection` for the IPC communication, as it had come up in my research for IPC mechanisms on OS X. I knew I didn't want to use a TCP socket as that seemed like too much overhead. The ability to pass messages to classes "directly" using `NSXPCConnection` was very appealing. However, I got a little lazy trying to learn it. It has a whole model for how the communication should work, including various procedures that need to be set up using its API. It started to feel like a bit of a pain. At that point I started looking into alternatives. One idea was to move the IPC into the Rust code and use Unix Domain Sockets (https://doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html). I was tempted to go this route, but I wasn't a fan of the need to always be listening, the potential need to spawn a thread to reload the mappings to free up the main workload, the need to figure out a way to pass `State` (which keeps our parsed mappings in memory) around, and the fact that only plain strings are passed, instead of messages in the case of `NSXPCConnection`. I came across https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemTechnology/SystemTechnology.html where I discovered BSD notifications and `notify.3`. This seemed to be the lightweight easy-to-use solution that I was looking for. After following a little sample code, it works like a charm.
2018-10-04Add a new `Mappings` classTeddy Wing
We'll reload the mappings file here.
2018-10-04Update TODOTeddy Wing
2018-10-04HeadphoneKey: Update for latest dome-key-map APITeddy Wing
There is no longer a return value for `c_run_key_action()`, and the `CKeyActionResult` struct no longer exists. Update the code to reflect this.
2018-10-04lib/dome-key-map: Update to get command handlingTeddy Wing
2018-10-03lib/dome-key-map: Update to include latest `Action::Map` parsingTeddy Wing
Enables us to use special keys and modifier keys in action definitions.
2018-10-02Update TODOTeddy Wing
2018-09-26HeadphoneKey: Load MapGroup into `_state`; Initialize Rust loggerTeddy Wing
This will load the map group from the mapping config file in the XDG config directory. Rust errors get logged to stderr.
2018-09-26HeadphoneKey(runAction): Get rid of keyboard simulationTeddy Wing
Delete the code that simulates key presses from map actions. Also delete the mode saving code and the unused `cleanup` label. Simulating key presses is now handled by the Rust library using the 'autopilot' crate. It felt easier that way to handle all types of key presses.
2018-09-26lib/dome-key-map: Update for file MapGroup and loggingTeddy Wing
2018-09-25TODO: Add notes for escapingTeddy Wing
Copied from the Vim help.
2018-09-25Update TODOTeddy Wing
2018-09-25Update TODOTeddy Wing
2018-09-25Makefile: Fix dependency on Rust libTeddy Wing
Turns out the order-only prerequisite from 8c363688ac173d34c865b8271ade8c845b67fa24 was a false lead. That just made Make ignore the timestamp on the file and caused it to rebuild the dependency tree correctly. Looks like we need an actual dependency on the Rust source files in order to get the tree working correctly. Can't just call into the sub-make and have it work. Change the `RUST_LIB` prerequisite to point to the actual file because otherwise it always has the latest timestamp, causing `xcodebuild` to run. Unfortunately we end up with duplication between this Makefile and the one in `dome-key-map`, but that seems unavoidable if we want to set up the dependencies correctly. Now it finally seems to work right.
2018-09-25Add TODOTeddy Wing
2018-09-24Makefile: Only run `xcodebuild` when there are changesTeddy Wing
Previously, Make would always run `xcodebuild`. I couldn't figure out why, but after some looking around and experimenting, it looked to be due to the `$(RUST_LIB)` prerequisite. Putting it in the order-only dependencies list seems to fix the never-up-to-date problem. Also use `:=` instead of `=` when defining `SOURCE_FILES`. During my research, I came across this recommendation: > always use := not = for shell (and wildcard, for that matter) for > performance reasons. From MadScientist (https://stackoverflow.com/users/939557/madscientist) on Stack Overflow: https://stackoverflow.com/questions/26694249/makefiles-using-wildcard-vs-find-for-specifying-source-files/26694693#26694693 Move the `DomeKey` debug product executable path into a variable and use it as a target to clarify the build target and also allow us to substitute the variable in the `run` task. Now finally, `make run` won't re-build the project if no changes have been made, it'll just run the executable.
2018-09-24Makefile: Add a target to run the programTeddy Wing
Equivalent of Xcode's "Build & Run" action that we can execute in the command line.
2018-09-24lib/dome-key-map: Simulate key pressesTeddy Wing
2018-09-24lib/dome-key-map: Add current mode deactivation functionalityTeddy Wing
2018-09-24HeadphoneKey: Get switching to mode workingTeddy Wing
* Update to latest dome-key-map, which handles in-mode internally using a `State` struct * Make a `State *` ivar to store the current dome-key-map state, and let it do the work of mode handling Currently doesn't handle exiting a mode, only entering one. But that last part actually does finally work now, yay! Still requires cleanup to get rid of the old `in_mode` handling.
2018-09-21HeadphoneKey: Start of mode handling (WIP)Teddy Wing
A nearly-wroking stab at making mode handling work. Here we store the current mode in the `HeadphoneKey` object. We try to save it when getting a mode back from `c_run_key_action()`, and use it as a filter when running `c_run_key_action()`. I had discovered a problem, though. During debugging, I found that the `_in_mode` ivar would end up pointing to the same thing as the current `trigger`. Guessed that this had to do with it being a const pointer, so I started to write some code to store the `Trigger` by value instead of by reference in `HeadphoneKey` `_in_mode`. At this point, a little frustrated, I thought about the overall problem of mode handling again. It occurred to me that I no longer like this idea of storing the current mode in the Objective-C object, as this recent work has left a bad taste in my mouth. Instead, I'm going to try moving mode handling into the Rust library, and make it opaque to the Objective-C code. Hoping that that approach will be a more pleasant endeavor.
2018-09-18HeadphoneKey: Add a method to switch modesTeddy Wing
This method will be used from `runAction` to switch to a different mode.
2018-09-18HeadphoneKey(runAction): Fix EXC_BAD_ACCESS on undefined mapTeddy Wing
If no map was defined for a headphone button, the fields in the `CKeyActionResult` `result` would be null pointers, causing the bad access exception. Before doing anything, check that the pointer points to something real. Also, fix the `kind` check to use the `ActionKind_Map` enum now that the `dome-key-map` library has been updated with the new definition of `CKeyActionResult`.
2018-09-18HeadphoneKey(runAction): Update for new `dome-key-map` interfaceTeddy Wing
The interface of `c_run_key_action()` changed. Update the code here to make it work like before.
2018-09-18Update `lib/dome-key-map` to latestTeddy Wing
Includes mode handling code.
2018-08-28HeadphoneKey(runAction): Use `while` loop over `result->action`Teddy Wing
Using `strlen` loops once over the string, so along with our `for` loop, we have two loops over the string. No big deal since these shouldn't be that long. But, using a `while` loop we can iterate just once. Reference: Alexandre C. (https://stackoverflow.com/users/373025/alexandre-c) https://stackoverflow.com/questions/3213827/how-to-iterate-over-a-string-in-c/3213903#3213903
2018-08-28HeadphoneKey(runAction): Take `strlen` out of loopTeddy Wing
This appears to fix the weirdness I was having in 815bf3e8601b6d0cfb0296c6f2c302aaf5059b23, where extra characters were getting sent to `simpleKeyPressWithKey:` even though there was only 1 element (the correct number of elements) in the `action` array/string. I guess before the length was getting recalculated on each iteration of the loop. Previously, this would result in the Vim `x` command getting entered just after the map action (for example `j`). Now it appears to work correctly.
2018-08-28HeadphoneKey: Press keys from `_key_buffer` mapTeddy Wing
Take the headphone keys in `_key_buffer` and get the associated map action by calling into the Rust library. If the map action has `MapKind::Map`, then we need to simulate key presses of the characters in the `action` field. Works, but it's a little finicky. Maybe I'm including the null byte in the loop?
2018-08-28HeadphoneKey.h: Use `HeadphoneButton` from `dome_key_map.h`Teddy Wing
Instead of our custom enum, use the one generated from the Rust library now that we have it integrated with the project.
2018-08-28Update 'dome-key-map' to latestTeddy Wing