Close
Showing results 1 to 10 of 14

Threaded View

  1. #6

    Default

    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 :


    1. You launch every wow instance with a unique virtual desktop name (see under to know how to do that).
    2. Copy the script I have made for you, save it as keybroadcast.py and make it executable with chmod +x <path_to_file>
    3. 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.
    4. 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.
    Last edited by intoxx : 03-17-2019 at 10:01 PM

Tags for this Thread

Posting Rules

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •