Age | Commit message (Collapse) | Author |
|
Pass the config through the app, and pass the timeout it contains to
`HeadphoneKey`.
This enables us to have a user-configurable timeout through a config
file.
|
|
The function now takes a third `Config *` argument. Create a new config
struct with `config_read_from_file()` and pass it to `c_parse_args()`.
TODO: Rename `config_read_from_file`
|
|
Need to update `c_parse_args()` call to pass new third argument.
|
|
|
|
Key actions like `<VolumeDown>`, `<Play>`, etc.
|
|
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.
|
|
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.
|
|
|
|
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.
|
|
Try to use `MPRemoteCommandCenter` to get Bluetooth button input.
Doesn't appear to work.
|
|
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.
|
|
Since media keys didn't work for Bluetooth button interception, revert
back to `NSApplication` instead of our subclass.
|
|
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.
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
Return this as the exit code so we can pass the information back to the
client.
|
|
|
|
|
|
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.
|
|
We'll reload the mappings file here.
|
|
|
|
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.
|
|
|
|
Enables us to use special keys and modifier keys in action definitions.
|
|
|
|
This will load the map group from the mapping config file in the XDG
config directory. Rust errors get logged to stderr.
|
|
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.
|
|
|
|
Copied from the Vim help.
|
|
|
|
|
|
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.
|
|
|
|
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.
|
|
Equivalent of Xcode's "Build & Run" action that we can execute in the
command line.
|
|
|
|
|
|
* 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.
|
|
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.
|
|
This method will be used from `runAction` to switch to a different mode.
|
|
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`.
|
|
The interface of `c_run_key_action()` changed. Update the code here to
make it work like before.
|
|
Includes mode handling code.
|
|
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
|
|
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.
|