autokey / autokey

AutoKey, a desktop automation utility for Linux and X11.

Home Page:https://autokey.github.io/index.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Insert of date is often not right

stefan-franz opened this issue · comments

AutoKey is a Xorg application and will not function in a Wayland session. Do you use Xorg (X11) or Wayland?

Xorg

Has this issue already been reported?

  • I have searched through the existing issues.

Is this a question rather than an issue?

  • This is not a question.

What type of issue is this?

Bug

Choose one or more terms that describe this issue:

  • autokey triggers
  • autokey-gtk
  • autokey-qt
  • beta
  • bug
  • critical
  • development
  • documentation
  • enhancement
  • installation/configuration
  • phrase expansion
  • scripting
  • technical debt
  • user interface

Other terms that describe this issue if not provided above:

No response

Which Linux distribution did you use?

Linux Mint 21.2

Which AutoKey GUI did you use?

Both

Which AutoKey version did you use?

0.95.10 and Qt 5.15.3

How did you install AutoKey?

With Linux Mint 21.2 Programm Installer

Can you briefly describe the issue?

I use Autokey to paste the actual date. But often the date is not correct or a part of the shortcut (in my case "dat#") ist no deleted.

The script is:
from datetime import datetime
keyboard.send_keys(datetime.now().strftime('%d.%m.%Y'))

Maybe you can improve her the performance or whatever that ist works in the future.

Can the issue be reproduced?

None

What are the steps to reproduce the issue?

Try out the script under Linux Mint 21.2 and past e.g. in thunderbird contacts info field some text and the date as described above.

What should have happened?

That the date es pasted correctly

What actually happened?

Auto key sometimes is not deleted or the date is pasted wrong.
The error comes in 2 of 3 attempts.

Do you have screenshots?

No response

Can you provide the output of the AutoKey command?

No response

Anything else?

No response

commented

This is yet another variation on a very old issue. It can't be fixed within AutoKey, but there are easy workarounds.

Many applications can't receive "typed" character events at machine speed and suffer overrun errors. The solution is to cut it down to one event by copying your string to the clipboard and then typing a Ctrl+V to paste it (or use the Paste using clipboard Ctrl+V option in phrases) or, if that won't work, slowing down the "typing" with my type_slow() function.


I notice that you are not running 0.96.0, our current release. This release contains a lot of bug fixes and a few new features. We highly encourage users to upgrade as soon as possible. You can find it here and instructions are here.

The installation is pretty easy to do and we also provide .deb packages for users of Debian and Debian-derived distributions (Ubuntu, Mint, ...).

Thanks for your support. the GTK V. 0.96 is runnung (with the common) on Linux Mint 21.2

For my date problem: Here is the script.

from datetime import datetime
keyboard.send_keys(datetime.now().strftime('%d.%m.%Y'))

could you please help me, how to adjust that script, with the slow function, you mentioned above?
Thanks in advance.
Stefan

commented

OK, but this is untested code.

Try this first. It uses the clipboard rather than typing slowly. If there's a problem, post back here.

output = time.strftime("%d.%m.%Y")
clipboard.fill_clipboard(output)
time.sleep(.1)
keyboard.send_keys("<ctrl>+v")

See our wiki for more information.

This could be enhanced by first saving the current contents of the clipboard and restoring them when done.

Note that clipboard API calls are ascynchronous. They return with success immediately, but have initiated another thread to actually do the requested action. That's why they should always be followed by a short delay to give them time to actually complete.

The X clipboard can occasionally be a bit weird. If anything doesn't work exactly as desired, post on Gitter and we can sort it out. One of our active users has explored this in great detail.

Thank you a lot. You helped me very much. Now it works! Great!

One question: my shortcut for the date ist dat#
Option: Remove typed abbrevation.
The date is always right displayed, but sometimes the "d" from the shortcut above is not deleted so the full return e.g. for today is
d12.12.2023 instead of 12.12.2023
Are there solution to solve this?

commented

Glad it works. Nothing specific. Some things you can try:

  • Keep track of which applications/windows have the problem. This might give some clues.
  • Try a slightly longer delay like 0.2 (probably won't help)
  • Rewrite with type_slowly() and see if that helps
  • The second version of type_slowly() has even more options for adding delays
  • Deselect Remove typed abbreviation and emit the appropriate number of backspaces yourself with the option of adding more delays before and or after doing so. In 0.96.0, there's even an API call to retrieve the trigger abbreviation, so you can determine its length and dynamically know how many backspaces are needed.
  • Workaround: use a hotkey instead of a trigger abbreviation (you can have both if desired)

I use mostly Autokey with Thunderbird V91 unter Linux Mint 21.2
How looks my script with the type_slowly() function?
More delay brings nothing.
Hotkey is the plan B if the type slowly() brings no solution.

output = time.strftime("%d.%m.%Y")
clipboard.fill_clipboard(output)
time.sleep(.1)
keyboard.send_keys("<ctrl>+v")
commented

OK. Again, my code is untested.

Here's a more extreme version contributed by @bjohas.

This one assumes the script is set to not remove the trigger abbreviation automatically and does it itself.

Parameters
string1: trigger abbreviation
string2: replacement text
backdelay: delay between emitting backspaces when deleting the trigger abbreviation
delay: delay between removing the typed abbreviation and starting to emit the replacement string
typedelay: delay between emitting characters of the replacement string

def type_slowly(string1, string2, backdelay=0.0, delay=0.3, typedelay=0.0):
  for c in string1:
    keyboard.send_keys("<backspace>")
    time.sleep(backdelay)
 
  time.sleep(delay)
  
  for c in string2:
    keyboard.send_keys(c)
    time.sleep(typedelay)

  return

output = time.strftime("%d.%m.%Y")
type_slowly("dat#", output, 0.2, 0.2, 0.2)

If this runs without blowing up (or after you fix my errors/typos), but still has the original problems, make the 3 delay parameters ridiculously long like 1,1,1. If that fixes it, then do a binary search for one delay parameter at a time, repeatedly cut it in half and see if it works. When it stops working, increase to half way back to the last value that worked and then half of what's left if it still doesn't work... Then do the same thing with each of the other two delay parameters, one at a time.

This takes a while to do, but is a systematic way to find optimal values and since you're continually dividing by two, it gets done in a lot faster than just going up and down incrementally. Of course, you can quit any time once it works and the whole thing is fast enough for your purposes. It doesn't have to be precise.

Once you find the values that work, it's a good idea to make them a little bit larger to compensate for cases where the general load of your computer (or whatever is behind the window you're interacting with) is high from doing other things and it may need a little more time than when the load is light.

Depending on how you set this up, you might have add one backspace for the trigger character (the one that marks the end of your trigger abbreviation, e.g. tab, space. all non-word, etc.).

Since the keyboard API calls don't handle multibyte character sets (anything that's not EN-US), you can't have any of them in your phrases. If you need them, it can be done, but it requires some tweaking.

Thanks a lot - that works. I don't know how the code works - but the result is fine.

Note for others: type_slowly("dat#.... "dat#" is my abbreviation to trigger the autokey to write the actual date.
Anyhow the code removes the 4 characters (dat#) and after that writes autokey the date.

def type_slowly(string1, string2, backdelay=0.0, delay=0.01, typedelay=0.0):
  for c in string1:
    keyboard.send_keys("<backspace>")
    time.sleep(backdelay)
 
  time.sleep(delay)
  
  for c in string2:
    keyboard.send_keys(c)
    time.sleep(typedelay)

  return

output = time.strftime("%d.%m.%Y")
type_slowly("dat#", output, 0.0, 0.0, 0.0)
commented

Glad it works!

The code you pasted above appears to have all the added delays set to zero. If that's what you're really using, then I don't understand why it helps at all.

The string "dat#" is only used to get its length so the script knows how many backspaces are required.

If you are interested, you can post on our user support forum or on Gitter and we can explain the script line by line, etc. You can always join us there to discuss anything related to AutoKey.

Since you are probably a newer AutoKey user, I highly recommend that you look through our wiki where you will find a lot of helpful articles and sample scripts.

Since this issue appears to be solved, you can close it. (I will eventually close close it if you don't.)