Qtile/Python - Key Binding

I’m trying to set a keybinding in qtile. The command that works in my terminal is this:
xsel | mimic3
Checking the qtile docs shows I should be able to format it like this:

Key([mod], "s",
        lazy.spawn(['xsel | mimic3'],shell=True),
        desc='Custom command'
       ),

However, that doesn’t seem to work so I tried a different format

Key([mod], "s",
    lazy.spawn(["sh", "-c", "xsel | mimic3"]),
    desc='Custom command'
   ),

Still doesn’t work.

I discovered that if I use an early version of mimic, it does work. So, digging into that a little more; I installed the early version of mimic from the AUR and it’s a binary. While mimic3 I installed via python because it’s not in the AUR and it’s a python script.

the mimic3 python script is located: ~/.local/bin/mimic3

So, I’m thinking maybe there’s an issue piping xsel into a python script since qtile is python based as well. So, I started researching how to run an python script from inside another python script and found subprocess.run With that, I thought I’d make a function and just call the function with the hotkey

@lazy.function
def mimic3_func():
    ps1=subprocess.run(['xsel'],capture_output=True,text=True,check=True)
    subprocess.run(['python','/home/kodiak/.local/bin/mimic3'],input=ps1.stdout,check=True)

Key([mod], "s",
    mimic3_func,
    desc='Custom command'
   ),

But, that just creates an error:

2022-10-15 17:46:31,463 ERROR libqtile base.py:cmd_function():L216 Exception calling "<function mimic3_func at 0x7f0120956710>":
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/libqtile/command/base.py", line 213, in cmd_function
    function(self, *args, **kwargs)
TypeError: mimic3_func() takes 0 positional arguments but 1 was given

Now I’m out of ideas, does anyone else have any?

Have you tried a script and subprocess.run?
This seems to work, hard to say as I am on running wayland so xsel can be a bit flaky :smiley:

#!/usr/bin/env bash
xsel | mimic3

hmm, that does not seem to work either. and that script works if run from my terminal so I tried:

         Key([mod], "s",
             lazy.spawn(['/home/kodiak/Scripts/select_tts_test.sh'],shell=True)
             ),

and

         Key([mod], "s",
             subprocess.run(['/home/kodiak/Scripts/select_tts_test.sh'])
             ),

When I use subprocess.run it just completely freezes Qtile and I have to use the SysRq RE to get to sddm login and reboot.

Interestingly if I run
python3 /home/kodiak/.config/qtile/config.py
To check if it compiles correctly, It immediately runs the the select_tts_test.sh script without having to press anything. So, I may not be using subprocess.run correctly. I tossed it into a function but I get the same error as above:

2022-10-16 10:39:28,832 ERROR libqtile base.py:cmd_function():L216 Exception calling "<function mimic3_func at 0x7f319f1fe710>":
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/libqtile/command/base.py", line 213, in cmd_function
    function(self, *args, **kwargs)
TypeError: mimic3_func() takes 0 positional arguments but 1 was given

If I don’t make it a @lazy.function (not really sure what that is to be honest) I get a different error

def mimic3_func():
    subprocess.run(['/home/kodiak/Scripts/select_tts_test.sh'],check=True)
2022-10-16 11:02:32,354 ERROR libqtile core.py:_xpoll():L340 Got an exception in poll loop
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/libqtile/backend/x11/core.py", line 308, in _xpoll
    ret = target(event)
  File "/usr/lib/python3.10/site-packages/libqtile/backend/x11/core.py", line 616, in handle_KeyPress
    self.qtile.process_key_event(keysym, event.state & self._valid_mask)
  File "/usr/lib/python3.10/site-packages/libqtile/core/manager.py", line 402, in process_key_event
    if cmd.check(self):
AttributeError: 'function' object has no attribute 'check'

So, this may mean I’m not making a function correctly either.

I don’t have qtile installed at the moment, let me install it later and I will have a look.

Well, I couldn’t get that to work. I’m pretty sure it’s something with mimic3 being python scripts that qtile doesn’t like. However, I got a workaround going that actually works better.
I’m just added the mimic3-server to my startup script (It makes it all faster anyway since the server is already running and prepped for processing). Then installed speech-dispatcher and now I’m just piping xsel into spd-say. So now my hotkey looks like this and works swimmingly.

         Key([mod], "s",
             lazy.spawn(["sh", "-c", "xsel | spd-say -e"]),
             desc='selected text to speech'
             ),
1 Like