GithubHelp home page GithubHelp logo

waddle's Introduction

waddle

Ortho keyboard with Rust firmware.
Keyboard created with CadQuery.

LICENCE

The firmware is under GNU GPL 3.0. The hardware is under CERN-OHL-S. See the respective directories for this.

waddle's People

Contributors

qwelyt avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

waddle's Issues

Add combos

While OnHold lets you change behavior if pressed or held, and chording lets you act as a different key if more are held at the same time, combos act when you press keys in series.

Chroding: Press J and K at the same time to produce W.
Combo: Press J. Release J. Press K within time_limit and produce W.

So chording is pressing at the same time, and combos are pressing in the right order in short succession.

Add double tap

KeyType{
    DoubleTap(Key, u8, Key),
// ...
}

If pressed once it works as normal key. If pressed and held, it works as a normal key.
If you double tap the key (press**press) within the time limit (u8) then it acts as key2.

How tap-tap&hold should be handled I'm not fully sure.

Perhaps there are several types hidden here.

KeyType {
   TapHold, // Press-Release-Press&Hold
   DoubleTap, // Press-Release-Press-Release
   DoubleTapHold, // Press-Release-Press-Release-Press&Hold
}

There are a lot of possibilities. Might be feature creep.

Add chording

I want to be able to press two keys "at the same time" and make them behave like a different key.

Eg. I press J, I get J. I press k I get k. But if I press JK in "quick succsession" I want them to trigger as Enter

Multiple KeyTypes on the same key

Having OnHold and DoubleTap is all nice and dandy. But I should not have to choose between them! I should be able to have both on the same key.

I should be able to say

(
   KeyCode(A), 
   DoubleTap(KeyCode(Esc), 100ms), 
   OnHold(KeyCode(Shift), 100ms), 
   TapHold(Function(...), 100ms, 100ms),
   DoubleTapHold(LayerMo(4), 100ms, 100ms, 50ms)

And that is ONE key. I should be able to do all the things on one and the same key without there being any problems. So this key for example would write A when pressed normally. If pressed twice within 100ms it would produce Esc. If held for 100ms it would produce Shift. You get far by just allowing this.
But I want more. TapHold would be press-release-press-hold, and that would execute a Function here.
DoubleTapHold is the same thing, but press-release-press-release-press-hold. And that would move us to to layer+4.

This allows one key to suddenly become 5 keys.

On top of this we have Chording and Combo that needs to be handled somehow. But all types should be allowed, always.

Rewrite state to tick pressed keys

The current way to check what keys are pressed is done like this

    fn debounced_scan(&mut self) -> State {
        let s1 = self.scan();
        delay_ms(20);
        let s2 = self.scan();
        State::intersect(s1, s2)
    }

we scan the matrix two time, do an intersection of the two states, and then say that the intersection is the state. This is a basic and working way of doing it, but it makes it harder to implement things like OnHold.

A different approach to the scanning is to "tick" the state. Lets say we have a mut State instead. Something like

struct Pos {
  row:u8, 
  col: u8
}
struct State {
  pressed: Vec<(Pos, u8)>, // Position of key, and how many ticks it has been pressed
  leds: u8,

impl State {
  fn update(&self, scan: Vec<Pos>) {
    scan.iter().map(self::tickOrAdd)
    self.pressed.iter().onlyKeepPosPresentInScan()
  }
}

So the state keeps a Vec(or Set or w/e) about which keys are pressed and for how many ticks they have been pressed. For each scan we do, we send in the list of pressed keys to State and lets the state update the pressed keys.
If a Pos is not present in pressed but it is in scan, it gets added to pressed with 0 ticks.
If a Pos is already present, increase the tick by one.
If the Pos is present in pressed but not in scan, remove the the Pos.

After each scan we can then poll the State and ask for all Pos with a higher tick than X. We can then ask Layout what key we should register based on how many ticks that Pos has. Layout can then decide if it should give us N or M based on the number of ticks.

This can make OnHold real easy. Just check what key we are based on ticks.

The scan() method then become something like

fn scan(mut &self) {
  let scan_result = self.scan();
  self.state.update(scan_result);
  delay(5);
}

And then when we have the state we can do something like let pressed_keys: Vec<u8> = state.getKeys() which returns the pressed keys -- based on the seen state and layout.

Reduce recusion to save stack space

In places like

fn get_key(position: &Position, layer: u8) -> Option<Key> {
match LAYOUT.get_key(layer, position) {
Key::KeyCode(kc) => Some(Key::KeyCode(kc)),
Key::Function(f) => Some(Key::Function(f)),
Key::PassThrough(go_down) => State::get_key(position, layer - go_down),
_ => None
}
}
there is a recursion happening, wasting stack space.

As the stack is quite limited it would be good to rewrite this part (and others like it) to remove the recursion. Do a loop instead.

Add OnHold

If I press A, I want to send the letter A.
If I hold A for X time I want the system to send Shift

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.