| Age | Commit message (Collapse) | Author |
|
The only config option we have is `timeout`, which has a default value.
Any future config options, it seems, should have default values also.
We shouldn't force users to create a config file, as the prior code
would do. They should be able to rely on the default, and create a
`config.toml` only if they want to change it.
If no config file is found, we should create a default `Config`.
Rename the method because now it still works without reading the config
file.
|
|
Use XDG handling from `state_load_map_group()` to do basically the same
thing here for reading the config from a `config.toml` file.
Use 'error-chain' to handle the `Result`s more easily. No more nested
pattern matching, we'll just have to unwrap one `Result` and write the
error to stderr in an FFI function.
|
|
A new function that will read a TOML config file. Doesn't currently
access the filesystem. This commit is mostly supporting code to allow
that to work.
* Add the 'toml' crate
* `parse_args()`: Take a mutable `Config` and return that config instead
of creating a new one. The recipe will now be to read the config from
a file first and then pass that config to this function to be updated.
* Modify `c_parse_args()` to take a `*Config` and mirror the new method
signature of `parse_args()`
|
|
This new field will be used by the calling Objective-C code as the
timeout between multi-button maps.
It will be defined in a `config.toml` file in the XDG config directory,
with a default if unspecified. That part of the code hasn't been written
yet, but we've prepared by deriving Serde `Deserialize` on the `Config`
struct in order to deserialise a TOML config file.
The latest Serde is v1.0.80, but we can't use it because 'cbindgen'
depends on an older version. We had been using 'cbindgen' v0.6.3, which
depends on serde v1.0.21. Decided to update 'cbindgen' in order to use a
newer version of Serde, but that puts us at v1.0.58 instead of the
latest:
error: failed to select a version for `serde_derive`.
... required by package `cbindgen v0.6.6`
... which is depended on by `dome-key-map v0.0.1 (file:///Users/tw/Documents/Development/dome-key-map)`
versions that meet the requirements `= 1.0.58` are: 1.0.58
all possible versions conflict with previously selected packages.
previously selected package `serde_derive v1.0.80`
... which is depended on by `dome-key-map v0.0.1 (file:///Users/tw/Documents/Development/dome-key-map)`
failed to select a version for `serde_derive` which could resolve this conflict
|
|
This "key" creates an empty action that doesn't do anything. Allows
users to clear the default behaviour of a headphone button.
|
|
|
|
Add a new parser for `NXKey`s. I originally thought I was going to add
this to the `key_code()` parser, but that one parses to `KeyCode`s.
Seemed like it would be easier to make a brand new parser to handle the
different type.
Need to add tests for this.
|
|
Get rid of the temporary name and give it a more permanent one. I had
actually written this test thinking it would be temporary and that I
would remove it later. Since it will actually launch iTunes by default
due to RCD, this test shouldn't be in the normal suite. However, it
seemed like it would be useful to keep it around in case, so leaving it
with an ignore skip.
|
|
`dkess_press_key()` now takes a `CGEventFlags` instead of an int.
|
|
Add this new key type to the enum and enable it to be `tap()`ped like
the others.
Made `NXKey` a type alias instead of a struct to allow us to refer to
any of the NX key constants using the `NXKey` type. This also meant
moving those NX constants outside of the `NXKey` impl and into the top
level. May end up wrapping them back up in some kind of namespace later.
Adjusted the public-ness of some functions to support this change.
|
|
These two functions are copied from `autopilot-rs/src/key.rs` at
ab7ebc9fd8bc210717c0210aa20335ea9ceed200. I wanted to use the library
directly, but they're private functions.
I need this code in order to be able to convert the 'autopilot' `Flag`
type into `CGEventFlags`. I need a `CGEventFlags` because my media key
simulator, `dkess_press_key()` (an FFI function), requires a
`CGEventFlags`-typed value.
Needed to change the `from` function to a top-level function due to this
error:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/autopilot_internal.rs:213:1
|
213 | impl From<Flag> for CGEventFlags {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead
Bringing the code into the project seemed to be the easiest way to
leverage the existing 'autopilot' work.
|
|
|
|
These keys get pressed using the special media key simulator Objective-C
library.
|
|
|
|
Added a build of `libdome_key_event_source_simulator.a` to the root of
the project to test running the function from Rust. Works. Needs to be
built with custom `RUSTFLAGS` in order to build:
$ RUSTFLAGS="-L ." cargo test dktest
We'll need to figure out how to add this to the Rust build script.
Now that we know it works, we can integrate the static library more
permanently into the project.
|
|
Not fully worked out yet. The idea is to somehow wrap 'autopilot' keys
and special `ev_keymap.h` keys.
|
|
Can't deal with segfaults any more. This code will be moved to
Objective-C.
|
|
Segfaults on key_code.rs:184:
error: process didn't exit successfully: `.../dome-key-map/target/debug/deps/dome_key_map-0efa5c8428fad354 send_media_key --nocapture` (signal: 11, SIGSEGV: invalid memory reference)
shell returned 101
This is my attempt to use first the 'cocoa' and 'core-graphics' crates,
then the 'objc' crate (because I hoped that would get around the
segfault), to simulate a media key event.
Once I got the types right and the code compiling, I couldn't get past
segfaults. After struggling with this for over a day and not being able
to figure out what on earth is going on, I wrote the exact same thing in
Objective-C and it just worked. That's it, I'm done with this. This code
is going to be expunged and I'm going to take a C function pointer in
the function that runs map actions that will simulate media key presses
in real Cocoa/Carbon. Enough of this headache.
|
|
Media keys (rewind, play/pause, fast forward on Mac function keys) are
different from normal keys. These use a different API, and sending
events to simulate those keys is different.
Here's a first stab at getting something working for posting simulated
media key events. This will be used for new special keys in mapping
actions. Haven't tested this at all yet, just happy that it finally
compiles.
Follow the two Stack Overflow answers referenced in the comments (from
Albert https://stackoverflow.com/users/133374/albert and Nick Sweeting
https://stackoverflow.com/users/2156113/nick-sweeting).
Add the `core-graphics` crate to give us access to `CGEvent`,
`CGKeyCode`, and related types.
Also include some commented `CGKeyCode` definitions for future use.
|
|
Otherwise we aren't able to pass it to the `config_free()` function.
|
|
Otherwise it gets freed too early by Rust. Add (re-add) a free function
for it too now that we know it must be freed manually.
|
|
I was getting this error when I brought the library into the Objective-C
application:
Undefined symbols for architecture x86_64:
"_parse_args", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Ended up renaming my FFI function to `c_parse_args()` (like with
`c_run_key_action()`) which fixed this. Going to have to rename those to
use a `dome_key_` prefix eventually.
Then, my `args` argument didn't have the right type. It had a `*const
c_char` type, which is a string, when it should have been an array of
strings. We just needed a double pointer. A Stack Overflow answer from
Tibor Benke (https://stackoverflow.com/users/3989982/tibor-benke) proved
helpful in this regard:
fn foo(argc: c_int, argv: *const *const c_char);
https://stackoverflow.com/questions/34379641/how-do-i-convert-rust-args-into-the-argc-and-argv-c-equivalents/34379937#34379937
Update the `map()` call to account for the new type, and check that we
don't have any null pointers within the array.
Finally, shift the first (command name) argument off the list when
parsing options as suggested in the 'getopts' doc example.
|
|
We want to be able to access the fields in `Config`, so make them
accessible across the FFI boundary.
* Return a regular, not boxed, `Config` from `parse_args()`.
* Add `repr(C)`s on our structs (had forgotten how this worked in
961b3b0b2d33a2c632fbc093b61e2c2d4dc07f70).
* Delete the `config_free()` function as I think the stuct doesn't need
to be freed being a POD struct. Hopefully that's the case.
|
|
This will allow us to parse command line arguments starting from a C
argv array (hopefully).
|
|
Parse command line options in this library. Need to figure out how to
communicate these over FFI to the Objective-C code.
|
|
I broke deactivation of the active mode by pressing the mode trigger
sequence in 9af4701e7364dac691ce8d2f2875a974091d5453. Get it working
again.
|
|
Move the key simulation and command execution code to a new method so
that it can be reused in both top-level map and mode branches.
This additionally enables command running from top-level maps
(previously it only worked for in-mode maps).
|
|
Get rid of the return values on `c_run_key_action()` and
`run_key_action_for_mode()`.
The reason why we returned a result previously was to feed information
back to the Objective-C caller to run subsequent parts of the pipeline,
like storing the current in-mode and simulating key presses. Now that
both of those are handled by the Rust code, we have no more need for
these return structs.
Get rid of the return values to clean up the code a bit.
|
|
Commands now stay `Action::String`s without getting re-parsed to
`Action::Command`s (as per 79dfb6c8cd536e9448f05421d5018785a8b590ce).
This test is therefore unnecessary.
|
|
Originally I was going to use `Action::Command` for this, which was
intended to hold a `Vec` of command arguments.
I decided against that approach. After thinking about command parsing a
bit, it's of course not just splitting into a `Vec` on whitespace. You
need to take into account quoting and whatever other idiosyncrasies.
Instead, I think I'm going to leave commands as `Action::String`s and
end up not using `Action::Command` for anything.
We take the shell command string from the action and feed it to a new
`Command`, executed using the `-c` option to the parent shell.
As I understand it, `spawn()` will reuse the parent process' stdout etc.
descriptors.
|
|
Previously I had only implemented it for top-level maps. Get it working
for in-mode maps too. Move the parsing code to a function so it can be
re-used in both places.
|
|
Actions should now be typed using the `tap()` method and `Action::Map`
types instead of `Action::String`s in order to enable modifier keys.
|
|
Non-working attempts.
|
|
Use `autopilot::key::tap()` to simulate each key and modifier in an
action.
Originally tried to do this using a method that takes a closure to
access the `KeyCodeConvertible` types inside `KeyboardKey`. Ended up
with a much cleaner API solution that only requires a single method
call.
|
|
I originally wrapped the contained `Vec` in an `Option` to that we
wouldn't have to initialise whole new empty `Vec` for every key in an
`Action` list.
However, this made less sense once I wrote the parser and ended up with
an empty `Vec` by default that I then had to convert into an `Option`.
Now I've started the code to type keys including modifiers, and the
`Option` no longer makes any sense at all. In order to type keys
(including modifiers), I'll be using Autopilot's `tap()` function:
pub fn tap<T: KeyCodeConvertible + Copy>(key: T, flags: &[Flag], delay_ms: u64) {
This function requires a slice, so I ended up getting a `Vec` from my
parser, converting it to an Option to satisfy my original interface, and
now would have to convert it back into a `Vec` or slice in order to be
able to pass it into `tap()`. Talk about unnecessary.
Get rid of the `Option` because it's more work for absolutely no reason.
|
|
Get rid of old commented code now that we have a working version.
|
|
First, `MapGroup::parse` parses actions to `Action::String`s. We then
run a second pass on the parsed actions to parse them into
`Action::Map`s.
A few failed attempts but finally got it working. Tried a few ways of
doing it and kept running into various borrowing problems. Glad it's
working now.
|
|
This reverts commit 5ef2443642a2d8b223afdf169200a725d2809b76. See that
commit for details.
|
|
Trying to add new escape special keys for '\' and '<' but having a bit
of trouble.
Looks like I'm not using `and` `satisfy` correctly, as I'm getting this
error:
error[E0271]: type mismatch resolving `<(impl combine::Parser, combine::combinator::Satisfy<_, [closure@src/parser.rs:263:56: 263:68]>) as combine::Parser>::Output == char`
--> src/parser.rs:260:18
|
260 | (choice!(
| __________________^
261 | | try(string_case_insensitive("Bslash")).map(|_| '\\'),
262 | | try(string_case_insensitive("lt")).map(|_| '<'),
263 | | try(action_character().and(satisfy(|c| c != '>')))
264 | | ).map(|c|
| |_________________^ expected tuple, found char
|
= note: expected type `(char, _)`
found type `char`
= note: required because of the requirements on the impl of `combine::Parser` for `combine::combinator::Try<(impl combine::Parser, combine::combinator::Satisfy<_, [closure@src/parser.rs:263:56: 263:68]>)>`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
I had added the `satisfy` not '>' after getting this test failure
without it:
---- parser::tests::action_parses_map_with_bslash_and_lt_special_keys stdout ----
thread 'parser::tests::action_parses_map_with_bslash_and_lt_special_keys' panicked at 'assertion failed: `(left == right)`
left: `Err(Errors { position: PointerOffset(4332007031), errors: [Unexpected(Token('l')), Expected(Token('>'))] })`,
right: `Ok(Map([KeyboardKeyWithModifiers { key: Character(Character(Character('a'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('\\'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('A'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('N'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('D'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('<'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('>'))), flags: None }, KeyboardKeyWithModifiers { key: Character(Character(Character('\\'))), flags: Some([Control]) }, KeyboardKeyWithModifiers { key: Character(Character(Character('<'))), flags: Some([Meta, Shift]) }]))`', src/parser.rs:928:9
as I suspected this was a problem with `<lt>`. But now that I think
about it, it could just as easily have been a problem with `<Bslash>`.
Not sure.
Anyway, I'm thinking of dropping these escapes because they're redundant
(we already have '\' escaping) and because I'm tired of these errors.
|
|
A simple test to check parsing of a simple string without any special
keys or modifiers.
|
|
Make this test do something, validating that it parses multiple modifier
prefixes in a special key.
|
|
Add a '>' closing bracket to the end of the test string to make sure
that the '<' gets escaped even with a '>' following it.
|
|
Previously we were able to parse modifier + KeyCode (`<C-Enter>`) special
keys and plain KeyCode ones (`<Esc>`).
This change adds parsing support for the final type of special key,
modifier + character (e.g. `<C-l>`).
action_character():
Move the `map` outside of this function and into `action_map()` to allow
us to reuse the parsed `char` in `special_key()`.
key_modifier():
* Move the `many()` parser and `Option` handling outside of this
function and into `special_key()`. Doing so enables us to say:
<C-l> // Character special keys _require_ a modifier (thus
// `many1`)
<[C-]Left> // KeyCode special keys may or may not have a modifier
// (thus `many`)
* Rename from `key_modifiers()` to singular now that it only parses a
single modifier.
special_key():
Parse both character and KeyCode special keys with modifiers.
action_parses_map_with_modifier():
Change input string to include a KeyCode-style special key with a
modifier since we didn't have one previously. This ensures we test both
kinds of special keys.
|
|
Add some parsing code for modifier keys inside special keys (`<`-
`>`-wrapped keys).
Currently only works for special keys defined in `special_key()`. Needs
to be extended to work for modified character keys (e.g. <C-l>), thus
the test in this commit doesn't pass.
|
|
Escape '<' and '\' by prepending a backslash. Since special characters
are enclosed in '<' '>' brackets, in order to type a literal '<', we
need a way to escape it. Use backslash, like in Vim.
|
|
Splits up the `action_map()` function and gives the parser a name.
|
|
Additionally, fix a problem in `key_code()` when using special key names
that start with the same character (like any of the F keys, or Enter and
Esc). The parser would discard the first character, like in the
`definitions()` parser. Use the same solution here, by wrapping the
parser choices in `try()`s.
Add `Esc` to the test to confirm that it fails not just for the F keys
but for all key names that start similarly.
|
|
Still need to test them though. They'll be used in conjunction with
another new parser, `action_map`, which will parser map-type action
strings.
`key_code` parses `autopilot::key::KeyCode`s, basically all special keys
and modifiers. `special_key` parses key codes inside `<` `>` braces.
Change the test to use `easy_parse` to give a clear error message.
Add `recursion_limit` to the crate on the advice of the compiler in
order for the `choice!` macro in `key_code()` to work properly.
Otherwise it spits out a giant error message complaining about
`rustc --explain E0277`. If I remove a handful of elements from the
`choice!`, it compiles, so it seems there's an upper bound restricted by
the recursion limit.
Modifier keys are included in a commented section as these are part of
the 'autopilot' `KeyCode` enum, but they'll be handled in a separate
parser.
|
|
* Some stub ideas for test text
* Fill in the test for special keys
* Add some convenience methods to more easily create the expected test
result objects
|
|
Ideas for some things we should be testing.
|