You were using the virtual desktop mode, that is why it worked, good.
Copying multiple Wow.exe is indeed a solution to your problem, but not a clean one.
There are many possibilities to achieve what you want, the cleanest way is to get a list of every running X11 window and to go through the tree and find the correct windows.
With xdotool alone, we can't really achieve that but we can use several tools to do it :
- You launch every wow instance with a unique virtual desktop name (see under to know how to do that).
- Copy the script I have made for you, save it as keybroadcast.py and make it executable with chmod +x <path_to_file>
- Edit the script where it is written "# RENAME ME", replace with your names, you can add more slave if you want, just follow the syntax (slave_1, slave_2 ...), it is a dictionnary.
- Execute it by invoking it with your terminal emulator or by passing it to the python3 interpreter, it doesn't need root privileges.
Dependencies : python3, xwininfo (install them from your package manager)
Code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author : Intoxx
import subprocess
from shlex import quote
def execute(cmd):
'''
Execute a given command @cmd in a shell
Return a list with the splitted result if there is any
Else it will return None
'''
result = None
try :
out = subprocess.check_output(cmd, encoding="UTF-8", shell=True)
except subprocess.CalledProcessError as error:
pass
else:
out = out.split() # Clear some whitespace
result = out if len(out) > 0 else None
return result
def find_window_by_name(name):
result = execute("xdotool search --name {}".format(quote(name)))
if result is not None:
result = result[0] # result is a list, I only want the first element
return result
def find_child_window_by_name(parent, name):
result = execute("xwininfo -children -id {} | grep {}".format(
quote(parent), quote(name)))
if result is not None:
result = result[0] # result is a list, I only want the first element
return result
def send_key_press(window, key):
execute("xdotool keydown --window {} {}".format(window, key))
def send_key_release(window, key):
execute("xdotool keyup --window {} {}".format(window, key))
def send_key(window, key):
execute("xdotool key --window {} {}".format(window, key))
if __name__ == '__main__':
'''
This program will try to find every virtual desktop with their appropriate name,
Then it will try to find inside each of them a window matching @IME_STRING variable
And finally if everything has been found, it will send the key "1" to every instance
'''
IME_STRING = '"Default IME": ("wow.exe" "Wine")'
instances = {
"host" : {
"virtual_desktop_name" : "WoW_1" # RENAME ME
},
"slave_1" : {
"virtual_desktop_name" : "WoW_2" # RENAME ME TOO (add more if needed with unique identifiers)
}
}
# Finding every instance for future usage
for i in instances:
# Find associated virtual desktop
virtual_desktop = find_window_by_name(instances[i]["virtual_desktop_name"])
if virtual_desktop is not None:
# Found, save it
instances[i]["virtual_desktop"] = virtual_desktop
# Search for a child window named @IME_STRING
default_ime = find_child_window_by_name(virtual_desktop,
IME_STRING)
if default_ime is not None:
# Found, save it
instances[i]["default_ime"] = default_ime
else:
print("Cannot find '{}' window for parent window '{}'".format(
IME_STRING, instances[i]["virtual_desktop_name"]))
else:
print("Cannot find '{}' virtual desktop".format(
instances[i]["virtual_desktop_name"]))
# Using them
for i in instances:
# Sending "1" key to every instance (press followed by release)
if instances[i]["default_ime"] is not None:
send_key(instances[i]["default_ime"], "1")
This code is pretty easy and make use of xwininfo to get informations about every virtual desktop window then it parse the tree in order to get every Default_IME window, everything is saved in a dictionnary.
Feel free to use it and add it to your current code.
I didn't add a lot of comments but if you have any questions, just ask, start by trying it.
(the magic part is in the usage of xwininfo combined with grep)
Don't forget to edit the names for the "virtual_desktop_name" to be like your.
If you don't want to use this python script, then you can simply open a terminal and write
Code:
xwininfo -children -id $(xdotool search --name "WoW_1") | grep '"Default IME": ("wow.exe" "Wine")' | awk '{print $1;}'
This will print to you the window id of the "Default IME" window associated with the virtual desktop named "WoW_1".
This also require awk tool which is usually already installed.
How to launch a wine instance with a specific virtual desktop name ?
Easy, edit the way you launch your wow instances with the following :
Code:
............ wine explorer /desktop="WoW_1","1920x1080".........
Documentation: https://wiki.winehq.org/Explorer
When adding explorer /desktop="NAME","WIDTHxHEIGHT" to your wine command line, it will bypass what you set in your winecfg for the virtual desktop and will create it directly with a size of WIDTH x HEIGHT pixels and the title of the window will be NAME.
Per example, my launching script is :
Code:
#!/bin/bash
NAME="WoW_1" # Don't put any space
RESOLUTION="1340x1080"
PREFIX="/usr/local/data/wine/wow_1"
WINEPREFIX=$PREFIX WINEDEBUG="-all" STAGING_SHARED_MEMORY=1 STAGING_WRITECOPY=1 wine explorer /desktop=$NAME,$RESOLUTION "$PREFIX/drive_c/Program Files (x86)/World of Warcraft/_retail_/Wow.exe"
This is a simple way to launch several instances of the same game, just copy the file and change the name, the dimensions and the prefixe for every wow instance you have.
You can take it if you want.
Well, this should give you an idea how to do it without the need to rename all of these .exe.
Intoxx.
Connect With Us