1

I'm trying to do what this question asked (this question has no valid answers with functional code using pynput): Press Windows+D with pynput. But, my attempts are not working as expected.

On Linux Ubuntu, pressing Windows + d will minimize all windows, thereby showing the desktop. Doing it again will bring all the windows back as they were.

Here's my code:

import time

from pynput.keyboard import Key, Controller

keyboard = Controller()
SUPER_KEY = Key.cmd

keyboard.press(SUPER_KEY)
# time.sleep(1)
keyboard.press('d')
keyboard.release('d')
keyboard.release(SUPER_KEY)

When I run it, I expect the Windows + d shortcut to be pressed, hiding all windows. Instead, only the Windows key is pressed, which brings up the program launcher search tool, and then a single d is left printed in my terminal, like this:

$ ./pynput_press_Windows+D_to_show_the_desktop.py 
$ d

How do I get this to work?

The reference documentation says (https://pynput.readthedocs.io/en/latest/keyboard.html) that Key.cmd is the "Super" or "Windows" key. I've also tried with Key.cmd_l and Key.cmd_r.

cmd = 0

A generic command button. On PC platforms, this corresponds to the Super key or Windows key, and on Mac it corresponds to the Command key. This may be a modifier.

cmd_l = 0

The left command button. On PC platforms, this corresponds to the Super key or Windows key, and on Mac it corresponds to the Command key. This may be a modifier.

cmd_r = 0

The right command button. On PC platforms, this corresponds to the Super key or Windows key, and on Mac it corresponds to the Command key. This may be a modifier.


Update 4 June 2023: keyboard monitor test program, to ensure Key.cmd + d is correct for my keyboard (it is): modified from https://pynput.readthedocs.io/en/latest/keyboard.html#monitoring-the-keyboard:

from pynput import keyboard

print("Keyboard monitor demo program. Press Esc to exit.")

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        print("Exiting the program.")
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

Sample output when I press Super + D:

$ ./pynput_monitor_keyboard.py 
Keyboard monitor demo program. Press Esc to exit.
Key.enter released
special key Key.cmd pressed
alphanumeric key d pressed
'd' released
Key.cmd released
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265

2 Answers2

1

If you have a dual language keyboard, a different keyboard "shortcut" may work. On my Russian-English keyboard, pressing the Russian "в" worked, which is "d" in the English layout. I learned this using keyboard monitoring from the documentation by pressing "win + d" on the keyboard.

from pynput.keyboard import Key, Controller

keyboard = Controller()

with keyboard.pressed(Key.cmd):
    keyboard.press('в')
    keyboard.release('в')
Сергей Кох
  • 1,417
  • 12
  • 6
  • 13
  • Thank you. I'll try out the keyboard monitoring. I'm on a regular US English keyboard. What OS are you on? – Gabriel Staples Jun 05 '23 at 01:49
  • I ran the test. For me, it is indeed `Key.cmd`, and `d`. I'll add the output to my question. – Gabriel Staples Jun 05 '23 at 02:24
  • Done. My question is updated. And I ran you code with the modification of using `d` instead of `в`, and it still doesn't work for me. The `Key.cmd` works right, but the `d` gets sent to the terminal instead of as a key joined to `Key.cmd` to show the desktop. – Gabriel Staples Jun 05 '23 at 02:29
  • 1
    @GabrielStaples I have windows 10, python 3.11, pycharm. I have tried before this the following libraries pyautogui, keyboard - they don't work on this keyboard shortcut. Only win32api worked right away. https://stackoverflow.com/questions/65664978/simulate-wind-show-desktop-from-python-script. – Сергей Кох Jun 05 '23 at 17:37
  • 1
    I think your code is correct, and that the fact it doesn't work on my Linux computer is a bug. I've opened a bug report with `pynput`: https://github.com/moses-palmer/pynput/issues/556 – Gabriel Staples Jun 08 '23 at 04:35
  • Upvoted for being useful, but I have written [my own answer here too.](https://stackoverflow.com/a/76544123/4561887) I'm concluding it's just a pynput bug. – Gabriel Staples Jun 24 '23 at 00:33
0

I just want to tie the loose ends on this question.

As far as I can tell, my code in the question is fine. @Сергей Кох's answer is fine too. There is just a bug in pynput is all, preventing it from working in Ubuntu. Super + D fails, Ctrl + Super + D fails, Ctrl + Alt + D fails.

I'm on Ubuntu 22.04.2, and even in the X11 window manager (as opposed to Wayland), it still doesn't work.

Here's my bug report: Bug on Linux: Windows (Super) + D doesn't work

Here is some valid code that should work. If you have a Mac or Windows, please try it out and leave a comment if this code works or not. Both techniques here should be equally valid. Note: a list of all possible keys is here: https://pynput.readthedocs.io/en/latest/keyboard.html#pynput.keyboard.Key

import time

from pynput.keyboard import Key, Controller


# ========== technique 1 ===========
# From: https://pynput.readthedocs.io/en/latest/keyboard.html
print("Trying technique 1")

keyboard = Controller()
SUPER_KEY = Key.cmd
with keyboard.pressed(SUPER_KEY):
    keyboard.press('d')
    keyboard.release('d')


time.sleep(1.0)


# ========== technique 2 ===========
print("Trying technique 2")

keyboard = Controller()
SUPER_KEY = Key.cmd

keyboard.press(SUPER_KEY)
keyboard.press('d')
keyboard.release('d')
keyboard.release(SUPER_KEY)

The suggestion was made to try Ctrl + Windows + D. It makes no difference, and also doesn't work due to whatever bug is going on. Here is my test code. Note: I also tried Key.ctrl_l instead of Key.ctrl, and it made no difference.

import time

from pynput.keyboard import Key, Controller


# ========== technique 1 ===========
# From: https://pynput.readthedocs.io/en/latest/keyboard.html
print("Trying technique 1")

keyboard = Controller()
SUPER_KEY = Key.cmd

with keyboard.pressed(Key.ctrl):
    with keyboard.pressed(SUPER_KEY):
        keyboard.press('d')
        keyboard.release('d')


time.sleep(1.0)


# ========== technique 2 ===========
print("Trying technique 2")

keyboard = Controller()
SUPER_KEY = Key.cmd

keyboard.press(Key.ctrl)
keyboard.press(SUPER_KEY)
keyboard.press('d')
keyboard.release('d')
keyboard.release(SUPER_KEY)
keyboard.release(Key.ctrl)

Ctrl + Alt + D also works manually, same as the options above, but not with pynput. This code also fails to have any effect. Note that I also tried Key.alt_gr and Key.alt_l in place of Key.alt in the code below, and both of those failed too:

import time

from pynput.keyboard import Key, Controller


# ========== technique 1 ===========
# From: https://pynput.readthedocs.io/en/latest/keyboard.html
print("Trying technique 1")

keyboard = Controller()

with keyboard.pressed(Key.ctrl):
    with keyboard.pressed(Key.alt):
        keyboard.press('d')
        keyboard.release('d')


time.sleep(1.0)


# ========== technique 2 ===========
print("Trying technique 2")

keyboard = Controller()

keyboard.press(Key.ctrl)
keyboard.press(Key.alt)
keyboard.press('d')
keyboard.release('d')
keyboard.release(Key.alt)
keyboard.release(Key.ctrl)

So, for people on Ubuntu, if you want to automate a tool to press Windows + D, use wmctrl or ydotool instead:

  1. I have posted a full demo in my answer here: Ask Ubuntu: How can I write a program to press keys, such as Windows + D, in Wayland? (replace xdotool in Wayland), and
  2. I have written a full article with even more info on my website here: Tutorial: Getting started with ydotool to automate key presses (or mouse movements) in Linux.
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265