'''
@date 2015-02-22
@author Hong-She Liang <starofrainnight@gmail.com>
'''

import re
import subprocess
import six
import sys
from . import common
from ..mouse.xdotool import Mouse
from ..keyboard.xdotool import Keyboard


def _check_output(*args, **kwargs):
    output = subprocess.check_output(*args, **kwargs)
    if six.PY3:
        output = output.decode(sys.getdefaultencoding())
    return output


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()

        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle

    @property
    def title(self):
        output = _check_output(
            ["xdotool", "getwindowname", str(self.__handle)])
        return output.strip('\r\n').strip()

    @property
    def class_name(self):
        '''Get the window's class name.
        '''
        output = _check_output(["wmctrl", "-lx"])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)', aline)
            if matched is None:
                continue

            if self.__handle != int(matched.group(1), 16):
                continue

            return matched.group(3).split('.')[-1]

        return ""

    @property
    def geometry(self):
        output = _check_output(
            ["xdotool", "getwindowgeometry", str(self.__handle)])
        matched = re.match(
            "(?:\n|.)*"
            "Absolute upper-left X:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "Absolute upper-left Y:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "idth:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "eight:[^\d]*(\d+)[^\d]*(?:\n|.)*", output, re.M)
        if matched is None:
            # Return text different from original after upgraded to ubuntu
            # 16.04
            matched = re.match(
                "(?:\n|.)*"
                "osition:[^\d]*(\d+),(\d+)[^\d]*(?:\n|.)*"
                "eometry:[^\d]*(\d+)x(\d+)[^\d]*(?:\n|.)*", output, re.M)

        return (int(matched.group(1)),
                int(matched.group(2)),
                int(matched.group(3)),
                int(matched.group(4)))

    def raise_(self):
        subprocess.call(["xdotool", "windowraise",
                         "--sync", str(self.__handle)])

    def activate(self):
        subprocess.call(["xdotool", "windowactivate",
                         "--sync", str(self.__handle)])

    def close(self):
        subprocess.call(["xdotool", "windowkill", str(self.__handle)])

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(["xdotool", "getactivewindow"])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None

        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(["xdotool", "getmouselocation"])
            matched = re.match("(?:\n|.)*window:(\d+)*(?:\n|.)*", output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)

        result = []

        command = ["xdotool", "search"]
        command.append("--all")
        # It will freeze the search behaviors
        # command.append("--sync")

        # Check all windows by default
        if kwargs.get('only_visible', False):
            command.append("--onlyvisible")

        # Seems xdotool can't work if class name and title
        # at the sametime. So we search by ourself.
        command += ["--name", '']  # Search all windows

        output = _check_output(command)
        window_ids = re.findall("\d+", output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]

        for window_id in window_ids:
            window = Window(window_id)

            if (("title" in kwargs) and
                    (re.match(str(kwargs["title"]), window.title) is None)):
                continue

            if (("class_name" in kwargs) and
                    (re.match(str(kwargs["class_name"]), window.class_name) is None)):
                continue

            result.append(window)

            if kwargs["limit"] > 0:
                if len(result) >= kwargs["limit"]:
                    break

        return result

c904d9081ee600ace5088a1359928cc2957074bb
<mask token>


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()
        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle
    <mask token>

    @property
    def class_name(self):
        """Get the window's class name.
        """
        output = _check_output(['wmctrl', '-lx'])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match('(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)',
                aline)
            if matched is None:
                continue
            if self.__handle != int(matched.group(1), 16):
                continue
            return matched.group(3).split('.')[-1]
        return ''

    @property
    def geometry(self):
        output = _check_output(['xdotool', 'getwindowgeometry', str(self.
            __handle)])
        matched = re.match(
            """(?:
|.)*Absolute upper-left X:[^\\d]*(\\d+)[^\\d]*(?:
|.)*Absolute upper-left Y:[^\\d]*(\\d+)[^\\d]*(?:
|.)*idth:[^\\d]*(\\d+)[^\\d]*(?:
|.)*eight:[^\\d]*(\\d+)[^\\d]*(?:
|.)*"""
            , output, re.M)
        if matched is None:
            matched = re.match(
                """(?:
|.)*osition:[^\\d]*(\\d+),(\\d+)[^\\d]*(?:
|.)*eometry:[^\\d]*(\\d+)x(\\d+)[^\\d]*(?:
|.)*"""
                , output, re.M)
        return int(matched.group(1)), int(matched.group(2)), int(matched.
            group(3)), int(matched.group(4))

    def raise_(self):
        subprocess.call(['xdotool', 'windowraise', '--sync', str(self.
            __handle)])
    <mask token>
    <mask token>

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(['xdotool', 'getactivewindow'])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None
        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(['xdotool', 'getmouselocation'])
            matched = re.match('(?:\n|.)*window:(\\d+)*(?:\n|.)*', output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)
        result = []
        command = ['xdotool', 'search']
        command.append('--all')
        if kwargs.get('only_visible', False):
            command.append('--onlyvisible')
        command += ['--name', '']
        output = _check_output(command)
        window_ids = re.findall('\\d+', output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]
        for window_id in window_ids:
            window = Window(window_id)
            if 'title' in kwargs and re.match(str(kwargs['title']), window.
                title) is None:
                continue
            if 'class_name' in kwargs and re.match(str(kwargs['class_name']
                ), window.class_name) is None:
                continue
            result.append(window)
            if kwargs['limit'] > 0:
                if len(result) >= kwargs['limit']:
                    break
        return result

<mask token>


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()
        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle
    <mask token>

    @property
    def class_name(self):
        """Get the window's class name.
        """
        output = _check_output(['wmctrl', '-lx'])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match('(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)',
                aline)
            if matched is None:
                continue
            if self.__handle != int(matched.group(1), 16):
                continue
            return matched.group(3).split('.')[-1]
        return ''

    @property
    def geometry(self):
        output = _check_output(['xdotool', 'getwindowgeometry', str(self.
            __handle)])
        matched = re.match(
            """(?:
|.)*Absolute upper-left X:[^\\d]*(\\d+)[^\\d]*(?:
|.)*Absolute upper-left Y:[^\\d]*(\\d+)[^\\d]*(?:
|.)*idth:[^\\d]*(\\d+)[^\\d]*(?:
|.)*eight:[^\\d]*(\\d+)[^\\d]*(?:
|.)*"""
            , output, re.M)
        if matched is None:
            matched = re.match(
                """(?:
|.)*osition:[^\\d]*(\\d+),(\\d+)[^\\d]*(?:
|.)*eometry:[^\\d]*(\\d+)x(\\d+)[^\\d]*(?:
|.)*"""
                , output, re.M)
        return int(matched.group(1)), int(matched.group(2)), int(matched.
            group(3)), int(matched.group(4))

    def raise_(self):
        subprocess.call(['xdotool', 'windowraise', '--sync', str(self.
            __handle)])
    <mask token>

    def close(self):
        subprocess.call(['xdotool', 'windowkill', str(self.__handle)])

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(['xdotool', 'getactivewindow'])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None
        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(['xdotool', 'getmouselocation'])
            matched = re.match('(?:\n|.)*window:(\\d+)*(?:\n|.)*', output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)
        result = []
        command = ['xdotool', 'search']
        command.append('--all')
        if kwargs.get('only_visible', False):
            command.append('--onlyvisible')
        command += ['--name', '']
        output = _check_output(command)
        window_ids = re.findall('\\d+', output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]
        for window_id in window_ids:
            window = Window(window_id)
            if 'title' in kwargs and re.match(str(kwargs['title']), window.
                title) is None:
                continue
            if 'class_name' in kwargs and re.match(str(kwargs['class_name']
                ), window.class_name) is None:
                continue
            result.append(window)
            if kwargs['limit'] > 0:
                if len(result) >= kwargs['limit']:
                    break
        return result

<mask token>


def _check_output(*args, **kwargs):
    output = subprocess.check_output(*args, **kwargs)
    if six.PY3:
        output = output.decode(sys.getdefaultencoding())
    return output


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()
        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle

    @property
    def title(self):
        output = _check_output(['xdotool', 'getwindowname', str(self.__handle)]
            )
        return output.strip('\r\n').strip()

    @property
    def class_name(self):
        """Get the window's class name.
        """
        output = _check_output(['wmctrl', '-lx'])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match('(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)',
                aline)
            if matched is None:
                continue
            if self.__handle != int(matched.group(1), 16):
                continue
            return matched.group(3).split('.')[-1]
        return ''

    @property
    def geometry(self):
        output = _check_output(['xdotool', 'getwindowgeometry', str(self.
            __handle)])
        matched = re.match(
            """(?:
|.)*Absolute upper-left X:[^\\d]*(\\d+)[^\\d]*(?:
|.)*Absolute upper-left Y:[^\\d]*(\\d+)[^\\d]*(?:
|.)*idth:[^\\d]*(\\d+)[^\\d]*(?:
|.)*eight:[^\\d]*(\\d+)[^\\d]*(?:
|.)*"""
            , output, re.M)
        if matched is None:
            matched = re.match(
                """(?:
|.)*osition:[^\\d]*(\\d+),(\\d+)[^\\d]*(?:
|.)*eometry:[^\\d]*(\\d+)x(\\d+)[^\\d]*(?:
|.)*"""
                , output, re.M)
        return int(matched.group(1)), int(matched.group(2)), int(matched.
            group(3)), int(matched.group(4))

    def raise_(self):
        subprocess.call(['xdotool', 'windowraise', '--sync', str(self.
            __handle)])

    def activate(self):
        subprocess.call(['xdotool', 'windowactivate', '--sync', str(self.
            __handle)])

    def close(self):
        subprocess.call(['xdotool', 'windowkill', str(self.__handle)])

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(['xdotool', 'getactivewindow'])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None
        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(['xdotool', 'getmouselocation'])
            matched = re.match('(?:\n|.)*window:(\\d+)*(?:\n|.)*', output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)
        result = []
        command = ['xdotool', 'search']
        command.append('--all')
        if kwargs.get('only_visible', False):
            command.append('--onlyvisible')
        command += ['--name', '']
        output = _check_output(command)
        window_ids = re.findall('\\d+', output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]
        for window_id in window_ids:
            window = Window(window_id)
            if 'title' in kwargs and re.match(str(kwargs['title']), window.
                title) is None:
                continue
            if 'class_name' in kwargs and re.match(str(kwargs['class_name']
                ), window.class_name) is None:
                continue
            result.append(window)
            if kwargs['limit'] > 0:
                if len(result) >= kwargs['limit']:
                    break
        return result

<mask token>
import re
import subprocess
import six
import sys
from . import common
from ..mouse.xdotool import Mouse
from ..keyboard.xdotool import Keyboard


def _check_output(*args, **kwargs):
    output = subprocess.check_output(*args, **kwargs)
    if six.PY3:
        output = output.decode(sys.getdefaultencoding())
    return output


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()
        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle

    @property
    def title(self):
        output = _check_output(['xdotool', 'getwindowname', str(self.__handle)]
            )
        return output.strip('\r\n').strip()

    @property
    def class_name(self):
        """Get the window's class name.
        """
        output = _check_output(['wmctrl', '-lx'])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match('(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)',
                aline)
            if matched is None:
                continue
            if self.__handle != int(matched.group(1), 16):
                continue
            return matched.group(3).split('.')[-1]
        return ''

    @property
    def geometry(self):
        output = _check_output(['xdotool', 'getwindowgeometry', str(self.
            __handle)])
        matched = re.match(
            """(?:
|.)*Absolute upper-left X:[^\\d]*(\\d+)[^\\d]*(?:
|.)*Absolute upper-left Y:[^\\d]*(\\d+)[^\\d]*(?:
|.)*idth:[^\\d]*(\\d+)[^\\d]*(?:
|.)*eight:[^\\d]*(\\d+)[^\\d]*(?:
|.)*"""
            , output, re.M)
        if matched is None:
            matched = re.match(
                """(?:
|.)*osition:[^\\d]*(\\d+),(\\d+)[^\\d]*(?:
|.)*eometry:[^\\d]*(\\d+)x(\\d+)[^\\d]*(?:
|.)*"""
                , output, re.M)
        return int(matched.group(1)), int(matched.group(2)), int(matched.
            group(3)), int(matched.group(4))

    def raise_(self):
        subprocess.call(['xdotool', 'windowraise', '--sync', str(self.
            __handle)])

    def activate(self):
        subprocess.call(['xdotool', 'windowactivate', '--sync', str(self.
            __handle)])

    def close(self):
        subprocess.call(['xdotool', 'windowkill', str(self.__handle)])

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(['xdotool', 'getactivewindow'])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None
        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(['xdotool', 'getmouselocation'])
            matched = re.match('(?:\n|.)*window:(\\d+)*(?:\n|.)*', output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)
        result = []
        command = ['xdotool', 'search']
        command.append('--all')
        if kwargs.get('only_visible', False):
            command.append('--onlyvisible')
        command += ['--name', '']
        output = _check_output(command)
        window_ids = re.findall('\\d+', output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]
        for window_id in window_ids:
            window = Window(window_id)
            if 'title' in kwargs and re.match(str(kwargs['title']), window.
                title) is None:
                continue
            if 'class_name' in kwargs and re.match(str(kwargs['class_name']
                ), window.class_name) is None:
                continue
            result.append(window)
            if kwargs['limit'] > 0:
                if len(result) >= kwargs['limit']:
                    break
        return result

'''
@date 2015-02-22
@author Hong-She Liang <starofrainnight@gmail.com>
'''

import re
import subprocess
import six
import sys
from . import common
from ..mouse.xdotool import Mouse
from ..keyboard.xdotool import Keyboard


def _check_output(*args, **kwargs):
    output = subprocess.check_output(*args, **kwargs)
    if six.PY3:
        output = output.decode(sys.getdefaultencoding())
    return output


class Window(common.Window):

    def __init__(self, handle):
        super(Window, self).__init__()

        self.__handle = int(handle)
        self._keyboard = Keyboard()

    @property
    def handle(self):
        return self.__handle

    @property
    def title(self):
        output = _check_output(
            ["xdotool", "getwindowname", str(self.__handle)])
        return output.strip('\r\n').strip()

    @property
    def class_name(self):
        '''Get the window's class name.
        '''
        output = _check_output(["wmctrl", "-lx"])
        lines = output.splitlines()
        for aline in lines:
            aline = aline.strip()
            matched = re.match(r'(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)', aline)
            if matched is None:
                continue

            if self.__handle != int(matched.group(1), 16):
                continue

            return matched.group(3).split('.')[-1]

        return ""

    @property
    def geometry(self):
        output = _check_output(
            ["xdotool", "getwindowgeometry", str(self.__handle)])
        matched = re.match(
            "(?:\n|.)*"
            "Absolute upper-left X:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "Absolute upper-left Y:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "idth:[^\d]*(\d+)[^\d]*(?:\n|.)*"
            "eight:[^\d]*(\d+)[^\d]*(?:\n|.)*", output, re.M)
        if matched is None:
            # Return text different from original after upgraded to ubuntu
            # 16.04
            matched = re.match(
                "(?:\n|.)*"
                "osition:[^\d]*(\d+),(\d+)[^\d]*(?:\n|.)*"
                "eometry:[^\d]*(\d+)x(\d+)[^\d]*(?:\n|.)*", output, re.M)

        return (int(matched.group(1)),
                int(matched.group(2)),
                int(matched.group(3)),
                int(matched.group(4)))

    def raise_(self):
        subprocess.call(["xdotool", "windowraise",
                         "--sync", str(self.__handle)])

    def activate(self):
        subprocess.call(["xdotool", "windowactivate",
                         "--sync", str(self.__handle)])

    def close(self):
        subprocess.call(["xdotool", "windowkill", str(self.__handle)])

    def send(self, *args, **kwargs):
        self._keyboard.send(*args, window=self.handle, **kwargs)


class Manager(common.Manager):

    def __init__(self):
        super(Manager, self).__init__()
        self.__mouse = Mouse()

    def get_active(self):
        output = _check_output(["xdotool", "getactivewindow"])
        return Window(int(output.strip('\r\n').strip()))

    def get_from_position(self, position):
        old_position = None

        if position != self.__mouse.position():
            old_position = self.__mouse.position()
            self.__mouse.move(position)
        try:
            output = _check_output(["xdotool", "getmouselocation"])
            matched = re.match("(?:\n|.)*window:(\d+)*(?:\n|.)*", output)
            return Window(int(matched.group(1)))
        finally:
            if old_position is not None:
                self.__mouse.move(old_position)

    def find(self, **kwargs):
        self._prepare_find_arguments(kwargs)

        result = []

        command = ["xdotool", "search"]
        command.append("--all")
        # It will freeze the search behaviors
        # command.append("--sync")

        # Check all windows by default
        if kwargs.get('only_visible', False):
            command.append("--onlyvisible")

        # Seems xdotool can't work if class name and title
        # at the sametime. So we search by ourself.
        command += ["--name", '']  # Search all windows

        output = _check_output(command)
        window_ids = re.findall("\d+", output, re.M)
        window_ids = [int(window_id) for window_id in window_ids]

        for window_id in window_ids:
            window = Window(window_id)

            if (("title" in kwargs) and
                    (re.match(str(kwargs["title"]), window.title) is None)):
                continue

            if (("class_name" in kwargs) and
                    (re.match(str(kwargs["class_name"]), window.class_name) is None)):
                continue

            result.append(window)

            if kwargs["limit"] > 0:
                if len(result) >= kwargs["limit"]:
                    break

        return result
