Before submitting a pull request, please make sure your code passes the following checks locally:
cargo test
passes without any errorscargo fmt
has properly formatted all filescargo clippy
has been run on all files without any errors or warnings in pedantic mode
These can be added to your pre-commit hooks to automate the checks. Beyond these checks, it is recommended to develop with standard Rust tooling like rust-analyzer. Once your code is passing locally, you can submit a pull request and a maintainer can pass it through the continuous integration checks.
Besides this, we do not have any specific contribution guidelines or codes of conduct for now, however most likely these will be fleshed out as Odilia matures more.
Odilia has a unique architecture which embeds alot of code into types. Here is what you need to know if you want to add a new feature:
- Find the AT-SPI event that corresponds to the desired feature
- Take a look at the docs for
common/events/
and try to find the right event. - For example, to create a feature that reads out changed text in an aria-live region, you would want the event
TextChangedEvent
.
- Take a look at the docs for
- Decide if there are any prerequisites to the feature being triggered (think: focused window only, open tab only, etc.)
- See if the prerequisite is already defined
- Check out the
odilia/src/tower/cache_event.rs
file for types that implement thePredicate
trait (defined in therefinement
create).
- Check out the
- Decide what, if any, state is required for your feature (caret position, last focused item, etc.)
- For example: to know if the current window is focused, the current window must be stored in the state of the screen reader.
- Check to see if we already have your state info as a type; you can check this at
odilia/src/state.rs
. - If not, make a newtype, add it to theState
struct, then implement theTryFromState
trait for the type (so it can be extracted by theTryFromState
implementation). - An example of how to implementTryFromState
can be found inodilia/src/state.rs
- Implement a new async function that takes
PreRequisiteType<EventType>
, andStateType
(if necessary). That function can return a list ofCommand
s that Odilia will act on.- Then, add it to the list of
.atspi_listener(fn_name)
calls inmain
. - The list of possible
Command
s can be found in the typeOdiliaCommand
enum incommon/src/commands.rs
.
- Then, add it to the list of
- If a new
Command
is required, create a newtype, implement theIntoCommands
trait, add it as a variant to the enum, then finally implement theCommandType
trait.- To add funcionality to this command, create an
async fn
that takesCommand(NewCommandType)
andNewStateType
(if necessary). Finally, add it to the list of.command_listener(fn_name)
calls inmain
.
- To add funcionality to this command, create an
If you'd like detailed performance benchmarks, we recommend using the flamegraph
package to show performance bottlenecks.
There is also hotspot
, a C++ program available in the AUR, and some major package repos, which can display how much time is spent in various portions of the program in an accessible (GUI) way.
First, install the subcommand with:
$ cargo install flamegraph
If needed, install Hotspot from the AUR/your package repo, as well as perf
which is required to produce the flame graph.
$ paru/yay -S hotspot perf
Finally, add the following to the root Cargo.toml
:
[profile.bench]
debug = true
Now, you can run the following commands to produce flamegraphes for individual benchmarks with the following command:
cargo flamegraph --bench load_test -- --bench [individual_bench_name]