1

I am using Pynput and Subprocess with NirCmd in an effort to create a HotKey that will turn my monitor off. The program works fine the first time the function is triggered. However, when triggering the function a second time, pressing any ctrl key at all, even by itself, will trigger the function. This is my code:

import subprocess
from string import ascii_lowercase, digits
from pynput.keyboard import Key, KeyCode, Listener

#Function mapped to HotKey
def monitor_off():
    subprocess.run("ECHO Testing", shell=True) #<--- This is an example operation to show that the program works when doing anything other than running NirCmd
    #subprocess.run("nircmd monitor off", shell=True) '''<--- This is the problematic operation'''

#Combination to trigger the function monitor_off
combination_to_function = {
frozenset([Key.ctrl_l, Key.ctrl_r]): monitor_off,
}

#Creating set to store the keys being actively pressed
current_keys = set()

'''When a key is pressed, add it to the current_keys set.
Then check if the current_keys set matches any of the hotkey combinations.
If it does, execute the function mapped to the combination(s)'''
def on_press(key):
    current_keys.add(key)
    if frozenset(current_keys) in combination_to_function:
        combination_to_function[frozenset(current_keys)]()

#When a key is released, remove it from the current_keys set
def on_release(key):
    current_keys.remove(key)

#Joining on_press and on_release to the main thread
with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()
Jackal
  • 195
  • 9
  • In my computer,only when I press two ctrl buttons at the same time, it will print `testing`. – jizhihaoSAMA Apr 02 '20 at 14:26
  • If I only press one button,it won't print `testing`. – jizhihaoSAMA Apr 02 '20 at 14:26
  • That is an example operation, to show you that the program works fine when doing anything other than calling NirCmd. – Jackal Apr 02 '20 at 14:29
  • I know,.Your problem is *when triggering the function a second time, pressing any ctrl key at all, even by itself, will trigger the function.*.But it worked fine in my computer. – jizhihaoSAMA Apr 02 '20 at 14:30
  • Did you use it with NirCmd? What I'm getting at is that the problem is in the interaction between NirCmd and subprocess, but I don't know what that problem is. – Jackal Apr 02 '20 at 14:31
  • You probably shouldn't be using `shell=True`. Try with the proper command line to nircmd, i.e. `subprocess.run(["c:/somewhere/nircmd.exe", "monitor", "off"])`. – AKX Apr 02 '20 at 14:32
  • You're definitely right that is a better way to run it, although the same problem still occurs. – Jackal Apr 02 '20 at 14:36

0 Answers0