moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.74k stars 244 forks source link

Odd behavior with Alt pressed on Windows 10 #527

Open tcsdmaic opened 1 year ago

tcsdmaic commented 1 year ago

I am trying to write a script to use global hotkeys to send the Windows Alt + ascii code keys to make symbols.

For example: holding down Alt while hitting 0, 1, 4, 9 in rapid succession will give you a solid bullet point. Or holding down Alt while hitting 0, 1, 7, 6 in rapid succession will give you a degree sign.

Here's what I have so far:

from pynput import keyboard
from pynput.keyboard import Key, Controller

mykeyboard = Controller()

def on_activate_o():
    with mykeyboard.pressed(Key.alt):
        mykeyboard.type('0149')

def on_activate_f():
    with mykeyboard.pressed(Key.alt):
        mykeyboard.type('0176')

with keyboard.GlobalHotKeys({
        'o': on_activate_o,
        'f': on_activate_f}) as h:
    h.join()

So what's interesting is if I specify using the Shift key instead of Alt, that works - when I hit 'o' I end up with that followed by ")!$(".

But with Alt, only the 3rd number is registering. I know this because if you are in MS Word and hit 'Alt' then it gives you numbers or letters for different menu items, and then hitting that number or letter opens that menu. So when I hit 'o', it opens the Mouse menu (which is Alt then '4'). If I change the '4' to '2' then when I hit 'o' in Word it opens the Undo menu.

Is there something I'm missing when it comes to using Alt in this manner?

SpecialCharacter commented 1 year ago

I think you have to suppress whatever function the Alt key is originally doing. I had the same issue with the Windows key.

tcsdmaic commented 1 year ago

If you had to do this with the Windows key, then could you provide what you did for reference? I tried adding a listener and adding the win32_event_filter to suppress Alt key events, but it isn't working.

SpecialCharacter commented 1 year ago

I first created a tracker for the Windows key:

            if key == Key.cmd:
                cmd = True
                print("cmd ", cmd)

Then I suppressed the combination (in my case, b):

def win32_event_filter(msg, data):
        global cmd

        if msg == 256 and data.vkCode == 66:                # data.vkCode == 66: "b"
        # if (msg == 257 or msg == 256) # Key down/up
            print("S u p p r e s s i n g Windows + B")      # test
                cmd = False
            listener._suppress = True
            return False
moses-palmer commented 1 year ago

@tcsdmaic, did the suggestion resolve your problem?