PyUserInput icon indicating copy to clipboard operation
PyUserInput copied to clipboard

type_string character sets

Open willwade opened this issue 10 years ago • 7 comments

this won't work;

k.type_string('I like lots of £')

Reason being is that ch_index (line 64 in base.py) is only for US keyboard layouts.. It could be over ridden but this may not be the neatest solution..

willwade avatar Jun 16 '14 23:06 willwade

a full UK layout is this incase anyone was wondering.. (!)

char_index = "asdfhgzxcv§bqweryt123465=97-80]ou[iplj'k;\,/nm."
shifted_index = 'ASDFHGZXCV±BQERYT!@£$^%+(&_*)OU{IPLJ"K:|<?NM>'

I'm totally stumped on the workaround for this..

willwade avatar Jun 18 '14 23:06 willwade

type_string is totally hackish. I'm still trying to find a solution to fit the ultimate goal of working with any layout and not just the more popular ones.

SavinaRoja avatar Jun 21 '14 20:06 SavinaRoja

its a tricky one for sure. I'm trying to find a solution for the mac which you can read about here - not sure if I'm/we're going to get anywhere though...

willwade avatar Jun 21 '14 20:06 willwade

I think @abarnert may have come up with a potential solution. We have (I have a fork on my machine) a keycode library that now (successfully!) looks up any keycode from a character and it returns with the modifier for that character as well as the keycode. E.g. ChatToKeyCode('H') returns (4,2) first num: keycode, second num: modifier key. With this type_string on the mac becomes far easier and reliable across any layout https://github.com/abarnert/pykeycode/issues/3 (see https://github.com/abarnert/pykeycode/blob/ctypes/keycode.py for the code..)

I have no idea what would be needed for windows/linux for this to work but it makes logical sense to me that lookup_character_value should return this key:modifier for all platforms. It would also make sense that their should be a lookup_keycode_char fn to for completeness (so you can enter via a raw keycode in pyKeyboard as well as by character). My feeling is that these two functions should form the base of keycode fetching rather than using the dicts. What do you think? Would this work for Win/*nix?

I will work on completing this fork over the weekend (and merging with the latest PR) - might make more sense that way!

willwade avatar Jun 25 '14 10:06 willwade

I now have a working fork at https://github.com/willwade/PyUserInput

Things changed which I wouldn't mind having a bit of musing over before I do a PR..

def lookup_character_value(self, keycode, modifier=0):
    """ Helper method to lookup a character value from a keycode """
    return mac_keycode.createStringForKey(keycode,m)

def lookup_keycode_value(self, character):
    """ Helper method to lookup a keycode from a character """
    key_code, modifier = mac_keycode.keyCodeForChar(character)
    return key_code, modifier

def is_char_shifted(self, character):
    """ Returns True if the key character is uppercase or shifted."""
    key_code, modifier = mac_keycode.keyCodeForChar(character)
    return True if modifier == 2 else False

is now in mac.py What do you think about that for all (Win and Unix)? i.e returning key_code and modifier. It bothers the hell out of me that there is a different way of accessing keys for windows and mac. Surely it should be uniform for both platforms e.g.

k.tap_key('Alternate') not k.press_key(k.alt_key)

Note there is an issue with modifiers:

  self.modifier_table = {'Shift':False,'Command':False,'Control':False,'Alternate':False}

so 'Shift' 'Command' (Windows key on a win keyboard) 'Control' Alternate' are the modifiers. There should be a standard across all platforms surely? (NB: Aliases)

This now means that type_string is really simple:

def type_string(self,char_string, interval=0):
    for ch in char_string:
        self.tap_key(ch)
        time.sleep(interval)

All shifted chars now work. There is a downside - see:

k.tap_key('p')

p k.tap_key('P') P

before this would have given the same 'p' because it always find the lowered form. the new code will potentially mess up old code but I actually think is better.. (or what should be expected)

To send some dodgy looking chars:

k.tap_key(u'£')

is how to do it. Not perfect IMHO.

mac_keycode could do with some tidying - maybe even bringing into mac.py. The ctypes implementation (see this thread) may be better to use if so Please reference @abarnet if this happens.

Let me know any thoughts and I can do a PR if required

willwade avatar Jul 02 '14 23:07 willwade

@willwade: I wouldn't worry too much about getting all the modifiers across every platform; the only ones that normally produce extra symbols are shift (all platforms), option/alt/open-apple (Mac only) and alt-gr/compose (Linux only). (Control also produces extra characters, but only non-printable ones.) So, you might just want to have two modifiers in your abstract layer: Shift, plus one with a bunch of aliases for Opt, Alt-Gr, etc.

Also, I think you want my code in layout.py, not the code in keycode.py. I should probably clean things up, merge the branch back to trunk, get rid of the compile step in setup.py, etc. so you can just use it directly.

Plus, you probably want to take advantage of the dead-key support; as a Mac user, I'd be disappointed if type_string('élan') gave me an error when I know perfectly well that it can be typed. (That being said, if I were a Japanese Mac user, I'd probably be even more disappointed that simple dead-key sequences like é worked but complex dead-key sequences like 万 didn't, but I haven't written the code for complex dead keys, and I'm not sure I want to…) But one of us should fix the API so it always returns a sequence of (key, mod) pairs instead of sometimes a list of them and sometimes just a pair. Or, if you don't want that feature, we can just strip the dead key support out.

Also, I haven't looked at what you're doing on linux, but both xim and gim have similar dead-key support to Mac (but only for simple dead keys). (Also, are you handling Ctrl-Shift-U on linux and Alt-KP on Windows? Because that lets you type a whole lot more characters, a lot more easily.)

abarnert avatar Jul 03 '14 04:07 abarnert

@SavinaRoja Since the keycodes vary based on the OS, how can i get the keycode for the same button for other OS. For instance, the backspace Keycode in Windows is 8, however i cant use that in Linux as in that is 20.

ranji2612 avatar Aug 26 '14 15:08 ranji2612