change window's "matchClass" to "className" instead? #922
Replies: 2 comments 1 reply
-
Welcome to the AutoKey community, @BloodyRain2k . Not sure exactly what you're referring to. Where are the options you refer to? AutoKey window filters match on both window class or title. This is a deficiency in AutoKey. That's usually fine except when you want to make a negative filter (match all windows except these...). There are a bunch of related open issues: #161 #200 #301 #305 . What one of our devs did was replace the window filter regex with a user supplied Python script. However, this code appears to have been lost. What you can do is match on something common and then use our API calls to get and test the specifics. This works fine, but gets in the way if you want to use the same hotkey (with a different window filter) for another action. Alternatively, you can call out (subprocess()) to xdotool which supports command chaining so you can do a number of tests/actions serially in one invocation like finding the right window and then acting on it. I have a bash startup script for KDE (not an AutoKey script) which sees what applications were restored and starts those that weren't and then sees what virtual desktop they're on and moves them if they're not where I want them. It's all done using xdotool. |
Beta Was this translation helpful? Give feedback.
-
I ended up writing my own script just for this case, as it seemed easier than requiring a keypress for it. The base for it was the #!/bin/env python3
import signal, subprocess, re, os
from dataclasses import dataclass
import sys
from time import sleep
@dataclass
class WindowInfo:
window_id:str
desktop_id:str
className:str
machine:str
title:str
class ExitReceiver:
def __init__(self) -> None:
self.should_exit = False
signal.signal(signal.SIGINT, self.exit_received)
signal.signal(signal.SIGTERM, self.exit_received)
def exit_received(self, code, *args):
print('exit received:', code, args)
self.should_exit = True
def run_wmctrl(args:list[str]) -> tuple[int,str]:
try:
with subprocess.Popen(["wmctrl"] + args, stdout=subprocess.PIPE) as p:
output = p.communicate()[0].decode()[:-1] # Drop trailing newline
returncode = p.returncode
return returncode, output
except FileNotFoundError:
return 1, 'ERROR: Please install wmctrl'
# window_id | desktop_id | class | machine | title
rx = re.compile(r'^(\w+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.+)$')
def find_window(title="", className="") -> list[WindowInfo]:
matches = []
code, msg = run_wmctrl(["-l", "-x"])
if code != 0:
raise Exception(msg)
for line in msg.split("\n"):
match = rx.search(line)
if not match:
continue
groups = match.groups()
if title and title not in groups[-1]:
continue
if className and className not in groups[2]:
continue
matches.append(WindowInfo(*groups))
return matches
if __name__ == "__main__":
matched_before = []
loop = ExitReceiver()
while not loop.should_exit:
windows = find_window("Save As", "codium.Codium")
if windows.__len__() > 0:
while matched_before.__len__() >= 5:
matched_before.pop(0)
for win in windows:
if win.window_id in matched_before:
continue
if run_wmctrl(["-i", "-R", win.window_id])[0] == 0:
matched_before.append(windows[0].window_id)
sleep(0.25) Works for the most part, until the service that runs it somehow loses access to the display... but that's a "me issue". |
Beta Was this translation helpful? Give feedback.
-
I was wondering if it would be possible to have a different parameter for class matching.
Instead of "yes, title is a class" have a separate one that's specifically for that?
This would allow matching a window by title and class instead of either or. Unless I'm missing something obvious in the wiki.
For example, I'm trying to use AutoKey to "fix" a bug in VSCodium, where the "Save As" dialog pops up behind the window.
While it does work to just look for a "Save As" window, I'd rather have it look specifically for the kind of "Save As" window that VSCodium creates.
But I don't see any way of doing that.
Maybe activating every match, checking the then active window's class and tossing it below if it's not the one I'm looking for.
But then the question would be if the next wouldn't end up being just the same.
This could simply be solved by being able to specify both filters in one call.
Adding a new parameter
className=
should be fine, andmatchClass=
could be left as is but marked asdeprecated
or something.And if the backend
wmctrl
doesn't support both filters at the same time, would it be possible to just get the class result first, then filter that with the title?Beta Was this translation helpful? Give feedback.
All reactions