Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add throttle delays to send_combo normal keystroke #134

Merged
merged 16 commits into from
Feb 25, 2023

Conversation

RedBearAK
Copy link
Contributor

@RedBearAK RedBearAK commented Feb 17, 2023

Changes

Modifies config_api to add a new function (throttle_delays) that the user can optionally call from their config, to insert two possible sleep delays in output.

Usage from config:

throttle_delays(
    key_pre_delay_ms    = 40,    # default: 0 ms, range: 0 to 150 ms, suggested: 1-50 ms
    key_post_delay_ms   = 70,    # default: 0 ms, range: 0 to 150 ms, suggested: 1-100 ms
)

Delay variables default to zero if there is no user input (or if input value is out of range), leaving no effect on the respective areas.

As shown in the comments in the example, the range is capped at 0 to 150 milliseconds for the keystroke delays to add to send_combo. A shorter "pre-keystroke" delay and longer "post-keystroke" delay may maximize effectiveness with the shortest possible delay for each situation.

The locations of the throttles are designed and tested to minimize the affect on using shortcut combos and regular typing.

Related issues

As noted in more than one issue previously, sometimes the output from the virtual keyboard seems to be getting misinterpreted by the receiving application window, leading to failing Unicode sequences, failing hotkeys/shortcut combos, and/or macro string output being corrupted in various ways. Mostly regarding the apparent timing of when the application believes the modifier keys are pressed or released. When this problem occurs, the only apparent solution to this appears to be throttling the speed of the emitted keystrokes until the issue disappears.

Checklist

  • Updated docs or README...

src/keyszer/output.py Outdated Show resolved Hide resolved
@RedBearAK
Copy link
Contributor Author

RedBearAK commented Feb 20, 2023

@joshgoebel

Check the new commits. A global dict stores the individual throttle variables and their default values (zero). Injected values from config update the matching key values in the dict, and output.py imports and directly uses the new dict for the keystroke delays, as well as importing sleep_ms from config_api.

Everything is much simpler.

The concept of just passing a global (unless it's an unchanging constant, which should work fine) between Python modules is a bust. Doesn't work well if the value needs to be kept in sync as it changes in the other module.

src/keyszer/output.py Outdated Show resolved Hide resolved
@RedBearAK
Copy link
Contributor Author

RedBearAK commented Feb 21, 2023

As updated in the first post, this would be the new API form:

throttle_delays(
    unicode_delay_ms    = 10,    # default: 0 ms, range: 0 to 100 ms, suggested: 10 ms
    key_pre_delay_ms    = 40,    # default: 0 ms, range: 0 to 150 ms, suggested: 1-50 ms
    key_post_delay_ms   = 70,    # default: 0 ms, range: 0 to 150 ms, suggested: 1-100 ms
)

@RedBearAK
Copy link
Contributor Author

RedBearAK commented Feb 22, 2023

Might be prudent to expand the range on the low end a bit. I heard some whisperings that this timing issue may be caused by IBus, and that does seem to be a big part of it. I tried ibus exit to shut down the IBus daemon, and the major issue in the VM is substantially mitigated. Not completely gone, it will still have macro failures with the delays disabled, and pretty bad ones sometimes (stopping in the middle of the macro). But hotkeys work with IBus shut down, and adding just 1ms of post keystroke delay allows the macros to recover.

Now I'm going to try and allow decimal values down to 0.001ms and see just how small a delay fixes the issue with IBus not running.

But, pretty sure without IBus the Unicode shortcut (Shift-Ctrl-u) won't work, just like it wouldn't work in Kubuntu until I set up IBus. I'll be testing that.

Edit: The Unicode shortcut definitely doesn't work in KWrite installed from Flathub, without IBus running. But it continues to work in GTK apps even without IBus active. Like it's a built-in capability of the GTK framework, in addition to being a feature of IBus.

Tried an alternative (Ctrl-Shift-Alt-U), but that would probably require fcitx to be configured as the input method. Does nothing in my current setup.

IBus is supposed to have an environment variable to choose the sync mode, and a different sync mode would theoretically mitigate the issue. But I haven't had any luck with that so far.

@RedBearAK
Copy link
Contributor Author

This is pretty crazy. There is partial reliability of macros with even 0.001ms of delay, as long as IBus is disabled. Although that's probably below the limit of what time.sleep() can actually produce. But there does seem to be a valid case for allowing values smaller than 1ms, like 0.01 to 0.1ms. Good results can still be obtained in that range.

Really strange failure happened at 0.001ms though:

CapsLock dzapped!!!!!

There is no "z" anywhere in the macro. So how that particular failure is possible, especially without IBus being involved, is beyond me. It's like a key code was only partially sent and was misinterpreted as a different key.

I'm just going to remove the int requirement. Since I'm already allowing the value to be zero, that will allow the user to try decimal values below 1ms if they feel like it.

@joshgoebel
Copy link
Owner

Really strange failure happened at 0.001ms though:

For which knob?

@RedBearAK
Copy link
Contributor Author

Really strange failure happened at 0.001ms though:

For which knob?

Wrong question, it was just too short of a delay. The others were set to zero at the time. The point is that even without IBus involved there is still a reliability issue with too many fast keystrokes.

Mystery solved with the "z", which I didn't notice is actually "Latin Small Letter Dz", a single Unicode character at U+01F3, which must have originated from the U+1F339 of the Unicode rose being cut off in the middle of the sequence. So, nothing too unusual actually happened there.

Had pretty good results with 0.1ms, but 1ms delay was very solid. (With IBus off.)

Tried adding the environment variable IBUS_ENABLE_SYNC_MODE=1 to both my user .profile and even the system environment file. Still haven't seen it having any noticeable effect on the problem with IBus active. So the only known solution for now when IBus is present is going to be the longer delays.

@RedBearAK RedBearAK changed the title Add throttle delays to Unicode function and output.py Add throttle delays to send_combo normal keystroke Feb 23, 2023
@joshgoebel
Copy link
Owner

joshgoebel commented Feb 25, 2023

At the end of a thread where it's tried to tell me several times the function is real:

Screen Shot 2023-02-24 at 10 17 54 PM

@joshgoebel
Copy link
Owner

Amazing how fast it understands what that copy and paste represents though. This stuff is so amazing and scary.

@RedBearAK
Copy link
Contributor Author

It's helpful to remember that like it always says, it is only a "language model". It's only simulating understanding based on the patterns it has ingested from the web. That's why it runs off the rails and gives bad examples a lot. There's literally no intelligence involved in what it's doing. It's just trying to predict what the next word "should" be by extrapolating.

But it's pretty damn handy for giving intelligible "mostly right" explanations of documentation that would ordinarily take hours or days to understand. And the code examples it gives back are often at least 90% functional.

@RedBearAK
Copy link
Contributor Author

Updated the PR with the changes to both files. Let me know what else needs to be completely rewritten. 👍🏽 😄

@RedBearAK
Copy link
Contributor Author

Added an updated Readme with a section to document the API, why/when it may be useful, and some sample values for different situations.

README.md Show resolved Hide resolved
@joshgoebel
Copy link
Owner

This is looking really good, almost there!

src/keyszer/output.py Outdated Show resolved Hide resolved
@joshgoebel
Copy link
Owner

I think we're good here - you happy?

@RedBearAK
Copy link
Contributor Author

I think we're good here - you happy?

I'd like to update the copying of the DEFAULTS dict references with deepcopy():

import copy
_THROTTLES = copy.deepcopy(THROTTLE_DELAY_DEFAULTS)

@joshgoebel
Copy link
Owner

You've been learning a lot, so congrats on that. :)

@RedBearAK
Copy link
Contributor Author

You've been learning a lot, so congrats on that. :)

Few things here and there. 😆

If you're fine with not erasing the inconsistency by adding deepcopy(), I'm fine with its current state. 👍🏽

@joshgoebel joshgoebel merged commit 3ddefca into joshgoebel:main Feb 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants