From dbcc090f56c71d08e9395b300a8d3156c1857553 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 22 Aug 2023 15:37:41 -0700 Subject: [PATCH 01/52] initial work to enable extensions --- ahk/_async/engine.py | 36 +++++++++++- ahk/_async/transport.py | 7 ++- ahk/_constants.py | 14 +++++ ahk/_sync/engine.py | 35 +++++++++++- ahk/_sync/transport.py | 5 +- ahk/_sync/window.py | 12 +--- ahk/extensions.py | 99 +++++++++++++++++++++++++++++++++ ahk/templates/daemon.ahk | 14 +++++ tests/_async/test_extensions.py | 67 ++++++++++++++++++++++ tests/_sync/test_extensions.py | 66 ++++++++++++++++++++++ 10 files changed, 342 insertions(+), 13 deletions(-) create mode 100644 ahk/extensions.py create mode 100644 tests/_async/test_extensions.py create mode 100644 tests/_sync/test_extensions.py diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index c0a6d8b..8804426 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -6,6 +6,7 @@ import tempfile import time import warnings +from functools import partial from typing import Any from typing import Awaitable from typing import Callable @@ -34,6 +35,7 @@ else: from typing import TypeAlias +from ..extensions import Extension, _extension_method_registry, _ExtensionMethodRegistry from ..keys import Key from .transport import AsyncDaemonProcessTransport from .transport import AsyncFutureResult @@ -135,13 +137,45 @@ def __init__( TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', + extensions: list[Extension] | None | Literal['auto'] = None, ): + self._extension_registry: _ExtensionMethodRegistry + self._extensions: list[Extension] + if extensions == 'auto': + is_async = False + is_async = True # unasync: remove + if is_async: + extensions = [entry.extension for name, entry in _extension_method_registry.async_methods.items()] + else: + extensions = [entry.extension for name, entry in _extension_method_registry.sync_methods.items()] + self._extension_registry = _extension_method_registry + self._extensions = extensions + else: + self._extensions = extensions or [] + self._extension_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + for ext in self._extensions: + self._extension_registry.merge(ext._extension_method_registry) + if TransportClass is None: TransportClass = AsyncDaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives) + transport = TransportClass(executable_path=executable_path, directives=directives, extensions=extensions) self._transport: AsyncTransport = transport + def __getattr__(self, name: str) -> Callable[..., Any]: + is_async = False + is_async = True # unasync: remove + if is_async: + if name in self._extension_registry.async_methods: + method = self._extension_registry.async_methods[name].method + return partial(method, self) + else: + if name in self._extension_registry.sync_methods: + method = self._extension_registry.sync_methods[name].method + return partial(method, self) + + raise AttributeError(f'{self.__class__.__name__!r} object has no attribute {name!r}') + def add_hotkey( self, keyname: str, callback: Callable[[], Any], ex_handler: Optional[Callable[[str, Exception], Any]] = None ) -> None: diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index d34f18b..46c4b97 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -38,6 +38,7 @@ import jinja2 +from ahk.extensions import Extension from ahk._hotkey import ThreadedHotkeyTransport, Hotkey, Hotstring from ahk.message import RequestMessage from ahk.message import ResponseMessage @@ -656,7 +657,9 @@ def __init__( directives: Optional[list[Directive | Type[Directive]]] = None, jinja_loader: Optional[jinja2.BaseLoader] = None, template: Optional[jinja2.Template] = None, + extensions: list[Extension] | None = None, ): + self._extensions = extensions or [] self._proc: Optional[AsyncAHKProcess] self._proc = None self._temp_script: Optional[str] = None @@ -711,7 +714,9 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A template = self._template kwargs['daemon'] = self.__template message_types = {str(tom, 'utf-8'): c.__name__.upper() for tom, c in _message_registry.items()} - return template.render(directives=self._directives, message_types=message_types, **kwargs) + return template.render( + directives=self._directives, message_types=message_types, extensions=self._extensions, **kwargs + ) @property def lock(self) -> Any: diff --git a/ahk/_constants.py b/ahk/_constants.py index f2aacd0..bf624f0 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -6,7 +6,16 @@ #NoEnv #Persistent #SingleInstance Off +{% block extension_directives %} +; BEGIN extension includes +{% for ext in extensions %} +{% for inc in ext.includes %} +{{ inc }} +{% endfor %} +{% endfor %} +; END extension includes +{% endblock extension_directives %} ; BEGIN user-defined directives {% block user_directives %} {% for directive in directives %} @@ -2833,7 +2842,12 @@ return decoded_commands } +; BEGIN extension scripts +{% for ext in extensions %} +{{ ext.script_text }} +{% endfor %} +; END extension scripts {% block before_autoexecute %} {% endblock before_autoexecute %} diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index faf7853..b9dfc19 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -6,6 +6,7 @@ import tempfile import time import warnings +from functools import partial from typing import Any from typing import Awaitable from typing import Callable @@ -34,6 +35,7 @@ else: from typing import TypeAlias +from ..extensions import Extension, _extension_method_registry, _ExtensionMethodRegistry from ..keys import Key from .transport import DaemonProcessTransport from .transport import FutureResult @@ -131,13 +133,44 @@ def __init__( TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', + extensions: list[Extension] | None | Literal['auto'] = None ): + self._extension_registry: _ExtensionMethodRegistry + self._extensions: list[Extension] + if extensions == 'auto': + is_async = False + if is_async: + extensions = [entry.extension for name, entry in _extension_method_registry.async_methods.items()] + else: + extensions = [entry.extension for name, entry in _extension_method_registry.sync_methods.items()] + self._extension_registry = _extension_method_registry + self._extensions = extensions + else: + self._extensions = extensions or [] + self._extension_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + for ext in self._extensions: + self._extension_registry.merge(ext._extension_method_registry) + + if TransportClass is None: TransportClass = DaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives) + transport = TransportClass(executable_path=executable_path, directives=directives, extensions=extensions) self._transport: Transport = transport + def __getattr__(self, name: str) -> Callable[..., Any]: + is_async = False + if is_async: + if name in self._extension_registry.async_methods: + method = self._extension_registry.async_methods[name].method + return partial(method, self) + else: + if name in self._extension_registry.sync_methods: + method = self._extension_registry.sync_methods[name].method + return partial(method, self) + + raise AttributeError(f'{self.__class__.__name__!r} object has no attribute {name!r}') + def add_hotkey( self, keyname: str, callback: Callable[[], Any], ex_handler: Optional[Callable[[str, Exception], Any]] = None ) -> None: diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index 0c964f8..11ccb00 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -38,6 +38,7 @@ import jinja2 +from ahk.extensions import Extension from ahk._hotkey import ThreadedHotkeyTransport, Hotkey, Hotstring from ahk.message import RequestMessage from ahk.message import ResponseMessage @@ -630,7 +631,9 @@ def __init__( directives: Optional[list[Directive | Type[Directive]]] = None, jinja_loader: Optional[jinja2.BaseLoader] = None, template: Optional[jinja2.Template] = None, + extensions: list[Extension] | None = None ): + self._extensions = extensions or [] self._proc: Optional[SyncAHKProcess] self._proc = None self._temp_script: Optional[str] = None @@ -684,7 +687,7 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A template = self._template kwargs['daemon'] = self.__template message_types = {str(tom, 'utf-8'): c.__name__.upper() for tom, c in _message_registry.items()} - return template.render(directives=self._directives, message_types=message_types, **kwargs) + return template.render(directives=self._directives, message_types=message_types, extensions=self._extensions, **kwargs) @property def lock(self) -> Any: diff --git a/ahk/_sync/window.py b/ahk/_sync/window.py index 8701e48..30d0a8b 100644 --- a/ahk/_sync/window.py +++ b/ahk/_sync/window.py @@ -61,15 +61,11 @@ def __hash__(self) -> int: return hash(self._ahk_id) def close(self) -> None: - self._engine.win_close( - title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast') - ) + self._engine.win_close(title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast')) return None def kill(self) -> None: - self._engine.win_kill( - title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast') - ) + self._engine.win_kill(title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast')) def exists(self) -> bool: return self._engine.win_exists( @@ -591,9 +587,7 @@ def set_transparent( blocking=blocking, ) - def set_trans_color( - self, color: Union[int, str], *, blocking: bool = True - ) -> Union[None, FutureResult[None]]: + def set_trans_color(self, color: Union[int, str], *, blocking: bool = True) -> Union[None, FutureResult[None]]: return self._engine.win_set_trans_color( color=color, title=f'ahk_id {self._ahk_id}', diff --git a/ahk/extensions.py b/ahk/extensions.py new file mode 100644 index 0000000..7d58233 --- /dev/null +++ b/ahk/extensions.py @@ -0,0 +1,99 @@ +from __future__ import annotations + +import asyncio +import warnings +from dataclasses import dataclass +from typing import Any +from typing import Callable +from typing import ParamSpec +from typing import TypeVar + +from .directives import Include + + +@dataclass +class _ExtensionEntry: + extension: Extension + method: Callable[..., Any] + + +@dataclass +class _ExtensionMethodRegistry: + sync_methods: dict[str, _ExtensionEntry] + async_methods: dict[str, _ExtensionEntry] + + def register(self, ext: Extension, f: Callable[P, T]) -> Callable[P, T]: + if asyncio.iscoroutinefunction(f): + if f.__name__ in self.async_methods: + warnings.warn( + f'Method of name {f.__name__!r} has already been registered. ' + f'Previously registered method {self.async_methods[f.__name__].method!r} ' + f'will be overridden by {f!r}' + ) + self.async_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) + else: + if f.__name__ in self.sync_methods: + warnings.warn( + f'Method of name {f.__name__!r} has already been registered. ' + f'Previously registered method {self.sync_methods[f.__name__].method!r} ' + f'will be overridden by {f!r}' + ) + self.sync_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) + return f + + def merge(self, other: _ExtensionMethodRegistry) -> None: + for fname, entry in other.async_methods.items(): + async_method = entry.method + if async_method.__name__ in self.async_methods: + warnings.warn( + f'Method of name {async_method.__name__!r} has already been registered. ' + f'Previously registered method {self.async_methods[async_method.__name__].method!r} ' + f'will be overridden by {async_method!r}' + ) + self.async_methods[async_method.__name__] = entry + for fname, entry in other.sync_methods.items(): + method = entry.method + if method.__name__ in self.sync_methods: + warnings.warn( + f'Method of name {method.__name__!r} has already been registered. ' + f'Previously registered method {self.sync_methods[method.__name__].method!r} ' + f'will be overridden by {method!r}' + ) + self.sync_methods[method.__name__] = entry + + +_extension_method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + + +T = TypeVar('T') +P = ParamSpec('P') + + +class Extension: + def __init__( + self, + includes: list[str] | None = None, + script_text: str | None = None, + # template: str | Template | None = None + ): + self._text: str = script_text or '' + # self._template: str | Template | None = template + self._includes: list[str] = includes or [] + self._extension_method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + + @property + def script_text(self) -> str: + return self._text + + @script_text.setter + def script_text(self, new_script: str) -> None: + self._text = new_script + + @property + def includes(self) -> list[Include]: + return [Include(inc) for inc in self._includes] + + def register(self, f: Callable[P, T]) -> Callable[P, T]: + self._extension_method_registry.register(self, f) + _extension_method_registry.register(self, f) + return f diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index fead619..22b7ab8 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -3,7 +3,16 @@ #NoEnv #Persistent #SingleInstance Off +{% block extension_directives %} +; BEGIN extension includes +{% for ext in extensions %} +{% for inc in ext.includes %} +{{ inc }} +{% endfor %} +{% endfor %} +; END extension includes +{% endblock extension_directives %} ; BEGIN user-defined directives {% block user_directives %} {% for directive in directives %} @@ -2830,7 +2839,12 @@ CommandArrayFromQuery(ByRef text) { return decoded_commands } +; BEGIN extension scripts +{% for ext in extensions %} +{{ ext.script_text }} +{% endfor %} +; END extension scripts {% block before_autoexecute %} {% endblock before_autoexecute %} diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py new file mode 100644 index 0000000..95651dc --- /dev/null +++ b/tests/_async/test_extensions.py @@ -0,0 +1,67 @@ +import asyncio +import time +import unittest + +import pytest + +from ahk import AsyncAHK +from ahk.extensions import Extension + +async_sleep = asyncio.sleep # unasync: remove + +sleep = time.sleep + +ext_text = '''\ +AHKDoSomething(ByRef command) { + global STRINGRESPONSEMESSAGE + arg := command[2] + return FormatResponse(STRINGRESPONSEMESSAGE, Format("test{}", arg)) +} +''' + +async_extension = Extension(script_text=ext_text) + + +@async_extension.register +async def do_something(ahk, arg: str) -> str: + res = await ahk._transport.function_call('AHKDoSomething', [arg]) + return res + + +class TestExtensions(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(extensions=[async_extension]) + + async def asyncTearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + async def test_ext(self): + res = await self.ahk.do_something('foo') + assert res == 'testfoo' + + +class TestExtensionsAuto(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(extensions='auto') + + async def asyncTearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + async def test_ext(self): + res = await self.ahk.do_something('foo') + assert res == 'testfoo' + + +class TestNoExtensions(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK() + await self.ahk.get_mouse_position() # cause daemon to start + + async def asyncTearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + async def test_ext(self): + assert not hasattr(self.ahk, 'do_something') diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py new file mode 100644 index 0000000..c78d392 --- /dev/null +++ b/tests/_sync/test_extensions.py @@ -0,0 +1,66 @@ +import asyncio +import time +import unittest + +import pytest + +from ahk import AHK +from ahk.extensions import Extension + + +sleep = time.sleep + +ext_text = '''\ +AHKDoSomething(ByRef command) { + global STRINGRESPONSEMESSAGE + arg := command[2] + return FormatResponse(STRINGRESPONSEMESSAGE, Format("test{}", arg)) +} +''' + +async_extension = Extension(script_text=ext_text) + + +@async_extension.register +def do_something(ahk, arg: str) -> str: + res = ahk._transport.function_call('AHKDoSomething', [arg]) + return res + + +class TestExtensions(unittest.TestCase): + def setUp(self) -> None: + self.ahk = AHK(extensions=[async_extension]) + + def tearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + def test_ext(self): + res = self.ahk.do_something('foo') + assert res == 'testfoo' + + +class TestExtensionsAuto(unittest.TestCase): + def setUp(self) -> None: + self.ahk = AHK(extensions='auto') + + def tearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + def test_ext(self): + res = self.ahk.do_something('foo') + assert res == 'testfoo' + + +class TestNoExtensions(unittest.TestCase): + def setUp(self) -> None: + self.ahk = AHK() + self.ahk.get_mouse_position() # cause daemon to start + + def tearDown(self) -> None: + self.ahk._transport._proc.kill() + time.sleep(0.2) + + def test_ext(self): + assert not hasattr(self.ahk, 'do_something') From 06a38f8a5c51826bce07ce9b39b1f2da028e6201 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 22 Aug 2023 17:32:12 -0700 Subject: [PATCH 02/52] fix typing import for python<3.10 --- ahk/extensions.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ahk/extensions.py b/ahk/extensions.py index 7d58233..af3deec 100644 --- a/ahk/extensions.py +++ b/ahk/extensions.py @@ -1,13 +1,18 @@ from __future__ import annotations import asyncio +import sys import warnings from dataclasses import dataclass from typing import Any from typing import Callable -from typing import ParamSpec from typing import TypeVar +if sys.version_info < (3, 10): + from typing_extensions import ParamSpec +else: + from typing import ParamSpec + from .directives import Include @@ -17,6 +22,10 @@ class _ExtensionEntry: method: Callable[..., Any] +T = TypeVar('T') +P = ParamSpec('P') + + @dataclass class _ExtensionMethodRegistry: sync_methods: dict[str, _ExtensionEntry] @@ -65,10 +74,6 @@ def merge(self, other: _ExtensionMethodRegistry) -> None: _extension_method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) -T = TypeVar('T') -P = ParamSpec('P') - - class Extension: def __init__( self, From 47c3b64eb70f42eaa89e4a85e620dc0c7f06a523 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 22 Aug 2023 18:49:26 -0700 Subject: [PATCH 03/52] prevent merging duplicate methods --- ahk/_async/engine.py | 8 ++++++-- ahk/_sync/engine.py | 7 +++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 8804426..38874f8 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -145,9 +145,13 @@ def __init__( is_async = False is_async = True # unasync: remove if is_async: - extensions = [entry.extension for name, entry in _extension_method_registry.async_methods.items()] + extensions = list( + set(entry.extension for name, entry in _extension_method_registry.async_methods.items()) + ) else: - extensions = [entry.extension for name, entry in _extension_method_registry.sync_methods.items()] + extensions = list( + set(entry.extension for name, entry in _extension_method_registry.sync_methods.items()) + ) self._extension_registry = _extension_method_registry self._extensions = extensions else: diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index b9dfc19..0a2c6a8 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -133,16 +133,16 @@ def __init__( TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', - extensions: list[Extension] | None | Literal['auto'] = None + extensions: list[Extension] | None | Literal['auto'] = None, ): self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': is_async = False if is_async: - extensions = [entry.extension for name, entry in _extension_method_registry.async_methods.items()] + extensions = list(set(entry.extension for name, entry in _extension_method_registry.async_methods.items())) else: - extensions = [entry.extension for name, entry in _extension_method_registry.sync_methods.items()] + extensions = list(set(entry.extension for name, entry in _extension_method_registry.sync_methods.items())) self._extension_registry = _extension_method_registry self._extensions = extensions else: @@ -151,7 +151,6 @@ def __init__( for ext in self._extensions: self._extension_registry.merge(ext._extension_method_registry) - if TransportClass is None: TransportClass = DaemonProcessTransport assert TransportClass is not None From 8e38afaf1a5d26eb8ee0e8b699e0e65924611f43 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 22 Aug 2023 19:16:23 -0700 Subject: [PATCH 04/52] cleanup --- ahk/_async/engine.py | 10 ++++------ ahk/_sync/engine.py | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 38874f8..c7937d3 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -145,13 +145,11 @@ def __init__( is_async = False is_async = True # unasync: remove if is_async: - extensions = list( - set(entry.extension for name, entry in _extension_method_registry.async_methods.items()) - ) + methods = _extension_method_registry.async_methods else: - extensions = list( - set(entry.extension for name, entry in _extension_method_registry.sync_methods.items()) - ) + methods = _extension_method_registry.sync_methods + extensions = list(set(entry.extension for name, entry in methods.items())) + self._extension_registry = _extension_method_registry self._extensions = extensions else: diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 0a2c6a8..8f93d06 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -140,9 +140,11 @@ def __init__( if extensions == 'auto': is_async = False if is_async: - extensions = list(set(entry.extension for name, entry in _extension_method_registry.async_methods.items())) + methods = _extension_method_registry.async_methods else: - extensions = list(set(entry.extension for name, entry in _extension_method_registry.sync_methods.items())) + methods = _extension_method_registry.sync_methods + extensions = list(set(entry.extension for name, entry in methods.items())) + self._extension_registry = _extension_method_registry self._extensions = extensions else: From 71cb07b718390ebc35af4a22c30357603c076e58 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 24 Aug 2023 18:59:31 -0700 Subject: [PATCH 05/52] new message identification --- ahk/_async/transport.py | 6 +- ahk/_constants.py | 392 +++++++++++++++------------------------ ahk/_sync/transport.py | 10 +- ahk/message.py | 34 +--- ahk/templates/daemon.ahk | 392 +++++++++++++++------------------------ 5 files changed, 320 insertions(+), 514 deletions(-) diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 46c4b97..96277d3 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -715,7 +715,11 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A kwargs['daemon'] = self.__template message_types = {str(tom, 'utf-8'): c.__name__.upper() for tom, c in _message_registry.items()} return template.render( - directives=self._directives, message_types=message_types, extensions=self._extensions, **kwargs + directives=self._directives, + message_types=message_types, + message_registry=_message_registry, + extensions=self._extensions, + **kwargs, ) @property diff --git a/ahk/_constants.py b/ahk/_constants.py index bf624f0..39b84fc 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -28,30 +28,26 @@ {% endblock directives %} {% block message_types %} -{% for tom, name in message_types.items() %} -{{ name }} := "{{ tom }}" -{% endfor %} +MESSAGE_TYPES := Object({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) {% endblock message_types %} - NOVALUE_SENTINEL := Chr(57344) FormatResponse(ByRef MessageType, ByRef payload) { + global MESSAGE_TYPES newline_count := CountNewlines(payload) - response := Format("{}`n{}`n{}`n", MessageType, newline_count, payload) + response := Format("{}`n{}`n{}`n", MESSAGE_TYPES[MessageType], newline_count, payload) return response } FormatNoValueResponse() { global NOVALUE_SENTINEL - global NOVALUERESPONSEMESSAGE - return FormatResponse(NOVALUERESPONSEMESSAGE, NOVALUE_SENTINEL) + return FormatResponse("ahk.message.NoValueResponseMessage", NOVALUE_SENTINEL) } FormatBinaryResponse(ByRef bin) { - global B64BINARYRESPONSEMESSAGE b64 := b64encode(bin) - return FormatResponse(B64BINARYRESPONSEMESSAGE, b64) + return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } AHKSetDetectHiddenWindows(ByRef command) { @@ -78,15 +74,15 @@ AHKGetTitleMatchMode(ByRef command) { {% block AHKGetTitleMatchMode %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, A_TitleMatchMode) + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } AHKGetTitleMatchSpeed(ByRef command) { {% block AHKGetTitleMatchSpeed %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, A_TitleMatchModeSpeed) + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } @@ -100,14 +96,14 @@ AHKGetSendLevel(ByRef command) { {% block AHKGetSendLevel %} - global INTEGERRESPONSEMESSAGE - return FormatResponse(INTEGERRESPONSEMESSAGE, A_SendLevel) + + return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } AHKWinExist(ByRef command) { {% block AHKWinExist %} - global BOOLEANRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -132,9 +128,9 @@ } if WinExist(title, text, extitle, extext) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } DetectHiddenWindows, %current_detect_hw% @@ -170,14 +166,12 @@ DetectHiddenWindows, %detect_hw% } - WinClose, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% - return FormatNoValueResponse() {% endblock AHKWinClose %} } @@ -207,7 +201,6 @@ DetectHiddenWindows, %detect_hw% } - WinKill, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -220,8 +213,6 @@ AHKWinWait(ByRef command) { {% block AHKWinWait %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -250,10 +241,10 @@ WinWait, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -264,11 +255,8 @@ {% endblock AHKWinWait %} } - AHKWinWaitActive(ByRef command) { {% block AHKWinWaitActive %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -297,10 +285,10 @@ WinWaitActive, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -311,11 +299,8 @@ {% endblock AHKWinWaitActive %} } - AHKWinWaitNotActive(ByRef command) { {% block AHKWinWaitNotActive %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -344,10 +329,10 @@ WinWaitNotActive, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -360,7 +345,6 @@ AHKWinWaitClose(ByRef command) { {% block AHKWinWaitClose %} - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -389,7 +373,7 @@ WinWaitClose, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { resp := FormatNoValueResponse() } @@ -412,7 +396,6 @@ match_mode := command[7] match_speed := command[8] - current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -427,7 +410,6 @@ DetectHiddenWindows, %detect_hw% } - WinMinimize, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -462,7 +444,6 @@ DetectHiddenWindows, %detect_hw% } - WinMaximize, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -483,7 +464,6 @@ match_mode := command[7] match_speed := command[8] - current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -498,7 +478,6 @@ DetectHiddenWindows, %detect_hw% } - WinRestore, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -511,7 +490,7 @@ AHKWinIsActive(ByRef command) { {% block AHKWinIsActive %} - global BOOLEANRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -535,9 +514,9 @@ } if WinActive(title, text, extitle, extext) { - response := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + response := FormatResponse("ahk.message.BooleanResponseMessage", 1) } else { - response := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + response := FormatResponse("ahk.message.BooleanResponseMessage", 0) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -548,7 +527,7 @@ AHKWinGetID(ByRef command) { {% block AHKWinGetID %} - global WINDOWRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -576,7 +555,7 @@ if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(WINDOWRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -587,7 +566,7 @@ AHKWinGetTitle(ByRef command) { {% block AHKWinGetTitle %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -616,13 +595,13 @@ SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% - return FormatResponse(STRINGRESPONSEMESSAGE, text) + return FormatResponse("ahk.message.StringResponseMessage", text) {% endblock AHKWinGetTitle %} } AHKWinGetIDLast(ByRef command) { {% block AHKWinGetIDLast %} - global WINDOWRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -650,7 +629,7 @@ if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(WINDOWRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -659,10 +638,9 @@ {% endblock AHKWinGetIDLast %} } - AHKWinGetPID(ByRef command) { {% block AHKWinGetPID %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -690,7 +668,7 @@ if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -699,10 +677,9 @@ {% endblock AHKWinGetPID %} } - AHKWinGetProcessName(ByRef command) { {% block AHKWinGetProcessName %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -730,7 +707,7 @@ if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -741,7 +718,7 @@ AHKWinGetProcessPath(ByRef command) { {% block AHKWinGetProcessPath %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -769,7 +746,7 @@ if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -778,10 +755,9 @@ {% endblock AHKWinGetProcessPath %} } - AHKWinGetCount(ByRef command) { {% block AHKWinGetCount %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -807,9 +783,9 @@ WinGet, output, Count, %title%, %text%, %extitle%, %extext% if (output = 0) { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -818,11 +794,9 @@ {% endblock AHKWinGetCount %} } - - AHKWinGetMinMax(ByRef command) { {% block AHKWinGetMinMax %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -850,7 +824,7 @@ if (output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -861,8 +835,7 @@ AHKWinGetControlList(ByRef command) { {% block AHKWinGetControlList %} - global EXCEPTIONRESPONSEMESSAGE - global WINDOWCONTROLLISTRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -886,7 +859,6 @@ DetectHiddenWindows, %detect_hw% } - WinGet, ahkid, ID, %title%, %text%, %extitle%, %extext% if (ahkid = "") { @@ -897,13 +869,13 @@ WinGet, ctrListID, ControlListHWND, %title%, %text%, %extitle%, %extext% if (ctrListID = "") { - return FormatResponse(WINDOWCONTROLLISTRESPONSEMESSAGE, Format("('{}', [])", ahkid)) + return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) } ctrListArr := StrSplit(ctrList, "`n") ctrListIDArr := StrSplit(ctrListID, "`n") if (ctrListArr.Length() != ctrListIDArr.Length()) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Control hwnd/class lists have unexpected lengths") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } output := Format("('{}', [", ahkid) @@ -914,7 +886,7 @@ } output .= "])" - response := FormatResponse(WINDOWCONTROLLISTRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowControlListResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -924,7 +896,7 @@ AHKWinGetTransparent(ByRef command) { {% block AHKWinGetTransparent %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -949,7 +921,7 @@ } WinGet, output, Transparent, %title%, %text%, %extitle%, %extext% - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -958,9 +930,7 @@ } AHKWinGetTransColor(ByRef command) { {% block AHKWinGetTransColor %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -985,7 +955,7 @@ } WinGet, output, TransColor, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -994,9 +964,7 @@ } AHKWinGetStyle(ByRef command) { {% block AHKWinGetStyle %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1021,7 +989,7 @@ } WinGet, output, Style, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -1030,9 +998,7 @@ } AHKWinGetExStyle(ByRef command) { {% block AHKWinGetExStyle %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1057,7 +1023,7 @@ } WinGet, output, ExStyle, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -1067,8 +1033,7 @@ AHKWinGetText(ByRef command) { {% block AHKWinGetText %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1094,9 +1059,9 @@ WinGetText, output,%title%,%text%,%extitle%,%extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was an error getting window text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window text") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -1106,8 +1071,6 @@ {% endblock AHKWinGetText %} } - - AHKWinSetTitle(ByRef command) { {% block AHKWinSetTitle %} new_title := command[2] @@ -1272,7 +1235,6 @@ {% endblock AHKWinHide %} } - AHKWinSetTop(ByRef command) { {% block AHKWinSetTop %} title := command[2] @@ -1407,7 +1369,7 @@ AHKWinSetStyle(ByRef command) { {% block AHKWinSetStyle %} - global BOOLEANRESPONSEMESSAGE + style := command[2] title := command[3] text := command[4] @@ -1431,12 +1393,11 @@ DetectHiddenWindows, %detect_hw% } - WinSet, Style, %style%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1447,7 +1408,7 @@ AHKWinSetExStyle(ByRef command) { {% block AHKWinSetExStyle %} - global BOOLEANRESPONSEMESSAGE + style := command[2] title := command[3] text := command[4] @@ -1471,12 +1432,11 @@ DetectHiddenWindows, %detect_hw% } - WinSet, ExStyle, %style%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1487,7 +1447,7 @@ AHKWinSetRegion(ByRef command) { {% block AHKWinSetRegion %} - global BOOLEANRESPONSEMESSAGE + options := command[2] title := command[3] text := command[4] @@ -1511,12 +1471,11 @@ DetectHiddenWindows, %detect_hw% } - WinSet, Region, %options%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1527,7 +1486,7 @@ AHKWinSetTransparent(ByRef command) { {% block AHKWinSetTransparent %} - global BOOLEANRESPONSEMESSAGE + transparency := command[2] title := command[3] text := command[4] @@ -1551,7 +1510,6 @@ DetectHiddenWindows, %detect_hw% } - WinSet, Transparent, %transparency%, %title%, %text%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1562,7 +1520,7 @@ AHKWinSetTransColor(ByRef command) { {% block AHKWinSetTransColor %} - global BOOLEANRESPONSEMESSAGE + color := command[2] title := command[3] text := command[4] @@ -1586,7 +1544,6 @@ DetectHiddenWindows, %detect_hw% } - WinSet, TransColor, %color%, %title%, %text%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -1599,8 +1556,7 @@ AHKImageSearch(ByRef command) { {% block AHKImageSearch %} - global COORDINATERESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + imagepath := command[6] x1 := command[2] y1 := command[3] @@ -1623,18 +1579,16 @@ ImageSearch, xpos, ypos,% x1,% y1,% x2,% y2, %imagepath% - if (coord_mode != "") { CoordMode, Pixel, %current_mode% } - if (ErrorLevel = 2) { - s := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") + s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") } else if (ErrorLevel = 1) { s := FormatNoValueResponse() } else { - s := FormatResponse(COORDINATERESPONSEMESSAGE, Format("({}, {})", xpos, ypos)) + s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) } return s @@ -1643,7 +1597,7 @@ AHKPixelGetColor(ByRef command) { {% block AHKPixelGetColor %} - global STRINGRESPONSEMESSAGE + x := command[2] y := command[3] coord_mode := command[4] @@ -1662,14 +1616,13 @@ CoordMode, Pixel, %current_mode% } - return FormatResponse(STRINGRESPONSEMESSAGE, color) + return FormatResponse("ahk.message.StringResponseMessage", color) {% endblock AHKPixelGetColor %} } AHKPixelSearch(ByRef command) { {% block AHKPixelSearch %} - global COORDINATERESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + x1 := command[2] y1 := command[3] x2 := command[4] @@ -1695,20 +1648,19 @@ return FormatNoValueResponse() } else if (ErrorLevel = 0) { payload := Format("({}, {})", resultx, resulty) - return FormatResponse(COORDINATERESPONSEMESSAGE, payload) + return FormatResponse("ahk.message.CoordinateResponseMessage", payload) } else if (ErrorLevel = 2) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem conducting the pixel search (ErrorLevel 2)") + return FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem conducting the pixel search (ErrorLevel 2)") } else { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") } {% endblock AHKPixelSearch %} } - AHKMouseGetPos(ByRef command) { {% block AHKMouseGetPos %} - global COORDINATERESPONSEMESSAGE + coord_mode := command[2] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { @@ -1717,7 +1669,7 @@ MouseGetPos, xpos, ypos payload := Format("({}, {})", xpos, ypos) - resp := FormatResponse(COORDINATERESPONSEMESSAGE, payload) + resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) if (coord_mode != "") { CoordMode, Mouse, %current_coord_mode% @@ -1729,10 +1681,6 @@ AHKKeyState(ByRef command) { {% block AHKKeyState %} - global INTEGERRESPONSEMESSAGE - global FLOATRESPONSEMESSAGE - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE keyname := command[2] mode := command[3] @@ -1747,15 +1695,15 @@ } if state is integer - return FormatResponse(INTEGERRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.IntegerResponseMessage", state) if state is float - return FormatResponse(FLOATRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.FloatResponseMessage", state) if state is alnum - return FormatResponse(STRINGRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.StringResponseMessage", state) - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.ExceptionResponseMessage", state) {% endblock AHKKeyState %} } @@ -1775,7 +1723,6 @@ {% endblock AHKMouseMove %} } - AHKClick(ByRef command) { {% block AHKClick %} x := command[2] @@ -1804,26 +1751,25 @@ AHKGetCoordMode(ByRef command) { {% block AHKGetCoordMode %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + target := command[2] if (target = "ToolTip") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeToolTip) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) } if (target = "Pixel") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModePixel) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModePixel) } if (target = "Mouse") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeMouse) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMouse) } if (target = "Caret") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeCaret) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeCaret) } if (target = "Menu") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeMenu) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMenu) } - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Invalid coord mode") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Invalid coord mode") {% endblock AHKGetCoordMode %} } @@ -1867,35 +1813,32 @@ AHKRegRead(ByRef command) { {% block RegRead %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + key_name := command[2] value_name := command[3] RegRead, output, %key_name%, %value_name% if (ErrorLevel = 1) { - resp := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + resp := FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } else { - resp := FormatResponse(STRINGRESPONSEMESSAGE, Format("{}", output)) + resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) } return resp {% endblock RegRead %} } - - AHKRegWrite(ByRef command) { {% block RegWrite %} - global EXCEPTIONRESPONSEMESSAGE + value_type := command[2] key_name := command[3] value_name := command[4] value := command[5] RegWrite, %value_type%, %key_name%, %value_name%, %value% if (ErrorLevel = 1) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } return FormatNoValueResponse() @@ -1904,12 +1847,12 @@ AHKRegDelete(ByRef command) { {% block RegDelete %} - global EXCEPTIONRESPONSEMESSAGE + key_name := command[2] value_name := command[3] RegDelete, %key_name%, %value_name% if (ErrorLevel = 1) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } return FormatNoValueResponse() @@ -1918,7 +1861,7 @@ AHKKeyWait(ByRef command) { {% block AHKKeyWait %} - global INTEGERRESPONSEMESSAGE + keyname := command[2] if (command.Length() = 2) { KeyWait,% keyname @@ -1926,7 +1869,7 @@ options := command[3] KeyWait,% keyname,% options } - return FormatResponse(INTEGERRESPONSEMESSAGE, ErrorLevel) + return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) {% endblock AHKKeyWait %} } @@ -1936,8 +1879,6 @@ {% endblock SetKeyDelay %} } - - AHKSend(ByRef command) { {% block AHKSend %} str := command[2] @@ -2001,7 +1942,6 @@ {% endblock AHKSendInput %} } - AHKSendEvent(ByRef command) { {% block AHKSendEvent %} str := command[2] @@ -2067,13 +2007,9 @@ {% endblock HideTrayTip %} } - - - AHKWinGetClass(ByRef command) { {% block AHKWinGetClass %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -2099,9 +2035,9 @@ WinGetClass, output,%title%,%text%,%extitle%,%extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was an error getting window class") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window class") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -2146,12 +2082,8 @@ {% endblock AHKWinActivate %} } - - - AHKWindowList(ByRef command) { {% block AHKWindowList %} - global WINDOWLISTRESPONSEMESSAGE current_detect_hw := Format("{}", A_DetectHiddenWindows) @@ -2182,7 +2114,7 @@ id := windows%A_Index% r .= id . "`," } - resp := FormatResponse(WINDOWLISTRESPONSEMESSAGE, r) + resp := FormatResponse("ahk.message.WindowListResponseMessage", r) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -2190,11 +2122,9 @@ {% endblock AHKWindowList %} } - - AHKControlClick(ByRef command) { {% block AHKControlClick %} - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2224,7 +2154,7 @@ ControlClick, %ctrl%, %title%, %text%, %button%, %click_count%, %options%, %exclude_title%, %exclude_text% if (ErrorLevel != 0) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Failed to click control") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "Failed to click control") } else { response := FormatNoValueResponse() } @@ -2239,8 +2169,7 @@ AHKControlGetText(ByRef command) { {% block AHKControlGetText %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2267,9 +2196,9 @@ ControlGetText, result, %ctrl%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, result) + response := FormatResponse("ahk.message.StringResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -2279,11 +2208,9 @@ {% endblock AHKControlGetText %} } - AHKControlGetPos(ByRef command) { {% block AHKControlGetPos %} - global POSITIONRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2309,10 +2236,10 @@ ControlGetPos, x, y, w, h, %ctrl%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) - response := FormatResponse(PositionResponseMessage, result) + response := FormatResponse("ahk.message.PositionResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% @@ -2321,7 +2248,6 @@ return response - {% endblock AHKControlGetPos %} } @@ -2358,39 +2284,34 @@ {% endblock AHKControlSend %} } - - - AHKWinFromMouse(ByRef command) { {% block AHKWinFromMouse %} - global WINDOWRESPONSEMESSAGE + MouseGetPos,,, MouseWin if (MouseWin = "") { return FormatNoValueResponse() } - return FormatResponse(WINDOWRESPONSEMESSAGE, MouseWin) + return FormatResponse("ahk.message.WindowResponseMessage", MouseWin) {% endblock AHKWinFromMouse %} } - AHKWinIsAlwaysOnTop(ByRef command) { {% block AHKWinIsAlwaysOnTop %} - global BOOLEANRESPONSEMESSAGE + title := command[2] WinGet, ExStyle, ExStyle, %title% if (ExStyle = "") return FormatNoValueResponse() if (ExStyle & 0x8) ; 0x8 is WS_EX_TOPMOST. - return FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + return FormatResponse("ahk.message.BooleanResponseMessage", 1) else - return FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + return FormatResponse("ahk.message.BooleanResponseMessage", 0) {% endblock AHKWinIsAlwaysOnTop %} } - AHKWinMove(ByRef command) { {% block AHKWinMove %} title := command[2] @@ -2432,8 +2353,6 @@ AHKWinGetPos(ByRef command) { {% block AHKWinGetPos %} - global POSITIONRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE title := command[2] text := command[3] @@ -2460,10 +2379,10 @@ WinGetPos, x, y, w, h, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the position") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) - response := FormatResponse(PositionResponseMessage, result) + response := FormatResponse("ahk.message.PositionResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% @@ -2474,23 +2393,21 @@ {% endblock AHKWinGetPos %} } - AHKGetVolume(ByRef command) { {% block AHKGetVolume %} - global EXCEPTIONRESPONSEMESSAGE - global FLOATRESPONSEMESSAGE + device_number := command[2] try { SoundGetWaveVolume, retval, %device_number% } catch e { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) return response } if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("There was a problem getting the volume with device of index {}", device_number)) + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {}", device_number)) } else { - response := FormatResponse(FLOATRESPONSEMESSAGE, Format("{}", retval)) + response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) } return response {% endblock AHKGetVolume %} @@ -2507,14 +2424,14 @@ AHKSoundGet(ByRef command) { {% block AHKSoundGet %} - global STRINGRESPONSEMESSAGE + device_number := command[2] component_type := command[3] control_type := command[4] SoundGet, retval, %component_type%, %control_type%, %device_number% ; TODO interpret return type - return FormatResponse(STRINGRESPONSEMESSAGE, Format("{}", retval)) + return FormatResponse("ahk.message.StringResponseMessage", Format("{}", retval)) {% endblock AHKSoundGet %} } @@ -2555,8 +2472,8 @@ AHKEcho(ByRef command) { {% block AHKEcho %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, command) + arg := command[2] + return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } @@ -2585,8 +2502,8 @@ AHKGetClipboard(ByRef command) { {% block AHKGetClipboard %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, Clipboard) + + return FormatResponse("ahk.message.StringResponseMessage", Clipboard) {% endblock AHKGetClipboard %} } @@ -2615,15 +2532,14 @@ } AHKClipWait(ByRef command) { - global TIMEOUTRESPONSEMESSAGE + timeout := command[2] wait_for_any_data := command[3] - ClipWait, %timeout%, %wait_for_any_data% if (ErrorLevel = 1) { - return FormatResponse(TIMEOUTRESPONSEMESSAGE, "timed out waiting for clipboard data") + return FormatResponse("ahk.message.TimeoutResponseMessage", "timed out waiting for clipboard data") } return FormatNoValueResponse() } @@ -2654,47 +2570,45 @@ } AHKGuiNew(ByRef command) { - global STRINGRESPONSEMESSAGE + options := command[2] title := command[3] Gui, New, %options%, %title% - return FormatResponse(STRINGRESPONSEMESSAGE, hwnd) + return FormatResponse("ahk.message.StringResponseMessage", hwnd) } AHKMsgBox(ByRef command) { - global TIMEOUTRESPONSEMESSAGE - global STRINGRESPONSEMESSAGE + options := command[2] title := command[3] text := command[4] timeout := command[5] MsgBox,% options, %title%, %text%, %timeout% IfMsgBox, Yes - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Yes") + ret := FormatResponse("ahk.message.StringResponseMessage", "Yes") IfMsgBox, No - ret := FormatResponse(STRINGRESPONSEMESSAGE, "No") + ret := FormatResponse("ahk.message.StringResponseMessage", "No") IfMsgBox, OK - ret := FormatResponse(STRINGRESPONSEMESSAGE, "OK") + ret := FormatResponse("ahk.message.StringResponseMessage", "OK") IfMsgBox, Cancel - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Cancel") + ret := FormatResponse("ahk.message.StringResponseMessage", "Cancel") IfMsgBox, Abort - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Abort") + ret := FormatResponse("ahk.message.StringResponseMessage", "Abort") IfMsgBox, Ignore - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Ignore") + ret := FormatResponse("ahk.message.StringResponseMessage", "Ignore") IfMsgBox, Retry - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Retry") + ret := FormatResponse("ahk.message.StringResponseMessage", "Retry") IfMsgBox, Continue - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Continue") + ret := FormatResponse("ahk.message.StringResponseMessage", "Continue") IfMsgBox, TryAgain - ret := FormatResponse(STRINGRESPONSEMESSAGE, "TryAgain") + ret := FormatResponse("ahk.message.StringResponseMessage", "TryAgain") IfMsgBox, Timeout - ret := FormatResponse(TIMEOUTRESPONSEMESSAGE, "MsgBox timed out") + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "MsgBox timed out") return ret } AHKInputBox(ByRef command) { - global STRINGRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE + title := command[2] prompt := command[3] hide := command[4] @@ -2708,17 +2622,17 @@ InputBox, output, %title%, %prompt%, %hide%, %width%, %height%, %x%, %y%, %locale%, %timeout%, %default% if (ErrorLevel = 2) { - ret := FormatResponse(TIMEOUTRESPONSEMESSAGE, "Input box timed out") + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "Input box timed out") } else if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } AHKFileSelectFile(byRef command) { - global STRINGRESPONSEMESSAGE + options := command[2] root := command[3] title := command[4] @@ -2727,13 +2641,13 @@ if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } AHKFileSelectFolder(byRef command) { - global STRINGRESPONSEMESSAGE + starting_folder := command[2] options := command[3] prompt := command[4] @@ -2743,7 +2657,7 @@ if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } @@ -2771,7 +2685,6 @@ pdwSkip := 0 ; We don't use any headers or preamble, so this is zero pdwFlags := 0 ; We don't need this, so make it null - ; The first call calculates the required size. The result is written to pbBinary success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) if (success = 0) { @@ -2799,7 +2712,6 @@ ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer - cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) if (cbBinary = 0) { return "" @@ -2813,7 +2725,6 @@ throw Exception(msg, -1) } - VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) ; Now we do the conversion to base64 and rteturn the string @@ -2826,7 +2737,6 @@ return ret } - ; End of included content CommandArrayFromQuery(ByRef text) { @@ -2868,14 +2778,14 @@ } catch e { {% block function_error_handle %} message := Format("Error occurred in {}. The error message was: {}", e.What, e.message) - pyresp := FormatResponse(EXCEPTIONRESPONSEMESSAGE, message) + pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } {% block send_response %} if (pyresp) { FileAppend, %pyresp%, *, UTF-8 } else { - msg := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("Unknown Error when calling {}", func)) + msg := FormatResponse("ahk.message.ExceptionResponseMessage", Format("Unknown Error when calling {}", func)) FileAppend, %msg%, *, UTF-8 } {% endblock send_response %} diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index 11ccb00..e786a19 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -631,7 +631,7 @@ def __init__( directives: Optional[list[Directive | Type[Directive]]] = None, jinja_loader: Optional[jinja2.BaseLoader] = None, template: Optional[jinja2.Template] = None, - extensions: list[Extension] | None = None + extensions: list[Extension] | None = None, ): self._extensions = extensions or [] self._proc: Optional[SyncAHKProcess] @@ -687,7 +687,13 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A template = self._template kwargs['daemon'] = self.__template message_types = {str(tom, 'utf-8'): c.__name__.upper() for tom, c in _message_registry.items()} - return template.render(directives=self._directives, message_types=message_types, extensions=self._extensions, **kwargs) + return template.render( + directives=self._directives, + message_types=message_types, + message_registry=_message_registry, + extensions=self._extensions, + **kwargs, + ) @property def lock(self) -> Any: diff --git a/ahk/message.py b/ahk/message.py index be10359..3a0f131 100644 --- a/ahk/message.py +++ b/ahk/message.py @@ -100,16 +100,18 @@ def tom_generator() -> Generator[bytes, None, None]: class ResponseMessage: - type: Optional[str] = None _type_order_mark = next(TOMS) + @classmethod + def fqn(cls) -> str: + return f'{cls.__module__}.{cls.__qualname__}' + @classmethod def __init_subclass__(cls: Type[T_ResponseMessageType], **kwargs: Any) -> None: tom = next(TOMS) cls._type_order_mark = tom assert tom not in _message_registry, f'cannot register class {cls!r} with TOM {tom!r} which is already in use' _message_registry[tom] = cls - assert cls.type is not None, f'must assign a type for class {cls!r}' super().__init_subclass__(**kwargs) def __init__(self, raw_content: bytes, engine: Optional[Union[AsyncAHK, AHK]] = None): @@ -117,7 +119,7 @@ def __init__(self, raw_content: bytes, engine: Optional[Union[AsyncAHK, AHK]] = self._engine: Optional[Union[AsyncAHK, AHK]] = engine def __repr__(self) -> str: - return f'ResponseMessage' + return f'ResponseMessage' @staticmethod def _tom_lookup(tom: bytes) -> 'ResponseMessageClassTypes': @@ -147,8 +149,6 @@ def unpack(self) -> Any: class TupleResponseMessage(ResponseMessage): - type = 'tuple' - def unpack(self) -> Tuple[Any, ...]: s = self._raw_content.decode(encoding='utf-8') val = ast.literal_eval(s) @@ -157,8 +157,6 @@ def unpack(self) -> Tuple[Any, ...]: class CoordinateResponseMessage(ResponseMessage): - type = 'coordinate' - def unpack(self) -> Tuple[int, int]: s = self._raw_content.decode(encoding='utf-8') val = ast.literal_eval(s) @@ -168,8 +166,6 @@ def unpack(self) -> Tuple[int, int]: class IntegerResponseMessage(ResponseMessage): - type = 'integer' - def unpack(self) -> int: s = self._raw_content.decode(encoding='utf-8') val = ast.literal_eval(s) @@ -178,8 +174,6 @@ def unpack(self) -> int: class BooleanResponseMessage(IntegerResponseMessage): - type = 'boolean' - def unpack(self) -> bool: val = super().unpack() assert val in (1, 0) @@ -187,15 +181,11 @@ def unpack(self) -> bool: class StringResponseMessage(ResponseMessage): - type = 'string' - def unpack(self) -> str: return self._raw_content.decode('utf-8') class WindowListResponseMessage(ResponseMessage): - type = 'windowlist' - def unpack(self) -> Union[List[Window], List[AsyncWindow]]: from ._async.engine import AsyncAHK from ._async.window import AsyncWindow @@ -216,8 +206,6 @@ def unpack(self) -> Union[List[Window], List[AsyncWindow]]: class NoValueResponseMessage(ResponseMessage): - type = 'novalue' - def unpack(self) -> None: assert self._raw_content == b'\xee\x80\x80', f'Unexpected or Malformed response: {self._raw_content!r}' return None @@ -228,7 +216,6 @@ class AHKExecutionException(Exception): class ExceptionResponseMessage(ResponseMessage): - type = 'exception' _exception_type: Type[Exception] = AHKExecutionException def unpack(self) -> NoReturn: @@ -237,8 +224,6 @@ def unpack(self) -> NoReturn: class WindowControlListResponseMessage(ResponseMessage): - type = 'windowcontrollist' - def unpack(self) -> Union[List[AsyncControl], List[Control]]: from ._async.engine import AsyncAHK from ._async.window import AsyncWindow, AsyncControl @@ -272,8 +257,6 @@ def unpack(self) -> Union[List[AsyncControl], List[Control]]: class WindowResponseMessage(ResponseMessage): - type = 'window' - def unpack(self) -> Union[Window, AsyncWindow]: from ._async.engine import AsyncAHK from ._async.window import AsyncWindow @@ -293,8 +276,6 @@ def unpack(self) -> Union[Window, AsyncWindow]: class PositionResponseMessage(TupleResponseMessage): - type = 'position' - def unpack(self) -> Position: resp = super().unpack() if not len(resp) == 4: @@ -304,8 +285,6 @@ def unpack(self) -> Position: class FloatResponseMessage(ResponseMessage): - type = 'float' - def unpack(self) -> float: s = self._raw_content.decode(encoding='utf-8') val = ast.literal_eval(s) @@ -314,13 +293,10 @@ def unpack(self) -> float: class TimeoutResponseMessage(ExceptionResponseMessage): - type = 'timeoutexception' _exception_type = TimeoutError class B64BinaryResponseMessage(ResponseMessage): - type = 'binary' - def unpack(self) -> bytes: b64_content = self._raw_content b = base64.b64decode(b64_content) diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 22b7ab8..3daf2c7 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -25,30 +25,26 @@ {% endblock directives %} {% block message_types %} -{% for tom, name in message_types.items() %} -{{ name }} := "{{ tom }}" -{% endfor %} +MESSAGE_TYPES := Object({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) {% endblock message_types %} - NOVALUE_SENTINEL := Chr(57344) FormatResponse(ByRef MessageType, ByRef payload) { + global MESSAGE_TYPES newline_count := CountNewlines(payload) - response := Format("{}`n{}`n{}`n", MessageType, newline_count, payload) + response := Format("{}`n{}`n{}`n", MESSAGE_TYPES[MessageType], newline_count, payload) return response } FormatNoValueResponse() { global NOVALUE_SENTINEL - global NOVALUERESPONSEMESSAGE - return FormatResponse(NOVALUERESPONSEMESSAGE, NOVALUE_SENTINEL) + return FormatResponse("ahk.message.NoValueResponseMessage", NOVALUE_SENTINEL) } FormatBinaryResponse(ByRef bin) { - global B64BINARYRESPONSEMESSAGE b64 := b64encode(bin) - return FormatResponse(B64BINARYRESPONSEMESSAGE, b64) + return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } AHKSetDetectHiddenWindows(ByRef command) { @@ -75,15 +71,15 @@ AHKSetTitleMatchMode(ByRef command) { AHKGetTitleMatchMode(ByRef command) { {% block AHKGetTitleMatchMode %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, A_TitleMatchMode) + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } AHKGetTitleMatchSpeed(ByRef command) { {% block AHKGetTitleMatchSpeed %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, A_TitleMatchModeSpeed) + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } @@ -97,14 +93,14 @@ AHKSetSendLevel(ByRef command) { AHKGetSendLevel(ByRef command) { {% block AHKGetSendLevel %} - global INTEGERRESPONSEMESSAGE - return FormatResponse(INTEGERRESPONSEMESSAGE, A_SendLevel) + + return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } AHKWinExist(ByRef command) { {% block AHKWinExist %} - global BOOLEANRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -129,9 +125,9 @@ AHKWinExist(ByRef command) { } if WinExist(title, text, extitle, extext) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } DetectHiddenWindows, %current_detect_hw% @@ -167,14 +163,12 @@ AHKWinClose(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinClose, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% - return FormatNoValueResponse() {% endblock AHKWinClose %} } @@ -204,7 +198,6 @@ AHKWinKill(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinKill, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -217,8 +210,6 @@ AHKWinKill(ByRef command) { AHKWinWait(ByRef command) { {% block AHKWinWait %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -247,10 +238,10 @@ AHKWinWait(ByRef command) { WinWait, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -261,11 +252,8 @@ AHKWinWait(ByRef command) { {% endblock AHKWinWait %} } - AHKWinWaitActive(ByRef command) { {% block AHKWinWaitActive %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -294,10 +282,10 @@ AHKWinWaitActive(ByRef command) { WinWaitActive, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -308,11 +296,8 @@ AHKWinWaitActive(ByRef command) { {% endblock AHKWinWaitActive %} } - AHKWinWaitNotActive(ByRef command) { {% block AHKWinWaitNotActive %} - global WINDOWRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -341,10 +326,10 @@ AHKWinWaitNotActive(ByRef command) { WinWaitNotActive, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { WinGet, output, ID - resp := FormatResponse(WINDOWRESPONSEMESSAGE, output) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -357,7 +342,6 @@ AHKWinWaitNotActive(ByRef command) { AHKWinWaitClose(ByRef command) { {% block AHKWinWaitClose %} - global TIMEOUTRESPONSEMESSAGE title := command[2] text := command[3] @@ -386,7 +370,7 @@ AHKWinWaitClose(ByRef command) { WinWaitClose, %title%, %text%,, %extitle%, %extext% } if (ErrorLevel = 1) { - resp := FormatResponse(TIMEOUTRESPONSEMESSAGE, "WinWait timed out waiting for window") + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") } else { resp := FormatNoValueResponse() } @@ -409,7 +393,6 @@ AHKWinMinimize(ByRef command) { match_mode := command[7] match_speed := command[8] - current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -424,7 +407,6 @@ AHKWinMinimize(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinMinimize, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -459,7 +441,6 @@ AHKWinMaximize(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinMaximize, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -480,7 +461,6 @@ AHKWinRestore(ByRef command) { match_mode := command[7] match_speed := command[8] - current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -495,7 +475,6 @@ AHKWinRestore(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinRestore, %title%, %text%, %secondstowait%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -508,7 +487,7 @@ AHKWinRestore(ByRef command) { AHKWinIsActive(ByRef command) { {% block AHKWinIsActive %} - global BOOLEANRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -532,9 +511,9 @@ AHKWinIsActive(ByRef command) { } if WinActive(title, text, extitle, extext) { - response := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + response := FormatResponse("ahk.message.BooleanResponseMessage", 1) } else { - response := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + response := FormatResponse("ahk.message.BooleanResponseMessage", 0) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -545,7 +524,7 @@ AHKWinIsActive(ByRef command) { AHKWinGetID(ByRef command) { {% block AHKWinGetID %} - global WINDOWRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -573,7 +552,7 @@ AHKWinGetID(ByRef command) { if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(WINDOWRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -584,7 +563,7 @@ AHKWinGetID(ByRef command) { AHKWinGetTitle(ByRef command) { {% block AHKWinGetTitle %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -613,13 +592,13 @@ AHKWinGetTitle(ByRef command) { SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% - return FormatResponse(STRINGRESPONSEMESSAGE, text) + return FormatResponse("ahk.message.StringResponseMessage", text) {% endblock AHKWinGetTitle %} } AHKWinGetIDLast(ByRef command) { {% block AHKWinGetIDLast %} - global WINDOWRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -647,7 +626,7 @@ AHKWinGetIDLast(ByRef command) { if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(WINDOWRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -656,10 +635,9 @@ AHKWinGetIDLast(ByRef command) { {% endblock AHKWinGetIDLast %} } - AHKWinGetPID(ByRef command) { {% block AHKWinGetPID %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -687,7 +665,7 @@ AHKWinGetPID(ByRef command) { if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -696,10 +674,9 @@ AHKWinGetPID(ByRef command) { {% endblock AHKWinGetPID %} } - AHKWinGetProcessName(ByRef command) { {% block AHKWinGetProcessName %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -727,7 +704,7 @@ AHKWinGetProcessName(ByRef command) { if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -738,7 +715,7 @@ AHKWinGetProcessName(ByRef command) { AHKWinGetProcessPath(ByRef command) { {% block AHKWinGetProcessPath %} - global STRINGRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -766,7 +743,7 @@ AHKWinGetProcessPath(ByRef command) { if (output = 0 || output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -775,10 +752,9 @@ AHKWinGetProcessPath(ByRef command) { {% endblock AHKWinGetProcessPath %} } - AHKWinGetCount(ByRef command) { {% block AHKWinGetCount %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -804,9 +780,9 @@ AHKWinGetCount(ByRef command) { WinGet, output, Count, %title%, %text%, %extitle%, %extext% if (output = 0) { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -815,11 +791,9 @@ AHKWinGetCount(ByRef command) { {% endblock AHKWinGetCount %} } - - AHKWinGetMinMax(ByRef command) { {% block AHKWinGetMinMax %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -847,7 +821,7 @@ AHKWinGetMinMax(ByRef command) { if (output = "") { response := FormatNoValueResponse() } else { - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -858,8 +832,7 @@ AHKWinGetMinMax(ByRef command) { AHKWinGetControlList(ByRef command) { {% block AHKWinGetControlList %} - global EXCEPTIONRESPONSEMESSAGE - global WINDOWCONTROLLISTRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -883,7 +856,6 @@ AHKWinGetControlList(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinGet, ahkid, ID, %title%, %text%, %extitle%, %extext% if (ahkid = "") { @@ -894,13 +866,13 @@ AHKWinGetControlList(ByRef command) { WinGet, ctrListID, ControlListHWND, %title%, %text%, %extitle%, %extext% if (ctrListID = "") { - return FormatResponse(WINDOWCONTROLLISTRESPONSEMESSAGE, Format("('{}', [])", ahkid)) + return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) } ctrListArr := StrSplit(ctrList, "`n") ctrListIDArr := StrSplit(ctrListID, "`n") if (ctrListArr.Length() != ctrListIDArr.Length()) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Control hwnd/class lists have unexpected lengths") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } output := Format("('{}', [", ahkid) @@ -911,7 +883,7 @@ AHKWinGetControlList(ByRef command) { } output .= "])" - response := FormatResponse(WINDOWCONTROLLISTRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.WindowControlListResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -921,7 +893,7 @@ AHKWinGetControlList(ByRef command) { AHKWinGetTransparent(ByRef command) { {% block AHKWinGetTransparent %} - global INTEGERRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -946,7 +918,7 @@ AHKWinGetTransparent(ByRef command) { } WinGet, output, Transparent, %title%, %text%, %extitle%, %extext% - response := FormatResponse(INTEGERRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -955,9 +927,7 @@ AHKWinGetTransparent(ByRef command) { } AHKWinGetTransColor(ByRef command) { {% block AHKWinGetTransColor %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -982,7 +952,7 @@ AHKWinGetTransColor(ByRef command) { } WinGet, output, TransColor, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -991,9 +961,7 @@ AHKWinGetTransColor(ByRef command) { } AHKWinGetStyle(ByRef command) { {% block AHKWinGetStyle %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1018,7 +986,7 @@ AHKWinGetStyle(ByRef command) { } WinGet, output, Style, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -1027,9 +995,7 @@ AHKWinGetStyle(ByRef command) { } AHKWinGetExStyle(ByRef command) { {% block AHKWinGetExStyle %} - global STRINGRESPONSEMESSAGE - global INTEGERRESPONSEMESSAGE - global NOVALUERESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1054,7 +1020,7 @@ AHKWinGetExStyle(ByRef command) { } WinGet, output, ExStyle, %title%, %text%, %extitle%, %extext% - response := FormatResponse(NOVALUERESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -1064,8 +1030,7 @@ AHKWinGetExStyle(ByRef command) { AHKWinGetText(ByRef command) { {% block AHKWinGetText %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -1091,9 +1056,9 @@ AHKWinGetText(ByRef command) { WinGetText, output,%title%,%text%,%extitle%,%extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was an error getting window text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window text") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -1103,8 +1068,6 @@ AHKWinGetText(ByRef command) { {% endblock AHKWinGetText %} } - - AHKWinSetTitle(ByRef command) { {% block AHKWinSetTitle %} new_title := command[2] @@ -1269,7 +1232,6 @@ AHKWinHide(ByRef command) { {% endblock AHKWinHide %} } - AHKWinSetTop(ByRef command) { {% block AHKWinSetTop %} title := command[2] @@ -1404,7 +1366,7 @@ AHKWinSetRedraw(ByRef command) { AHKWinSetStyle(ByRef command) { {% block AHKWinSetStyle %} - global BOOLEANRESPONSEMESSAGE + style := command[2] title := command[3] text := command[4] @@ -1428,12 +1390,11 @@ AHKWinSetStyle(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinSet, Style, %style%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1444,7 +1405,7 @@ AHKWinSetStyle(ByRef command) { AHKWinSetExStyle(ByRef command) { {% block AHKWinSetExStyle %} - global BOOLEANRESPONSEMESSAGE + style := command[2] title := command[3] text := command[4] @@ -1468,12 +1429,11 @@ AHKWinSetExStyle(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinSet, ExStyle, %style%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1484,7 +1444,7 @@ AHKWinSetExStyle(ByRef command) { AHKWinSetRegion(ByRef command) { {% block AHKWinSetRegion %} - global BOOLEANRESPONSEMESSAGE + options := command[2] title := command[3] text := command[4] @@ -1508,12 +1468,11 @@ AHKWinSetRegion(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinSet, Region, %options%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) } else { - resp := FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1524,7 +1483,7 @@ AHKWinSetRegion(ByRef command) { AHKWinSetTransparent(ByRef command) { {% block AHKWinSetTransparent %} - global BOOLEANRESPONSEMESSAGE + transparency := command[2] title := command[3] text := command[4] @@ -1548,7 +1507,6 @@ AHKWinSetTransparent(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinSet, Transparent, %transparency%, %title%, %text%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -1559,7 +1517,7 @@ AHKWinSetTransparent(ByRef command) { AHKWinSetTransColor(ByRef command) { {% block AHKWinSetTransColor %} - global BOOLEANRESPONSEMESSAGE + color := command[2] title := command[3] text := command[4] @@ -1583,7 +1541,6 @@ AHKWinSetTransColor(ByRef command) { DetectHiddenWindows, %detect_hw% } - WinSet, TransColor, %color%, %title%, %text%, %extitle%, %extext% DetectHiddenWindows, %current_detect_hw% @@ -1596,8 +1553,7 @@ AHKWinSetTransColor(ByRef command) { AHKImageSearch(ByRef command) { {% block AHKImageSearch %} - global COORDINATERESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + imagepath := command[6] x1 := command[2] y1 := command[3] @@ -1620,18 +1576,16 @@ AHKImageSearch(ByRef command) { ImageSearch, xpos, ypos,% x1,% y1,% x2,% y2, %imagepath% - if (coord_mode != "") { CoordMode, Pixel, %current_mode% } - if (ErrorLevel = 2) { - s := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") + s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") } else if (ErrorLevel = 1) { s := FormatNoValueResponse() } else { - s := FormatResponse(COORDINATERESPONSEMESSAGE, Format("({}, {})", xpos, ypos)) + s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) } return s @@ -1640,7 +1594,7 @@ AHKImageSearch(ByRef command) { AHKPixelGetColor(ByRef command) { {% block AHKPixelGetColor %} - global STRINGRESPONSEMESSAGE + x := command[2] y := command[3] coord_mode := command[4] @@ -1659,14 +1613,13 @@ AHKPixelGetColor(ByRef command) { CoordMode, Pixel, %current_mode% } - return FormatResponse(STRINGRESPONSEMESSAGE, color) + return FormatResponse("ahk.message.StringResponseMessage", color) {% endblock AHKPixelGetColor %} } AHKPixelSearch(ByRef command) { {% block AHKPixelSearch %} - global COORDINATERESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + x1 := command[2] y1 := command[3] x2 := command[4] @@ -1692,20 +1645,19 @@ AHKPixelSearch(ByRef command) { return FormatNoValueResponse() } else if (ErrorLevel = 0) { payload := Format("({}, {})", resultx, resulty) - return FormatResponse(COORDINATERESPONSEMESSAGE, payload) + return FormatResponse("ahk.message.CoordinateResponseMessage", payload) } else if (ErrorLevel = 2) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem conducting the pixel search (ErrorLevel 2)") + return FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem conducting the pixel search (ErrorLevel 2)") } else { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") } {% endblock AHKPixelSearch %} } - AHKMouseGetPos(ByRef command) { {% block AHKMouseGetPos %} - global COORDINATERESPONSEMESSAGE + coord_mode := command[2] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { @@ -1714,7 +1666,7 @@ AHKMouseGetPos(ByRef command) { MouseGetPos, xpos, ypos payload := Format("({}, {})", xpos, ypos) - resp := FormatResponse(COORDINATERESPONSEMESSAGE, payload) + resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) if (coord_mode != "") { CoordMode, Mouse, %current_coord_mode% @@ -1726,10 +1678,6 @@ AHKMouseGetPos(ByRef command) { AHKKeyState(ByRef command) { {% block AHKKeyState %} - global INTEGERRESPONSEMESSAGE - global FLOATRESPONSEMESSAGE - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE keyname := command[2] mode := command[3] @@ -1744,15 +1692,15 @@ AHKKeyState(ByRef command) { } if state is integer - return FormatResponse(INTEGERRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.IntegerResponseMessage", state) if state is float - return FormatResponse(FLOATRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.FloatResponseMessage", state) if state is alnum - return FormatResponse(STRINGRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.StringResponseMessage", state) - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, state) + return FormatResponse("ahk.message.ExceptionResponseMessage", state) {% endblock AHKKeyState %} } @@ -1772,7 +1720,6 @@ AHKMouseMove(ByRef command) { {% endblock AHKMouseMove %} } - AHKClick(ByRef command) { {% block AHKClick %} x := command[2] @@ -1801,26 +1748,25 @@ AHKClick(ByRef command) { AHKGetCoordMode(ByRef command) { {% block AHKGetCoordMode %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + target := command[2] if (target = "ToolTip") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeToolTip) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) } if (target = "Pixel") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModePixel) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModePixel) } if (target = "Mouse") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeMouse) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMouse) } if (target = "Caret") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeCaret) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeCaret) } if (target = "Menu") { - return FormatResponse(STRINGRESPONSEMESSAGE, A_CoordModeMenu) + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMenu) } - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Invalid coord mode") + return FormatResponse("ahk.message.ExceptionResponseMessage", "Invalid coord mode") {% endblock AHKGetCoordMode %} } @@ -1864,35 +1810,32 @@ AHKMouseClickDrag(ByRef command) { AHKRegRead(ByRef command) { {% block RegRead %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + key_name := command[2] value_name := command[3] RegRead, output, %key_name%, %value_name% if (ErrorLevel = 1) { - resp := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + resp := FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } else { - resp := FormatResponse(STRINGRESPONSEMESSAGE, Format("{}", output)) + resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) } return resp {% endblock RegRead %} } - - AHKRegWrite(ByRef command) { {% block RegWrite %} - global EXCEPTIONRESPONSEMESSAGE + value_type := command[2] key_name := command[3] value_name := command[4] value := command[5] RegWrite, %value_type%, %key_name%, %value_name%, %value% if (ErrorLevel = 1) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } return FormatNoValueResponse() @@ -1901,12 +1844,12 @@ AHKRegWrite(ByRef command) { AHKRegDelete(ByRef command) { {% block RegDelete %} - global EXCEPTIONRESPONSEMESSAGE + key_name := command[2] value_name := command[3] RegDelete, %key_name%, %value_name% if (ErrorLevel = 1) { - return FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("registry error: {}", A_LastError)) + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) } return FormatNoValueResponse() @@ -1915,7 +1858,7 @@ AHKRegDelete(ByRef command) { AHKKeyWait(ByRef command) { {% block AHKKeyWait %} - global INTEGERRESPONSEMESSAGE + keyname := command[2] if (command.Length() = 2) { KeyWait,% keyname @@ -1923,7 +1866,7 @@ AHKKeyWait(ByRef command) { options := command[3] KeyWait,% keyname,% options } - return FormatResponse(INTEGERRESPONSEMESSAGE, ErrorLevel) + return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) {% endblock AHKKeyWait %} } @@ -1933,8 +1876,6 @@ SetKeyDelay(ByRef command) { {% endblock SetKeyDelay %} } - - AHKSend(ByRef command) { {% block AHKSend %} str := command[2] @@ -1998,7 +1939,6 @@ AHKSendInput(ByRef command) { {% endblock AHKSendInput %} } - AHKSendEvent(ByRef command) { {% block AHKSendEvent %} str := command[2] @@ -2064,13 +2004,9 @@ HideTrayTip(ByRef command) { {% endblock HideTrayTip %} } - - - AHKWinGetClass(ByRef command) { {% block AHKWinGetClass %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + title := command[2] text := command[3] extitle := command[4] @@ -2096,9 +2032,9 @@ AHKWinGetClass(ByRef command) { WinGetClass, output,%title%,%text%,%extitle%,%extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was an error getting window class") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window class") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, output) + response := FormatResponse("ahk.message.StringResponseMessage", output) } DetectHiddenWindows, %current_detect_hw% @@ -2143,12 +2079,8 @@ AHKWinActivate(ByRef command) { {% endblock AHKWinActivate %} } - - - AHKWindowList(ByRef command) { {% block AHKWindowList %} - global WINDOWLISTRESPONSEMESSAGE current_detect_hw := Format("{}", A_DetectHiddenWindows) @@ -2179,7 +2111,7 @@ AHKWindowList(ByRef command) { id := windows%A_Index% r .= id . "`," } - resp := FormatResponse(WINDOWLISTRESPONSEMESSAGE, r) + resp := FormatResponse("ahk.message.WindowListResponseMessage", r) DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% SetTitleMatchMode, %current_match_speed% @@ -2187,11 +2119,9 @@ AHKWindowList(ByRef command) { {% endblock AHKWindowList %} } - - AHKControlClick(ByRef command) { {% block AHKControlClick %} - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2221,7 +2151,7 @@ AHKControlClick(ByRef command) { ControlClick, %ctrl%, %title%, %text%, %button%, %click_count%, %options%, %exclude_title%, %exclude_text% if (ErrorLevel != 0) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "Failed to click control") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "Failed to click control") } else { response := FormatNoValueResponse() } @@ -2236,8 +2166,7 @@ AHKControlClick(ByRef command) { AHKControlGetText(ByRef command) { {% block AHKControlGetText %} - global STRINGRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2264,9 +2193,9 @@ AHKControlGetText(ByRef command) { ControlGetText, result, %ctrl%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") } else { - response := FormatResponse(STRINGRESPONSEMESSAGE, result) + response := FormatResponse("ahk.message.StringResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% SetTitleMatchMode, %current_match_mode% @@ -2276,11 +2205,9 @@ AHKControlGetText(ByRef command) { {% endblock AHKControlGetText %} } - AHKControlGetPos(ByRef command) { {% block AHKControlGetPos %} - global POSITIONRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE + ctrl := command[2] title := command[3] text := command[4] @@ -2306,10 +2233,10 @@ AHKControlGetPos(ByRef command) { ControlGetPos, x, y, w, h, %ctrl%, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the text") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) - response := FormatResponse(PositionResponseMessage, result) + response := FormatResponse("ahk.message.PositionResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% @@ -2318,7 +2245,6 @@ AHKControlGetPos(ByRef command) { return response - {% endblock AHKControlGetPos %} } @@ -2355,39 +2281,34 @@ AHKControlSend(ByRef command) { {% endblock AHKControlSend %} } - - - AHKWinFromMouse(ByRef command) { {% block AHKWinFromMouse %} - global WINDOWRESPONSEMESSAGE + MouseGetPos,,, MouseWin if (MouseWin = "") { return FormatNoValueResponse() } - return FormatResponse(WINDOWRESPONSEMESSAGE, MouseWin) + return FormatResponse("ahk.message.WindowResponseMessage", MouseWin) {% endblock AHKWinFromMouse %} } - AHKWinIsAlwaysOnTop(ByRef command) { {% block AHKWinIsAlwaysOnTop %} - global BOOLEANRESPONSEMESSAGE + title := command[2] WinGet, ExStyle, ExStyle, %title% if (ExStyle = "") return FormatNoValueResponse() if (ExStyle & 0x8) ; 0x8 is WS_EX_TOPMOST. - return FormatResponse(BOOLEANRESPONSEMESSAGE, 1) + return FormatResponse("ahk.message.BooleanResponseMessage", 1) else - return FormatResponse(BOOLEANRESPONSEMESSAGE, 0) + return FormatResponse("ahk.message.BooleanResponseMessage", 0) {% endblock AHKWinIsAlwaysOnTop %} } - AHKWinMove(ByRef command) { {% block AHKWinMove %} title := command[2] @@ -2429,8 +2350,6 @@ AHKWinMove(ByRef command) { AHKWinGetPos(ByRef command) { {% block AHKWinGetPos %} - global POSITIONRESPONSEMESSAGE - global EXCEPTIONRESPONSEMESSAGE title := command[2] text := command[3] @@ -2457,10 +2376,10 @@ AHKWinGetPos(ByRef command) { WinGetPos, x, y, w, h, %title%, %text%, %extitle%, %extext% if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, "There was a problem getting the position") + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) - response := FormatResponse(PositionResponseMessage, result) + response := FormatResponse("ahk.message.PositionResponseMessage", result) } DetectHiddenWindows, %current_detect_hw% @@ -2471,23 +2390,21 @@ AHKWinGetPos(ByRef command) { {% endblock AHKWinGetPos %} } - AHKGetVolume(ByRef command) { {% block AHKGetVolume %} - global EXCEPTIONRESPONSEMESSAGE - global FLOATRESPONSEMESSAGE + device_number := command[2] try { SoundGetWaveVolume, retval, %device_number% } catch e { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) return response } if (ErrorLevel = 1) { - response := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("There was a problem getting the volume with device of index {}", device_number)) + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {}", device_number)) } else { - response := FormatResponse(FLOATRESPONSEMESSAGE, Format("{}", retval)) + response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) } return response {% endblock AHKGetVolume %} @@ -2504,14 +2421,14 @@ AHKSoundBeep(ByRef command) { AHKSoundGet(ByRef command) { {% block AHKSoundGet %} - global STRINGRESPONSEMESSAGE + device_number := command[2] component_type := command[3] control_type := command[4] SoundGet, retval, %component_type%, %control_type%, %device_number% ; TODO interpret return type - return FormatResponse(STRINGRESPONSEMESSAGE, Format("{}", retval)) + return FormatResponse("ahk.message.StringResponseMessage", Format("{}", retval)) {% endblock AHKSoundGet %} } @@ -2552,8 +2469,8 @@ CountNewlines(ByRef s) { AHKEcho(ByRef command) { {% block AHKEcho %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, command) + arg := command[2] + return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } @@ -2582,8 +2499,8 @@ AHKShowToolTip(ByRef command) { AHKGetClipboard(ByRef command) { {% block AHKGetClipboard %} - global STRINGRESPONSEMESSAGE - return FormatResponse(STRINGRESPONSEMESSAGE, Clipboard) + + return FormatResponse("ahk.message.StringResponseMessage", Clipboard) {% endblock AHKGetClipboard %} } @@ -2612,15 +2529,14 @@ AHKSetClipboardAll(ByRef command) { } AHKClipWait(ByRef command) { - global TIMEOUTRESPONSEMESSAGE + timeout := command[2] wait_for_any_data := command[3] - ClipWait, %timeout%, %wait_for_any_data% if (ErrorLevel = 1) { - return FormatResponse(TIMEOUTRESPONSEMESSAGE, "timed out waiting for clipboard data") + return FormatResponse("ahk.message.TimeoutResponseMessage", "timed out waiting for clipboard data") } return FormatNoValueResponse() } @@ -2651,47 +2567,45 @@ AHKMenuTrayIcon(ByRef command) { } AHKGuiNew(ByRef command) { - global STRINGRESPONSEMESSAGE + options := command[2] title := command[3] Gui, New, %options%, %title% - return FormatResponse(STRINGRESPONSEMESSAGE, hwnd) + return FormatResponse("ahk.message.StringResponseMessage", hwnd) } AHKMsgBox(ByRef command) { - global TIMEOUTRESPONSEMESSAGE - global STRINGRESPONSEMESSAGE + options := command[2] title := command[3] text := command[4] timeout := command[5] MsgBox,% options, %title%, %text%, %timeout% IfMsgBox, Yes - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Yes") + ret := FormatResponse("ahk.message.StringResponseMessage", "Yes") IfMsgBox, No - ret := FormatResponse(STRINGRESPONSEMESSAGE, "No") + ret := FormatResponse("ahk.message.StringResponseMessage", "No") IfMsgBox, OK - ret := FormatResponse(STRINGRESPONSEMESSAGE, "OK") + ret := FormatResponse("ahk.message.StringResponseMessage", "OK") IfMsgBox, Cancel - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Cancel") + ret := FormatResponse("ahk.message.StringResponseMessage", "Cancel") IfMsgBox, Abort - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Abort") + ret := FormatResponse("ahk.message.StringResponseMessage", "Abort") IfMsgBox, Ignore - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Ignore") + ret := FormatResponse("ahk.message.StringResponseMessage", "Ignore") IfMsgBox, Retry - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Retry") + ret := FormatResponse("ahk.message.StringResponseMessage", "Retry") IfMsgBox, Continue - ret := FormatResponse(STRINGRESPONSEMESSAGE, "Continue") + ret := FormatResponse("ahk.message.StringResponseMessage", "Continue") IfMsgBox, TryAgain - ret := FormatResponse(STRINGRESPONSEMESSAGE, "TryAgain") + ret := FormatResponse("ahk.message.StringResponseMessage", "TryAgain") IfMsgBox, Timeout - ret := FormatResponse(TIMEOUTRESPONSEMESSAGE, "MsgBox timed out") + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "MsgBox timed out") return ret } AHKInputBox(ByRef command) { - global STRINGRESPONSEMESSAGE - global TIMEOUTRESPONSEMESSAGE + title := command[2] prompt := command[3] hide := command[4] @@ -2705,17 +2619,17 @@ AHKInputBox(ByRef command) { InputBox, output, %title%, %prompt%, %hide%, %width%, %height%, %x%, %y%, %locale%, %timeout%, %default% if (ErrorLevel = 2) { - ret := FormatResponse(TIMEOUTRESPONSEMESSAGE, "Input box timed out") + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "Input box timed out") } else if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } AHKFileSelectFile(byRef command) { - global STRINGRESPONSEMESSAGE + options := command[2] root := command[3] title := command[4] @@ -2724,13 +2638,13 @@ AHKFileSelectFile(byRef command) { if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } AHKFileSelectFolder(byRef command) { - global STRINGRESPONSEMESSAGE + starting_folder := command[2] options := command[3] prompt := command[4] @@ -2740,7 +2654,7 @@ AHKFileSelectFolder(byRef command) { if (ErrorLevel = 1) { ret := FormatNoValueResponse() } else { - ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + ret := FormatResponse("ahk.message.StringResponseMessage", output) } return ret } @@ -2768,7 +2682,6 @@ b64decode(ByRef pszString) { pdwSkip := 0 ; We don't use any headers or preamble, so this is zero pdwFlags := 0 ; We don't need this, so make it null - ; The first call calculates the required size. The result is written to pbBinary success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) if (success = 0) { @@ -2796,7 +2709,6 @@ b64encode(ByRef data) { ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer - cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) if (cbBinary = 0) { return "" @@ -2810,7 +2722,6 @@ b64encode(ByRef data) { throw Exception(msg, -1) } - VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) ; Now we do the conversion to base64 and rteturn the string @@ -2823,7 +2734,6 @@ b64encode(ByRef data) { return ret } - ; End of included content CommandArrayFromQuery(ByRef text) { @@ -2865,14 +2775,14 @@ Loop { } catch e { {% block function_error_handle %} message := Format("Error occurred in {}. The error message was: {}", e.What, e.message) - pyresp := FormatResponse(EXCEPTIONRESPONSEMESSAGE, message) + pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } {% block send_response %} if (pyresp) { FileAppend, %pyresp%, *, UTF-8 } else { - msg := FormatResponse(EXCEPTIONRESPONSEMESSAGE, Format("Unknown Error when calling {}", func)) + msg := FormatResponse("ahk.message.ExceptionResponseMessage", Format("Unknown Error when calling {}", func)) FileAppend, %msg%, *, UTF-8 } {% endblock send_response %} From ae954efc4bc677f5753160042078a923b60b4f05 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 24 Aug 2023 19:01:20 -0700 Subject: [PATCH 06/52] use Critical on daemon thread --- ahk/_constants.py | 2 ++ ahk/templates/daemon.ahk | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ahk/_constants.py b/ahk/_constants.py index 39b84fc..baea312 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -27,6 +27,8 @@ {% endblock user_directives %} {% endblock directives %} +Critical, 100 + {% block message_types %} MESSAGE_TYPES := Object({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) {% endblock message_types %} diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 3daf2c7..32f136c 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -24,6 +24,8 @@ {% endblock user_directives %} {% endblock directives %} +Critical, 100 + {% block message_types %} MESSAGE_TYPES := Object({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) {% endblock message_types %} From 52c18774c57fb902a90f158ce3798679bab9268b Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 24 Aug 2023 21:08:49 -0700 Subject: [PATCH 07/52] extension documentation --- ahk/_async/engine.py | 6 + ahk/_sync/engine.py | 6 + docs/api/index.rst | 1 + docs/api/message.rst | 7 ++ docs/extending.rst | 256 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 6 files changed, 277 insertions(+) create mode 100644 docs/api/message.rst create mode 100644 docs/extending.rst diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index c7937d3..7d2e51c 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -204,6 +204,12 @@ def add_hotkey( warnings.warn(warning.message, warning.category, stacklevel=2) return None + async def function_call(self, function_name: str, args: list[str], blocking: bool = True) -> Any: + """ + Call an AHK function defined in the daemon script. This method is intended for use by extension authors. + """ + return await self._transport.function_call(function_name, args, blocking=blocking, engine=self) # type: ignore[call-overload] + def add_hotstring( self, trigger: str, diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 8f93d06..2d7cfd6 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -198,6 +198,12 @@ def add_hotkey( warnings.warn(warning.message, warning.category, stacklevel=2) return None + def function_call(self, function_name: str, args: list[str], blocking: bool = True) -> Any: + """ + Call an AHK function defined in the daemon script. This method is intended for use by extension authors. + """ + return self._transport.function_call(function_name, args, blocking=blocking, engine=self) # type: ignore[call-overload] + def add_hotstring( self, trigger: str, diff --git a/docs/api/index.rst b/docs/api/index.rst index 5563455..4a2b461 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -14,3 +14,4 @@ about the programming interface. This is largely auto-generated documentation. async methods directives + message diff --git a/docs/api/message.rst b/docs/api/message.rst new file mode 100644 index 0000000..d1afe0f --- /dev/null +++ b/docs/api/message.rst @@ -0,0 +1,7 @@ +Message +======= + + +.. automodule:: ahk.message + :members: + :undoc-members: diff --git a/docs/extending.rst b/docs/extending.rst new file mode 100644 index 0000000..26579af --- /dev/null +++ b/docs/extending.rst @@ -0,0 +1,256 @@ +Extending AHK +============= + +.. attention:: + The extension feature is in early stages of development and may change at any time, including breaking changes in minor version releases. + +You can extend AHK to add more functionality. This is particularly useful for those who may want to +contribute their own solutions into the ecosystem that others can use. + +For users of an extension, their interface will typically look like this: + +1. Install the extension (e.g., ``pip install ...``) +2. import the extension(s) and enable extensions when instantiating the ``AHK`` class + +.. code-block:: + + from my_great_extension import the_extension + from ahk import AHK + ahk = AHK(extensions='auto') # use all available/imported extensions + ahk.my_great_method('foo', 'bar', 'baz') # new methods are available from the extension! + + +This document will describe how you can create your own extensions and also cover some basics of packaging and +distributing an extension for ``ahk`` on PyPI. + + +Background +---------- + +First, a little background is necessary into the inner mechanisms of how ``ahk`` does what it does. It is important for +extension authors to understand these key points: + +- Python calls AHK functions by name and can pass any number of strings as parameters. +- Functions written in AHK (v1) accept exactly one argument (an array of zero or more strings) and must return responses in a specific message format (we'll discuss these specifics later) +- The message returned from AHK to Python indicates the type of the return value so Python can parse the response message into an appropriate Python type. There are several predefined message types available in the :py:mod:`ahk.message` module. Extension authors may also create their own message types (discussed later). + + + +Writing an extension +-------------------- + +The basics of writing an extension requires two key components: + + +- A function written in AHK (v1) that conforms to the required spec (accepts one argument of an array of strings and returns a formatted message). +- A python function that accepts an instance of `AHK` (or `AsyncAHK for `async` functions) as its first parameter (think of it like a method of the `AHK` class). It may also accept any additional parameters. + + +Example +^^^^^^^ + +This simple example extension will provide a new method on the ``AHK`` class called ``simple_math``. This new method +accepts three arguments: two operands (``lhs`` and ``rhs``) and an operator (``+`` or ``*``). + +When complete, the interface will look something like this: + +.. code-block:: + + ahk = AHK(extensions='auto') + print(ahk.simple_math(2, 2, '+')) # 4 + + +Let's begin writing the extension. + +First, we'll start with the AutoHotkey code. This will be an AHK (v1) function that accepts a single argument, which +is an array containing the arguments of the function passed by Python. These start at index 2. + +Ultimately, the function will perform some operation utilizing these inputs and will return a formatted response +(using the ``FormatResponse`` function which is already defined for you. It accepts two arguments: the messaage type name +and the raw payload. + +.. code-block:: + + + SimpleMath(ByRef command) { + + ; `command` is an array with passed arguments, starting at index 2 + lhs := command[2] + rhs := command[3] + operator := command[4] + + if (operator = "+") { + result := (lhs + rhs) + } else if (operator = "*") { + result := (lhs * rhs) + } else { ; invalid operator argument + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("Invalid operator: {}", operator)) + } + + return FormatResponse("ahk.message.IntegerResponseMessage", result) + } + + +Note that the ``FormatResponse`` function is already implemented for you! + + +Next, we'll create the Python components of our extension: a Python function and the extension itself. The extension +itself is an instance of the ``Extension`` class and it accepts an argument ``script_text`` which will be a string +containing the AutoHotkey code we just wrote above. + + +.. code-block:: + + from ahk import AHK + from ahk.extensions import Extension + from typing import Literal + + script_text = r'''\ + ; a string of your AHK script + ; Omitted here for brevity -- copy/paste from the previous code block + ''' + simple_math_extension = Extension(script_text=script_text) + + @simple_meth_extension.register # register the method for the extension + def simple_math(ahk: AHK, lhs: int, rhs: int, operator: Literal['+', '*']) -> int: + assert isinstance(lhs, int) + assert isinstance(rhs, int) + # assert operator in ('+', '*') # we'll leave this out so we can demo raising exceptions from AHK + args = [str(lhs), str(rhs), operator] # all args must be strings + result = ahk.function_call('SimpleMath', args, blocking=True) + return result + + +After the extension is created, it can be used automatically! + +.. code-block:: + + # ... above code omitted for brevity + ahk = AHK(extensions='auto') + + result = ahk.simple_math(2, 4, operator='+') + print('2 + 4 =', result) + assert result == 6 + + result = ahk.simple_math(2, 4, operator='*') + print('2 * 4 =', result) + assert result == 8 + + # this will raise our custom exception from our AHK code + try: + ahk.simple_math(0, 0, operator='invalid') + except Exception as e: + print('An exception was raised. Exception message was:', e) + +If you use this example code, it should output something like this: :: + + 2 + 4 = 6 + 2 * 4 = 8 + An exception was raised. Exception message was: Invalid operator: % + + + + +Includes +^^^^^^^^ + +In addition to supplying AutoHotkey extension code via ``script_text``, you may also do this using includes. + +.. code-block:: + + from ahk.extensions import Extension + my_extension = Extension(includes=['myscript.ahk']) # equivalent to "#Include myscript.ahk" + + +Available Message Types +^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + + * - Message type + - Python return type + - Payload description + * - :py:class:`ahk.message.TupleResponseMessage` + - A ``tuple`` object containing any number of literal types (``Tuple[Any, ...]``) + - A string representing a tuple literal (i.e. usable with ``ast.literal_eval``) + * - :py:class:`ahk.message.CoordinateResponseMessage` + - A tuple containing two integers (``Tuple[int, int]``) + - A string representing the tuple literal + * - :py:class:`ahk.message.IntegerResponseMessage` + - An integer (``int``) + - A string literal representing an integer + * - :py:class:`ahk.message.BooleanResponseMessage` + - A boolean (``bool``) + - A string literal of either ``0`` or ``1`` + * - :py:class:`ahk.message.StringResponseMessage` + - A string (``str``) + - Any string + * - :py:class:`ahk.message.WindowListResponseMessage` + - A list of :py:class:`~ahk._sync.window.Window` (or :py:class:`~ahk._async.window.AsyncWindow`) objects + - A string containing a comma-delimited list of window IDs + * - :py:class:`ahk.message.NoValueResponseMessage` + - NoneType (``None``) + - A sentinel value (use ``FormatNoValueResponse()`` in AHK for returning this message) + * - :py:class:`ahk.message.ExceptionResponseMessage` + - raises an Exception. + - A string with the exception message + * - :py:class:`ahk.message.WindowControlListResponseMessage` + - A list of :py:class:`~ahk._sync.window.Control` (or :py:class:`~ahk._async.window.AsyncControl`) objects + - A string literal representing a tuple containing the window hwnd and a list of tuples each containing the control hwnd and class for each control + * - :py:class:`ahk.message.WindowResponseMessage` + - A :py:class:`~ahk._sync.Window` (or ``AsyncWindow``) object + - A string containing the ID of the window + * - :py:class:`ahk.message.PositionResponseMessage` + - A ``Postion`` namedtuple object, consisting of 4 integers with named attributes ``x``, ``y``, ``width``, and ``height`` + - A string representing the tuple literal + * - :py:class:`ahk.message.FloatResponseMessage` + - ``float`` + - A string literal representation of a float + * - :py:class:`ahk.message.TimeoutResponseMessage` + - raises a ``TimeoutException`` + - A string containing the exception message + * - :py:class:`ahk.message.B64BinaryResponseMessage` + - ``bytes`` object + - A string containing base64-encoded binary data + + +Returning custom types (make your own message type) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can design your extension functions to ultimately return different types by implementing your own message class. + +To do this, subclass :py:class:`ahk.message.ResponseMessage` (or any of its other subclasses) and implement the ``unpack`` method. + +For example, suppose you want your method to return a datetime object, you might do something like this: + +.. code-block:: + + import datetime + from ahk.message import IntegerResponseMessage + class DatetimeResponseMessage(IntegerResponseMessage): + def unpack(self) -> datetime.datetime: + val = super().unpack() # get the integer timestamp + return datetime.datetime.fromtimestamp(val) + +In AHK code, you can reference custom response messages by the their fully qualified name, including the namespace. +(if you're not sure what this means, you can see this value by calling ``DateTimeResponseMessage.fqn()``) + + + +Packaging +^^^^^^^^^ + +Coming soon. + +Notes +^^^^^ + +- AHK functions MUST always return a message. Failing to return a message will result in an exception being raised. If the function should return nothing, use ``return FormatNoValueResponse()`` which will translate to ``None`` in Python. +- You cannot define hotkeys, hotstrings, or write any AutoHotkey code that would cause the end of autoexecution + + +Extending with jinja +^^^^^^^^^^^^^^^^^^^^ + +Coming soon. diff --git a/docs/index.rst b/docs/index.rst index 736ce73..90e24c2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,6 +17,7 @@ ahk Python wrapper documentation quickstart README api/index + extending From 8327cb0808d110b5c87a914518f9cf5a03b6f6ca Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 24 Aug 2023 23:48:52 -0700 Subject: [PATCH 08/52] notes --- docs/extending.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/extending.rst b/docs/extending.rst index 26579af..ed3badb 100644 --- a/docs/extending.rst +++ b/docs/extending.rst @@ -236,6 +236,13 @@ For example, suppose you want your method to return a datetime object, you might In AHK code, you can reference custom response messages by the their fully qualified name, including the namespace. (if you're not sure what this means, you can see this value by calling ``DateTimeResponseMessage.fqn()``) +Notes +^^^^^ + +- AHK functions MUST always return a message. Failing to return a message will result in an exception being raised. If the function should return nothing, use ``return FormatNoValueResponse()`` which will translate to ``None`` in Python. +- You cannot define hotkeys, hotstrings, or write any AutoHotkey code that would cause the end of autoexecution +- Extensions must be imported *before* instantiating the ``AHK`` instance +- Although extensions can be declared explicitly, using ``extensions='auto'`` is the recommended method for enabling extensions Packaging @@ -243,12 +250,6 @@ Packaging Coming soon. -Notes -^^^^^ - -- AHK functions MUST always return a message. Failing to return a message will result in an exception being raised. If the function should return nothing, use ``return FormatNoValueResponse()`` which will translate to ``None`` in Python. -- You cannot define hotkeys, hotstrings, or write any AutoHotkey code that would cause the end of autoexecution - Extending with jinja ^^^^^^^^^^^^^^^^^^^^ From be14d1c6620d46022c7960417ba4f9f6dbef38ad Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Fri, 25 Aug 2023 00:26:18 -0700 Subject: [PATCH 09/52] update tests --- tests/_async/test_extensions.py | 5 ++--- tests/_sync/test_extensions.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index 95651dc..1842a2e 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -13,9 +13,8 @@ ext_text = '''\ AHKDoSomething(ByRef command) { - global STRINGRESPONSEMESSAGE arg := command[2] - return FormatResponse(STRINGRESPONSEMESSAGE, Format("test{}", arg)) + return FormatResponse("ahk.message.StringResponseMessage", Format("test{}", arg)) } ''' @@ -24,7 +23,7 @@ @async_extension.register async def do_something(ahk, arg: str) -> str: - res = await ahk._transport.function_call('AHKDoSomething', [arg]) + res = await ahk.function_call('AHKDoSomething', [arg]) return res diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index c78d392..8eadcb2 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -12,9 +12,8 @@ ext_text = '''\ AHKDoSomething(ByRef command) { - global STRINGRESPONSEMESSAGE arg := command[2] - return FormatResponse(STRINGRESPONSEMESSAGE, Format("test{}", arg)) + return FormatResponse("ahk.message.StringResponseMessage", Format("test{}", arg)) } ''' @@ -23,7 +22,7 @@ @async_extension.register def do_something(ahk, arg: str) -> str: - res = ahk._transport.function_call('AHKDoSomething', [arg]) + res = ahk.function_call('AHKDoSomething', [arg]) return res From e3b66b147de5f4d73a7bf6b0642a71558358487c Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Fri, 25 Aug 2023 01:31:23 -0700 Subject: [PATCH 10/52] prepare 1.4.0rc1 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index f1cfc96..ad170b6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = ahk -version = 1.3.0 +version = 1.4.0rc1 author_email = spencer.young@spyoung.com author = Spencer Young description = A Python wrapper for AHK From 92c0c7758dea690761c14c1c289eb6a3e70df9e2 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Fri, 25 Aug 2023 01:49:46 -0700 Subject: [PATCH 11/52] add stacklevel to warnings --- ahk/extensions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ahk/extensions.py b/ahk/extensions.py index af3deec..00f8ddf 100644 --- a/ahk/extensions.py +++ b/ahk/extensions.py @@ -37,7 +37,8 @@ def register(self, ext: Extension, f: Callable[P, T]) -> Callable[P, T]: warnings.warn( f'Method of name {f.__name__!r} has already been registered. ' f'Previously registered method {self.async_methods[f.__name__].method!r} ' - f'will be overridden by {f!r}' + f'will be overridden by {f!r}', + stacklevel=2, ) self.async_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) else: @@ -45,7 +46,8 @@ def register(self, ext: Extension, f: Callable[P, T]) -> Callable[P, T]: warnings.warn( f'Method of name {f.__name__!r} has already been registered. ' f'Previously registered method {self.sync_methods[f.__name__].method!r} ' - f'will be overridden by {f!r}' + f'will be overridden by {f!r}', + stacklevel=2, ) self.sync_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) return f From 09bc6767f6db4768bb11b8d2cb0b4b0be1032dcf Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 30 Aug 2023 14:56:58 -0700 Subject: [PATCH 12/52] extension registry cleanup --- ahk/_async/engine.py | 41 ++++++------ ahk/_async/transport.py | 6 +- ahk/_constants.py | 10 --- ahk/_sync/engine.py | 40 ++++++------ ahk/_sync/transport.py | 6 +- ahk/extensions.py | 108 ++++++++++++++++++++++---------- ahk/templates/daemon.ahk | 10 --- tests/_async/test_extensions.py | 6 +- tests/_sync/test_extensions.py | 6 +- 9 files changed, 129 insertions(+), 104 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 7d2e51c..d0b1bf0 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -35,7 +35,12 @@ else: from typing import TypeAlias -from ..extensions import Extension, _extension_method_registry, _ExtensionMethodRegistry +from ..extensions import ( + Extension, + _ExtensionMethodRegistry, + _extension_registry, + _resolve_extensions, +) from ..keys import Key from .transport import AsyncDaemonProcessTransport from .transport import AsyncFutureResult @@ -142,38 +147,28 @@ def __init__( self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': - is_async = False - is_async = True # unasync: remove - if is_async: - methods = _extension_method_registry.async_methods - else: - methods = _extension_method_registry.sync_methods - extensions = list(set(entry.extension for name, entry in methods.items())) - - self._extension_registry = _extension_method_registry - self._extensions = extensions + self._extensions = list(_extension_registry) else: - self._extensions = extensions or [] - self._extension_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) - for ext in self._extensions: - self._extension_registry.merge(ext._extension_method_registry) - + self._extensions = _resolve_extensions(extensions) if extensions else [] + self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + for ext in self._extensions: + self._method_registry.merge(ext._extension_method_registry) if TransportClass is None: TransportClass = AsyncDaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives, extensions=extensions) + transport = TransportClass(executable_path=executable_path, directives=directives, extensions=self._extensions) self._transport: AsyncTransport = transport def __getattr__(self, name: str) -> Callable[..., Any]: is_async = False is_async = True # unasync: remove if is_async: - if name in self._extension_registry.async_methods: - method = self._extension_registry.async_methods[name].method + if name in self._method_registry.async_methods: + method = self._method_registry.async_methods[name] return partial(method, self) else: - if name in self._extension_registry.sync_methods: - method = self._extension_registry.sync_methods[name].method + if name in self._method_registry.sync_methods: + method = self._method_registry.sync_methods[name] return partial(method, self) raise AttributeError(f'{self.__class__.__name__!r} object has no attribute {name!r}') @@ -204,10 +199,12 @@ def add_hotkey( warnings.warn(warning.message, warning.category, stacklevel=2) return None - async def function_call(self, function_name: str, args: list[str], blocking: bool = True) -> Any: + async def function_call(self, function_name: str, args: list[str] | None = None, blocking: bool = True) -> Any: """ Call an AHK function defined in the daemon script. This method is intended for use by extension authors. """ + if args is None: + args = [] return await self._transport.function_call(function_name, args, blocking=blocking, engine=self) # type: ignore[call-overload] def add_hotstring( diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 96277d3..c6b9842 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -38,7 +38,7 @@ import jinja2 -from ahk.extensions import Extension +from ahk.extensions import Extension, _resolve_includes from ahk._hotkey import ThreadedHotkeyTransport, Hotkey, Hotstring from ahk.message import RequestMessage from ahk.message import ResponseMessage @@ -689,6 +689,10 @@ def __init__( if template is None: template = self.__template self._template: jinja2.Template = template + directives = directives or [] + if extensions: + includes = _resolve_includes(extensions) + directives = includes + directives super().__init__(executable_path=executable_path, directives=directives) @property diff --git a/ahk/_constants.py b/ahk/_constants.py index baea312..f7485eb 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -6,16 +6,6 @@ #NoEnv #Persistent #SingleInstance Off -{% block extension_directives %} -; BEGIN extension includes -{% for ext in extensions %} -{% for inc in ext.includes %} -{{ inc }} - -{% endfor %} -{% endfor %} -; END extension includes -{% endblock extension_directives %} ; BEGIN user-defined directives {% block user_directives %} {% for directive in directives %} diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 2d7cfd6..2240106 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -35,7 +35,12 @@ else: from typing import TypeAlias -from ..extensions import Extension, _extension_method_registry, _ExtensionMethodRegistry +from ..extensions import ( + Extension, + _ExtensionMethodRegistry, + _extension_registry, + _resolve_extensions, +) from ..keys import Key from .transport import DaemonProcessTransport from .transport import FutureResult @@ -138,36 +143,27 @@ def __init__( self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': - is_async = False - if is_async: - methods = _extension_method_registry.async_methods - else: - methods = _extension_method_registry.sync_methods - extensions = list(set(entry.extension for name, entry in methods.items())) - - self._extension_registry = _extension_method_registry - self._extensions = extensions + self._extensions = list(_extension_registry) else: - self._extensions = extensions or [] - self._extension_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) - for ext in self._extensions: - self._extension_registry.merge(ext._extension_method_registry) - + self._extensions = _resolve_extensions(extensions) if extensions else [] + self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + for ext in self._extensions: + self._method_registry.merge(ext._extension_method_registry) if TransportClass is None: TransportClass = DaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives, extensions=extensions) + transport = TransportClass(executable_path=executable_path, directives=directives, extensions=self._extensions) self._transport: Transport = transport def __getattr__(self, name: str) -> Callable[..., Any]: is_async = False if is_async: - if name in self._extension_registry.async_methods: - method = self._extension_registry.async_methods[name].method + if name in self._method_registry.async_methods: + method = self._method_registry.async_methods[name] return partial(method, self) else: - if name in self._extension_registry.sync_methods: - method = self._extension_registry.sync_methods[name].method + if name in self._method_registry.sync_methods: + method = self._method_registry.sync_methods[name] return partial(method, self) raise AttributeError(f'{self.__class__.__name__!r} object has no attribute {name!r}') @@ -198,10 +194,12 @@ def add_hotkey( warnings.warn(warning.message, warning.category, stacklevel=2) return None - def function_call(self, function_name: str, args: list[str], blocking: bool = True) -> Any: + def function_call(self, function_name: str, args: list[str] | None = None, blocking: bool = True) -> Any: """ Call an AHK function defined in the daemon script. This method is intended for use by extension authors. """ + if args is None: + args = [] return self._transport.function_call(function_name, args, blocking=blocking, engine=self) # type: ignore[call-overload] def add_hotstring( diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index e786a19..8408566 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -38,7 +38,7 @@ import jinja2 -from ahk.extensions import Extension +from ahk.extensions import Extension, _resolve_includes from ahk._hotkey import ThreadedHotkeyTransport, Hotkey, Hotstring from ahk.message import RequestMessage from ahk.message import ResponseMessage @@ -662,6 +662,10 @@ def __init__( if template is None: template = self.__template self._template: jinja2.Template = template + directives = directives or [] + if extensions: + includes = _resolve_includes(extensions) + directives = includes + directives super().__init__(executable_path=executable_path, directives=directives) @property diff --git a/ahk/extensions.py b/ahk/extensions.py index 00f8ddf..ee71c9d 100644 --- a/ahk/extensions.py +++ b/ahk/extensions.py @@ -1,8 +1,11 @@ from __future__ import annotations import asyncio +import itertools import sys +import typing import warnings +from collections import deque from dataclasses import dataclass from typing import Any from typing import Callable @@ -10,8 +13,10 @@ if sys.version_info < (3, 10): from typing_extensions import ParamSpec + from typing_extensions import Concatenate else: from typing import ParamSpec + from typing import Concatenate from .directives import Include @@ -26,67 +31,64 @@ class _ExtensionEntry: P = ParamSpec('P') +if typing.TYPE_CHECKING: + from ahk import AHK, AsyncAHK + + TAHK = TypeVar('TAHK', bound=typing.Union[AHK, AsyncAHK]) + + @dataclass class _ExtensionMethodRegistry: - sync_methods: dict[str, _ExtensionEntry] - async_methods: dict[str, _ExtensionEntry] + sync_methods: dict[str, Callable[..., Any]] + async_methods: dict[str, Callable[..., Any]] - def register(self, ext: Extension, f: Callable[P, T]) -> Callable[P, T]: + def register(self, f: Callable[Concatenate[TAHK, P], T]) -> Callable[Concatenate[TAHK, P], T]: if asyncio.iscoroutinefunction(f): if f.__name__ in self.async_methods: warnings.warn( f'Method of name {f.__name__!r} has already been registered. ' - f'Previously registered method {self.async_methods[f.__name__].method!r} ' + f'Previously registered method {self.async_methods[f.__name__]!r} ' f'will be overridden by {f!r}', stacklevel=2, ) - self.async_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) + self.async_methods[f.__name__] = f else: if f.__name__ in self.sync_methods: warnings.warn( f'Method of name {f.__name__!r} has already been registered. ' - f'Previously registered method {self.sync_methods[f.__name__].method!r} ' + f'Previously registered method {self.sync_methods[f.__name__]!r} ' f'will be overridden by {f!r}', stacklevel=2, ) - self.sync_methods[f.__name__] = _ExtensionEntry(extension=ext, method=f) + self.sync_methods[f.__name__] = f return f def merge(self, other: _ExtensionMethodRegistry) -> None: - for fname, entry in other.async_methods.items(): - async_method = entry.method - if async_method.__name__ in self.async_methods: - warnings.warn( - f'Method of name {async_method.__name__!r} has already been registered. ' - f'Previously registered method {self.async_methods[async_method.__name__].method!r} ' - f'will be overridden by {async_method!r}' - ) - self.async_methods[async_method.__name__] = entry - for fname, entry in other.sync_methods.items(): - method = entry.method - if method.__name__ in self.sync_methods: - warnings.warn( - f'Method of name {method.__name__!r} has already been registered. ' - f'Previously registered method {self.sync_methods[method.__name__].method!r} ' - f'will be overridden by {method!r}' - ) - self.sync_methods[method.__name__] = entry + for name, method in other.methods: + self.register(method) + + @property + def methods(self) -> list[tuple[str, Callable[..., Any]]]: + return list(itertools.chain(self.async_methods.items(), self.sync_methods.items())) -_extension_method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) +_extension_registry: dict[Extension, _ExtensionMethodRegistry] = {} class Extension: def __init__( self, - includes: list[str] | None = None, script_text: str | None = None, - # template: str | Template | None = None + includes: list[str] | None = None, + dependencies: list[Extension] | None = None, ): self._text: str = script_text or '' - # self._template: str | Template | None = template self._includes: list[str] = includes or [] - self._extension_method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) + self.dependencies: list[Extension] = dependencies or [] + self._extension_method_registry: _ExtensionMethodRegistry = _ExtensionMethodRegistry( + sync_methods={}, async_methods={} + ) + _extension_registry[self] = self._extension_method_registry @property def script_text(self) -> str: @@ -100,7 +102,47 @@ def script_text(self, new_script: str) -> None: def includes(self) -> list[Include]: return [Include(inc) for inc in self._includes] - def register(self, f: Callable[P, T]) -> Callable[P, T]: - self._extension_method_registry.register(self, f) - _extension_method_registry.register(self, f) + def register(self, f: Callable[Concatenate[TAHK, P], T]) -> Callable[Concatenate[TAHK, P], T]: + self._extension_method_registry.register(f) return f + + def __hash__(self) -> int: + return hash((self._text, tuple(self.includes), tuple(self.dependencies))) + + def __eq__(self, other: Any) -> bool: + if isinstance(other, Extension): + return hash(self) == hash(other) + return NotImplemented + + +def _resolve_extension(extension: Extension, seen: set[Extension]) -> list[Extension]: + ret: deque[Extension] = deque() + todo = [extension] + while todo: + ext = todo.pop() + if ext in seen: + continue + ret.appendleft(ext) + seen.add(ext) + todo.extend(ext.dependencies) + return list(ret) + + +def _resolve_extensions(extensions: list[Extension]) -> list[Extension]: + seen: set[Extension] = set() + ret: list[Extension] = [] + for ext in extensions: + ret.extend(_resolve_extension(ext, seen=seen)) + return ret + + +def _resolve_includes(extensions: list[Extension]) -> list[Include]: + extensions = _resolve_extensions(extensions) + ret = [] + seen: set[Include] = set() + for ext in extensions: + for include in ext.includes: + if include in seen: + continue + ret.append(include) + return ret diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 32f136c..112a373 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -3,16 +3,6 @@ #NoEnv #Persistent #SingleInstance Off -{% block extension_directives %} -; BEGIN extension includes -{% for ext in extensions %} -{% for inc in ext.includes %} -{{ inc }} - -{% endfor %} -{% endfor %} -; END extension includes -{% endblock extension_directives %} ; BEGIN user-defined directives {% block user_directives %} {% for directive in directives %} diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index 1842a2e..e76ebfe 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -35,7 +35,7 @@ async def asyncTearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - async def test_ext(self): + async def test_ext_explicit(self): res = await self.ahk.do_something('foo') assert res == 'testfoo' @@ -48,7 +48,7 @@ async def asyncTearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - async def test_ext(self): + async def test_ext_auto(self): res = await self.ahk.do_something('foo') assert res == 'testfoo' @@ -62,5 +62,5 @@ async def asyncTearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - async def test_ext(self): + async def test_ext_no_ext(self): assert not hasattr(self.ahk, 'do_something') diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 8eadcb2..b7c8d14 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -34,7 +34,7 @@ def tearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - def test_ext(self): + def test_ext_explicit(self): res = self.ahk.do_something('foo') assert res == 'testfoo' @@ -47,7 +47,7 @@ def tearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - def test_ext(self): + def test_ext_auto(self): res = self.ahk.do_something('foo') assert res == 'testfoo' @@ -61,5 +61,5 @@ def tearDown(self) -> None: self.ahk._transport._proc.kill() time.sleep(0.2) - def test_ext(self): + def test_ext_no_ext(self): assert not hasattr(self.ahk, 'do_something') From 3eba8b823d086b4df27b386390f01b15ab7de02e Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 30 Aug 2023 16:12:50 -0700 Subject: [PATCH 13/52] better error messages --- ahk/_async/transport.py | 25 +++++++++++++++++++++---- ahk/_sync/transport.py | 23 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index c6b9842..8aab54d 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -260,6 +260,13 @@ async def readline(self) -> bytes: assert isinstance(line, bytes) return line + async def read(self) -> bytes: + assert self._proc is not None + assert self._proc.stdout is not None + b = await self._proc.stdout.read() + assert isinstance(b, bytes) + return b + def kill(self) -> None: assert self._proc is not None, 'no process to kill' self._proc.kill() @@ -280,12 +287,12 @@ def communicate(self, input_bytes: Optional[bytes] = None, timeout: Optional[int async def async_create_process(runargs: List[str]) -> asyncio.subprocess.Process: # unasync: remove return await asyncio.subprocess.create_subprocess_exec( - *runargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE + *runargs, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) def sync_create_process(runargs: List[str]) -> subprocess.Popen[bytes]: - return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) class AhkExecutableNotFoundError(EnvironmentError): @@ -775,8 +782,13 @@ async def _send_nonblocking( try: lines_to_read = int(num_lines) + 1 except ValueError as e: + try: + stdout = tom + num_lines + await proc.read() + except Exception: + stdout = b'' raise AHKProtocolError( - 'Unexpected data received. This is usually the result of an unhandled error in the AHK process.' + 'Unexpected data received. This is usually the result of an unhandled error in the AHK process' + + (f': {stdout!r}' if stdout else '') ) from e for _ in range(lines_to_read): part = await proc.readline() @@ -827,8 +839,13 @@ async def send( try: lines_to_read = int(num_lines) + 1 except ValueError as e: + try: + stdout = tom + num_lines + await self._proc.read() + except Exception: + stdout = b'' raise AHKProtocolError( - 'Unexpected data received. This is usually the result of an unhandled error in the AHK process.' + 'Unexpected data received. This is usually the result of an unhandled error in the AHK process' + + (f': {stdout!r}' if stdout else '') ) from e for _ in range(lines_to_read): part = await self._proc.readline() diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index 8408566..a15b81c 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -247,6 +247,13 @@ def readline(self) -> bytes: assert isinstance(line, bytes) return line + def read(self) -> bytes: + assert self._proc is not None + assert self._proc.stdout is not None + b = self._proc.stdout.read() + assert isinstance(b, bytes) + return b + def kill(self) -> None: assert self._proc is not None, 'no process to kill' self._proc.kill() @@ -266,7 +273,7 @@ def communicate(self, input_bytes: Optional[bytes] = None, timeout: Optional[int def sync_create_process(runargs: List[str]) -> subprocess.Popen[bytes]: - return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) class AhkExecutableNotFoundError(EnvironmentError): @@ -747,8 +754,13 @@ def _send_nonblocking( try: lines_to_read = int(num_lines) + 1 except ValueError as e: + try: + stdout = tom + num_lines + proc.read() + except Exception: + stdout = b'' raise AHKProtocolError( - 'Unexpected data received. This is usually the result of an unhandled error in the AHK process.' + 'Unexpected data received. This is usually the result of an unhandled error in the AHK process' + + (f': {stdout!r}' if stdout else '') ) from e for _ in range(lines_to_read): part = proc.readline() @@ -791,8 +803,13 @@ def send( try: lines_to_read = int(num_lines) + 1 except ValueError as e: + try: + stdout = tom + num_lines + self._proc.read() + except Exception: + stdout = b'' raise AHKProtocolError( - 'Unexpected data received. This is usually the result of an unhandled error in the AHK process.' + 'Unexpected data received. This is usually the result of an unhandled error in the AHK process' + + (f': {stdout!r}' if stdout else '') ) from e for _ in range(lines_to_read): part = self._proc.readline() From aa6afecc726b65e9c821c38a4a07c5c9f6392257 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 30 Aug 2023 16:13:07 -0700 Subject: [PATCH 14/52] fix extension tests --- tests/_async/test_extensions.py | 15 ++++++++++----- tests/_sync/test_extensions.py | 14 +++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index e76ebfe..1a2b9d9 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -1,4 +1,6 @@ import asyncio +import random +import string import time import unittest @@ -11,11 +13,14 @@ sleep = time.sleep -ext_text = '''\ -AHKDoSomething(ByRef command) { +function_name = 'AHKDoSomething' +function_name = 'AAHKDoSomething' # unasync: remove + +ext_text = f'''\ +{function_name}(ByRef command) {{ arg := command[2] - return FormatResponse("ahk.message.StringResponseMessage", Format("test{}", arg)) -} + return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) +}} ''' async_extension = Extension(script_text=ext_text) @@ -23,7 +28,7 @@ @async_extension.register async def do_something(ahk, arg: str) -> str: - res = await ahk.function_call('AHKDoSomething', [arg]) + res = await ahk.function_call(function_name, [arg]) return res diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index b7c8d14..6c011ad 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -1,4 +1,6 @@ import asyncio +import random +import string import time import unittest @@ -10,11 +12,13 @@ sleep = time.sleep -ext_text = '''\ -AHKDoSomething(ByRef command) { +function_name = 'AHKDoSomething' + +ext_text = f'''\ +{function_name}(ByRef command) {{ arg := command[2] - return FormatResponse("ahk.message.StringResponseMessage", Format("test{}", arg)) -} + return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) +}} ''' async_extension = Extension(script_text=ext_text) @@ -22,7 +26,7 @@ @async_extension.register def do_something(ahk, arg: str) -> str: - res = ahk.function_call('AHKDoSomething', [arg]) + res = ahk.function_call(function_name, [arg]) return res From b5325943d07a30220ca1e75661b83260111fb56c Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Mon, 18 Sep 2023 14:20:16 -0700 Subject: [PATCH 15/52] [WIP] initial v2 work --- ahk/_async/engine.py | 23 +- ahk/_async/transport.py | 33 +- ahk/_sync/engine.py | 23 +- ahk/_sync/transport.py | 33 +- ahk/templates/daemon-v2.ahk | 2840 +++++++++++++++++++++++++++++++ tests/_async/test_clipboard.py | 5 + tests/_async/test_extensions.py | 18 +- tests/_async/test_gui.py | 5 + tests/_async/test_hotkeys.py | 5 + tests/_async/test_keys.py | 10 + tests/_async/test_mouse.py | 5 + tests/_async/test_registry.py | 5 + tests/_async/test_screen.py | 10 + tests/_async/test_scripts.py | 5 + tests/_async/test_window.py | 9 + tests/_sync/test_clipboard.py | 5 + tests/_sync/test_extensions.py | 18 +- tests/_sync/test_gui.py | 5 + tests/_sync/test_hotkeys.py | 5 + tests/_sync/test_keys.py | 10 + tests/_sync/test_mouse.py | 5 + tests/_sync/test_registry.py | 5 + tests/_sync/test_screen.py | 10 + tests/_sync/test_scripts.py | 5 + tests/_sync/test_window.py | 9 + 25 files changed, 3082 insertions(+), 24 deletions(-) create mode 100644 ahk/templates/daemon-v2.ahk diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index d0b1bf0..6f34927 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -143,6 +143,7 @@ def __init__( directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, + version: Optional[Literal['v1', 'v2']] = None, ): self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] @@ -156,7 +157,9 @@ def __init__( if TransportClass is None: TransportClass = AsyncDaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives, extensions=self._extensions) + transport = TransportClass( + executable_path=executable_path, directives=directives, extensions=self._extensions, version=version + ) self._transport: AsyncTransport = transport def __getattr__(self, name: str) -> Callable[..., Any]: @@ -753,6 +756,8 @@ async def mouse_move( args = [str(x), str(y), str(speed)] if relative: args.append('R') + else: + args.append('') resp = await self._transport.function_call('AHKMouseMove', args, blocking=blocking) return resp @@ -1314,7 +1319,7 @@ async def show_traytip( self, title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, @@ -1324,6 +1329,14 @@ async def show_traytip( """ Analog for `TrayTip `_ """ + if second is None: + second = 1.0 + else: + if self._transport._version == 'v2': + warnings.warn( + 'supplying seconds is not supported when using AutoHotkey v2. This parameter will be ignored' + ) + option = type_id + (16 if silent else 0) + (32 if large_icon else 0) args = [title, text, str(second), str(option)] return await self._transport.function_call('AHKTrayTip', args, blocking=blocking) @@ -3410,7 +3423,7 @@ async def set_clipboard_all( with tempfile.NamedTemporaryFile(prefix='ahk-python', suffix='.clip', mode='wb', delete=False) as f: f.write(contents) - args = [f'*c {f.name}'] + args = [f'*c {f.name}' if self._transport._version != 'v2' else f.name] try: resp = await self._transport.function_call('AHKSetClipboardAll', args, blocking=blocking) return resp @@ -3510,6 +3523,8 @@ async def reg_write( args.append('') if value is not None: args.append(value) + else: + args.append('') return await self._transport.function_call('AHKRegWrite', args, blocking=blocking) # fmt: off @@ -3531,6 +3546,8 @@ async def reg_read( args = [key_name] if value_name is not None: args.append(value_name) + else: + args.append('') return await self._transport.function_call('AHKRegRead', args, blocking=blocking) # fmt: off diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 8aab54d..3e1c6ec 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -299,14 +299,17 @@ class AhkExecutableNotFoundError(EnvironmentError): pass -def _resolve_executable_path(executable_path: str = '') -> str: +def _resolve_executable_path(executable_path: str = '', version: Optional[Literal['v1', 'v2']] = None) -> str: if not executable_path: executable_path = ( os.environ.get('AHK_PATH', '') + or (which('AutoHotkeyV2.exe') if version == 'v2' else '') + or (which('AutoHotkey32.exe') if version == 'v2' else '') + or (which('AutoHotkey64.exe') if version == 'v2' else '') or which('AutoHotkey.exe') - or which('AutoHotkeyU64.exe') - or which('AutoHotkeyU32.exe') - or which('AutoHotkeyA32.exe') + or (which('AutoHotkeyU64.exe') if version != 'v2' else '') + or (which('AutoHotkeyU32.exe') if version != 'v2' else '') + or (which('AutoHotkeyA32.exe') if version != 'v2' else '') or '' ) @@ -347,11 +350,13 @@ def __init__( /, executable_path: str = '', directives: Optional[list[Union[Directive, Type[Directive]]]] = None, + version: Optional[Literal['v1', 'v2']] = None, **kwargs: Any, ): - self._executable_path: str = _resolve_executable_path(executable_path=executable_path) + self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives) self._directives: list[Union[Directive, Type[Directive]]] = directives or [] + self._version: Literal['v1', 'v2'] = version or 'v1' def on_clipboard_change( self, callback: Callable[[int], Any], ex_handler: Optional[Callable[[int, Exception], Any]] = None @@ -665,6 +670,7 @@ def __init__( jinja_loader: Optional[jinja2.BaseLoader] = None, template: Optional[jinja2.Template] = None, extensions: list[Extension] | None = None, + version: Optional[Literal['v1', 'v2']] = None, ): self._extensions = extensions or [] self._proc: Optional[AsyncAHKProcess] @@ -674,6 +680,16 @@ def __init__( self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() self._a_execution_lock = asyncio.Lock() # unasync: remove + + if version is None or version == 'v1': + template_name = 'daemon.ahk' + const_script = _DAEMON_SCRIPT_TEMPLATE + elif version == 'v2': + template_name = 'daemon-v2.ahk' + const_script = '' # TODO: set v2 constant + else: + raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') + if jinja_loader is None: try: loader: jinja2.BaseLoader @@ -689,10 +705,10 @@ def __init__( else: self._jinja_env = jinja2.Environment(loader=jinja_loader, trim_blocks=True, autoescape=False) try: - self.__template = self._jinja_env.get_template('daemon.ahk') + self.__template = self._jinja_env.get_template(template_name) except jinja2.TemplateNotFound: warnings.warn('daemon template missing. Falling back to constant', category=UserWarning) - self.__template = self._jinja_env.from_string(_DAEMON_SCRIPT_TEMPLATE) + self.__template = self._jinja_env.from_string(const_script) if template is None: template = self.__template self._template: jinja2.Template = template @@ -700,7 +716,7 @@ def __init__( if extensions: includes = _resolve_includes(extensions) directives = includes + directives - super().__init__(executable_path=executable_path, directives=directives) + super().__init__(executable_path=executable_path, directives=directives, version=version) @property def template(self) -> jinja2.Template: @@ -730,6 +746,7 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A message_types=message_types, message_registry=_message_registry, extensions=self._extensions, + ahk_version=self._version, **kwargs, ) diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 2240106..4858e43 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -139,6 +139,7 @@ def __init__( directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, + version: Optional[Literal['v1', 'v2']] = None, ): self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] @@ -152,7 +153,9 @@ def __init__( if TransportClass is None: TransportClass = DaemonProcessTransport assert TransportClass is not None - transport = TransportClass(executable_path=executable_path, directives=directives, extensions=self._extensions) + transport = TransportClass( + executable_path=executable_path, directives=directives, extensions=self._extensions, version=version + ) self._transport: Transport = transport def __getattr__(self, name: str) -> Callable[..., Any]: @@ -744,6 +747,8 @@ def mouse_move( args = [str(x), str(y), str(speed)] if relative: args.append('R') + else: + args.append('') resp = self._transport.function_call('AHKMouseMove', args, blocking=blocking) return resp @@ -1302,7 +1307,7 @@ def show_traytip( self, title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, @@ -1312,6 +1317,14 @@ def show_traytip( """ Analog for `TrayTip `_ """ + if second is None: + second = 1.0 + else: + if self._transport._version == 'v2': + warnings.warn( + 'supplying seconds is not supported when using AutoHotkey v2. This parameter will be ignored' + ) + option = type_id + (16 if silent else 0) + (32 if large_icon else 0) args = [title, text, str(second), str(option)] return self._transport.function_call('AHKTrayTip', args, blocking=blocking) @@ -3398,7 +3411,7 @@ def set_clipboard_all( with tempfile.NamedTemporaryFile(prefix='ahk-python', suffix='.clip', mode='wb', delete=False) as f: f.write(contents) - args = [f'*c {f.name}'] + args = [f'*c {f.name}' if self._transport._version != 'v2' else f.name] try: resp = self._transport.function_call('AHKSetClipboardAll', args, blocking=blocking) return resp @@ -3498,6 +3511,8 @@ def reg_write( args.append('') if value is not None: args.append(value) + else: + args.append('') return self._transport.function_call('AHKRegWrite', args, blocking=blocking) # fmt: off @@ -3519,6 +3534,8 @@ def reg_read( args = [key_name] if value_name is not None: args.append(value_name) + else: + args.append('') return self._transport.function_call('AHKRegRead', args, blocking=blocking) # fmt: off diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index a15b81c..e94db02 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -280,14 +280,17 @@ class AhkExecutableNotFoundError(EnvironmentError): pass -def _resolve_executable_path(executable_path: str = '') -> str: +def _resolve_executable_path(executable_path: str = '', version: Optional[Literal['v1', 'v2']] = None) -> str: if not executable_path: executable_path = ( os.environ.get('AHK_PATH', '') + or (which('AutoHotkeyV2.exe') if version == 'v2' else '') + or (which('AutoHotkey32.exe') if version == 'v2' else '') + or (which('AutoHotkey64.exe') if version == 'v2' else '') or which('AutoHotkey.exe') - or which('AutoHotkeyU64.exe') - or which('AutoHotkeyU32.exe') - or which('AutoHotkeyA32.exe') + or (which('AutoHotkeyU64.exe') if version != 'v2' else '') + or (which('AutoHotkeyU32.exe') if version != 'v2' else '') + or (which('AutoHotkeyA32.exe') if version != 'v2' else '') or '' ) @@ -328,11 +331,13 @@ def __init__( /, executable_path: str = '', directives: Optional[list[Union[Directive, Type[Directive]]]] = None, + version: Optional[Literal['v1', 'v2']] = None, **kwargs: Any, ): - self._executable_path: str = _resolve_executable_path(executable_path=executable_path) + self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives) self._directives: list[Union[Directive, Type[Directive]]] = directives or [] + self._version: Literal['v1', 'v2'] = version or 'v1' def on_clipboard_change( self, callback: Callable[[int], Any], ex_handler: Optional[Callable[[int, Exception], Any]] = None @@ -639,6 +644,7 @@ def __init__( jinja_loader: Optional[jinja2.BaseLoader] = None, template: Optional[jinja2.Template] = None, extensions: list[Extension] | None = None, + version: Optional[Literal['v1', 'v2']] = None, ): self._extensions = extensions or [] self._proc: Optional[SyncAHKProcess] @@ -647,6 +653,16 @@ def __init__( self.__template: jinja2.Template self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() + + if version is None or version == 'v1': + template_name = 'daemon.ahk' + const_script = _DAEMON_SCRIPT_TEMPLATE + elif version == 'v2': + template_name = 'daemon-v2.ahk' + const_script = '' # TODO: set v2 constant + else: + raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') + if jinja_loader is None: try: loader: jinja2.BaseLoader @@ -662,10 +678,10 @@ def __init__( else: self._jinja_env = jinja2.Environment(loader=jinja_loader, trim_blocks=True, autoescape=False) try: - self.__template = self._jinja_env.get_template('daemon.ahk') + self.__template = self._jinja_env.get_template(template_name) except jinja2.TemplateNotFound: warnings.warn('daemon template missing. Falling back to constant', category=UserWarning) - self.__template = self._jinja_env.from_string(_DAEMON_SCRIPT_TEMPLATE) + self.__template = self._jinja_env.from_string(const_script) if template is None: template = self.__template self._template: jinja2.Template = template @@ -673,7 +689,7 @@ def __init__( if extensions: includes = _resolve_includes(extensions) directives = includes + directives - super().__init__(executable_path=executable_path, directives=directives) + super().__init__(executable_path=executable_path, directives=directives, version=version) @property def template(self) -> jinja2.Template: @@ -703,6 +719,7 @@ def _render_script(self, template: Optional[jinja2.Template] = None, **kwargs: A message_types=message_types, message_registry=_message_registry, extensions=self._extensions, + ahk_version=self._version, **kwargs, ) diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk new file mode 100644 index 0000000..f3bb0d4 --- /dev/null +++ b/ahk/templates/daemon-v2.ahk @@ -0,0 +1,2840 @@ +{% block daemon_script %} +{% block directives %} +;#NoEnv +;#Persistent +#Warn All, Off +#SingleInstance Off +; BEGIN user-defined directives +{% block user_directives %} +{% for directive in directives %} +{{ directive }} + +{% endfor %} + +; END user-defined directives +{% endblock user_directives %} +{% endblock directives %} + +Critical 100 + + +{% block message_types %} +MESSAGE_TYPES := Map({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) +{% endblock message_types %} + +NOVALUE_SENTINEL := Chr(57344) + +StrCount(haystack, needle) { + StrReplace(haystack, needle, "",, &count) + return count +} + +FormatResponse(MessageType, payload) { + global MESSAGE_TYPES + newline_count := StrCount(payload, "`n") + response := Format("{}`n{}`n{}`n", MESSAGE_TYPES[MessageType], newline_count, payload) + return response +} + +FormatNoValueResponse() { + global NOVALUE_SENTINEL + return FormatResponse("ahk.message.NoValueResponseMessage", NOVALUE_SENTINEL) +} + +FormatBinaryResponse(bin) { + b64 := b64encode(bin) + return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) +} + +AHKSetDetectHiddenWindows(command) { + {% block AHKSetDetectHiddenWindows %} + value := command[2] + DetectHiddenWindows(value) + return FormatNoValueResponse() + {% endblock AHKSetDetectHiddenWindows %} +} + +AHKSetTitleMatchMode(command) { + {% block AHKSetTitleMatchMode %} + val1 := command[2] + val2 := command[3] + if (val1 != "") { + SetTitleMatchMode(val1) + } + if (val2 != "") { + SetTitleMatchMode(val2) + } + return FormatNoValueResponse() + {% endblock AHKSetTitleMatchMode %} +} + +AHKGetTitleMatchMode(command) { + {% block AHKGetTitleMatchMode %} + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) + {% endblock AHKGetTitleMatchMode %} +} + +AHKGetTitleMatchSpeed(command) { + {% block AHKGetTitleMatchSpeed %} + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) + {% endblock AHKGetTitleMatchSpeed %} +} + +AHKSetSendLevel(command) { + {% block AHKSetSendLevel %} + level := command[2] + SendLevel(level) + return FormatNoValueResponse() + {% endblock AHKSetSendLevel %} +} + +AHKGetSendLevel(command) { + {% block AHKGetSendLevel %} + + return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) + {% endblock AHKGetSendLevel %} +} + +AHKWinExist(command) { + {% block AHKWinExist %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + if WinExist(title, text, extitle, extext) { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } else { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinExist %} +} + +AHKWinClose(command) { + {% block AHKWinClose %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + secondstowait := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinClose(title, text, secondstowait, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinClose %} +} + +AHKWinKill(command) { + {% block AHKWinKill %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + secondstowait := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinKill(title, text, secondstowait, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinKill %} +} + +AHKWinWait(command) { + {% block AHKWinWait %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + if (timeout != "") { + WinWait(title, text, timeout, extitle, extext) + } else { + WinWait(title, text,, extitle, extext) + } + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + output := WinGetId() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinWait %} +} + +AHKWinWaitActive(command) { + {% block AHKWinWaitActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + if (timeout != "") { + WinWaitActive(title, text, timeout, extitle, extext) + } else { + WinWaitActive(title, text,, extitle, extext) + } + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinWaitActive %} +} + +AHKWinWaitNotActive(command) { + {% block AHKWinWaitNotActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + if (timeout != "") { + WinWaitNotActive(title, text, timeout, extitle, extext) + } else { + WinWaitNotActive(title, text,, extitle, extext) + } + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinWaitNotActive %} +} + +AHKWinWaitClose(command) { + {% block AHKWinWaitClose %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + if (timeout != "") { + WinWaitClose(title, text, timeout, extitle, extext) + } else { + WinWaitClose(title, text,, extitle, extext) + } + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + resp := FormatNoValueResponse() + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinWaitClose %} +} + +AHKWinMinimize(command) { + {% block AHKWinMinimize %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMinimize(title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinMinimize %} +} + +AHKWinMaximize(command) { + {% block AHKWinMaximize %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMaximize(title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinMaximize %} +} + +AHKWinRestore(command) { + {% block AHKWinRestore %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinRestore(title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinRestore %} +} + +AHKWinIsActive(command) { + {% block AHKWinIsActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + if WinActive(title, text, extitle, extext) { + response := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } else { + response := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinIsActive %} +} + +AHKWinGetID(command) { + {% block AHKWinGetID %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetID %} +} + +AHKWinGetTitle(command) { + {% block AHKWinGetTitle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + text := WinGetTitle(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatResponse("ahk.message.StringResponseMessage", text) + {% endblock AHKWinGetTitle %} +} + +AHKWinGetIDLast(command) { + {% block AHKWinGetIDLast %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetIDLast(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetIDLast %} +} + +AHKWinGetPID(command) { + {% block AHKWinGetPID %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetPID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetPID %} +} + +AHKWinGetProcessName(command) { + {% block AHKWinGetProcessName %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetProcessName(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetProcessName %} +} + +AHKWinGetProcessPath(command) { + {% block AHKWinGetProcessPath %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetProcessPath(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetProcessPath %} +} + +AHKWinGetCount(command) { + {% block AHKWinGetCount %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetCount(title, text, extitle, extext) + if (output = 0) { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetCount %} +} + +AHKWinGetMinMax(command) { + {% block AHKWinGetMinMax %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetMinMax(title, text, extitle, extext) + if (output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetMinMax %} +} + +AHKWinGetControlList(command) { + {% block AHKWinGetControlList %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + ahkid := WinGetID(title, text, extitle, extext) + + if (ahkid = "") { + return FormatNoValueResponse() + } + + ctrList := WinGetControls(title, text, extitle, extext) + ctrListID := WinGetControlsHwnd(title, text, extitle, extext) + + if (ctrListID = "") { + return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) + } + + ctrListArr := StrSplit(ctrList, "`n") + ctrListIDArr := StrSplit(ctrListID, "`n") + if (ctrListArr.Length() != ctrListIDArr.Length()) { + return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") + } + + output := Format("('{}', [", ahkid) + + for index, hwnd in ctrListIDArr { + classname := ctrListArr[index] + output .= Format("('{}', '{}'), ", hwnd, classname) + + } + output .= "])" + response := FormatResponse("ahk.message.WindowControlListResponseMessage", output) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetControlList %} +} + +AHKWinGetTransparent(command) { + {% block AHKWinGetTransparent %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetTransparent(title, text, extitle, extext) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetTransparent %} +} +AHKWinGetTransColor(command) { + {% block AHKWinGetTransColor %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetTransColor(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetTransColor %} +} +AHKWinGetStyle(command) { + {% block AHKWinGetStyle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetStyle %} +} +AHKWinGetExStyle(command) { + {% block AHKWinGetExStyle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetExStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetExStyle %} +} + +AHKWinGetText(command) { + {% block AHKWinGetText %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetText(title,text,extitle,extext) + + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window text") + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetText %} +} + +AHKWinSetTitle(command) { + {% block AHKWinSetTitle %} + new_title := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + WinSetTitle(title, text, new_title, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetTitle %} +} + +AHKWinSetAlwaysOnTop(command) { + {% block AHKWinSetAlwaysOnTop %} + toggle := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetAlwaysOnTop(toggle, title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetAlwaysOnTop %} +} + +AHKWinSetBottom(command) { + {% block AHKWinSetBottom %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMoveBottom(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetBottom %} +} + +AHKWinShow(command) { + {% block AHKWinShow %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinShow(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinShow %} +} + +AHKWinHide(command) { + {% block AHKWinHide %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinHide(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinHide %} +} + +AHKWinSetTop(command) { + {% block AHKWinSetTop %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMoveTop(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetTop %} +} + +AHKWinSetEnable(command) { + {% block AHKWinSetEnable %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetEnabled(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetEnable %} +} + +AHKWinSetDisable(command) { + {% block AHKWinSetDisable %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetDisabled(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetDisable %} +} + +AHKWinSetRedraw(command) { + {% block AHKWinSetRedraw %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinRedraw(title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetRedraw %} +} + +AHKWinSetStyle(command) { + {% block AHKWinSetStyle %} + + style := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetStyle(style, title, text, extitle, extext) +; if (ErrorLevel = 1) { +; resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) +; } else { +; resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) +; } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return resp + {% endblock AHKWinSetStyle %} +} + +AHKWinSetExStyle(command) { + {% block AHKWinSetExStyle %} + + style := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetExStyle(style, title, text, extitle, extext) + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } else { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return resp + {% endblock AHKWinSetExStyle %} +} + +AHKWinSetRegion(command) { + {% block AHKWinSetRegion %} + + options := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetRegion(options, title, text, extitle, extext) + if (ErrorLevel = 1) { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } else { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return resp + {% endblock AHKWinSetRegion %} +} + +AHKWinSetTransparent(command) { + {% block AHKWinSetTransparent %} + + transparency := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetTransparent(transparency, title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKWinSetTransparent %} +} + +AHKWinSetTransColor(command) { + {% block AHKWinSetTransColor %} + + color := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinSetTransColor(color, title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinSetTransColor %} +} + +AHKImageSearch(command) { + {% block AHKImageSearch %} + + imagepath := command[6] + x1 := command[2] + y1 := command[3] + x2 := command[4] + y2 := command[5] + coord_mode := command[7] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + + if (x2 = "A_ScreenWidth") { + x2 := A_ScreenWidth + } + if (y2 = "A_ScreenHeight") { + y2 := A_ScreenHeight + } + + ImageSearch(xpos, ypos, x1, y1, x2, y2, imagepath) + + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + + if (ErrorLevel = 2) { + s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") + } else if (ErrorLevel = 1) { + s := FormatNoValueResponse() + } else { + s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) + } + + return s + {% endblock AHKImageSearch %} +} + +AHKPixelGetColor(command) { + {% block AHKPixelGetColor %} + + x := command[2] + y := command[3] + coord_mode := command[4] + options := command[5] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + + color := PixelGetColor(x, y, options) + ; TODO: check errorlevel + + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + + return FormatResponse("ahk.message.StringResponseMessage", color) + {% endblock AHKPixelGetColor %} +} + +AHKPixelSearch(command) { + {% block AHKPixelSearch %} + + x1 := command[2] + y1 := command[3] + x2 := command[4] + y2 := command[5] + color := command[6] + variation := command[7] + options := command[8] + coord_mode := command[9] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + + PixelSearch(resultx, resulty, x1, y1, x2, y2, color, variation) + + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + + if (ErrorLevel = 1) { + return FormatNoValueResponse() + } else if (ErrorLevel = 0) { + payload := Format("({}, {})", resultx, resulty) + return FormatResponse("ahk.message.CoordinateResponseMessage", payload) + } else if (ErrorLevel = 2) { + return FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem conducting the pixel search (ErrorLevel 2)") + } else { + return FormatResponse("ahk.message.ExceptionResponseMessage", "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") + } + + {% endblock AHKPixelSearch %} +} + +AHKMouseGetPos(command) { + {% block AHKMouseGetPos %} + + coord_mode := command[2] + current_coord_mode := Format("{}", A_CoordModeMouse) + if (coord_mode != "") { + CoordMode(Mouse, coord_mode) + } + MouseGetPos(&xpos, &ypos) + + payload := Format("({}, {})", xpos, ypos) + resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) + + if (coord_mode != "") { + CoordMode(Mouse, current_coord_mode) + } + + return resp + {% endblock AHKMouseGetPos %} +} + +AHKKeyState(command) { + {% block AHKKeyState %} + + keyname := command[2] + mode := command[3] + if (mode != "") { + state := GetKeyState(keyname, mode) + } else{ + state := GetKeyState(keyname) + } + + if (state = "") { + return FormatNoValueResponse() + } + + if state is integer + return FormatResponse("ahk.message.IntegerResponseMessage", state) + + if state is float + return FormatResponse("ahk.message.FloatResponseMessage", state) + + if state is alnum + return FormatResponse("ahk.message.StringResponseMessage", state) + + return FormatResponse("ahk.message.ExceptionResponseMessage", state) + {% endblock AHKKeyState %} +} + +AHKMouseMove(command) { + {% block AHKMouseMove %} + x := command[2] + y := command[3] + speed := command[4] + relative := command[5] + if (relative != "") { + MouseMove(x, y, speed, "R") + } else { + MouseMove(x, y, speed) + } + resp := FormatNoValueResponse() + return resp + {% endblock AHKMouseMove %} +} + +AHKClick(command) { + {% block AHKClick %} + x := command[2] + y := command[3] + button := command[4] + click_count := command[5] + direction := command[6] + r := command[7] + relative_to := command[8] + current_coord_rel := Format("{}", A_CoordModeMouse) + + if (relative_to != "") { + CoordMode(Mouse, relative_to) + } + + Click(x, y, button, direction, r) + + if (relative_to != "") { + CoordMode(Mouse, current_coord_rel) + } + + return FormatNoValueResponse() + + {% endblock AHKClick %} +} + +AHKGetCoordMode(command) { + {% block AHKGetCoordMode %} + + target := command[2] + + if (target = "ToolTip") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) + } + if (target = "Pixel") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModePixel) + } + if (target = "Mouse") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMouse) + } + if (target = "Caret") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeCaret) + } + if (target = "Menu") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMenu) + } + return FormatResponse("ahk.message.ExceptionResponseMessage", "Invalid coord mode") + {% endblock AHKGetCoordMode %} +} + +AHKSetCoordMode(command) { + {% block AHKSetCoordMode %} + target := command[2] + relative_to := command[3] + CoordMode(target, relative_to) + + return FormatNoValueResponse() + {% endblock AHKSetCoordMode %} +} + +AHKMouseClickDrag(command) { + {% block AHKMouseClickDrag %} + button := command[2] + x1 := command[3] + y1 := command[4] + x2 := command[5] + y2 := command[6] + speed := command[7] + relative := command[8] + relative_to := command[9] + + current_coord_rel := Format("{}", A_CoordModeMouse) + + if (relative_to != "") { + CoordMode(Mouse, relative_to) + } + + MouseClickDrag(button, x1, y1, x2, y2, speed, relative) + + if (relative_to != "") { + CoordMode(Mouse, current_coord_rel) + } + + return FormatNoValueResponse() + + {% endblock AHKMouseClickDrag %} +} + +AHKRegRead(command) { + {% block RegRead %} + + key_name := command[2] + value_name := command[3] + + output := RegRead(key_name, value_name) + resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) + return resp + {% endblock RegRead %} +} + +AHKRegWrite(command) { + {% block RegWrite %} + value_type := command[2] + key_name := command[3] + value_name := command[4] + value := command[5] +; RegWrite(value_type, key_name, value_name, value) + if (value_name != "") { + RegWrite(value, value_type, key_name) + } else { + RegWrite(value, value_type, key_name, value_name) + } + return FormatNoValueResponse() + {% endblock RegWrite %} +} + +AHKRegDelete(command) { + {% block RegDelete %} + + key_name := command[2] + value_name := command[3] + if (value_name != "") { + RegDelete(key_name, value_name) + } else { + RegDelete(key_name) + } + return FormatNoValueResponse() + + {% endblock RegDelete %} +} + +AHKKeyWait(command) { + {% block AHKKeyWait %} + + keyname := command[2] + if (command.Length() = 2) { + KeyWait(keyname) + } else { + options := command[3] + KeyWait(keyname, options) + } + return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) + {% endblock AHKKeyWait %} +} + +;SetKeyDelay(command) { +; {% block SetKeyDelay %} +; SetKeyDelay(command[2], command[3]) +; {% endblock SetKeyDelay %} +;} + +AHKSend(command) { + {% block AHKSend %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + Send(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSend %} +} + +AHKSendRaw(command) { + {% block AHKSendRaw %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendRaw(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendRaw %} +} + +AHKSendInput(command) { + {% block AHKSendInput %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendInput(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendInput %} +} + +AHKSendEvent(command) { + {% block AHKSendEvent %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendEvent(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendEvent %} +} + +AHKSendPlay(command) { + {% block AHKSendPlay %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelayPlay) + current_key_duration := Format("{}", A_KeyDurationPlay) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration, Play) + } + + SendPlay(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendPlay %} +} + +AHKSetCapsLockState(command) { + {% block AHKSetCapsLockState %} + state := command[2] + if (state = "") { + SetCapsLockState(!GetKeyState("CapsLock", "T")) + } else { + SetCapsLockState(state) + } + return FormatNoValueResponse() + {% endblock AHKSetCapsLockState %} +} + +HideTrayTip(command) { + {% block HideTrayTip %} + TrayTip ; Attempt to hide it the normal way. + if SubStr(A_OSVersion,1,3) = "10." { + Menu Tray, NoIcon + Sleep 200 ; It may be necessary to adjust this sleep. + Menu Tray, Icon + } + {% endblock HideTrayTip %} +} + +AHKWinGetClass(command) { + {% block AHKWinGetClass %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + output := WinGetClass(title,text,extitle,extext) + + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window class") + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return response + {% endblock AHKWinGetClass %} +} + +AHKWinActivate(command) { + {% block AHKWinActivate %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinActivate(title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinActivate %} +} + +AHKWindowList(command) { + {% block AHKWindowList %} + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + if (detect_hw) { + DetectHiddenWindows(detect_hw) + } + + windows := WinGetList(title, text, extitle, extext) + r := "" + for id in windows + { + r .= id . "`," + } + resp := FormatResponse("ahk.message.WindowListResponseMessage", r) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return resp + {% endblock AHKWindowList %} +} + +AHKControlClick(command) { + {% block AHKControlClick %} + + ctrl := command[2] + title := command[3] + text := command[4] + button := command[5] + click_count := command[6] + options := command[7] + exclude_title := command[8] + exclude_text := command[9] + detect_hw := command[10] + match_mode := command[11] + match_speed := command[12] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + ControlClick(ctrl, title, text, button, click_count, options, exclude_title, exclude_text) + + if (ErrorLevel != 0) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "Failed to click control") + } else { + response := FormatNoValueResponse() + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return response + {% endblock AHKControlClick %} +} + +AHKControlGetText(command) { + {% block AHKControlGetText %} + + ctrl := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + result := ControlGetText(ctrl, title, text, extitle, extext) + + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") + } else { + response := FormatResponse("ahk.message.StringResponseMessage", result) + } + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return response + {% endblock AHKControlGetText %} +} + +AHKControlGetPos(command) { + {% block AHKControlGetPos %} + + ctrl := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + ControlGetPos(x, y, w, h, ctrl, title, text, extitle, extext) + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") + } else { + result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) + response := FormatResponse("ahk.message.PositionResponseMessage", result) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return response + + {% endblock AHKControlGetPos %} +} + +AHKControlSend(command) { + {% block AHKControlSend %} + ctrl := command[2] + keys := command[3] + title := command[4] + text := command[5] + extitle := command[6] + extext := command[7] + detect_hw := command[8] + match_mode := command[9] + match_speed := command[10] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + ControlSend(ctrl, keys, title, text, extitle, extext) + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + return FormatNoValueResponse() + {% endblock AHKControlSend %} +} + +AHKWinFromMouse(command) { + {% block AHKWinFromMouse %} + + MouseGetPos(,, MouseWin) + + if (MouseWin = "") { + return FormatNoValueResponse() + } + + return FormatResponse("ahk.message.WindowResponseMessage", MouseWin) + {% endblock AHKWinFromMouse %} +} + +AHKWinIsAlwaysOnTop(command) { + {% block AHKWinIsAlwaysOnTop %} + + title := command[2] + WinGet(ExStyle, ExStyle, title) + if (ExStyle = "") + return FormatNoValueResponse() + + if (ExStyle & 0x8) ; 0x8 is WS_EX_TOPMOST. + return FormatResponse("ahk.message.BooleanResponseMessage", 1) + else + return FormatResponse("ahk.message.BooleanResponseMessage", 0) + {% endblock AHKWinIsAlwaysOnTop %} +} + +AHKWinMove(command) { + {% block AHKWinMove %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + x := command[9] + y := command[10] + width := command[11] + height := command[12] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMove(title, text, x, y, width, height, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + + {% endblock AHKWinMove %} +} + +AHKWinGetPos(command) { + {% block AHKWinGetPos %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinGetPos(x, y, w, h, title, text, extitle, extext) + + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") + } else { + result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) + response := FormatResponse("ahk.message.PositionResponseMessage", result) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return response + {% endblock AHKWinGetPos %} +} + +AHKGetVolume(command) { + {% block AHKGetVolume %} + + device_number := command[2] + + try { + SoundGetWaveVolume(retval, device_number) + } catch as e { + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) + return response + } + if (ErrorLevel = 1) { + response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {}", device_number)) + } else { + response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) + } + return response + {% endblock AHKGetVolume %} +} + +AHKSoundBeep(command) { + {% block AHKSoundBeep %} + freq := command[2] + duration := command[3] + SoundBeep(freq, duration) + return FormatNoValueResponse() + {% endblock AHKSoundBeep %} +} + +AHKSoundGet(command) { + {% block AHKSoundGet %} + + device_number := command[2] + component_type := command[3] + control_type := command[4] + + SoundGet(retval, component_type, control_type, device_number) + ; TODO interpret return type + return FormatResponse("ahk.message.StringResponseMessage", Format("{}", retval)) + {% endblock AHKSoundGet %} +} + +AHKSoundSet(command) { + {% block AHKSoundSet %} + device_number := command[2] + component_type := command[3] + control_type := command[4] + value := command[5] + SoundSet(value, component_type, control_type, device_number) + return FormatNoValueResponse() + {% endblock AHKSoundSet %} +} + +AHKSoundPlay(command) { + {% block AHKSoundPlay %} + filename := command[2] + SoundPlay(filename) + return FormatNoValueResponse() + {% endblock AHKSoundPlay %} +} + +AHKSetVolume(command) { + {% block AHKSetVolume %} + device_number := command[2] + value := command[3] + SoundSetWaveVolume(value, device_number) + return FormatNoValueResponse() + {% endblock AHKSetVolume %} +} + + +AHKEcho(command) { + {% block AHKEcho %} + arg := command[2] + return FormatResponse("ahk.message.StringResponseMessage", arg) + {% endblock AHKEcho %} +} + +AHKTraytip(command) { + {% block AHKTraytip %} + title := command[2] + text := command[3] + second := command[4] + option := command[5] + + TrayTip(title, text, option) + return FormatNoValueResponse() + {% endblock AHKTraytip %} +} + +AHKShowToolTip(command) { + {% block AHKShowToolTip %} + text := command[2] + x := command[3] + y := command[4] + which := command[5] + ToolTip(text, x, y, which) + return FormatNoValueResponse() + {% endblock AHKShowToolTip %} +} + +AHKGetClipboard(command) { + {% block AHKGetClipboard %} + + return FormatResponse("ahk.message.StringResponseMessage", A_Clipboard) + {% endblock AHKGetClipboard %} +} + +AHKGetClipboardAll(command) { + {% block AHKGetClipboardAll %} + data := ClipboardAll() + return FormatBinaryResponse(data) + {% endblock AHKGetClipboardAll %} +} + +AHKSetClipboard(command) { + {% block AHKSetClipboard %} + text := command[2] + A_Clipboard := text + return FormatNoValueResponse() + {% endblock AHKSetClipboard %} +} + +AHKSetClipboardAll(command) { + {% block AHKSetClipboardAll %} + ; TODO there should be a way for us to accept a base64 string instead + filename := command[2] + contents := FileRead(filename, "RAW") + ClipboardAll(contents) + return FormatNoValueResponse() + {% endblock AHKSetClipboardAll %} +} + +AHKClipWait(command) { + + timeout := command[2] + wait_for_any_data := command[3] + + ClipWait(timeout, wait_for_any_data) + + if (ErrorLevel = 1) { + return FormatResponse("ahk.message.TimeoutResponseMessage", "timed out waiting for clipboard data") + } + return FormatNoValueResponse() +} + +AHKBlockInput(command) { + value := command[2] + BlockInput(value) + return FormatNoValueResponse() +} + +AHKMenuTrayTip(command) { + value := command[2] + Menu(Tray, Tip, value) + return FormatNoValueResponse() +} + +AHKMenuTrayShow(command) { + Menu(Tray, Icon) + return FormatNoValueResponse() +} + +AHKMenuTrayIcon(command) { + filename := command[2] + icon_number := command[3] + freeze := command[4] + Menu(Tray, Icon, filename, icon_number,freeze) + return FormatNoValueResponse() +} + +AHKGuiNew(command) { + + options := command[2] + title := command[3] + Gui(New, options, title) + return FormatResponse("ahk.message.StringResponseMessage", hwnd) +} + +AHKMsgBox(command) { + + options := command[2] + title := command[3] + text := command[4] + timeout := command[5] + if (timeout != "") { + options := "" options " T" timeout + } + res := MsgBox(text, title, options) + if (res = "Timeout") { + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "MsgBox timed out") + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", res) + } + return ret +} + +AHKInputBox(command) { + + title := command[2] + prompt := command[3] + hide := command[4] + width := command[5] + height := command[6] + x := command[7] + y := command[8] + locale := command[9] + timeout := command[10] + default := command[11] + + ; TODO: support options correctly + options := "" + if (timeout != "") { + options .= "T" timeout + } + output := InputBox(prompt, title, options, default) + if (output.Result = "Timeout") { + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "Input box timed out") + } else if (output.Result = "Cancel") { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output.Value) + } + return ret +} + +AHKFileSelectFile(command) { + + options := command[2] + root := command[3] + title := command[4] + filter := command[5] + output := FileSelectFile(options, root, title, filter) + if (ErrorLevel = 1) { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output) + } + return ret +} + +AHKFileSelectFolder(command) { + + starting_folder := command[2] + options := command[3] + prompt := command[4] + + output := FileSelectFolder(starting_folder, options, prompt) + + if (ErrorLevel = 1) { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output) + } + return ret +} + +; LC_* functions are substantially from Libcrypt +; Modified from https://github.com/ahkscript/libcrypt.ahk +; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 +; Original License: +; The MIT License (MIT) +; +; Copyright (c) 2014 The ahkscript community (ahkscript.org) +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in all +; copies or substantial portions of the Software. + + +LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") +{ + Bin_ := Buffer(StrPut(Text_, Encoding_)) + LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) + return Base64_ +} + +LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") +{ + Len_ := LC_Base64_Decode(&Bin_, &Text_) + return StrGet(StrPtr(Bin_), Len_, Encoding_) +} + +LC_Base64_Encode(&Out_, &In_, In_Len) +{ + return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) +} + +LC_Base64_Decode(&Out_, &In_) +{ + return LC_Str2Bin(&Out_, &In_, 0x1) +} + +LC_Bin2Str(&Out_, &In_, In_Len, Flags_) +{ + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) + VarSetStrCapacity(&Out_, Out_Len * 2) + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) + return Out_Len +} + +LC_Str2Bin(&Out_, &In_, Flags_) +{ + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) + VarSetStrCapacity(&Out_, Out_Len) + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) + return Out_Len +} +; End of libcrypt code + +b64decode(pszString) { + ; TODO load DLL globally for performance + ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw + ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. + ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. + ; [in] DWORD dwFlags, Indicates the format of the string to be converted. (see table in link above) + ; [in] BYTE *pbBinary, A pointer to a buffer that receives the returned sequence of bytes. If this parameter is NULL, the function calculates the length of the buffer needed and returns the size, in bytes, of required memory in the DWORD pointed to by pcbBinary. + ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. + ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. + ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. + return LC_Base64_Decode_Text(pszString) + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + buff_size := 0 ; The function will write to this variable on our first call + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size, 0) +; granted := VarSetStrCapacity(&ret, buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + + return StrGet(ret, "UTF-8") +} + +b64encode(data) { + ; REF: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa + ; [in] const BYTE *pbBinary: A pointer to the array of bytes to be converted into a string. + ; [in] DWORD cbBinary: The number of elements in the pbBinary array. + ; [in] DWORD dwFlags: Specifies the format of the resulting formatted string (see table in REF) + ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size + ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer + LC_Base64_Encode(&Base64_, &data, data.Size) + return Base64_ + cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) + if (cbBinary = 0) { + return "" + } + + dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF + + ; First step is to get the size so we can set the capacity of our return buffer correctly + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Exception(msg, -1) + } + + VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) + + ; Now we do the conversion to base64 and rteturn the string + + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Exception(msg, -1) + } + return ret +} + +; End of included content + +CommandArrayFromQuery(text) { + decoded_commands := [] + encoded_array := StrSplit(text, "|") + function_name := encoded_array[1] + encoded_array.RemoveAt(1) + decoded_commands.push(function_name) + for index, encoded_value in encoded_array { + decoded_value := b64decode(encoded_value) + decoded_commands.push(decoded_value) + } + return decoded_commands +} + +; BEGIN extension scripts +{% for ext in extensions %} +{{ ext.script_text }} + +{% endfor %} +; END extension scripts +{% block before_autoexecute %} +{% endblock before_autoexecute %} + +{% block autoexecute %} +stdin := FileOpen("*", "r `n", "UTF-8") ; Requires [v1.1.17+] +stdout := FileOpen("*", "w", "UTF-8") +pyresp := "" + +Loop { + query := RTrim(stdin.ReadLine(), "`n") + commandArray := CommandArrayFromQuery(query) + try { + func_name := commandArray[1] + {% block before_function %} + {% endblock before_function %} + pyresp := %func_name%(commandArray) + {% block after_function %} + {% endblock after_function %} + } catch Any as e { + {% block function_error_handle %} + message := Format("Error occurred in {}. The error message was: {}", e.line, e.message) + pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) + {% endblock function_error_handle %} + } + {% block send_response %} + if (pyresp) { +; MsgBox(pyresp) + stdout.Write(pyresp) + stdout.Read(0) + } else { + msg := FormatResponse("ahk.message.ExceptionResponseMessage", Format("Unknown Error when calling {}", func_name)) +; MsgBox(msg) + stdout.Write(msg) + stdout.Read(0) + } + {% endblock send_response %} +} + +{% endblock autoexecute %} +{% endblock daemon_script %} diff --git a/tests/_async/test_clipboard.py b/tests/_async/test_clipboard.py index e3d526a..516ae62 100644 --- a/tests/_async/test_clipboard.py +++ b/tests/_async/test_clipboard.py @@ -39,3 +39,8 @@ async def test_on_clipboard_change(self): await self.ahk.set_clipboard('bar') await async_sleep(1) m.assert_called() + + +class TestWindowAsyncV2(TestWindowAsync): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index 1a2b9d9..11430eb 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -17,7 +17,7 @@ function_name = 'AAHKDoSomething' # unasync: remove ext_text = f'''\ -{function_name}(ByRef command) {{ +{function_name}(command) {{ arg := command[2] return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) }} @@ -69,3 +69,19 @@ async def asyncTearDown(self) -> None: async def test_ext_no_ext(self): assert not hasattr(self.ahk, 'do_something') + + +class TestExtensionsV2(TestExtensions): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(extensions=[async_extension], version='v2') + + +class TestExtensionsAutoV2(TestExtensionsAuto): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(extensions='auto', version='v2') + + +class TestNoExtensionsV2(TestNoExtensions): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') + await self.ahk.get_mouse_position() # cause daemon to start diff --git a/tests/_async/test_gui.py b/tests/_async/test_gui.py index 259d43c..6955313 100644 --- a/tests/_async/test_gui.py +++ b/tests/_async/test_gui.py @@ -34,3 +34,8 @@ async def test_input_box(self): assert win is not None with pytest.raises(TimeoutError): r = await box.result() + + +class TestGuiV2(TestGui): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_hotkeys.py b/tests/_async/test_hotkeys.py index 804252e..462cbe9 100644 --- a/tests/_async/test_hotkeys.py +++ b/tests/_async/test_hotkeys.py @@ -67,3 +67,8 @@ async def test_clear_hotkeys(self): await self.ahk.key_press('a') await async_sleep(1) m.assert_not_called() + + +class TestHotkeysAsyncV2(TestHotkeysAsync): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_keys.py b/tests/_async/test_keys.py index 7fa44c4..d06309c 100644 --- a/tests/_async/test_keys.py +++ b/tests/_async/test_keys.py @@ -77,3 +77,13 @@ async def test_hotstring_callback(self): await self.ahk.send('btw ') await async_sleep(1) m.assert_called() + + +class TestWindowAsyncV2(TestWindowAsync): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') + self.p = subprocess.Popen('notepad') + time.sleep(1) + self.win = await self.ahk.win_get(title='Untitled - Notepad') + self.assertIsNotNone(self.win) + await self.ahk.set_capslock_state('Off') diff --git a/tests/_async/test_mouse.py b/tests/_async/test_mouse.py index da78fb8..26477e6 100644 --- a/tests/_async/test_mouse.py +++ b/tests/_async/test_mouse.py @@ -64,3 +64,8 @@ async def test_mouse_move_nonblocking(self): assert pos != current_pos assert pos != (500, 500) await res.result() + + +class TestMouseAsyncV2(TestMouseAsync): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_registry.py b/tests/_async/test_registry.py index e6f9e8e..11f8812 100644 --- a/tests/_async/test_registry.py +++ b/tests/_async/test_registry.py @@ -51,3 +51,8 @@ async def test_reg_delete_default(self): await self.ahk.reg_delete(r'HKEY_CURRENT_USER\SOFTWARE\python-ahk') with pytest.raises(AHKExecutionException): await self.ahk.reg_read(r'HKEY_CURRENT_USER\SOFTWARE\python-ahk') + + +class TestScriptsV2(TestScripts): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_screen.py b/tests/_async/test_screen.py index d59ab30..5efc408 100644 --- a/tests/_async/test_screen.py +++ b/tests/_async/test_screen.py @@ -79,3 +79,13 @@ async def test_image_search_with_option(self): # result = await self.ahk.pixel_get_color(x, y) # self.assertIsNotNone(result) # self.assertEqual(int(result, 16), 0xFF0000) + + +class TestScreenV2(TestScreen): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') + self.before_windows = await self.ahk.list_windows() + self.im = Image.new('RGB', (20, 20)) + for coord in product(range(20), range(20)): + self.im.putpixel(coord, (255, 0, 0)) + time.sleep(1) diff --git a/tests/_async/test_scripts.py b/tests/_async/test_scripts.py index cbb1d22..52dc044 100644 --- a/tests/_async/test_scripts.py +++ b/tests/_async/test_scripts.py @@ -60,3 +60,8 @@ async def test_run_script_nonblocking(self): script = 'FileAppend, foo, *, UTF-8' fut = await self.ahk.run_script(script, blocking=False) assert await fut.result() == 'foo' + + +class TestScriptsV2(TestScripts): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') diff --git a/tests/_async/test_window.py b/tests/_async/test_window.py index ade7374..0865443 100644 --- a/tests/_async/test_window.py +++ b/tests/_async/test_window.py @@ -188,3 +188,12 @@ async def test_win_move(self): async def test_win_is_active(self): await self.win.activate() assert await self.win.is_active() is True + + +class TestWindowAsyncV2(TestWindowAsync): + async def asyncSetUp(self) -> None: + self.ahk = AsyncAHK(version='v2') + self.p = subprocess.Popen('notepad') + time.sleep(1) + self.win = await self.ahk.win_get(title='Untitled - Notepad') + self.assertIsNotNone(self.win) diff --git a/tests/_sync/test_clipboard.py b/tests/_sync/test_clipboard.py index 46156e1..22ec1e8 100644 --- a/tests/_sync/test_clipboard.py +++ b/tests/_sync/test_clipboard.py @@ -38,3 +38,8 @@ def test_on_clipboard_change(self): self.ahk.set_clipboard('bar') sleep(1) m.assert_called() + + +class TestWindowAsyncV2(TestWindowAsync): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 6c011ad..e74f41f 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -15,7 +15,7 @@ function_name = 'AHKDoSomething' ext_text = f'''\ -{function_name}(ByRef command) {{ +{function_name}(command) {{ arg := command[2] return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) }} @@ -67,3 +67,19 @@ def tearDown(self) -> None: def test_ext_no_ext(self): assert not hasattr(self.ahk, 'do_something') + + +class TestExtensionsV2(TestExtensions): + def setUp(self) -> None: + self.ahk = AHK(extensions=[async_extension], version='v2') + + +class TestExtensionsAutoV2(TestExtensionsAuto): + def setUp(self) -> None: + self.ahk = AHK(extensions='auto', version='v2') + + +class TestNoExtensionsV2(TestNoExtensions): + def setUp(self) -> None: + self.ahk = AHK(version='v2') + self.ahk.get_mouse_position() # cause daemon to start diff --git a/tests/_sync/test_gui.py b/tests/_sync/test_gui.py index f5caf9b..db35d5c 100644 --- a/tests/_sync/test_gui.py +++ b/tests/_sync/test_gui.py @@ -33,3 +33,8 @@ def test_input_box(self): assert win is not None with pytest.raises(TimeoutError): r = box.result() + + +class TestGuiV2(TestGui): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_hotkeys.py b/tests/_sync/test_hotkeys.py index ec13a58..701c39d 100644 --- a/tests/_sync/test_hotkeys.py +++ b/tests/_sync/test_hotkeys.py @@ -64,3 +64,8 @@ def test_clear_hotkeys(self): self.ahk.key_press('a') sleep(1) m.assert_not_called() + + +class TestHotkeysAsyncV2(TestHotkeysAsync): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_keys.py b/tests/_sync/test_keys.py index f826940..4a18cdf 100644 --- a/tests/_sync/test_keys.py +++ b/tests/_sync/test_keys.py @@ -76,3 +76,13 @@ def test_hotstring_callback(self): self.ahk.send('btw ') sleep(1) m.assert_called() + + +class TestWindowAsyncV2(TestWindowAsync): + def setUp(self) -> None: + self.ahk = AHK(version='v2') + self.p = subprocess.Popen('notepad') + time.sleep(1) + self.win = self.ahk.win_get(title='Untitled - Notepad') + self.assertIsNotNone(self.win) + self.ahk.set_capslock_state('Off') diff --git a/tests/_sync/test_mouse.py b/tests/_sync/test_mouse.py index 97f1faf..e5616c6 100644 --- a/tests/_sync/test_mouse.py +++ b/tests/_sync/test_mouse.py @@ -63,3 +63,8 @@ def test_mouse_move_nonblocking(self): assert pos != current_pos assert pos != (500, 500) res.result() + + +class TestMouseAsyncV2(TestMouseAsync): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_registry.py b/tests/_sync/test_registry.py index 735b0aa..c9d604f 100644 --- a/tests/_sync/test_registry.py +++ b/tests/_sync/test_registry.py @@ -51,3 +51,8 @@ def test_reg_delete_default(self): self.ahk.reg_delete(r'HKEY_CURRENT_USER\SOFTWARE\python-ahk') with pytest.raises(AHKExecutionException): self.ahk.reg_read(r'HKEY_CURRENT_USER\SOFTWARE\python-ahk') + + +class TestScriptsV2(TestScripts): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_screen.py b/tests/_sync/test_screen.py index 00ff707..fb2164e 100644 --- a/tests/_sync/test_screen.py +++ b/tests/_sync/test_screen.py @@ -79,3 +79,13 @@ def test_image_search_with_option(self): # result = await self.ahk.pixel_get_color(x, y) # self.assertIsNotNone(result) # self.assertEqual(int(result, 16), 0xFF0000) + + +class TestScreenV2(TestScreen): + def setUp(self) -> None: + self.ahk = AHK(version='v2') + self.before_windows = self.ahk.list_windows() + self.im = Image.new('RGB', (20, 20)) + for coord in product(range(20), range(20)): + self.im.putpixel(coord, (255, 0, 0)) + time.sleep(1) diff --git a/tests/_sync/test_scripts.py b/tests/_sync/test_scripts.py index ccf8758..fae4751 100644 --- a/tests/_sync/test_scripts.py +++ b/tests/_sync/test_scripts.py @@ -60,3 +60,8 @@ def test_run_script_nonblocking(self): script = 'FileAppend, foo, *, UTF-8' fut = self.ahk.run_script(script, blocking=False) assert fut.result() == 'foo' + + +class TestScriptsV2(TestScripts): + def setUp(self) -> None: + self.ahk = AHK(version='v2') diff --git a/tests/_sync/test_window.py b/tests/_sync/test_window.py index bdb5b0d..55c63b1 100644 --- a/tests/_sync/test_window.py +++ b/tests/_sync/test_window.py @@ -188,3 +188,12 @@ def test_win_move(self): def test_win_is_active(self): self.win.activate() assert self.win.is_active() is True + + +class TestWindowAsyncV2(TestWindowAsync): + def setUp(self) -> None: + self.ahk = AHK(version='v2') + self.p = subprocess.Popen('notepad') + time.sleep(1) + self.win = self.ahk.win_get(title='Untitled - Notepad') + self.assertIsNotNone(self.win) From 2d7db7a71c993d59ad8f111137ee6e496e7f2b50 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Mon, 18 Sep 2023 14:23:18 -0700 Subject: [PATCH 16/52] double timeout for double the tests --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5356b57..91e42f3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,7 +23,7 @@ jobs: python -m pip install tox python -m pip install ahk-binary - name: Test with coverage/pytest - timeout-minutes: 5 + timeout-minutes: 10 env: PYTHONUNBUFFERED: "1" run: | From 1a5f2f3690d6c4c81597c1b156bfee915cb85b24 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Mon, 18 Sep 2023 14:25:13 -0700 Subject: [PATCH 17/52] upgrade binary requirement --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 91e42f3..bf3e4ce 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,7 +21,7 @@ jobs: python -m pip install -r requirements-dev.txt python -m pip install . python -m pip install tox - python -m pip install ahk-binary + python -m pip install "ahk-binary==2023.9.0rc1" - name: Test with coverage/pytest timeout-minutes: 10 env: From dfed6627ad8974be72db890331d77e17f64b4bfe Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:10:11 -0700 Subject: [PATCH 18/52] fix v1 bug in edge case in listing window controls This bug could cause title match mode and detect hidden window settings to not be returned to original values if the lengths of `ctrList` and `ctrListID` do not match. --- ahk/_constants.py | 3 +++ ahk/templates/daemon.ahk | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ahk/_constants.py b/ahk/_constants.py index f7485eb..352b329 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -867,6 +867,9 @@ ctrListArr := StrSplit(ctrList, "`n") ctrListIDArr := StrSplit(ctrListID, "`n") if (ctrListArr.Length() != ctrListIDArr.Length()) { + DetectHiddenWindows, %current_detect_hw% + SetTitleMatchMode, %current_match_mode% + SetTitleMatchMode, %current_match_speed% return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 112a373..842cc3e 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -864,6 +864,9 @@ AHKWinGetControlList(ByRef command) { ctrListArr := StrSplit(ctrList, "`n") ctrListIDArr := StrSplit(ctrListID, "`n") if (ctrListArr.Length() != ctrListIDArr.Length()) { + DetectHiddenWindows, %current_detect_hw% + SetTitleMatchMode, %current_match_mode% + SetTitleMatchMode, %current_match_speed% return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } From bc672e95df81620ddafa3bedddae6d45b6a19258 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:10:49 -0700 Subject: [PATCH 19/52] v2 - fix uses of ErrorLevel from v1 --- ahk/templates/daemon-v2.ahk | 926 +++++++++++++++++++---------------- tests/_async/test_scripts.py | 32 ++ tests/_sync/test_scripts.py | 32 ++ 3 files changed, 564 insertions(+), 426 deletions(-) diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index f3bb0d4..96461d6 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -231,22 +231,24 @@ AHKWinWait(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - if (timeout != "") { - WinWait(title, text, timeout, extitle, extext) - } else { - WinWait(title, text,, extitle, extext) - } - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") - } else { - output := WinGetId() - resp := FormatResponse("ahk.message.WindowResponseMessage", output) + try { + if (timeout != "") { + output := WinWait(title, text, timeout, extitle, extext) + if (output = 0) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + resp := resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } else { + output := WinWait(title, text,, extitle, extext) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp {% endblock AHKWinWait %} } @@ -275,22 +277,24 @@ AHKWinWaitActive(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - if (timeout != "") { - WinWaitActive(title, text, timeout, extitle, extext) - } else { - WinWaitActive(title, text,, extitle, extext) - } - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") - } else { - output := WinGetID() - resp := FormatResponse("ahk.message.WindowResponseMessage", output) + try { + if (timeout != "") { + output := WinWaitActive(title, text, timeout, extitle, extext) + if (output = 0) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWaitActive timed out waiting for the window") + } else { + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } else { + output := WinWaitActive(title, text,, extitle, extext) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp {% endblock AHKWinWaitActive %} } @@ -319,22 +323,25 @@ AHKWinWaitNotActive(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - if (timeout != "") { - WinWaitNotActive(title, text, timeout, extitle, extext) - } else { - WinWaitNotActive(title, text,, extitle, extext) - } - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") - } else { - output := WinGetID() - resp := FormatResponse("ahk.message.WindowResponseMessage", output) + try { + if (timeout != "") { + if (WinWaitNotActive(title, text, timeout, extitle, extext) = 1) { + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } else { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } + } else { + WinWaitNotActive(title, text,, extitle, extext) + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp {% endblock AHKWinWaitNotActive %} } @@ -363,21 +370,23 @@ AHKWinWaitClose(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - if (timeout != "") { - WinWaitClose(title, text, timeout, extitle, extext) - } else { - WinWaitClose(title, text,, extitle, extext) - } - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") - } else { - resp := FormatNoValueResponse() + try { + if (timeout != "") { + if (WinWaitClose(title, text, timeout, extitle, extext) = 1) { + resp := FormatNoValueResponse() + } else { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } + } else { + WinWaitClose(title, text,, extitle, extext) + resp := FormatNoValueResponse() + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp {% endblock AHKWinWaitClose %} } @@ -405,13 +414,14 @@ AHKWinMinimize(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinMinimize(title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinMinimize(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinMinimize %} } @@ -473,13 +483,14 @@ AHKWinRestore(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinRestore(title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinRestore(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinRestore %} } @@ -494,7 +505,7 @@ AHKWinIsActive(command) { detect_hw := command[6] match_mode := command[7] match_speed := command[8] - current_match_mode := Format("{}", A_TitleMatchMode) + current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { SetTitleMatchMode(match_mode) @@ -508,15 +519,18 @@ AHKWinIsActive(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - if WinActive(title, text, extitle, extext) { - response := FormatResponse("ahk.message.BooleanResponseMessage", 1) - } else { - response := FormatResponse("ahk.message.BooleanResponseMessage", 0) + try { + if WinActive(title, text, extitle, extext) { + response := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } else { + response := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinIsActive %} } @@ -546,16 +560,19 @@ AHKWinGetID(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetID(title, text, extitle, extext) - if (output = 0 || output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.WindowResponseMessage", output) + try { + output := WinGetID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetID %} } @@ -585,12 +602,14 @@ AHKWinGetTitle(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - text := WinGetTitle(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + text := WinGetTitle(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatResponse("ahk.message.StringResponseMessage", text) {% endblock AHKWinGetTitle %} } @@ -621,15 +640,19 @@ AHKWinGetIDLast(command) { DetectHiddenWindows(detect_hw) } - output := WinGetIDLast(title, text, extitle, extext) - if (output = 0 || output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.WindowResponseMessage", output) + try { + output := WinGetIDLast(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetIDLast %} } @@ -659,16 +682,19 @@ AHKWinGetPID(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetPID(title, text, extitle, extext) - if (output = 0 || output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.IntegerResponseMessage", output) + try { + output := WinGetPID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetPID %} } @@ -699,15 +725,19 @@ AHKWinGetProcessName(command) { DetectHiddenWindows(detect_hw) } - output := WinGetProcessName(title, text, extitle, extext) - if (output = 0 || output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.StringResponseMessage", output) + try { + output := WinGetProcessName(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetProcessName %} } @@ -737,16 +767,19 @@ AHKWinGetProcessPath(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetProcessPath(title, text, extitle, extext) - if (output = 0 || output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.StringResponseMessage", output) + try { + output := WinGetProcessPath(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetProcessPath %} } @@ -777,15 +810,19 @@ AHKWinGetCount(command) { DetectHiddenWindows(detect_hw) } - output := WinGetCount(title, text, extitle, extext) - if (output = 0) { - response := FormatResponse("ahk.message.IntegerResponseMessage", output) - } else { - response := FormatResponse("ahk.message.IntegerResponseMessage", output) + try { + output := WinGetCount(title, text, extitle, extext) + if (output = 0) { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetCount %} } @@ -816,15 +853,19 @@ AHKWinGetMinMax(command) { DetectHiddenWindows(detect_hw) } - output := WinGetMinMax(title, text, extitle, extext) - if (output = "") { - response := FormatNoValueResponse() - } else { - response := FormatResponse("ahk.message.IntegerResponseMessage", output) + try { + output := WinGetMinMax(title, text, extitle, extext) + if (output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetMinMax %} } @@ -861,15 +902,21 @@ AHKWinGetControlList(command) { return FormatNoValueResponse() } - ctrList := WinGetControls(title, text, extitle, extext) - ctrListID := WinGetControlsHwnd(title, text, extitle, extext) - + try { + ctrList := WinGetControls(title, text, extitle, extext) + ctrListID := WinGetControlsHwnd(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } if (ctrListID = "") { return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) } - ctrListArr := StrSplit(ctrList, "`n") - ctrListIDArr := StrSplit(ctrListID, "`n") + ; ctrListArr := StrSplit(ctrList, "`n") + ; ctrListIDArr := StrSplit(ctrListID, "`n") if (ctrListArr.Length() != ctrListIDArr.Length()) { return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } @@ -883,9 +930,6 @@ AHKWinGetControlList(command) { } output .= "])" response := FormatResponse("ahk.message.WindowControlListResponseMessage", output) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetControlList %} } @@ -915,12 +959,15 @@ AHKWinGetTransparent(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetTransparent(title, text, extitle, extext) - response := FormatResponse("ahk.message.IntegerResponseMessage", output) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + output := WinGetTransparent(title, text, extitle, extext) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response {% endblock AHKWinGetTransparent %} } @@ -949,12 +996,15 @@ AHKWinGetTransColor(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetTransColor(title, text, extitle, extext) - response := FormatResponse("ahk.message.NoValueResponseMessage", output) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + output := WinGetTransColor(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response {% endblock AHKWinGetTransColor %} } @@ -984,14 +1034,19 @@ AHKWinGetStyle(command) { DetectHiddenWindows(detect_hw) } - output := WinGetStyle(title, text, extitle, extext) - response := FormatResponse("ahk.message.NoValueResponseMessage", output) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + output := WinGetStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response {% endblock AHKWinGetStyle %} } + AHKWinGetExStyle(command) { {% block AHKWinGetExStyle %} @@ -1017,12 +1072,15 @@ AHKWinGetExStyle(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetExStyle(title, text, extitle, extext) - response := FormatResponse("ahk.message.NoValueResponseMessage", output) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + output := WinGetExStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response {% endblock AHKWinGetExStyle %} } @@ -1052,17 +1110,16 @@ AHKWinGetText(command) { DetectHiddenWindows(detect_hw) } - output := WinGetText(title,text,extitle,extext) - - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window text") - } else { + try { + output := WinGetText(title,text,extitle,extext) response := FormatResponse("ahk.message.StringResponseMessage", output) } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetText %} } @@ -1091,10 +1148,14 @@ AHKWinSetTitle(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - WinSetTitle(title, text, new_title, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinSetTitle(title, text, new_title, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetTitle %} } @@ -1123,11 +1184,14 @@ AHKWinSetAlwaysOnTop(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetAlwaysOnTop(toggle, title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinSetAlwaysOnTop(toggle, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetAlwaysOnTop %} } @@ -1156,11 +1220,14 @@ AHKWinSetBottom(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinMoveBottom(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinMoveBottom(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetBottom %} } @@ -1189,11 +1256,14 @@ AHKWinShow(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinShow(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinShow(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinShow %} } @@ -1222,11 +1292,14 @@ AHKWinHide(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinHide(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinHide(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinHide %} } @@ -1255,11 +1328,14 @@ AHKWinSetTop(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinMoveTop(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinMoveTop(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetTop %} } @@ -1288,11 +1364,14 @@ AHKWinSetEnable(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetEnabled(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinSetEnabled(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetEnable %} } @@ -1321,11 +1400,14 @@ AHKWinSetDisable(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetDisabled(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinSetDisabled(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetDisable %} } @@ -1354,11 +1436,14 @@ AHKWinSetRedraw(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinRedraw(title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinRedraw(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetRedraw %} } @@ -1388,17 +1473,15 @@ AHKWinSetStyle(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetStyle(style, title, text, extitle, extext) -; if (ErrorLevel = 1) { -; resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) -; } else { -; resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) -; } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp + try { + WinSetStyle(style, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) {% endblock AHKWinSetStyle %} } @@ -1428,16 +1511,15 @@ AHKWinSetExStyle(command) { DetectHiddenWindows(detect_hw) } - WinSetExStyle(style, title, text, extitle, extext) - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) - } else { - resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + try { + WinSetExStyle(style, title, text, extitle, extext) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) {% endblock AHKWinSetExStyle %} } @@ -1466,17 +1548,15 @@ AHKWinSetRegion(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetRegion(options, title, text, extitle, extext) - if (ErrorLevel = 1) { - resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) - } else { - resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + try { + WinSetRegion(options, title, text, extitle, extext) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - return resp + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) {% endblock AHKWinSetRegion %} } @@ -1505,11 +1585,14 @@ AHKWinSetTransparent(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetTransparent(transparency, title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + try { + WinSetTransparent(transparency, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetTransparent %} } @@ -1539,13 +1622,14 @@ AHKWinSetTransColor(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinSetTransColor(color, title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinSetTransColor(color, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinSetTransColor %} } @@ -1573,18 +1657,16 @@ AHKImageSearch(command) { y2 := A_ScreenHeight } - ImageSearch(xpos, ypos, x1, y1, x2, y2, imagepath) - - if (coord_mode != "") { - CoordMode(Pixel, current_mode) + try { + if ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) + s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) + else + s := FormatNoValueResponse() } - - if (ErrorLevel = 2) { - s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") - } else if (ErrorLevel = 1) { - s := FormatNoValueResponse() - } else { - s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } } return s @@ -1605,11 +1687,13 @@ AHKPixelGetColor(command) { CoordMode(Pixel, coord_mode) } - color := PixelGetColor(x, y, options) - ; TODO: check errorlevel - - if (coord_mode != "") { - CoordMode(Pixel, current_mode) + try { + color := PixelGetColor(x, y, options) + } + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } } return FormatResponse("ahk.message.StringResponseMessage", color) @@ -1633,24 +1717,22 @@ AHKPixelSearch(command) { if (coord_mode != "") { CoordMode(Pixel, coord_mode) } - - PixelSearch(resultx, resulty, x1, y1, x2, y2, color, variation) - - if (coord_mode != "") { - CoordMode(Pixel, current_mode) + try { + if (PixelSearch(&resultx, &resulty, x1, y1, x2, y2, color, variation) = 1) { + payload := Format("({}, {})", resultx, resulty) + ret := FormatResponse("ahk.message.CoordinateResponseMessage", payload) + } else { + ret := FormatNoValueResponse() + } } - - if (ErrorLevel = 1) { - return FormatNoValueResponse() - } else if (ErrorLevel = 0) { - payload := Format("({}, {})", resultx, resulty) - return FormatResponse("ahk.message.CoordinateResponseMessage", payload) - } else if (ErrorLevel = 2) { - return FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem conducting the pixel search (ErrorLevel 2)") - } else { - return FormatResponse("ahk.message.ExceptionResponseMessage", "Unexpected error. This is probably a bug. Please report this at https://github.com/spyoungtech/ahk/issues") + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } } + return ret + {% endblock AHKPixelSearch %} } @@ -1690,16 +1772,17 @@ AHKKeyState(command) { return FormatNoValueResponse() } - if state is integer + if IsInteger(state) return FormatResponse("ahk.message.IntegerResponseMessage", state) - if state is float + if IsFloat(state) return FormatResponse("ahk.message.FloatResponseMessage", state) - if state is alnum + if IsAlnum(state) return FormatResponse("ahk.message.StringResponseMessage", state) - return FormatResponse("ahk.message.ExceptionResponseMessage", state) + msg := Format("Unexpected key state {}", state) + return FormatResponse("ahk.message.ExceptionResponseMessage", msg) {% endblock AHKKeyState %} } @@ -1855,12 +1938,12 @@ AHKKeyWait(command) { keyname := command[2] if (command.Length() = 2) { - KeyWait(keyname) + ret := KeyWait(keyname) } else { options := command[3] - KeyWait(keyname, options) + ret := KeyWait(keyname, options) } - return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) + return FormatResponse("ahk.message.IntegerResponseMessage", ret) {% endblock AHKKeyWait %} } @@ -1882,6 +1965,7 @@ AHKSend(command) { SetKeyDelay(key_delay, key_press_duration) } + Send(str) if (key_delay != "" or key_press_duration != "") { @@ -2022,18 +2106,16 @@ AHKWinGetClass(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - output := WinGetClass(title,text,extitle,extext) - - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was an error getting window class") - } else { + try { + output := WinGetClass(title,text,extitle,extext) response := FormatResponse("ahk.message.StringResponseMessage", output) } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return response {% endblock AHKWinGetClass %} } @@ -2063,12 +2145,14 @@ AHKWinActivate(command) { DetectHiddenWindows(detect_hw) } - WinActivate(title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinActivate(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinActivate %} } @@ -2097,17 +2181,20 @@ AHKWindowList(command) { if (detect_hw) { DetectHiddenWindows(detect_hw) } - - windows := WinGetList(title, text, extitle, extext) - r := "" - for id in windows - { - r .= id . "`," + try { + windows := WinGetList(title, text, extitle, extext) + r := "" + for id in windows + { + r .= id . "`," + } + resp := FormatResponse("ahk.message.WindowListResponseMessage", r) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) } - resp := FormatResponse("ahk.message.WindowListResponseMessage", r) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) return resp {% endblock AHKWindowList %} } @@ -2141,18 +2228,15 @@ AHKControlClick(command) { DetectHiddenWindows(detect_hw) } - ControlClick(ctrl, title, text, button, click_count, options, exclude_title, exclude_text) - - if (ErrorLevel != 0) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "Failed to click control") - } else { - response := FormatNoValueResponse() + try { + ControlClick(ctrl, title, text, button, click_count, options, exclude_title, exclude_text) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + response := FormatNoValueResponse() return response {% endblock AHKControlClick %} } @@ -2183,16 +2267,15 @@ AHKControlGetText(command) { DetectHiddenWindows(detect_hw) } - result := ControlGetText(ctrl, title, text, extitle, extext) - - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") - } else { - response := FormatResponse("ahk.message.StringResponseMessage", result) + try { + result := ControlGetText(ctrl, title, text, extitle, extext) } - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + response := FormatResponse("ahk.message.StringResponseMessage", result) return response {% endblock AHKControlGetText %} @@ -2224,20 +2307,17 @@ AHKControlGetPos(command) { DetectHiddenWindows(detect_hw) } - ControlGetPos(x, y, w, h, ctrl, title, text, extitle, extext) - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the text") - } else { + try { + ControlGetPos(&x, &y, &w, &h, ctrl, title, text, extitle, extext) result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) response := FormatResponse("ahk.message.PositionResponseMessage", result) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response - {% endblock AHKControlGetPos %} } @@ -2266,10 +2346,15 @@ AHKControlSend(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - ControlSend(ctrl, keys, title, text, extitle, extext) - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + + try { + ControlSend(ctrl, keys, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKControlSend %} } @@ -2289,9 +2374,9 @@ AHKWinFromMouse(command) { AHKWinIsAlwaysOnTop(command) { {% block AHKWinIsAlwaysOnTop %} - + ; TODO: detect hidden windows / etc? title := command[2] - WinGet(ExStyle, ExStyle, title) + ExStyle := WinGetExStyle(title) if (ExStyle = "") return FormatNoValueResponse() @@ -2330,12 +2415,14 @@ AHKWinMove(command) { DetectHiddenWindows(detect_hw) } - WinMove(title, text, x, y, width, height, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinMove(title, text, x, y, width, height, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinMove %} @@ -2366,18 +2453,16 @@ AHKWinGetPos(command) { DetectHiddenWindows(detect_hw) } - WinGetPos(x, y, w, h, title, text, extitle, extext) - - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") - } else { + try { + WinGetPos(&x, &y, &w, &h, title, text, extitle, extext) result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) response := FormatResponse("ahk.message.PositionResponseMessage", result) } - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return response {% endblock AHKWinGetPos %} @@ -2388,17 +2473,8 @@ AHKGetVolume(command) { device_number := command[2] - try { - SoundGetWaveVolume(retval, device_number) - } catch as e { - response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {} ({})", device_number, e.message)) - return response - } - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", Format("There was a problem getting the volume with device of index {}", device_number)) - } else { - response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) - } + retval := SoundGetVolume(,device_number) + response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) return response {% endblock AHKGetVolume %} } @@ -2414,25 +2490,13 @@ AHKSoundBeep(command) { AHKSoundGet(command) { {% block AHKSoundGet %} - - device_number := command[2] - component_type := command[3] - control_type := command[4] - - SoundGet(retval, component_type, control_type, device_number) - ; TODO interpret return type - return FormatResponse("ahk.message.StringResponseMessage", Format("{}", retval)) + return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundGet is not supported in ahk v2") {% endblock AHKSoundGet %} } AHKSoundSet(command) { {% block AHKSoundSet %} - device_number := command[2] - component_type := command[3] - control_type := command[4] - value := command[5] - SoundSet(value, component_type, control_type, device_number) - return FormatNoValueResponse() + return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundSet is not supported in ahk v2") {% endblock AHKSoundSet %} } @@ -2448,7 +2512,7 @@ AHKSetVolume(command) { {% block AHKSetVolume %} device_number := command[2] value := command[3] - SoundSetWaveVolume(value, device_number) + SoundSetVolume(value,,device_number) return FormatNoValueResponse() {% endblock AHKSetVolume %} } @@ -2521,11 +2585,10 @@ AHKClipWait(command) { timeout := command[2] wait_for_any_data := command[3] - ClipWait(timeout, wait_for_any_data) - - if (ErrorLevel = 1) { + if ClipWait(timeout, wait_for_any_data) + return FormatNoValueResponse() + else return FormatResponse("ahk.message.TimeoutResponseMessage", "timed out waiting for clipboard data") - } return FormatNoValueResponse() } @@ -2615,11 +2678,26 @@ AHKFileSelectFile(command) { root := command[3] title := command[4] filter := command[5] - output := FileSelectFile(options, root, title, filter) - if (ErrorLevel = 1) { + output := FileSelect(options, root, title, filter) + if (output = "") { ret := FormatNoValueResponse() } else { - ret := FormatResponse("ahk.message.StringResponseMessage", output) + if IsObject(output) { + if (output.Length = 0) { + ret := FormatNoValueResponse() + } + else { + files := "" + for index, filename in output + if (A_Index != 1) { + files .= "`n" + } + files .= filename + ret := FormatResponse("ahk.message.StringResponseMessage", files) + } + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output) + } } return ret } @@ -2630,9 +2708,9 @@ AHKFileSelectFolder(command) { options := command[3] prompt := command[4] - output := FileSelectFolder(starting_folder, options, prompt) + output := DirSelect(starting_folder, options, prompt) - if (ErrorLevel = 1) { + if (output = "") { ret := FormatNoValueResponse() } else { ret := FormatResponse("ahk.message.StringResponseMessage", output) @@ -2777,8 +2855,6 @@ b64encode(data) { return ret } -; End of included content - CommandArrayFromQuery(text) { decoded_commands := [] encoded_array := StrSplit(text, "|") @@ -2818,18 +2894,16 @@ Loop { {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {}. The error message was: {}", e.line, e.message) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what e.line, e.message e.extra) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } {% block send_response %} if (pyresp) { -; MsgBox(pyresp) stdout.Write(pyresp) stdout.Read(0) } else { msg := FormatResponse("ahk.message.ExceptionResponseMessage", Format("Unknown Error when calling {}", func_name)) -; MsgBox(msg) stdout.Write(msg) stdout.Read(0) } diff --git a/tests/_async/test_scripts.py b/tests/_async/test_scripts.py index 52dc044..6afb46a 100644 --- a/tests/_async/test_scripts.py +++ b/tests/_async/test_scripts.py @@ -65,3 +65,35 @@ async def test_run_script_nonblocking(self): class TestScriptsV2(TestScripts): async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(version='v2') + + async def test_run_script_text(self): + assert await self.ahk.win_get(title='Untitled - Notepad') is None + script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' + result = await self.ahk.run_script(script) + assert result == 'foobar' + + async def test_run_script_file(self): + assert await self.ahk.win_get(title='Untitled - Notepad') is None + with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: + f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') + res = await self.ahk.run_script(f.name) + assert res == 'foobar' + + async def test_run_script_file_unicode(self): + assert await self.ahk.win_get(title='Untitled - Notepad') is None + subprocess.Popen('Notepad') + await self.ahk.win_wait(title='Untitled - Notepad', timeout=3) + with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: + f.write( + 'WinActivate "Untitled - Notepad"\nSend "א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת װ ױ"' + ) + await self.ahk.run_script(f.name) + notepad = await self.ahk.win_wait(title='*Untitled - Notepad', timeout=3) + assert notepad is not None + text = await notepad.get_text() + assert 'א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת װ ױ' in text + + async def test_run_script_nonblocking(self): + script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foo")\nstdout.Read(0)' + fut = await self.ahk.run_script(script, blocking=False) + assert await fut.result() == 'foo' diff --git a/tests/_sync/test_scripts.py b/tests/_sync/test_scripts.py index fae4751..ae48e13 100644 --- a/tests/_sync/test_scripts.py +++ b/tests/_sync/test_scripts.py @@ -65,3 +65,35 @@ def test_run_script_nonblocking(self): class TestScriptsV2(TestScripts): def setUp(self) -> None: self.ahk = AHK(version='v2') + + def test_run_script_text(self): + assert self.ahk.win_get(title='Untitled - Notepad') is None + script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' + result = self.ahk.run_script(script) + assert result == 'foobar' + + def test_run_script_file(self): + assert self.ahk.win_get(title='Untitled - Notepad') is None + with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: + f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') + res = self.ahk.run_script(f.name) + assert res == 'foobar' + + def test_run_script_file_unicode(self): + assert self.ahk.win_get(title='Untitled - Notepad') is None + subprocess.Popen('Notepad') + self.ahk.win_wait(title='Untitled - Notepad', timeout=3) + with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: + f.write( + 'WinActivate "Untitled - Notepad"\nSend "א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת װ ױ"' + ) + self.ahk.run_script(f.name) + notepad = self.ahk.win_wait(title='*Untitled - Notepad', timeout=3) + assert notepad is not None + text = notepad.get_text() + assert 'א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת װ ױ' in text + + def test_run_script_nonblocking(self): + script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foo")\nstdout.Read(0)' + fut = self.ahk.run_script(script, blocking=False) + assert fut.result() == 'foo' From 5bc8d17232dde479e2be919a95e9e2b67dcb0585 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:15:52 -0700 Subject: [PATCH 20/52] set constant script for v2 --- _set_constants.py | 6 + ahk/_async/transport.py | 7 +- ahk/_constants.py | 2917 +++++++++++++++++++++++++++++++++++++++ ahk/_sync/transport.py | 4 +- 4 files changed, 2930 insertions(+), 4 deletions(-) diff --git a/_set_constants.py b/_set_constants.py index b6ecb29..50c5471 100644 --- a/_set_constants.py +++ b/_set_constants.py @@ -8,6 +8,9 @@ with open('ahk/templates/hotkeys.ahk') as hotkeyfile: hotkey_script = hotkeyfile.read() +with open('ahk/templates/daemon-v2.ahk') as fv2: + daemon_script_v2 = fv2.read() + GIT_EXECUTABLE = shutil.which('git') if not GIT_EXECUTABLE: @@ -22,6 +25,9 @@ HOTKEYS_SCRIPT_TEMPLATE = r"""{hotkey_script} """ + +DAEMON_SCRIPT_V2_TEMPLATE = r"""{daemon_script_v2} +""" ''' with open('ahk/_constants.py', encoding='utf-8') as f: diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 3e1c6ec..68f0233 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -44,7 +44,10 @@ from ahk.message import ResponseMessage from ahk.message import Position from ahk.message import _message_registry -from ahk._constants import DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE +from ahk._constants import ( + DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, + DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, +) from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor @@ -686,7 +689,7 @@ def __init__( const_script = _DAEMON_SCRIPT_TEMPLATE elif version == 'v2': template_name = 'daemon-v2.ahk' - const_script = '' # TODO: set v2 constant + const_script = _DAEMON_SCRIPT_V2_TEMPLATE else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') diff --git a/ahk/_constants.py b/ahk/_constants.py index 352b329..a5c1521 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2890,3 +2890,2920 @@ FileAppend, %KEEPALIVE%`n, *, UTF-8 """ + +DAEMON_SCRIPT_V2_TEMPLATE = r"""{% block daemon_script %} +{% block directives %} +;#NoEnv +;#Persistent +#Warn All, Off +#SingleInstance Off +; BEGIN user-defined directives +{% block user_directives %} +{% for directive in directives %} +{{ directive }} + +{% endfor %} + +; END user-defined directives +{% endblock user_directives %} +{% endblock directives %} + +Critical 100 + + +{% block message_types %} +MESSAGE_TYPES := Map({% for tom, msg_class in message_registry.items() %}"{{ msg_class.fqn() }}", "{{ tom.decode('utf-8') }}"{% if not loop.last %}, {% endif %}{% endfor %}) +{% endblock message_types %} + +NOVALUE_SENTINEL := Chr(57344) + +StrCount(haystack, needle) { + StrReplace(haystack, needle, "",, &count) + return count +} + +FormatResponse(MessageType, payload) { + global MESSAGE_TYPES + newline_count := StrCount(payload, "`n") + response := Format("{}`n{}`n{}`n", MESSAGE_TYPES[MessageType], newline_count, payload) + return response +} + +FormatNoValueResponse() { + global NOVALUE_SENTINEL + return FormatResponse("ahk.message.NoValueResponseMessage", NOVALUE_SENTINEL) +} + +FormatBinaryResponse(bin) { + b64 := b64encode(bin) + return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) +} + +AHKSetDetectHiddenWindows(command) { + {% block AHKSetDetectHiddenWindows %} + value := command[2] + DetectHiddenWindows(value) + return FormatNoValueResponse() + {% endblock AHKSetDetectHiddenWindows %} +} + +AHKSetTitleMatchMode(command) { + {% block AHKSetTitleMatchMode %} + val1 := command[2] + val2 := command[3] + if (val1 != "") { + SetTitleMatchMode(val1) + } + if (val2 != "") { + SetTitleMatchMode(val2) + } + return FormatNoValueResponse() + {% endblock AHKSetTitleMatchMode %} +} + +AHKGetTitleMatchMode(command) { + {% block AHKGetTitleMatchMode %} + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) + {% endblock AHKGetTitleMatchMode %} +} + +AHKGetTitleMatchSpeed(command) { + {% block AHKGetTitleMatchSpeed %} + + return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) + {% endblock AHKGetTitleMatchSpeed %} +} + +AHKSetSendLevel(command) { + {% block AHKSetSendLevel %} + level := command[2] + SendLevel(level) + return FormatNoValueResponse() + {% endblock AHKSetSendLevel %} +} + +AHKGetSendLevel(command) { + {% block AHKGetSendLevel %} + + return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) + {% endblock AHKGetSendLevel %} +} + +AHKWinExist(command) { + {% block AHKWinExist %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + if WinExist(title, text, extitle, extext) { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } else { + resp := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return resp + {% endblock AHKWinExist %} +} + +AHKWinClose(command) { + {% block AHKWinClose %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + secondstowait := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinClose(title, text, secondstowait, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinClose %} +} + +AHKWinKill(command) { + {% block AHKWinKill %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + secondstowait := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinKill(title, text, secondstowait, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinKill %} +} + +AHKWinWait(command) { + {% block AHKWinWait %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + if (timeout != "") { + output := WinWait(title, text, timeout, extitle, extext) + if (output = 0) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } else { + resp := resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } else { + output := WinWait(title, text,, extitle, extext) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return resp + {% endblock AHKWinWait %} +} + +AHKWinWaitActive(command) { + {% block AHKWinWaitActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + if (timeout != "") { + output := WinWaitActive(title, text, timeout, extitle, extext) + if (output = 0) { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWaitActive timed out waiting for the window") + } else { + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } else { + output := WinWaitActive(title, text,, extitle, extext) + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return resp + {% endblock AHKWinWaitActive %} +} + +AHKWinWaitNotActive(command) { + {% block AHKWinWaitNotActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + if (timeout != "") { + if (WinWaitNotActive(title, text, timeout, extitle, extext) = 1) { + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } else { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } + } else { + WinWaitNotActive(title, text,, extitle, extext) + output := WinGetID() + resp := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return resp + {% endblock AHKWinWaitNotActive %} +} + +AHKWinWaitClose(command) { + {% block AHKWinWaitClose %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + timeout := command[9] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + if (timeout != "") { + if (WinWaitClose(title, text, timeout, extitle, extext) = 1) { + resp := FormatNoValueResponse() + } else { + resp := FormatResponse("ahk.message.TimeoutResponseMessage", "WinWait timed out waiting for window") + } + } else { + WinWaitClose(title, text,, extitle, extext) + resp := FormatNoValueResponse() + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return resp + {% endblock AHKWinWaitClose %} +} + +AHKWinMinimize(command) { + {% block AHKWinMinimize %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinMinimize(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinMinimize %} +} + +AHKWinMaximize(command) { + {% block AHKWinMaximize %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + WinMaximize(title, text, extitle, extext) + + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + + return FormatNoValueResponse() + {% endblock AHKWinMaximize %} +} + +AHKWinRestore(command) { + {% block AHKWinRestore %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinRestore(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinRestore %} +} + +AHKWinIsActive(command) { + {% block AHKWinIsActive %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + if WinActive(title, text, extitle, extext) { + response := FormatResponse("ahk.message.BooleanResponseMessage", 1) + } else { + response := FormatResponse("ahk.message.BooleanResponseMessage", 0) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinIsActive %} +} + +AHKWinGetID(command) { + {% block AHKWinGetID %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetID %} +} + +AHKWinGetTitle(command) { + {% block AHKWinGetTitle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + text := WinGetTitle(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.StringResponseMessage", text) + {% endblock AHKWinGetTitle %} +} + +AHKWinGetIDLast(command) { + {% block AHKWinGetIDLast %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetIDLast(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.WindowResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetIDLast %} +} + +AHKWinGetPID(command) { + {% block AHKWinGetPID %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetPID(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetPID %} +} + +AHKWinGetProcessName(command) { + {% block AHKWinGetProcessName %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetProcessName(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetProcessName %} +} + +AHKWinGetProcessPath(command) { + {% block AHKWinGetProcessPath %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetProcessPath(title, text, extitle, extext) + if (output = 0 || output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetProcessPath %} +} + +AHKWinGetCount(command) { + {% block AHKWinGetCount %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetCount(title, text, extitle, extext) + if (output = 0) { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetCount %} +} + +AHKWinGetMinMax(command) { + {% block AHKWinGetMinMax %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetMinMax(title, text, extitle, extext) + if (output = "") { + response := FormatNoValueResponse() + } else { + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetMinMax %} +} + +AHKWinGetControlList(command) { + {% block AHKWinGetControlList %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + ahkid := WinGetID(title, text, extitle, extext) + + if (ahkid = "") { + return FormatNoValueResponse() + } + + try { + ctrList := WinGetControls(title, text, extitle, extext) + ctrListID := WinGetControlsHwnd(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + if (ctrListID = "") { + return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) + } + + ; ctrListArr := StrSplit(ctrList, "`n") + ; ctrListIDArr := StrSplit(ctrListID, "`n") + if (ctrListArr.Length() != ctrListIDArr.Length()) { + return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") + } + + output := Format("('{}', [", ahkid) + + for index, hwnd in ctrListIDArr { + classname := ctrListArr[index] + output .= Format("('{}', '{}'), ", hwnd, classname) + + } + output .= "])" + response := FormatResponse("ahk.message.WindowControlListResponseMessage", output) + return response + {% endblock AHKWinGetControlList %} +} + +AHKWinGetTransparent(command) { + {% block AHKWinGetTransparent %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetTransparent(title, text, extitle, extext) + response := FormatResponse("ahk.message.IntegerResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetTransparent %} +} +AHKWinGetTransColor(command) { + {% block AHKWinGetTransColor %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetTransColor(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetTransColor %} +} +AHKWinGetStyle(command) { + {% block AHKWinGetStyle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetStyle %} +} + +AHKWinGetExStyle(command) { + {% block AHKWinGetExStyle %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetExStyle(title, text, extitle, extext) + response := FormatResponse("ahk.message.NoValueResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKWinGetExStyle %} +} + +AHKWinGetText(command) { + {% block AHKWinGetText %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + output := WinGetText(title,text,extitle,extext) + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + + return response + {% endblock AHKWinGetText %} +} + +AHKWinSetTitle(command) { + {% block AHKWinSetTitle %} + new_title := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetTitle(title, text, new_title, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetTitle %} +} + +AHKWinSetAlwaysOnTop(command) { + {% block AHKWinSetAlwaysOnTop %} + toggle := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetAlwaysOnTop(toggle, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetAlwaysOnTop %} +} + +AHKWinSetBottom(command) { + {% block AHKWinSetBottom %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinMoveBottom(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetBottom %} +} + +AHKWinShow(command) { + {% block AHKWinShow %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinShow(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinShow %} +} + +AHKWinHide(command) { + {% block AHKWinHide %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinHide(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinHide %} +} + +AHKWinSetTop(command) { + {% block AHKWinSetTop %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinMoveTop(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetTop %} +} + +AHKWinSetEnable(command) { + {% block AHKWinSetEnable %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetEnabled(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetEnable %} +} + +AHKWinSetDisable(command) { + {% block AHKWinSetDisable %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetDisabled(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetDisable %} +} + +AHKWinSetRedraw(command) { + {% block AHKWinSetRedraw %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinRedraw(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetRedraw %} +} + +AHKWinSetStyle(command) { + {% block AHKWinSetStyle %} + + style := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetStyle(style, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) + {% endblock AHKWinSetStyle %} +} + +AHKWinSetExStyle(command) { + {% block AHKWinSetExStyle %} + + style := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + WinSetExStyle(style, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) + {% endblock AHKWinSetExStyle %} +} + +AHKWinSetRegion(command) { + {% block AHKWinSetRegion %} + + options := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetRegion(options, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatResponse("ahk.message.BooleanResponseMessage", 1) + {% endblock AHKWinSetRegion %} +} + +AHKWinSetTransparent(command) { + {% block AHKWinSetTransparent %} + + transparency := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetTransparent(transparency, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetTransparent %} +} + +AHKWinSetTransColor(command) { + {% block AHKWinSetTransColor %} + + color := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + WinSetTransColor(color, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinSetTransColor %} +} + +AHKImageSearch(command) { + {% block AHKImageSearch %} + + imagepath := command[6] + x1 := command[2] + y1 := command[3] + x2 := command[4] + y2 := command[5] + coord_mode := command[7] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + + if (x2 = "A_ScreenWidth") { + x2 := A_ScreenWidth + } + if (y2 = "A_ScreenHeight") { + y2 := A_ScreenHeight + } + + try { + if ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) + s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) + else + s := FormatNoValueResponse() + } + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + } + + return s + {% endblock AHKImageSearch %} +} + +AHKPixelGetColor(command) { + {% block AHKPixelGetColor %} + + x := command[2] + y := command[3] + coord_mode := command[4] + options := command[5] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + + try { + color := PixelGetColor(x, y, options) + } + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + } + + return FormatResponse("ahk.message.StringResponseMessage", color) + {% endblock AHKPixelGetColor %} +} + +AHKPixelSearch(command) { + {% block AHKPixelSearch %} + + x1 := command[2] + y1 := command[3] + x2 := command[4] + y2 := command[5] + color := command[6] + variation := command[7] + options := command[8] + coord_mode := command[9] + + current_mode := Format("{}", A_CoordModePixel) + + if (coord_mode != "") { + CoordMode(Pixel, coord_mode) + } + try { + if (PixelSearch(&resultx, &resulty, x1, y1, x2, y2, color, variation) = 1) { + payload := Format("({}, {})", resultx, resulty) + ret := FormatResponse("ahk.message.CoordinateResponseMessage", payload) + } else { + ret := FormatNoValueResponse() + } + } + finally { + if (coord_mode != "") { + CoordMode(Pixel, current_mode) + } + } + + return ret + + {% endblock AHKPixelSearch %} +} + +AHKMouseGetPos(command) { + {% block AHKMouseGetPos %} + + coord_mode := command[2] + current_coord_mode := Format("{}", A_CoordModeMouse) + if (coord_mode != "") { + CoordMode(Mouse, coord_mode) + } + MouseGetPos(&xpos, &ypos) + + payload := Format("({}, {})", xpos, ypos) + resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) + + if (coord_mode != "") { + CoordMode(Mouse, current_coord_mode) + } + + return resp + {% endblock AHKMouseGetPos %} +} + +AHKKeyState(command) { + {% block AHKKeyState %} + + keyname := command[2] + mode := command[3] + if (mode != "") { + state := GetKeyState(keyname, mode) + } else{ + state := GetKeyState(keyname) + } + + if (state = "") { + return FormatNoValueResponse() + } + + if IsInteger(state) + return FormatResponse("ahk.message.IntegerResponseMessage", state) + + if IsFloat(state) + return FormatResponse("ahk.message.FloatResponseMessage", state) + + if IsAlnum(state) + return FormatResponse("ahk.message.StringResponseMessage", state) + + msg := Format("Unexpected key state {}", state) + return FormatResponse("ahk.message.ExceptionResponseMessage", msg) + {% endblock AHKKeyState %} +} + +AHKMouseMove(command) { + {% block AHKMouseMove %} + x := command[2] + y := command[3] + speed := command[4] + relative := command[5] + if (relative != "") { + MouseMove(x, y, speed, "R") + } else { + MouseMove(x, y, speed) + } + resp := FormatNoValueResponse() + return resp + {% endblock AHKMouseMove %} +} + +AHKClick(command) { + {% block AHKClick %} + x := command[2] + y := command[3] + button := command[4] + click_count := command[5] + direction := command[6] + r := command[7] + relative_to := command[8] + current_coord_rel := Format("{}", A_CoordModeMouse) + + if (relative_to != "") { + CoordMode(Mouse, relative_to) + } + + Click(x, y, button, direction, r) + + if (relative_to != "") { + CoordMode(Mouse, current_coord_rel) + } + + return FormatNoValueResponse() + + {% endblock AHKClick %} +} + +AHKGetCoordMode(command) { + {% block AHKGetCoordMode %} + + target := command[2] + + if (target = "ToolTip") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) + } + if (target = "Pixel") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModePixel) + } + if (target = "Mouse") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMouse) + } + if (target = "Caret") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeCaret) + } + if (target = "Menu") { + return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeMenu) + } + return FormatResponse("ahk.message.ExceptionResponseMessage", "Invalid coord mode") + {% endblock AHKGetCoordMode %} +} + +AHKSetCoordMode(command) { + {% block AHKSetCoordMode %} + target := command[2] + relative_to := command[3] + CoordMode(target, relative_to) + + return FormatNoValueResponse() + {% endblock AHKSetCoordMode %} +} + +AHKMouseClickDrag(command) { + {% block AHKMouseClickDrag %} + button := command[2] + x1 := command[3] + y1 := command[4] + x2 := command[5] + y2 := command[6] + speed := command[7] + relative := command[8] + relative_to := command[9] + + current_coord_rel := Format("{}", A_CoordModeMouse) + + if (relative_to != "") { + CoordMode(Mouse, relative_to) + } + + MouseClickDrag(button, x1, y1, x2, y2, speed, relative) + + if (relative_to != "") { + CoordMode(Mouse, current_coord_rel) + } + + return FormatNoValueResponse() + + {% endblock AHKMouseClickDrag %} +} + +AHKRegRead(command) { + {% block RegRead %} + + key_name := command[2] + value_name := command[3] + + output := RegRead(key_name, value_name) + resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) + return resp + {% endblock RegRead %} +} + +AHKRegWrite(command) { + {% block RegWrite %} + value_type := command[2] + key_name := command[3] + value_name := command[4] + value := command[5] +; RegWrite(value_type, key_name, value_name, value) + if (value_name != "") { + RegWrite(value, value_type, key_name) + } else { + RegWrite(value, value_type, key_name, value_name) + } + return FormatNoValueResponse() + {% endblock RegWrite %} +} + +AHKRegDelete(command) { + {% block RegDelete %} + + key_name := command[2] + value_name := command[3] + if (value_name != "") { + RegDelete(key_name, value_name) + } else { + RegDelete(key_name) + } + return FormatNoValueResponse() + + {% endblock RegDelete %} +} + +AHKKeyWait(command) { + {% block AHKKeyWait %} + + keyname := command[2] + if (command.Length() = 2) { + ret := KeyWait(keyname) + } else { + options := command[3] + ret := KeyWait(keyname, options) + } + return FormatResponse("ahk.message.IntegerResponseMessage", ret) + {% endblock AHKKeyWait %} +} + +;SetKeyDelay(command) { +; {% block SetKeyDelay %} +; SetKeyDelay(command[2], command[3]) +; {% endblock SetKeyDelay %} +;} + +AHKSend(command) { + {% block AHKSend %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + + Send(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSend %} +} + +AHKSendRaw(command) { + {% block AHKSendRaw %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendRaw(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendRaw %} +} + +AHKSendInput(command) { + {% block AHKSendInput %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendInput(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendInput %} +} + +AHKSendEvent(command) { + {% block AHKSendEvent %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelay) + current_key_duration := Format("{}", A_KeyDuration) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration) + } + + SendEvent(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendEvent %} +} + +AHKSendPlay(command) { + {% block AHKSendPlay %} + str := command[2] + key_delay := command[3] + key_press_duration := command[4] + current_delay := Format("{}", A_KeyDelayPlay) + current_key_duration := Format("{}", A_KeyDurationPlay) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(key_delay, key_press_duration, Play) + } + + SendPlay(str) + + if (key_delay != "" or key_press_duration != "") { + SetKeyDelay(current_delay, current_key_duration) + } + return FormatNoValueResponse() + {% endblock AHKSendPlay %} +} + +AHKSetCapsLockState(command) { + {% block AHKSetCapsLockState %} + state := command[2] + if (state = "") { + SetCapsLockState(!GetKeyState("CapsLock", "T")) + } else { + SetCapsLockState(state) + } + return FormatNoValueResponse() + {% endblock AHKSetCapsLockState %} +} + +HideTrayTip(command) { + {% block HideTrayTip %} + TrayTip ; Attempt to hide it the normal way. + if SubStr(A_OSVersion,1,3) = "10." { + Menu Tray, NoIcon + Sleep 200 ; It may be necessary to adjust this sleep. + Menu Tray, Icon + } + {% endblock HideTrayTip %} +} + +AHKWinGetClass(command) { + {% block AHKWinGetClass %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + try { + output := WinGetClass(title,text,extitle,extext) + response := FormatResponse("ahk.message.StringResponseMessage", output) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + + return response + {% endblock AHKWinGetClass %} +} + +AHKWinActivate(command) { + {% block AHKWinActivate %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + WinActivate(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKWinActivate %} +} + +AHKWindowList(command) { + {% block AHKWindowList %} + + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + if (detect_hw) { + DetectHiddenWindows(detect_hw) + } + try { + windows := WinGetList(title, text, extitle, extext) + r := "" + for id in windows + { + r .= id . "`," + } + resp := FormatResponse("ahk.message.WindowListResponseMessage", r) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return resp + {% endblock AHKWindowList %} +} + +AHKControlClick(command) { + {% block AHKControlClick %} + + ctrl := command[2] + title := command[3] + text := command[4] + button := command[5] + click_count := command[6] + options := command[7] + exclude_title := command[8] + exclude_text := command[9] + detect_hw := command[10] + match_mode := command[11] + match_speed := command[12] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + ControlClick(ctrl, title, text, button, click_count, options, exclude_title, exclude_text) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + response := FormatNoValueResponse() + return response + {% endblock AHKControlClick %} +} + +AHKControlGetText(command) { + {% block AHKControlGetText %} + + ctrl := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + result := ControlGetText(ctrl, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + response := FormatResponse("ahk.message.StringResponseMessage", result) + + return response + {% endblock AHKControlGetText %} +} + +AHKControlGetPos(command) { + {% block AHKControlGetPos %} + + ctrl := command[2] + title := command[3] + text := command[4] + extitle := command[5] + extext := command[6] + detect_hw := command[7] + match_mode := command[8] + match_speed := command[9] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + ControlGetPos(&x, &y, &w, &h, ctrl, title, text, extitle, extext) + result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) + response := FormatResponse("ahk.message.PositionResponseMessage", result) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return response + {% endblock AHKControlGetPos %} +} + +AHKControlSend(command) { + {% block AHKControlSend %} + ctrl := command[2] + keys := command[3] + title := command[4] + text := command[5] + extitle := command[6] + extext := command[7] + detect_hw := command[8] + match_mode := command[9] + match_speed := command[10] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + ControlSend(ctrl, keys, title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + {% endblock AHKControlSend %} +} + +AHKWinFromMouse(command) { + {% block AHKWinFromMouse %} + + MouseGetPos(,, MouseWin) + + if (MouseWin = "") { + return FormatNoValueResponse() + } + + return FormatResponse("ahk.message.WindowResponseMessage", MouseWin) + {% endblock AHKWinFromMouse %} +} + +AHKWinIsAlwaysOnTop(command) { + {% block AHKWinIsAlwaysOnTop %} + ; TODO: detect hidden windows / etc? + title := command[2] + ExStyle := WinGetExStyle(title) + if (ExStyle = "") + return FormatNoValueResponse() + + if (ExStyle & 0x8) ; 0x8 is WS_EX_TOPMOST. + return FormatResponse("ahk.message.BooleanResponseMessage", 1) + else + return FormatResponse("ahk.message.BooleanResponseMessage", 0) + {% endblock AHKWinIsAlwaysOnTop %} +} + +AHKWinMove(command) { + {% block AHKWinMove %} + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + x := command[9] + y := command[10] + width := command[11] + height := command[12] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + WinMove(title, text, x, y, width, height, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + return FormatNoValueResponse() + + {% endblock AHKWinMove %} +} + +AHKWinGetPos(command) { + {% block AHKWinGetPos %} + + title := command[2] + text := command[3] + extitle := command[4] + extext := command[5] + detect_hw := command[6] + match_mode := command[7] + match_speed := command[8] + + current_match_mode := Format("{}", A_TitleMatchMode) + current_match_speed := Format("{}", A_TitleMatchModeSpeed) + if (match_mode != "") { + SetTitleMatchMode(match_mode) + } + if (match_speed != "") { + SetTitleMatchMode(match_speed) + } + current_detect_hw := Format("{}", A_DetectHiddenWindows) + + if (detect_hw != "") { + DetectHiddenWindows(detect_hw) + } + + try { + WinGetPos(&x, &y, &w, &h, title, text, extitle, extext) + result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) + response := FormatResponse("ahk.message.PositionResponseMessage", result) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } + + return response + {% endblock AHKWinGetPos %} +} + +AHKGetVolume(command) { + {% block AHKGetVolume %} + + device_number := command[2] + + retval := SoundGetVolume(,device_number) + response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) + return response + {% endblock AHKGetVolume %} +} + +AHKSoundBeep(command) { + {% block AHKSoundBeep %} + freq := command[2] + duration := command[3] + SoundBeep(freq, duration) + return FormatNoValueResponse() + {% endblock AHKSoundBeep %} +} + +AHKSoundGet(command) { + {% block AHKSoundGet %} + return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundGet is not supported in ahk v2") + {% endblock AHKSoundGet %} +} + +AHKSoundSet(command) { + {% block AHKSoundSet %} + return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundSet is not supported in ahk v2") + {% endblock AHKSoundSet %} +} + +AHKSoundPlay(command) { + {% block AHKSoundPlay %} + filename := command[2] + SoundPlay(filename) + return FormatNoValueResponse() + {% endblock AHKSoundPlay %} +} + +AHKSetVolume(command) { + {% block AHKSetVolume %} + device_number := command[2] + value := command[3] + SoundSetVolume(value,,device_number) + return FormatNoValueResponse() + {% endblock AHKSetVolume %} +} + + +AHKEcho(command) { + {% block AHKEcho %} + arg := command[2] + return FormatResponse("ahk.message.StringResponseMessage", arg) + {% endblock AHKEcho %} +} + +AHKTraytip(command) { + {% block AHKTraytip %} + title := command[2] + text := command[3] + second := command[4] + option := command[5] + + TrayTip(title, text, option) + return FormatNoValueResponse() + {% endblock AHKTraytip %} +} + +AHKShowToolTip(command) { + {% block AHKShowToolTip %} + text := command[2] + x := command[3] + y := command[4] + which := command[5] + ToolTip(text, x, y, which) + return FormatNoValueResponse() + {% endblock AHKShowToolTip %} +} + +AHKGetClipboard(command) { + {% block AHKGetClipboard %} + + return FormatResponse("ahk.message.StringResponseMessage", A_Clipboard) + {% endblock AHKGetClipboard %} +} + +AHKGetClipboardAll(command) { + {% block AHKGetClipboardAll %} + data := ClipboardAll() + return FormatBinaryResponse(data) + {% endblock AHKGetClipboardAll %} +} + +AHKSetClipboard(command) { + {% block AHKSetClipboard %} + text := command[2] + A_Clipboard := text + return FormatNoValueResponse() + {% endblock AHKSetClipboard %} +} + +AHKSetClipboardAll(command) { + {% block AHKSetClipboardAll %} + ; TODO there should be a way for us to accept a base64 string instead + filename := command[2] + contents := FileRead(filename, "RAW") + ClipboardAll(contents) + return FormatNoValueResponse() + {% endblock AHKSetClipboardAll %} +} + +AHKClipWait(command) { + + timeout := command[2] + wait_for_any_data := command[3] + + if ClipWait(timeout, wait_for_any_data) + return FormatNoValueResponse() + else + return FormatResponse("ahk.message.TimeoutResponseMessage", "timed out waiting for clipboard data") + return FormatNoValueResponse() +} + +AHKBlockInput(command) { + value := command[2] + BlockInput(value) + return FormatNoValueResponse() +} + +AHKMenuTrayTip(command) { + value := command[2] + Menu(Tray, Tip, value) + return FormatNoValueResponse() +} + +AHKMenuTrayShow(command) { + Menu(Tray, Icon) + return FormatNoValueResponse() +} + +AHKMenuTrayIcon(command) { + filename := command[2] + icon_number := command[3] + freeze := command[4] + Menu(Tray, Icon, filename, icon_number,freeze) + return FormatNoValueResponse() +} + +AHKGuiNew(command) { + + options := command[2] + title := command[3] + Gui(New, options, title) + return FormatResponse("ahk.message.StringResponseMessage", hwnd) +} + +AHKMsgBox(command) { + + options := command[2] + title := command[3] + text := command[4] + timeout := command[5] + if (timeout != "") { + options := "" options " T" timeout + } + res := MsgBox(text, title, options) + if (res = "Timeout") { + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "MsgBox timed out") + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", res) + } + return ret +} + +AHKInputBox(command) { + + title := command[2] + prompt := command[3] + hide := command[4] + width := command[5] + height := command[6] + x := command[7] + y := command[8] + locale := command[9] + timeout := command[10] + default := command[11] + + ; TODO: support options correctly + options := "" + if (timeout != "") { + options .= "T" timeout + } + output := InputBox(prompt, title, options, default) + if (output.Result = "Timeout") { + ret := FormatResponse("ahk.message.TimeoutResponseMessage", "Input box timed out") + } else if (output.Result = "Cancel") { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output.Value) + } + return ret +} + +AHKFileSelectFile(command) { + + options := command[2] + root := command[3] + title := command[4] + filter := command[5] + output := FileSelect(options, root, title, filter) + if (output = "") { + ret := FormatNoValueResponse() + } else { + if IsObject(output) { + if (output.Length = 0) { + ret := FormatNoValueResponse() + } + else { + files := "" + for index, filename in output + if (A_Index != 1) { + files .= "`n" + } + files .= filename + ret := FormatResponse("ahk.message.StringResponseMessage", files) + } + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output) + } + } + return ret +} + +AHKFileSelectFolder(command) { + + starting_folder := command[2] + options := command[3] + prompt := command[4] + + output := DirSelect(starting_folder, options, prompt) + + if (output = "") { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse("ahk.message.StringResponseMessage", output) + } + return ret +} + +; LC_* functions are substantially from Libcrypt +; Modified from https://github.com/ahkscript/libcrypt.ahk +; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 +; Original License: +; The MIT License (MIT) +; +; Copyright (c) 2014 The ahkscript community (ahkscript.org) +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in all +; copies or substantial portions of the Software. + + +LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") +{ + Bin_ := Buffer(StrPut(Text_, Encoding_)) + LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) + return Base64_ +} + +LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") +{ + Len_ := LC_Base64_Decode(&Bin_, &Text_) + return StrGet(StrPtr(Bin_), Len_, Encoding_) +} + +LC_Base64_Encode(&Out_, &In_, In_Len) +{ + return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) +} + +LC_Base64_Decode(&Out_, &In_) +{ + return LC_Str2Bin(&Out_, &In_, 0x1) +} + +LC_Bin2Str(&Out_, &In_, In_Len, Flags_) +{ + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) + VarSetStrCapacity(&Out_, Out_Len * 2) + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) + return Out_Len +} + +LC_Str2Bin(&Out_, &In_, Flags_) +{ + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) + VarSetStrCapacity(&Out_, Out_Len) + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) + return Out_Len +} +; End of libcrypt code + +b64decode(pszString) { + ; TODO load DLL globally for performance + ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw + ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. + ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. + ; [in] DWORD dwFlags, Indicates the format of the string to be converted. (see table in link above) + ; [in] BYTE *pbBinary, A pointer to a buffer that receives the returned sequence of bytes. If this parameter is NULL, the function calculates the length of the buffer needed and returns the size, in bytes, of required memory in the DWORD pointed to by pcbBinary. + ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. + ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. + ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. + return LC_Base64_Decode_Text(pszString) + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + buff_size := 0 ; The function will write to this variable on our first call + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size, 0) +; granted := VarSetStrCapacity(&ret, buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + + return StrGet(ret, "UTF-8") +} + +b64encode(data) { + ; REF: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa + ; [in] const BYTE *pbBinary: A pointer to the array of bytes to be converted into a string. + ; [in] DWORD cbBinary: The number of elements in the pbBinary array. + ; [in] DWORD dwFlags: Specifies the format of the resulting formatted string (see table in REF) + ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size + ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer + LC_Base64_Encode(&Base64_, &data, data.Size) + return Base64_ + cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) + if (cbBinary = 0) { + return "" + } + + dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF + + ; First step is to get the size so we can set the capacity of our return buffer correctly + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Exception(msg, -1) + } + + VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) + + ; Now we do the conversion to base64 and rteturn the string + + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Exception(msg, -1) + } + return ret +} + +CommandArrayFromQuery(text) { + decoded_commands := [] + encoded_array := StrSplit(text, "|") + function_name := encoded_array[1] + encoded_array.RemoveAt(1) + decoded_commands.push(function_name) + for index, encoded_value in encoded_array { + decoded_value := b64decode(encoded_value) + decoded_commands.push(decoded_value) + } + return decoded_commands +} + +; BEGIN extension scripts +{% for ext in extensions %} +{{ ext.script_text }} + +{% endfor %} +; END extension scripts +{% block before_autoexecute %} +{% endblock before_autoexecute %} + +{% block autoexecute %} +stdin := FileOpen("*", "r `n", "UTF-8") ; Requires [v1.1.17+] +stdout := FileOpen("*", "w", "UTF-8") +pyresp := "" + +Loop { + query := RTrim(stdin.ReadLine(), "`n") + commandArray := CommandArrayFromQuery(query) + try { + func_name := commandArray[1] + {% block before_function %} + {% endblock before_function %} + pyresp := %func_name%(commandArray) + {% block after_function %} + {% endblock after_function %} + } catch Any as e { + {% block function_error_handle %} + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what e.line, e.message e.extra) + pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) + {% endblock function_error_handle %} + } + {% block send_response %} + if (pyresp) { + stdout.Write(pyresp) + stdout.Read(0) + } else { + msg := FormatResponse("ahk.message.ExceptionResponseMessage", Format("Unknown Error when calling {}", func_name)) + stdout.Write(msg) + stdout.Read(0) + } + {% endblock send_response %} +} + +{% endblock autoexecute %} +{% endblock daemon_script %} + +""" diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index e94db02..ef7c74b 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -44,7 +44,7 @@ from ahk.message import ResponseMessage from ahk.message import Position from ahk.message import _message_registry -from ahk._constants import DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE +from ahk._constants import DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor @@ -659,7 +659,7 @@ def __init__( const_script = _DAEMON_SCRIPT_TEMPLATE elif version == 'v2': template_name = 'daemon-v2.ahk' - const_script = '' # TODO: set v2 constant + const_script = _DAEMON_SCRIPT_V2_TEMPLATE else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') From dcc1e3654f7950dc056429b753e51fc62306bb8b Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:22:43 -0700 Subject: [PATCH 21/52] Add #Requires directive to daemon scripts --- ahk/_constants.py | 2 ++ ahk/templates/daemon-v2.ahk | 1 + ahk/templates/daemon.ahk | 1 + 3 files changed, 4 insertions(+) diff --git a/ahk/_constants.py b/ahk/_constants.py index a5c1521..f4f385a 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -3,6 +3,7 @@ DAEMON_SCRIPT_TEMPLATE = r"""{% block daemon_script %} {% block directives %} +#Requires AutoHotkey v1.1.17+ #NoEnv #Persistent #SingleInstance Off @@ -2895,6 +2896,7 @@ {% block directives %} ;#NoEnv ;#Persistent +#Requires Autohotkey >= 2.0- #Warn All, Off #SingleInstance Off ; BEGIN user-defined directives diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 96461d6..629ef80 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -2,6 +2,7 @@ {% block directives %} ;#NoEnv ;#Persistent +#Requires Autohotkey >= 2.0- #Warn All, Off #SingleInstance Off ; BEGIN user-defined directives diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 842cc3e..83ca10c 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -1,5 +1,6 @@ {% block daemon_script %} {% block directives %} +#Requires AutoHotkey v1.1.17+ #NoEnv #Persistent #SingleInstance Off From 2a4bdd166505e496d477d16bbac7be56754446ed Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:24:29 -0700 Subject: [PATCH 22/52] fix error message --- ahk/_constants.py | 2 +- ahk/templates/daemon-v2.ahk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index f4f385a..7a46306 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -5789,7 +5789,7 @@ {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what e.line, e.message e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message e.extra) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 629ef80..de568fd 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -2895,7 +2895,7 @@ Loop { {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what e.line, e.message e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message e.extra) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } From 71a0362c5fd089cfb44b398906094644631c6af6 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:26:58 -0700 Subject: [PATCH 23/52] fix error message --- ahk/_constants.py | 8 +++----- ahk/templates/daemon-v2.ahk | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 7a46306..2c54d19 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -3810,9 +3810,7 @@ return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) } - ; ctrListArr := StrSplit(ctrList, "`n") - ; ctrListIDArr := StrSplit(ctrListID, "`n") - if (ctrListArr.Length() != ctrListIDArr.Length()) { + if (ctrList.Length != ctrListID.Length) { return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } @@ -4832,7 +4830,7 @@ {% block AHKKeyWait %} keyname := command[2] - if (command.Length() = 2) { + if (command.Length = 2) { ret := KeyWait(keyname) } else { options := command[3] @@ -5789,7 +5787,7 @@ {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message, e.extra) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index de568fd..5129370 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -916,9 +916,7 @@ AHKWinGetControlList(command) { return FormatResponse("ahk.message.WindowControlListResponseMessage", Format("('{}', [])", ahkid)) } - ; ctrListArr := StrSplit(ctrList, "`n") - ; ctrListIDArr := StrSplit(ctrListID, "`n") - if (ctrListArr.Length() != ctrListIDArr.Length()) { + if (ctrList.Length != ctrListID.Length) { return FormatResponse("ahk.message.ExceptionResponseMessage", "Control hwnd/class lists have unexpected lengths") } @@ -1938,7 +1936,7 @@ AHKKeyWait(command) { {% block AHKKeyWait %} keyname := command[2] - if (command.Length() = 2) { + if (command.Length = 2) { ret := KeyWait(keyname) } else { options := command[3] @@ -2895,7 +2893,7 @@ Loop { {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message, e.extra) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } From 5b0ccafa368e8acbd2473b4c62dfb4a3bb0b9764 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 12:30:17 -0700 Subject: [PATCH 24/52] Add stack to error message in v2 --- ahk/_constants.py | 2 +- ahk/templates/daemon-v2.ahk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 2c54d19..2f08c31 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -5787,7 +5787,7 @@ {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message, e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}`nStack:`n{}", e.what, e.line, e.message, e.extra, e.stack) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 5129370..c38dd3c 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -2893,7 +2893,7 @@ Loop { {% endblock after_function %} } catch Any as e { {% block function_error_handle %} - message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}", e.what, e.line, e.message, e.extra) + message := Format("Error occurred in {} (line {}). The error message was: {}. Specifically: {}`nStack:`n{}", e.what, e.line, e.message, e.extra, e.stack) pyresp := FormatResponse("ahk.message.ExceptionResponseMessage", message) {% endblock function_error_handle %} } From f6c42f3cd7b5cf109a7f0fa9471653931235d2f4 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 13:06:23 -0700 Subject: [PATCH 25/52] misc fixes from warnings --- ahk/_constants.py | 183 ++++++++++++++++++------------------ ahk/templates/daemon-v2.ahk | 183 ++++++++++++++++++------------------ 2 files changed, 180 insertions(+), 186 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 2f08c31..505dc99 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2895,8 +2895,8 @@ DAEMON_SCRIPT_V2_TEMPLATE = r"""{% block daemon_script %} {% block directives %} ;#NoEnv -;#Persistent #Requires Autohotkey >= 2.0- +Persistent #Warn All, Off #SingleInstance Off ; BEGIN user-defined directives @@ -3790,14 +3790,11 @@ if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - ahkid := WinGetID(title, text, extitle, extext) - - if (ahkid = "") { - return FormatNoValueResponse() - } - try { + ahkid := WinGetID(title, text, extitle, extext) + if (ahkid = "") { + return FormatNoValueResponse() + } ctrList := WinGetControls(title, text, extitle, extext) ctrListID := WinGetControlsHwnd(title, text, extitle, extext) } @@ -3816,8 +3813,8 @@ output := Format("('{}', [", ahkid) - for index, hwnd in ctrListIDArr { - classname := ctrListArr[index] + for index, hwnd in ctrListID { + classname := ctrList[index] output .= Format("('{}', '{}'), ", hwnd, classname) } @@ -4258,7 +4255,7 @@ DetectHiddenWindows(detect_hw) } try { - WinSetEnabled(title, text, extitle, extext) + WinSetEnabled(1, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -4294,7 +4291,7 @@ DetectHiddenWindows(detect_hw) } try { - WinSetDisabled(title, text, extitle, extext) + WinSetEnabled(0, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -4540,7 +4537,7 @@ current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } if (x2 = "A_ScreenWidth") { @@ -4558,7 +4555,7 @@ } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -4577,7 +4574,7 @@ current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } try { @@ -4585,7 +4582,7 @@ } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -4608,7 +4605,7 @@ current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } try { if (PixelSearch(&resultx, &resulty, x1, y1, x2, y2, color, variation) = 1) { @@ -4620,7 +4617,7 @@ } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -4635,7 +4632,7 @@ coord_mode := command[2] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { - CoordMode(Mouse, coord_mode) + CoordMode("Mouse", coord_mode) } MouseGetPos(&xpos, &ypos) @@ -4643,7 +4640,7 @@ resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) if (coord_mode != "") { - CoordMode(Mouse, current_coord_mode) + CoordMode("Mouse", current_coord_mode) } return resp @@ -4707,13 +4704,13 @@ current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { - CoordMode(Mouse, relative_to) + CoordMode("Mouse", relative_to) } Click(x, y, button, direction, r) if (relative_to != "") { - CoordMode(Mouse, current_coord_rel) + CoordMode("Mouse", current_coord_rel) } return FormatNoValueResponse() @@ -4769,13 +4766,13 @@ current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { - CoordMode(Mouse, relative_to) + CoordMode("Mouse", relative_to) } MouseClickDrag(button, x1, y1, x2, y2, speed, relative) if (relative_to != "") { - CoordMode(Mouse, current_coord_rel) + CoordMode("Mouse", current_coord_rel) } return FormatNoValueResponse() @@ -4880,7 +4877,7 @@ SetKeyDelay(key_delay, key_press_duration) } - SendRaw(str) + Send("{Raw}" str) if (key_delay != "" or key_press_duration != "") { SetKeyDelay(current_delay, current_key_duration) @@ -4940,7 +4937,7 @@ current_key_duration := Format("{}", A_KeyDurationPlay) if (key_delay != "" or key_press_duration != "") { - SetKeyDelay(key_delay, key_press_duration, Play) + SetKeyDelay(key_delay, key_press_duration, "Play") } SendPlay(str) @@ -4968,9 +4965,9 @@ {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { - Menu Tray, NoIcon + A_IconHidden := true Sleep 200 ; It may be necessary to adjust this sleep. - Menu Tray, Icon + A_IconHidden := false } {% endblock HideTrayTip %} } @@ -5255,7 +5252,7 @@ AHKWinFromMouse(command) { {% block AHKWinFromMouse %} - MouseGetPos(,, MouseWin) + MouseGetPos(,, &MouseWin) if (MouseWin = "") { return FormatNoValueResponse() @@ -5493,12 +5490,12 @@ AHKMenuTrayTip(command) { value := command[2] - Menu(Tray, Tip, value) + A_IconTip := value return FormatNoValueResponse() } AHKMenuTrayShow(command) { - Menu(Tray, Icon) + A_IconHidden := 0 return FormatNoValueResponse() } @@ -5506,17 +5503,17 @@ filename := command[2] icon_number := command[3] freeze := command[4] - Menu(Tray, Icon, filename, icon_number,freeze) + TraySetIcon(filename, icon_number, freeze) return FormatNoValueResponse() } -AHKGuiNew(command) { - - options := command[2] - title := command[3] - Gui(New, options, title) - return FormatResponse("ahk.message.StringResponseMessage", hwnd) -} +;AHKGuiNew(command) { +; +; options := command[2] +; title := command[3] +; Gui(New, options, title) +; return FormatResponse("ahk.message.StringResponseMessage", hwnd) +;} AHKMsgBox(command) { @@ -5681,36 +5678,36 @@ ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. return LC_Base64_Decode_Text(pszString) - if (pszString = "") { - return "" - } - - cchString := StrLen(pszString) - - dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. - getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) - buff_size := 0 ; The function will write to this variable on our first call - pdwSkip := 0 ; We don't use any headers or preamble, so this is zero - pdwFlags := 0 ; We don't need this, so make it null - - ; The first call calculates the required size. The result is written to pbBinary - success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) - if (success = 0) { - return "" - } - - ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value - ret := Buffer(buff_size, 0) -; granted := VarSetStrCapacity(&ret, buff_size) - - ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to - - success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) - if (success=0) { - return "" - } - - return StrGet(ret, "UTF-8") +; if (pszString = "") { +; return "" +; } +; +; cchString := StrLen(pszString) +; +; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. +; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) +; buff_size := 0 ; The function will write to this variable on our first call +; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero +; pdwFlags := 0 ; We don't need this, so make it null +; +; ; The first call calculates the required size. The result is written to pbBinary +; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success = 0) { +; return "" +; } +; +; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value +; ret := Buffer(buff_size, 0) +;; granted := VarSetStrCapacity(&ret, buff_size) +; +; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to +; +; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success=0) { +; return "" +; } +; +; return StrGet(ret, "UTF-8") } b64encode(data) { @@ -5722,30 +5719,30 @@ ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer LC_Base64_Encode(&Base64_, &data, data.Size) return Base64_ - cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) - if (cbBinary = 0) { - return "" - } - - dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF - - ; First step is to get the size so we can set the capacity of our return buffer correctly - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) - if (success = 0) { - msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) - throw Exception(msg, -1) - } - - VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) - - ; Now we do the conversion to base64 and rteturn the string - - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) - if (success = 0) { - msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) - throw Exception(msg, -1) - } - return ret +; cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) +; if (cbBinary = 0) { +; return "" +; } +; +; dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF +; +; ; First step is to get the size so we can set the capacity of our return buffer correctly +; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) +; if (success = 0) { +; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) +; throw Exception(msg, -1) +; } +; +; VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) +; +; ; Now we do the conversion to base64 and rteturn the string +; +; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) +; if (success = 0) { +; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) +; throw Exception(msg, -1) +; } +; return ret } CommandArrayFromQuery(text) { diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index c38dd3c..3ecb9da 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -1,8 +1,8 @@ {% block daemon_script %} {% block directives %} ;#NoEnv -;#Persistent #Requires Autohotkey >= 2.0- +Persistent #Warn All, Off #SingleInstance Off ; BEGIN user-defined directives @@ -896,14 +896,11 @@ AHKWinGetControlList(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - ahkid := WinGetID(title, text, extitle, extext) - - if (ahkid = "") { - return FormatNoValueResponse() - } - try { + ahkid := WinGetID(title, text, extitle, extext) + if (ahkid = "") { + return FormatNoValueResponse() + } ctrList := WinGetControls(title, text, extitle, extext) ctrListID := WinGetControlsHwnd(title, text, extitle, extext) } @@ -922,8 +919,8 @@ AHKWinGetControlList(command) { output := Format("('{}', [", ahkid) - for index, hwnd in ctrListIDArr { - classname := ctrListArr[index] + for index, hwnd in ctrListID { + classname := ctrList[index] output .= Format("('{}', '{}'), ", hwnd, classname) } @@ -1364,7 +1361,7 @@ AHKWinSetEnable(command) { DetectHiddenWindows(detect_hw) } try { - WinSetEnabled(title, text, extitle, extext) + WinSetEnabled(1, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -1400,7 +1397,7 @@ AHKWinSetDisable(command) { DetectHiddenWindows(detect_hw) } try { - WinSetDisabled(title, text, extitle, extext) + WinSetEnabled(0, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -1646,7 +1643,7 @@ AHKImageSearch(command) { current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } if (x2 = "A_ScreenWidth") { @@ -1664,7 +1661,7 @@ AHKImageSearch(command) { } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -1683,7 +1680,7 @@ AHKPixelGetColor(command) { current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } try { @@ -1691,7 +1688,7 @@ AHKPixelGetColor(command) { } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -1714,7 +1711,7 @@ AHKPixelSearch(command) { current_mode := Format("{}", A_CoordModePixel) if (coord_mode != "") { - CoordMode(Pixel, coord_mode) + CoordMode("Pixel", coord_mode) } try { if (PixelSearch(&resultx, &resulty, x1, y1, x2, y2, color, variation) = 1) { @@ -1726,7 +1723,7 @@ AHKPixelSearch(command) { } finally { if (coord_mode != "") { - CoordMode(Pixel, current_mode) + CoordMode("Pixel", current_mode) } } @@ -1741,7 +1738,7 @@ AHKMouseGetPos(command) { coord_mode := command[2] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { - CoordMode(Mouse, coord_mode) + CoordMode("Mouse", coord_mode) } MouseGetPos(&xpos, &ypos) @@ -1749,7 +1746,7 @@ AHKMouseGetPos(command) { resp := FormatResponse("ahk.message.CoordinateResponseMessage", payload) if (coord_mode != "") { - CoordMode(Mouse, current_coord_mode) + CoordMode("Mouse", current_coord_mode) } return resp @@ -1813,13 +1810,13 @@ AHKClick(command) { current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { - CoordMode(Mouse, relative_to) + CoordMode("Mouse", relative_to) } Click(x, y, button, direction, r) if (relative_to != "") { - CoordMode(Mouse, current_coord_rel) + CoordMode("Mouse", current_coord_rel) } return FormatNoValueResponse() @@ -1875,13 +1872,13 @@ AHKMouseClickDrag(command) { current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { - CoordMode(Mouse, relative_to) + CoordMode("Mouse", relative_to) } MouseClickDrag(button, x1, y1, x2, y2, speed, relative) if (relative_to != "") { - CoordMode(Mouse, current_coord_rel) + CoordMode("Mouse", current_coord_rel) } return FormatNoValueResponse() @@ -1986,7 +1983,7 @@ AHKSendRaw(command) { SetKeyDelay(key_delay, key_press_duration) } - SendRaw(str) + Send("{Raw}" str) if (key_delay != "" or key_press_duration != "") { SetKeyDelay(current_delay, current_key_duration) @@ -2046,7 +2043,7 @@ AHKSendPlay(command) { current_key_duration := Format("{}", A_KeyDurationPlay) if (key_delay != "" or key_press_duration != "") { - SetKeyDelay(key_delay, key_press_duration, Play) + SetKeyDelay(key_delay, key_press_duration, "Play") } SendPlay(str) @@ -2074,9 +2071,9 @@ HideTrayTip(command) { {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { - Menu Tray, NoIcon + A_IconHidden := true Sleep 200 ; It may be necessary to adjust this sleep. - Menu Tray, Icon + A_IconHidden := false } {% endblock HideTrayTip %} } @@ -2361,7 +2358,7 @@ AHKControlSend(command) { AHKWinFromMouse(command) { {% block AHKWinFromMouse %} - MouseGetPos(,, MouseWin) + MouseGetPos(,, &MouseWin) if (MouseWin = "") { return FormatNoValueResponse() @@ -2599,12 +2596,12 @@ AHKBlockInput(command) { AHKMenuTrayTip(command) { value := command[2] - Menu(Tray, Tip, value) + A_IconTip := value return FormatNoValueResponse() } AHKMenuTrayShow(command) { - Menu(Tray, Icon) + A_IconHidden := 0 return FormatNoValueResponse() } @@ -2612,17 +2609,17 @@ AHKMenuTrayIcon(command) { filename := command[2] icon_number := command[3] freeze := command[4] - Menu(Tray, Icon, filename, icon_number,freeze) + TraySetIcon(filename, icon_number, freeze) return FormatNoValueResponse() } -AHKGuiNew(command) { - - options := command[2] - title := command[3] - Gui(New, options, title) - return FormatResponse("ahk.message.StringResponseMessage", hwnd) -} +;AHKGuiNew(command) { +; +; options := command[2] +; title := command[3] +; Gui(New, options, title) +; return FormatResponse("ahk.message.StringResponseMessage", hwnd) +;} AHKMsgBox(command) { @@ -2787,36 +2784,36 @@ b64decode(pszString) { ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. return LC_Base64_Decode_Text(pszString) - if (pszString = "") { - return "" - } - - cchString := StrLen(pszString) - - dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. - getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) - buff_size := 0 ; The function will write to this variable on our first call - pdwSkip := 0 ; We don't use any headers or preamble, so this is zero - pdwFlags := 0 ; We don't need this, so make it null - - ; The first call calculates the required size. The result is written to pbBinary - success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) - if (success = 0) { - return "" - } - - ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value - ret := Buffer(buff_size, 0) -; granted := VarSetStrCapacity(&ret, buff_size) - - ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to - - success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) - if (success=0) { - return "" - } - - return StrGet(ret, "UTF-8") +; if (pszString = "") { +; return "" +; } +; +; cchString := StrLen(pszString) +; +; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. +; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) +; buff_size := 0 ; The function will write to this variable on our first call +; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero +; pdwFlags := 0 ; We don't need this, so make it null +; +; ; The first call calculates the required size. The result is written to pbBinary +; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success = 0) { +; return "" +; } +; +; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value +; ret := Buffer(buff_size, 0) +;; granted := VarSetStrCapacity(&ret, buff_size) +; +; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to +; +; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success=0) { +; return "" +; } +; +; return StrGet(ret, "UTF-8") } b64encode(data) { @@ -2828,30 +2825,30 @@ b64encode(data) { ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer LC_Base64_Encode(&Base64_, &data, data.Size) return Base64_ - cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) - if (cbBinary = 0) { - return "" - } - - dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF - - ; First step is to get the size so we can set the capacity of our return buffer correctly - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) - if (success = 0) { - msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) - throw Exception(msg, -1) - } - - VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) - - ; Now we do the conversion to base64 and rteturn the string - - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) - if (success = 0) { - msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) - throw Exception(msg, -1) - } - return ret +; cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) +; if (cbBinary = 0) { +; return "" +; } +; +; dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF +; +; ; First step is to get the size so we can set the capacity of our return buffer correctly +; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) +; if (success = 0) { +; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) +; throw Exception(msg, -1) +; } +; +; VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) +; +; ; Now we do the conversion to base64 and rteturn the string +; +; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) +; if (success = 0) { +; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) +; throw Exception(msg, -1) +; } +; return ret } CommandArrayFromQuery(text) { From a45e10d119c023d787978630b7c24c38e582f403 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 13:13:56 -0700 Subject: [PATCH 26/52] fix controlsend arg order, fix script tests for not found window --- ahk/_constants.py | 2 +- ahk/templates/daemon-v2.ahk | 2 +- tests/_async/test_scripts.py | 6 +++--- tests/_sync/test_scripts.py | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 505dc99..c98988a 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -5238,7 +5238,7 @@ } try { - ControlSend(ctrl, keys, title, text, extitle, extext) + ControlSend(keys, ctrl, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 3ecb9da..bfa30b6 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -2344,7 +2344,7 @@ AHKControlSend(command) { } try { - ControlSend(ctrl, keys, title, text, extitle, extext) + ControlSend(keys, ctrl, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) diff --git a/tests/_async/test_scripts.py b/tests/_async/test_scripts.py index 6afb46a..7766c9c 100644 --- a/tests/_async/test_scripts.py +++ b/tests/_async/test_scripts.py @@ -67,20 +67,20 @@ async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(version='v2') async def test_run_script_text(self): - assert await self.ahk.win_get(title='Untitled - Notepad') is None + assert not await self.ahk.exists(title='Untitled - Notepad') script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' result = await self.ahk.run_script(script) assert result == 'foobar' async def test_run_script_file(self): - assert await self.ahk.win_get(title='Untitled - Notepad') is None + assert not await self.ahk.exists(title='Untitled - Notepad') with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') res = await self.ahk.run_script(f.name) assert res == 'foobar' async def test_run_script_file_unicode(self): - assert await self.ahk.win_get(title='Untitled - Notepad') is None + assert not await self.ahk.exists(title='Untitled - Notepad') subprocess.Popen('Notepad') await self.ahk.win_wait(title='Untitled - Notepad', timeout=3) with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: diff --git a/tests/_sync/test_scripts.py b/tests/_sync/test_scripts.py index ae48e13..09c8769 100644 --- a/tests/_sync/test_scripts.py +++ b/tests/_sync/test_scripts.py @@ -67,20 +67,20 @@ def setUp(self) -> None: self.ahk = AHK(version='v2') def test_run_script_text(self): - assert self.ahk.win_get(title='Untitled - Notepad') is None + assert not self.ahk.exists(title='Untitled - Notepad') script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' result = self.ahk.run_script(script) assert result == 'foobar' def test_run_script_file(self): - assert self.ahk.win_get(title='Untitled - Notepad') is None + assert not self.ahk.exists(title='Untitled - Notepad') with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') res = self.ahk.run_script(f.name) assert res == 'foobar' def test_run_script_file_unicode(self): - assert self.ahk.win_get(title='Untitled - Notepad') is None + assert not self.ahk.exists(title='Untitled - Notepad') subprocess.Popen('Notepad') self.ahk.win_wait(title='Untitled - Notepad', timeout=3) with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: From 41d4e2f046b030864bb4cfe4aa2c02325e3d3fad Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 15:30:17 -0700 Subject: [PATCH 27/52] v2 window functionality --- ahk/_async/engine.py | 2 +- ahk/_async/window.py | 15 +++++++++------ ahk/_constants.py | 38 +++++++++++++++++++++++++++---------- ahk/_sync/engine.py | 2 +- ahk/_sync/window.py | 25 +++++++++++++++--------- ahk/templates/daemon-v2.ahk | 38 +++++++++++++++++++++++++++---------- tests/_async/test_window.py | 14 +++++++++++--- tests/_sync/test_window.py | 14 +++++++++++--- 8 files changed, 105 insertions(+), 43 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 6f34927..fb58598 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -1204,7 +1204,7 @@ async def send_input(self, s: str, *, blocking: bool = True) -> Union[None, Asyn """ Analog for `SendInput `_ """ - args = [s] + args = [s, '', ''] resp = await self._transport.function_call('AHKSendInput', args, blocking=blocking) return resp diff --git a/ahk/_async/window.py b/ahk/_async/window.py index 5de120a..08229b0 100644 --- a/ahk/_async/window.py +++ b/ahk/_async/window.py @@ -54,7 +54,7 @@ def __init__(self, engine: AsyncAHK, ahk_id: str): self._ahk_id: str = ahk_id def __repr__(self) -> str: - return f'<{self.__class__.__qualname__} ahk_id={self._ahk_id}>' + return f'<{self.__class__.__qualname__} ahk_id={self._ahk_id!r}>' def __eq__(self, other: object) -> bool: if not isinstance(other, AsyncWindow): @@ -302,17 +302,20 @@ def always_on_top(self, toggle: Literal['On', 'Off', 'Toggle', 1, -1, 0]) -> Any # fmt: off @overload - async def send(self, keys: str) -> None: ... + async def send(self, keys: str, control: str = '') -> None: ... @overload - async def send(self, keys: str, *, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + async def send(self, keys: str, control: str = '', *, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def send(self, keys: str, *, blocking: Literal[True]) -> None: ... + async def send(self, keys: str, control: str = '', *, blocking: Literal[True]) -> None: ... @overload - async def send(self, keys: str, *, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + async def send(self, keys: str, control: str = '', *, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... # fmt: on - async def send(self, keys: str, *, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: + async def send( + self, keys: str, control: str = '', *, blocking: bool = True + ) -> Union[None, AsyncFutureResult[None]]: return await self._engine.control_send( keys=keys, + control=control, title=f'ahk_id {self._ahk_id}', blocking=blocking, detect_hidden_windows=True, diff --git a/ahk/_constants.py b/ahk/_constants.py index c98988a..0bd28f1 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -3056,13 +3056,18 @@ if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinClose(title, text, secondstowait, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + if (secondstowait != "") { + WinClose(title, text, secondstowait, extitle, extext) + } else { + WinClose(title, text,, extitle, extext) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinClose %} } @@ -4039,7 +4044,7 @@ DetectHiddenWindows(detect_hw) } try { - WinSetTitle(title, text, new_title, extitle, extext) + WinSetTitle(new_title, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -4074,6 +4079,15 @@ if (detect_hw != "") { DetectHiddenWindows(detect_hw) } + + if (toggle = "On") { + toggle := 1 + } else if (toggle = "Off") { + toggle := 0 + } else if (toggle = "") { + toggle := 1 + } + try { WinSetAlwaysOnTop(toggle, title, text, extitle, extext) } @@ -5238,7 +5252,11 @@ } try { - ControlSend(keys, ctrl, title, text, extitle, extext) + if (ctrl != "") { + ControlSendText(keys, ctrl, title, text, extitle, extext) + } else { + ControlSendText(keys,, title, text, extitle, extext) + } } finally { DetectHiddenWindows(current_detect_hw) @@ -5306,7 +5324,7 @@ } try { - WinMove(title, text, x, y, width, height, extitle, extext) + WinMove(x, y, width, height, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 4858e43..c0b464d 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -1192,7 +1192,7 @@ def send_input(self, s: str, *, blocking: bool = True) -> Union[None, FutureResu """ Analog for `SendInput `_ """ - args = [s] + args = [s, '', ''] resp = self._transport.function_call('AHKSendInput', args, blocking=blocking) return resp diff --git a/ahk/_sync/window.py b/ahk/_sync/window.py index 30d0a8b..baaed41 100644 --- a/ahk/_sync/window.py +++ b/ahk/_sync/window.py @@ -50,7 +50,7 @@ def __init__(self, engine: AHK, ahk_id: str): self._ahk_id: str = ahk_id def __repr__(self) -> str: - return f'<{self.__class__.__qualname__} ahk_id={self._ahk_id}>' + return f'<{self.__class__.__qualname__} ahk_id={self._ahk_id!r}>' def __eq__(self, other: object) -> bool: if not isinstance(other, Window): @@ -61,11 +61,15 @@ def __hash__(self) -> int: return hash(self._ahk_id) def close(self) -> None: - self._engine.win_close(title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast')) + self._engine.win_close( + title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast') + ) return None def kill(self) -> None: - self._engine.win_kill(title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast')) + self._engine.win_kill( + title=f'ahk_id {self._ahk_id}', detect_hidden_windows=True, title_match_mode=(1, 'Fast') + ) def exists(self) -> bool: return self._engine.win_exists( @@ -277,17 +281,18 @@ def always_on_top(self, toggle: Literal['On', 'Off', 'Toggle', 1, -1, 0]) -> Any # fmt: off @overload - def send(self, keys: str) -> None: ... + def send(self, keys: str, control: str = '') -> None: ... @overload - def send(self, keys: str, *, blocking: Literal[False]) -> FutureResult[None]: ... + def send(self, keys: str, control: str = '', *, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def send(self, keys: str, *, blocking: Literal[True]) -> None: ... + def send(self, keys: str, control: str = '', *, blocking: Literal[True]) -> None: ... @overload - def send(self, keys: str, *, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + def send(self, keys: str, control: str = '', *, blocking: bool = True) -> Union[None, FutureResult[None]]: ... # fmt: on - def send(self, keys: str, *, blocking: bool = True) -> Union[None, FutureResult[None]]: + def send(self, keys: str, control: str = '', *, blocking: bool = True) -> Union[None, FutureResult[None]]: return self._engine.control_send( keys=keys, + control=control, title=f'ahk_id {self._ahk_id}', blocking=blocking, detect_hidden_windows=True, @@ -587,7 +592,9 @@ def set_transparent( blocking=blocking, ) - def set_trans_color(self, color: Union[int, str], *, blocking: bool = True) -> Union[None, FutureResult[None]]: + def set_trans_color( + self, color: Union[int, str], *, blocking: bool = True + ) -> Union[None, FutureResult[None]]: return self._engine.win_set_trans_color( color=color, title=f'ahk_id {self._ahk_id}', diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index bfa30b6..09a9128 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -162,13 +162,18 @@ AHKWinClose(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinClose(title, text, secondstowait, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + if (secondstowait != "") { + WinClose(title, text, secondstowait, extitle, extext) + } else { + WinClose(title, text,, extitle, extext) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinClose %} } @@ -1145,7 +1150,7 @@ AHKWinSetTitle(command) { DetectHiddenWindows(detect_hw) } try { - WinSetTitle(title, text, new_title, extitle, extext) + WinSetTitle(new_title, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) @@ -1180,6 +1185,15 @@ AHKWinSetAlwaysOnTop(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } + + if (toggle = "On") { + toggle := 1 + } else if (toggle = "Off") { + toggle := 0 + } else if (toggle = "") { + toggle := 1 + } + try { WinSetAlwaysOnTop(toggle, title, text, extitle, extext) } @@ -2344,7 +2358,11 @@ AHKControlSend(command) { } try { - ControlSend(keys, ctrl, title, text, extitle, extext) + if (ctrl != "") { + ControlSendText(keys, ctrl, title, text, extitle, extext) + } else { + ControlSendText(keys,, title, text, extitle, extext) + } } finally { DetectHiddenWindows(current_detect_hw) @@ -2412,7 +2430,7 @@ AHKWinMove(command) { } try { - WinMove(title, text, x, y, width, height, extitle, extext) + WinMove(x, y, width, height, title, text, extitle, extext) } finally { DetectHiddenWindows(current_detect_hw) diff --git a/tests/_async/test_window.py b/tests/_async/test_window.py index 0865443..d5ab5d4 100644 --- a/tests/_async/test_window.py +++ b/tests/_async/test_window.py @@ -6,6 +6,10 @@ import tracemalloc from unittest import IsolatedAsyncioTestCase +import pytest + +import ahk + tracemalloc.start() from ahk import AsyncAHK @@ -113,12 +117,12 @@ async def test_win_set_title(self): assert await self.win.get_title() == 'Foo' async def test_control_send_window(self): - await self.win.send('hello world') + await self.win.send('hello world', control='Edit1') text = await self.win.get_text() assert 'hello world' in text async def test_send_literal_comma(self): - await self.win.send('hello, world') + await self.win.send('hello, world', control='Edit1') text = await self.win.get_text() assert 'hello, world' in text @@ -131,7 +135,7 @@ async def test_type_escape(self): async def test_send_literal_tilde_n(self): expected_text = '```nim\nimport std/strformat\n```' - await self.win.send(expected_text) + await self.win.send(expected_text, control='Edit1') text = await self.win.get_text() assert '```nim' in text assert '\nimport std/strformat' in text @@ -197,3 +201,7 @@ async def asyncSetUp(self) -> None: time.sleep(1) self.win = await self.ahk.win_get(title='Untitled - Notepad') self.assertIsNotNone(self.win) + + async def test_win_get_returns_none_nonexistent(self): + with pytest.raises(ahk.message.AHKExecutionException): + win = await self.ahk.win_get(title='DOES NOT EXIST') diff --git a/tests/_sync/test_window.py b/tests/_sync/test_window.py index 55c63b1..66ea08a 100644 --- a/tests/_sync/test_window.py +++ b/tests/_sync/test_window.py @@ -6,6 +6,10 @@ import tracemalloc from unittest import TestCase +import pytest + +import ahk + tracemalloc.start() from ahk import AHK @@ -113,12 +117,12 @@ def test_win_set_title(self): assert self.win.get_title() == 'Foo' def test_control_send_window(self): - self.win.send('hello world') + self.win.send('hello world', control='Edit1') text = self.win.get_text() assert 'hello world' in text def test_send_literal_comma(self): - self.win.send('hello, world') + self.win.send('hello, world', control='Edit1') text = self.win.get_text() assert 'hello, world' in text @@ -131,7 +135,7 @@ def test_type_escape(self): def test_send_literal_tilde_n(self): expected_text = '```nim\nimport std/strformat\n```' - self.win.send(expected_text) + self.win.send(expected_text, control='Edit1') text = self.win.get_text() assert '```nim' in text assert '\nimport std/strformat' in text @@ -197,3 +201,7 @@ def setUp(self) -> None: time.sleep(1) self.win = self.ahk.win_get(title='Untitled - Notepad') self.assertIsNotNone(self.win) + + def test_win_get_returns_none_nonexistent(self): + with pytest.raises(ahk.message.AHKExecutionException): + win = self.ahk.win_get(title='DOES NOT EXIST') From 5def14e348b34f7824089a4c4cbccce8af3e0a59 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 16:20:09 -0700 Subject: [PATCH 28/52] v2 hotkeys --- _set_constants.py | 6 ++ ahk/_async/transport.py | 4 +- ahk/_constants.py | 179 ++++++++++++++++++++++++++++++++++- ahk/_hotkey.py | 30 +++++- ahk/_sync/transport.py | 7 +- ahk/templates/daemon-v2.ahk | 4 +- ahk/templates/hotkeys-v2.ahk | 169 +++++++++++++++++++++++++++++++++ ahk/templates/hotkeys.ahk | 1 + tests/_async/test_keys.py | 4 +- tests/_async/test_scripts.py | 6 +- tests/_sync/test_keys.py | 4 +- tests/_sync/test_scripts.py | 6 +- 12 files changed, 397 insertions(+), 23 deletions(-) create mode 100644 ahk/templates/hotkeys-v2.ahk diff --git a/_set_constants.py b/_set_constants.py index 50c5471..a44a283 100644 --- a/_set_constants.py +++ b/_set_constants.py @@ -11,6 +11,9 @@ with open('ahk/templates/daemon-v2.ahk') as fv2: daemon_script_v2 = fv2.read() +with open('ahk/templates/hotkeys-v2.ahk') as hotkeyfilev2: + hotkey_script_v2 = hotkeyfilev2.read() + GIT_EXECUTABLE = shutil.which('git') if not GIT_EXECUTABLE: @@ -28,6 +31,9 @@ DAEMON_SCRIPT_V2_TEMPLATE = r"""{daemon_script_v2} """ + +HOTKEYS_SCRIPT_V2_TEMPLATE = r"""{hotkey_script_v2} +""" ''' with open('ahk/_constants.py', encoding='utf-8') as f: diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 68f0233..2483066 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -357,7 +357,9 @@ def __init__( **kwargs: Any, ): self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) - self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives) + self._hotkey_transport = ThreadedHotkeyTransport( + executable_path=self._executable_path, directives=directives, version=version + ) self._directives: list[Union[Directive, Type[Directive]]] = directives or [] self._version: Literal['v1', 'v2'] = version or 'v1' diff --git a/ahk/_constants.py b/ahk/_constants.py index 0bd28f1..1da5599 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2791,7 +2791,8 @@ """ -HOTKEYS_SCRIPT_TEMPLATE = r"""#Persistent +HOTKEYS_SCRIPT_TEMPLATE = r"""#Requires AutoHotkey v1.1.17+ +#Persistent {% for directive in directives %} {% if directive.apply_to_hotkeys_process %} @@ -4814,9 +4815,9 @@ value := command[5] ; RegWrite(value_type, key_name, value_name, value) if (value_name != "") { - RegWrite(value, value_type, key_name) - } else { RegWrite(value, value_type, key_name, value_name) + } else { + RegWrite(value, value_type, key_name) } return FormatNoValueResponse() {% endblock RegWrite %} @@ -5822,3 +5823,175 @@ {% endblock daemon_script %} """ + +HOTKEYS_SCRIPT_V2_TEMPLATE = r"""#Requires AutoHotkey >= 2.0- +{% for directive in directives %} +{% if directive.apply_to_hotkeys_process %} + +{{ directive }} +{% endif %} +{% endfor %} + +{% if on_clipboard %} +OnClipboardChange("ClipChanged") +{% endif %} +KEEPALIVE := Chr(57344) +;SetTimer, keepalive, 1000 + +stdout := FileOpen("*", "w", "UTF-8") + +WriteStdout(s) { + global stdout + Critical "On" + stdout.Write(s) + stdout.Read(0) + Critical "Off" +} + +; LC_* functions are substantially from Libcrypt +; Modified from https://github.com/ahkscript/libcrypt.ahk +; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 +; Original License: +; The MIT License (MIT) +; +; Copyright (c) 2014 The ahkscript community (ahkscript.org) +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in all +; copies or substantial portions of the Software. + + +LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") +{ + Bin_ := Buffer(StrPut(Text_, Encoding_)) + LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) + return Base64_ +} + +LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") +{ + Len_ := LC_Base64_Decode(&Bin_, &Text_) + return StrGet(StrPtr(Bin_), Len_, Encoding_) +} + +LC_Base64_Encode(&Out_, &In_, In_Len) +{ + return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) +} + +LC_Base64_Decode(&Out_, &In_) +{ + return LC_Str2Bin(&Out_, &In_, 0x1) +} + +LC_Bin2Str(&Out_, &In_, In_Len, Flags_) +{ + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) + VarSetStrCapacity(&Out_, Out_Len * 2) + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) + return Out_Len +} + +LC_Str2Bin(&Out_, &In_, Flags_) +{ + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) + VarSetStrCapacity(&Out_, Out_Len) + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) + return Out_Len +} +; End of libcrypt code + +b64decode(pszString) { + ; TODO load DLL globally for performance + ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw + ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. + ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. + ; [in] DWORD dwFlags, Indicates the format of the string to be converted. (see table in link above) + ; [in] BYTE *pbBinary, A pointer to a buffer that receives the returned sequence of bytes. If this parameter is NULL, the function calculates the length of the buffer needed and returns the size, in bytes, of required memory in the DWORD pointed to by pcbBinary. + ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. + ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. + ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. + return LC_Base64_Decode_Text(pszString) +; if (pszString = "") { +; return "" +; } +; +; cchString := StrLen(pszString) +; +; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. +; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) +; buff_size := 0 ; The function will write to this variable on our first call +; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero +; pdwFlags := 0 ; We don't need this, so make it null +; +; ; The first call calculates the required size. The result is written to pbBinary +; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success = 0) { +; return "" +; } +; +; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value +; ret := Buffer(buff_size, 0) +;; granted := VarSetStrCapacity(&ret, buff_size) +; +; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to +; +; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success=0) { +; return "" +; } +; +; return StrGet(ret, "UTF-8") +} + + +{% for hotkey in hotkeys %} + +{{ hotkey.keyname }}:: +{ + WriteStdout("{{ hotkey._id }}`n") + return +} +{% endfor %} + +{% for hotstring in hotstrings %} +{% if hotstring.replacement %} +:{{ hotstring.options }}:{{ hotstring.trigger }}:: + hostring_{{ hotstring._id }}_func(hs) { + replacement_b64 := "{{ hotstring._replacement_as_b64 }}" + replacement := b64decode(replacement_b64) + Send(replacement) + } +{% else %} +:{{ hotstring.options }}:{{ hotstring.trigger }}:: + hostring_{{ hotstring._id }}_func(hs) { + WriteStdout("{{ hotstring._id }}`n") + } +{% endif %} + + +{% endfor %} + +{% if on_clipboard %} + + +ClipChanged(Type) { + CLIPBOARD_SENTINEL := Chr(57345) + ret := Format("{}{}`n", CLIPBOARD_SENTINEL, Type) + WriteStdout(ret) + return +} +{% endif %} + + +;keepalive: +;global KEEPALIVE +;FileAppend, %KEEPALIVE%`n, *, UTF-8 + +""" diff --git a/ahk/_hotkey.py b/ahk/_hotkey.py index f36ebab..a3058bf 100644 --- a/ahk/_hotkey.py +++ b/ahk/_hotkey.py @@ -16,6 +16,7 @@ from typing import Callable from typing import Dict from typing import List +from typing import Literal from typing import Optional from typing import Protocol from typing import runtime_checkable @@ -38,7 +39,7 @@ from queue import Queue from ahk._utils import hotkey_escape -from ._constants import HOTKEYS_SCRIPT_TEMPLATE as _HOTKEY_SCRIPT +from ._constants import HOTKEYS_SCRIPT_TEMPLATE as _HOTKEY_SCRIPT, HOTKEYS_SCRIPT_V2_TEMPLATE as _HOTKEY_V2_SCRIPT P_HotkeyCallbackParam = ParamSpec('P_HotkeyCallbackParam') T_HotkeyCallbackReturn = TypeVar('T_HotkeyCallbackReturn') @@ -64,7 +65,9 @@ def __init__( executable_path: str, default_ex_handler: Optional[Callable[[str, Exception], Any]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, + version: Optional[Literal['v1', 'v2']] = None, ): + self._version = version self._executable_path = executable_path self._hotkeys: Dict[str, Hotkey] = {} self._default_ex_handler: Callable[[str, Exception], Any] = default_ex_handler or _default_ex_handler @@ -165,14 +168,30 @@ def __init__( executable_path: str, default_ex_handler: Optional[Callable[[str, Exception], Any]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, + version: Optional[Literal['v1', 'v2']] = None, ): - super().__init__(executable_path=executable_path, default_ex_handler=default_ex_handler, directives=directives) + super().__init__( + executable_path=executable_path, + default_ex_handler=default_ex_handler, + directives=directives, + version=version, + ) self._callback_threads: List[threading.Thread] = [] self._proc: Optional[subprocess.Popen[bytes]] = None self._callback_queue: Queue[Union[str, Type[STOP]]] = Queue() self._listener_thread: Optional[threading.Thread] = None self._dispatcher_thread: Optional[threading.Thread] = None loader: jinja2.BaseLoader + + if version is None or version == 'v1': + template_name = 'hotkeys.ahk' + const_script = _HOTKEY_SCRIPT + elif version == 'v2': + template_name = 'hotkeys-v2.ahk' + const_script = _HOTKEY_V2_SCRIPT + else: + raise ValueError(f'Invalid version {version!r}') + try: loader = jinja2.PackageLoader('ahk', 'templates') except ValueError: @@ -185,10 +204,10 @@ def __init__( self._jinja_env: jinja2.Environment = jinja2.Environment(loader=loader, autoescape=False) self._template: jinja2.Template try: - self._template = self._jinja_env.get_template('hotkeys.ahk') + self._template = self._jinja_env.get_template(template_name) except jinja2.TemplateNotFound: warnings.warn('hotkey template not found, falling back to constant', category=UserWarning) - self._template = self._jinja_env.from_string(_HOTKEY_SCRIPT) + self._template = self._jinja_env.from_string(const_script) def _do_callback( self, @@ -314,12 +333,13 @@ def listener(self) -> None: [self._executable_path, '/CP65001', '/ErrorStdOut', exc_file], stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + stderr=subprocess.STDOUT, ) atexit.register(kill, self._proc) while self._running: assert self._proc.stdout is not None line = self._proc.stdout.readline() + print(line, file=sys.stderr) if line.rstrip(b'\n') == _KEEPALIVE_SENTINEL: logging.debug('keepalive received') continue diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index ef7c74b..caaf58c 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -44,7 +44,10 @@ from ahk.message import ResponseMessage from ahk.message import Position from ahk.message import _message_registry -from ahk._constants import DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE +from ahk._constants import ( + DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, + DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, +) from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor @@ -335,7 +338,7 @@ def __init__( **kwargs: Any, ): self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) - self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives) + self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives, version=version) self._directives: list[Union[Directive, Type[Directive]]] = directives or [] self._version: Literal['v1', 'v2'] = version or 'v1' diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 09a9128..98bb484 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -1920,9 +1920,9 @@ AHKRegWrite(command) { value := command[5] ; RegWrite(value_type, key_name, value_name, value) if (value_name != "") { - RegWrite(value, value_type, key_name) - } else { RegWrite(value, value_type, key_name, value_name) + } else { + RegWrite(value, value_type, key_name) } return FormatNoValueResponse() {% endblock RegWrite %} diff --git a/ahk/templates/hotkeys-v2.ahk b/ahk/templates/hotkeys-v2.ahk new file mode 100644 index 0000000..0619dee --- /dev/null +++ b/ahk/templates/hotkeys-v2.ahk @@ -0,0 +1,169 @@ +#Requires AutoHotkey >= 2.0- +{% for directive in directives %} +{% if directive.apply_to_hotkeys_process %} + +{{ directive }} +{% endif %} +{% endfor %} + +{% if on_clipboard %} +OnClipboardChange("ClipChanged") +{% endif %} +KEEPALIVE := Chr(57344) +;SetTimer, keepalive, 1000 + +stdout := FileOpen("*", "w", "UTF-8") + +WriteStdout(s) { + global stdout + Critical "On" + stdout.Write(s) + stdout.Read(0) + Critical "Off" +} + +; LC_* functions are substantially from Libcrypt +; Modified from https://github.com/ahkscript/libcrypt.ahk +; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 +; Original License: +; The MIT License (MIT) +; +; Copyright (c) 2014 The ahkscript community (ahkscript.org) +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in all +; copies or substantial portions of the Software. + + +LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") +{ + Bin_ := Buffer(StrPut(Text_, Encoding_)) + LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) + return Base64_ +} + +LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") +{ + Len_ := LC_Base64_Decode(&Bin_, &Text_) + return StrGet(StrPtr(Bin_), Len_, Encoding_) +} + +LC_Base64_Encode(&Out_, &In_, In_Len) +{ + return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) +} + +LC_Base64_Decode(&Out_, &In_) +{ + return LC_Str2Bin(&Out_, &In_, 0x1) +} + +LC_Bin2Str(&Out_, &In_, In_Len, Flags_) +{ + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) + VarSetStrCapacity(&Out_, Out_Len * 2) + DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) + return Out_Len +} + +LC_Str2Bin(&Out_, &In_, Flags_) +{ + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) + VarSetStrCapacity(&Out_, Out_Len) + DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) + return Out_Len +} +; End of libcrypt code + +b64decode(pszString) { + ; TODO load DLL globally for performance + ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw + ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. + ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. + ; [in] DWORD dwFlags, Indicates the format of the string to be converted. (see table in link above) + ; [in] BYTE *pbBinary, A pointer to a buffer that receives the returned sequence of bytes. If this parameter is NULL, the function calculates the length of the buffer needed and returns the size, in bytes, of required memory in the DWORD pointed to by pcbBinary. + ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. + ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. + ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. + return LC_Base64_Decode_Text(pszString) +; if (pszString = "") { +; return "" +; } +; +; cchString := StrLen(pszString) +; +; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. +; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) +; buff_size := 0 ; The function will write to this variable on our first call +; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero +; pdwFlags := 0 ; We don't need this, so make it null +; +; ; The first call calculates the required size. The result is written to pbBinary +; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success = 0) { +; return "" +; } +; +; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value +; ret := Buffer(buff_size, 0) +;; granted := VarSetStrCapacity(&ret, buff_size) +; +; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to +; +; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) +; if (success=0) { +; return "" +; } +; +; return StrGet(ret, "UTF-8") +} + + +{% for hotkey in hotkeys %} + +{{ hotkey.keyname }}:: +{ + WriteStdout("{{ hotkey._id }}`n") + return +} +{% endfor %} + +{% for hotstring in hotstrings %} +{% if hotstring.replacement %} +:{{ hotstring.options }}:{{ hotstring.trigger }}:: + hostring_{{ hotstring._id }}_func(hs) { + replacement_b64 := "{{ hotstring._replacement_as_b64 }}" + replacement := b64decode(replacement_b64) + Send(replacement) + } +{% else %} +:{{ hotstring.options }}:{{ hotstring.trigger }}:: + hostring_{{ hotstring._id }}_func(hs) { + WriteStdout("{{ hotstring._id }}`n") + } +{% endif %} + + +{% endfor %} + +{% if on_clipboard %} + + +ClipChanged(Type) { + CLIPBOARD_SENTINEL := Chr(57345) + ret := Format("{}{}`n", CLIPBOARD_SENTINEL, Type) + WriteStdout(ret) + return +} +{% endif %} + + +;keepalive: +;global KEEPALIVE +;FileAppend, %KEEPALIVE%`n, *, UTF-8 diff --git a/ahk/templates/hotkeys.ahk b/ahk/templates/hotkeys.ahk index d40361d..0857134 100644 --- a/ahk/templates/hotkeys.ahk +++ b/ahk/templates/hotkeys.ahk @@ -1,3 +1,4 @@ +#Requires AutoHotkey v1.1.17+ #Persistent {% for directive in directives %} {% if directive.apply_to_hotkeys_process %} diff --git a/tests/_async/test_keys.py b/tests/_async/test_keys.py index d06309c..a5116c5 100644 --- a/tests/_async/test_keys.py +++ b/tests/_async/test_keys.py @@ -13,7 +13,7 @@ sleep = time.sleep -class TestWindowAsync(unittest.IsolatedAsyncioTestCase): +class TestKeysAsync(unittest.IsolatedAsyncioTestCase): win: AsyncWindow async def asyncSetUp(self) -> None: @@ -79,7 +79,7 @@ async def test_hotstring_callback(self): m.assert_called() -class TestWindowAsyncV2(TestWindowAsync): +class TestKeysAsyncV2(TestKeysAsync): async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(version='v2') self.p = subprocess.Popen('notepad') diff --git a/tests/_async/test_scripts.py b/tests/_async/test_scripts.py index 7766c9c..0019006 100644 --- a/tests/_async/test_scripts.py +++ b/tests/_async/test_scripts.py @@ -67,20 +67,20 @@ async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(version='v2') async def test_run_script_text(self): - assert not await self.ahk.exists(title='Untitled - Notepad') + assert not await self.ahk.win_exists(title='Untitled - Notepad') script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' result = await self.ahk.run_script(script) assert result == 'foobar' async def test_run_script_file(self): - assert not await self.ahk.exists(title='Untitled - Notepad') + assert not await self.ahk.win_exists(title='Untitled - Notepad') with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') res = await self.ahk.run_script(f.name) assert res == 'foobar' async def test_run_script_file_unicode(self): - assert not await self.ahk.exists(title='Untitled - Notepad') + assert not await self.ahk.win_exists(title='Untitled - Notepad') subprocess.Popen('Notepad') await self.ahk.win_wait(title='Untitled - Notepad', timeout=3) with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: diff --git a/tests/_sync/test_keys.py b/tests/_sync/test_keys.py index 4a18cdf..9f68239 100644 --- a/tests/_sync/test_keys.py +++ b/tests/_sync/test_keys.py @@ -12,7 +12,7 @@ sleep = time.sleep -class TestWindowAsync(unittest.TestCase): +class TestKeysAsync(unittest.TestCase): win: Window def setUp(self) -> None: @@ -78,7 +78,7 @@ def test_hotstring_callback(self): m.assert_called() -class TestWindowAsyncV2(TestWindowAsync): +class TestKeysAsyncV2(TestKeysAsync): def setUp(self) -> None: self.ahk = AHK(version='v2') self.p = subprocess.Popen('notepad') diff --git a/tests/_sync/test_scripts.py b/tests/_sync/test_scripts.py index 09c8769..2bfec2f 100644 --- a/tests/_sync/test_scripts.py +++ b/tests/_sync/test_scripts.py @@ -67,20 +67,20 @@ def setUp(self) -> None: self.ahk = AHK(version='v2') def test_run_script_text(self): - assert not self.ahk.exists(title='Untitled - Notepad') + assert not self.ahk.win_exists(title='Untitled - Notepad') script = 'stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)' result = self.ahk.run_script(script) assert result == 'foobar' def test_run_script_file(self): - assert not self.ahk.exists(title='Untitled - Notepad') + assert not self.ahk.win_exists(title='Untitled - Notepad') with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False) as f: f.write('stdout := FileOpen("*", "w", "UTF-8")\nstdout.Write("foobar")\nstdout.Read(0)') res = self.ahk.run_script(f.name) assert res == 'foobar' def test_run_script_file_unicode(self): - assert not self.ahk.exists(title='Untitled - Notepad') + assert not self.ahk.win_exists(title='Untitled - Notepad') subprocess.Popen('Notepad') self.ahk.win_wait(title='Untitled - Notepad', timeout=3) with tempfile.NamedTemporaryFile(suffix='.ahk', mode='w', delete=False, encoding='utf-8') as f: From 19500a92718701c460a4fd50c139a5808fc7ef5a Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 16:39:40 -0700 Subject: [PATCH 29/52] remove debug print --- ahk/_hotkey.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ahk/_hotkey.py b/ahk/_hotkey.py index a3058bf..07e2c16 100644 --- a/ahk/_hotkey.py +++ b/ahk/_hotkey.py @@ -339,7 +339,6 @@ def listener(self) -> None: while self._running: assert self._proc.stdout is not None line = self._proc.stdout.readline() - print(line, file=sys.stderr) if line.rstrip(b'\n') == _KEEPALIVE_SENTINEL: logging.debug('keepalive received') continue From 9170f9ec015510c5dcc508036160e881d9feac40 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 21:54:38 -0700 Subject: [PATCH 30/52] fix base64 encoding ; versioned extensions --- ahk/_async/engine.py | 4 +- ahk/_constants.py | 212 +++++++++++++---------------------- ahk/_sync/engine.py | 4 +- ahk/extensions.py | 2 + ahk/templates/daemon-v2.ahk | 205 +++++++++++++-------------------- ahk/templates/hotkeys-v2.ahk | 7 +- tests/_async/test_screen.py | 7 +- tests/_sync/test_screen.py | 7 +- 8 files changed, 174 insertions(+), 274 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index fb58598..8ec6b8c 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -148,7 +148,7 @@ def __init__( self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': - self._extensions = list(_extension_registry) + self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)] else: self._extensions = _resolve_extensions(extensions) if extensions else [] self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) @@ -2785,6 +2785,8 @@ async def image_search( if coord_mode is not None: args.append(coord_mode) + else: + args.append('') resp = await self._transport.function_call('AHKImageSearch', args, blocking=blocking) return resp diff --git a/ahk/_constants.py b/ahk/_constants.py index 1da5599..4d7abcb 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2898,7 +2898,7 @@ ;#NoEnv #Requires Autohotkey >= 2.0- Persistent -#Warn All, Off +;#Warn All, Off #SingleInstance Off ; BEGIN user-defined directives {% block user_directives %} @@ -3097,13 +3097,18 @@ if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinKill(title, text, secondstowait, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + if (secondstowait != "") { + WinKill(title, text, secondstowait, extitle, extext) + } else { + WinKill(title, text,, extitle, extext) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinKill %} } @@ -4563,10 +4568,11 @@ } try { - if ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) + if (ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) = 1) { s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) - else + } else { s := FormatNoValueResponse() + } } finally { if (coord_mode != "") { @@ -5467,7 +5473,7 @@ AHKGetClipboardAll(command) { {% block AHKGetClipboardAll %} data := ClipboardAll() - return FormatBinaryResponse(data) + return FormatBinaryResponse(&data) {% endblock AHKGetClipboardAll %} } @@ -5484,7 +5490,7 @@ ; TODO there should be a way for us to accept a base64 string instead filename := command[2] contents := FileRead(filename, "RAW") - ClipboardAll(contents) + A_Clipboard := ClipboardAll(contents) return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } @@ -5627,66 +5633,7 @@ return ret } -; LC_* functions are substantially from Libcrypt -; Modified from https://github.com/ahkscript/libcrypt.ahk -; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 -; Original License: -; The MIT License (MIT) -; -; Copyright (c) 2014 The ahkscript community (ahkscript.org) -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this software and associated documentation files (the "Software"), to deal -; in the Software without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of the Software, and to permit persons to whom the Software is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in all -; copies or substantial portions of the Software. - - -LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") -{ - Bin_ := Buffer(StrPut(Text_, Encoding_)) - LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) - return Base64_ -} - -LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") -{ - Len_ := LC_Base64_Decode(&Bin_, &Text_) - return StrGet(StrPtr(Bin_), Len_, Encoding_) -} - -LC_Base64_Encode(&Out_, &In_, In_Len) -{ - return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) -} - -LC_Base64_Decode(&Out_, &In_) -{ - return LC_Str2Bin(&Out_, &In_, 0x1) -} - -LC_Bin2Str(&Out_, &In_, In_Len, Flags_) -{ - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) - VarSetStrCapacity(&Out_, Out_Len * 2) - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) - return Out_Len -} - -LC_Str2Bin(&Out_, &In_, Flags_) -{ - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) - VarSetStrCapacity(&Out_, Out_Len) - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) - return Out_Len -} -; End of libcrypt code - -b64decode(pszString) { +b64decode(&pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. @@ -5696,74 +5643,72 @@ ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. - return LC_Base64_Decode_Text(pszString) -; if (pszString = "") { -; return "" -; } -; -; cchString := StrLen(pszString) -; -; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. -; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) ; buff_size := 0 ; The function will write to this variable on our first call -; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero -; pdwFlags := 0 ; We don't need this, so make it null -; -; ; The first call calculates the required size. The result is written to pbBinary -; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success = 0) { -; return "" -; } -; -; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value -; ret := Buffer(buff_size, 0) -;; granted := VarSetStrCapacity(&ret, buff_size) -; -; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to -; -; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success=0) { -; return "" -; } -; -; return StrGet(ret, "UTF-8") + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", &buff_size := 0, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret.Ptr, "UIntP", &buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + return StrGet(ret, "UTF-8") } -b64encode(data) { + +b64encode(&data) { ; REF: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa ; [in] const BYTE *pbBinary: A pointer to the array of bytes to be converted into a string. ; [in] DWORD cbBinary: The number of elements in the pbBinary array. ; [in] DWORD dwFlags: Specifies the format of the resulting formatted string (see table in REF) ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer - LC_Base64_Encode(&Base64_, &data, data.Size) - return Base64_ -; cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) -; if (cbBinary = 0) { -; return "" -; } -; -; dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF -; -; ; First step is to get the size so we can set the capacity of our return buffer correctly -; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) -; if (success = 0) { -; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) -; throw Exception(msg, -1) -; } -; -; VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) -; -; ; Now we do the conversion to base64 and rteturn the string -; -; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) -; if (success = 0) { -; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) -; throw Exception(msg, -1) -; } -; return ret + + cbBinary := data.Size + if (cbBinary = 0) { + return "" + } + dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF + + ; First step is to get the size so we can set the capacity of our return buffer correctly + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", &buff_size := 0) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Error(msg, -1) + } + + VarSetStrCapacity(&ret, buff_size * 2) + + ; Now we do the conversion to base64 and rteturn the string + + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", &buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Error(msg, -1) + } + return ret } + CommandArrayFromQuery(text) { decoded_commands := [] encoded_array := StrSplit(text, "|") @@ -5771,7 +5716,7 @@ encoded_array.RemoveAt(1) decoded_commands.push(function_name) for index, encoded_value in encoded_array { - decoded_value := b64decode(encoded_value) + decoded_value := b64decode(&encoded_value) decoded_commands.push(decoded_value) } return decoded_commands @@ -5832,9 +5777,7 @@ {% endif %} {% endfor %} -{% if on_clipboard %} -OnClipboardChange("ClipChanged") -{% endif %} + KEEPALIVE := Chr(57344) ;SetTimer, keepalive, 1000 @@ -5987,6 +5930,9 @@ WriteStdout(ret) return } + +OnClipboardChange(ClipChanged) + {% endif %} diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index c0b464d..1a0246e 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -144,7 +144,7 @@ def __init__( self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': - self._extensions = list(_extension_registry) + self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)] else: self._extensions = _resolve_extensions(extensions) if extensions else [] self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) @@ -2773,6 +2773,8 @@ def image_search( if coord_mode is not None: args.append(coord_mode) + else: + args.append('') resp = self._transport.function_call('AHKImageSearch', args, blocking=blocking) return resp diff --git a/ahk/extensions.py b/ahk/extensions.py index ee71c9d..88b387d 100644 --- a/ahk/extensions.py +++ b/ahk/extensions.py @@ -81,7 +81,9 @@ def __init__( script_text: str | None = None, includes: list[str] | None = None, dependencies: list[Extension] | None = None, + requires_autohotkey: typing.Literal['v1', 'v2'] | None = None, ): + self._requires = requires_autohotkey self._text: str = script_text or '' self._includes: list[str] = includes or [] self.dependencies: list[Extension] = dependencies or [] diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 98bb484..2e41cd8 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -3,7 +3,7 @@ ;#NoEnv #Requires Autohotkey >= 2.0- Persistent -#Warn All, Off +;#Warn All, Off #SingleInstance Off ; BEGIN user-defined directives {% block user_directives %} @@ -202,13 +202,18 @@ AHKWinKill(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinKill(title, text, secondstowait, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + if (secondstowait != "") { + WinKill(title, text, secondstowait, extitle, extext) + } else { + WinKill(title, text,, extitle, extext) + } + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinKill %} } @@ -1668,10 +1673,11 @@ AHKImageSearch(command) { } try { - if ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) + if (ImageSearch(&xpos, &ypos, x1, y1, x2, y2, imagepath) = 1) { s := FormatResponse("ahk.message.CoordinateResponseMessage", Format("({}, {})", xpos, ypos)) - else + } else { s := FormatNoValueResponse() + } } finally { if (coord_mode != "") { @@ -2572,7 +2578,7 @@ AHKGetClipboard(command) { AHKGetClipboardAll(command) { {% block AHKGetClipboardAll %} data := ClipboardAll() - return FormatBinaryResponse(data) + return FormatBinaryResponse(&data) {% endblock AHKGetClipboardAll %} } @@ -2589,7 +2595,7 @@ AHKSetClipboardAll(command) { ; TODO there should be a way for us to accept a base64 string instead filename := command[2] contents := FileRead(filename, "RAW") - ClipboardAll(contents) + A_Clipboard := ClipboardAll(contents) return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } @@ -2732,66 +2738,7 @@ AHKFileSelectFolder(command) { return ret } -; LC_* functions are substantially from Libcrypt -; Modified from https://github.com/ahkscript/libcrypt.ahk -; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 -; Original License: -; The MIT License (MIT) -; -; Copyright (c) 2014 The ahkscript community (ahkscript.org) -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this software and associated documentation files (the "Software"), to deal -; in the Software without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of the Software, and to permit persons to whom the Software is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in all -; copies or substantial portions of the Software. - - -LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") -{ - Bin_ := Buffer(StrPut(Text_, Encoding_)) - LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) - return Base64_ -} - -LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") -{ - Len_ := LC_Base64_Decode(&Bin_, &Text_) - return StrGet(StrPtr(Bin_), Len_, Encoding_) -} - -LC_Base64_Encode(&Out_, &In_, In_Len) -{ - return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) -} - -LC_Base64_Decode(&Out_, &In_) -{ - return LC_Str2Bin(&Out_, &In_, 0x1) -} - -LC_Bin2Str(&Out_, &In_, In_Len, Flags_) -{ - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) - VarSetStrCapacity(&Out_, Out_Len * 2) - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) - return Out_Len -} - -LC_Str2Bin(&Out_, &In_, Flags_) -{ - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) - VarSetStrCapacity(&Out_, Out_Len) - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) - return Out_Len -} -; End of libcrypt code - -b64decode(pszString) { +b64decode(&pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. @@ -2801,74 +2748,72 @@ b64decode(pszString) { ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. - return LC_Base64_Decode_Text(pszString) -; if (pszString = "") { -; return "" -; } -; -; cchString := StrLen(pszString) -; -; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. -; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) ; buff_size := 0 ; The function will write to this variable on our first call -; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero -; pdwFlags := 0 ; We don't need this, so make it null -; -; ; The first call calculates the required size. The result is written to pbBinary -; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success = 0) { -; return "" -; } -; -; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value -; ret := Buffer(buff_size, 0) -;; granted := VarSetStrCapacity(&ret, buff_size) -; -; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to -; -; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success=0) { -; return "" -; } -; -; return StrGet(ret, "UTF-8") + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", &buff_size := 0, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret.Ptr, "UIntP", &buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + return StrGet(ret, "UTF-8") } -b64encode(data) { + +b64encode(&data) { ; REF: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptbinarytostringa ; [in] const BYTE *pbBinary: A pointer to the array of bytes to be converted into a string. ; [in] DWORD cbBinary: The number of elements in the pbBinary array. ; [in] DWORD dwFlags: Specifies the format of the resulting formatted string (see table in REF) ; [out, optional] LPSTR pszString: A pointer to the string, or null (0) to calculate size ; [in, out] DWORD *pcchString: A pointer to a DWORD variable that contains the size, in TCHARs, of the pszString buffer - LC_Base64_Encode(&Base64_, &data, data.Size) - return Base64_ -; cbBinary := StrLen(data) * (A_IsUnicode ? 2 : 1) -; if (cbBinary = 0) { -; return "" -; } -; -; dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF -; -; ; First step is to get the size so we can set the capacity of our return buffer correctly -; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", buff_size) -; if (success = 0) { -; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) -; throw Exception(msg, -1) -; } -; -; VarSetCapacity(ret, buff_size * (A_IsUnicode ? 2 : 1)) -; -; ; Now we do the conversion to base64 and rteturn the string -; -; success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) -; if (success = 0) { -; msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) -; throw Exception(msg, -1) -; } -; return ret + + cbBinary := data.Size + if (cbBinary = 0) { + return "" + } + dwFlags := 0x00000001 | 0x40000000 ; CRYPT_STRING_BASE64 + CRYPT_STRING_NOCRLF + + ; First step is to get the size so we can set the capacity of our return buffer correctly + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Ptr", 0, "UIntP", &buff_size := 0) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Error(msg, -1) + } + + VarSetStrCapacity(&ret, buff_size * 2) + + ; Now we do the conversion to base64 and rteturn the string + + success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", &buff_size) + if (success = 0) { + msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) + throw Error(msg, -1) + } + return ret } + CommandArrayFromQuery(text) { decoded_commands := [] encoded_array := StrSplit(text, "|") @@ -2876,7 +2821,7 @@ CommandArrayFromQuery(text) { encoded_array.RemoveAt(1) decoded_commands.push(function_name) for index, encoded_value in encoded_array { - decoded_value := b64decode(encoded_value) + decoded_value := b64decode(&encoded_value) decoded_commands.push(decoded_value) } return decoded_commands diff --git a/ahk/templates/hotkeys-v2.ahk b/ahk/templates/hotkeys-v2.ahk index 0619dee..9ce3677 100644 --- a/ahk/templates/hotkeys-v2.ahk +++ b/ahk/templates/hotkeys-v2.ahk @@ -6,9 +6,7 @@ {% endif %} {% endfor %} -{% if on_clipboard %} -OnClipboardChange("ClipChanged") -{% endif %} + KEEPALIVE := Chr(57344) ;SetTimer, keepalive, 1000 @@ -161,6 +159,9 @@ ClipChanged(Type) { WriteStdout(ret) return } + +OnClipboardChange(ClipChanged) + {% endif %} diff --git a/tests/_async/test_screen.py b/tests/_async/test_screen.py index 5efc408..5cf283c 100644 --- a/tests/_async/test_screen.py +++ b/tests/_async/test_screen.py @@ -1,5 +1,6 @@ import asyncio import os +import pathlib import threading import time from itertools import product @@ -43,7 +44,7 @@ async def test_image_search(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = await self.ahk.image_search('testimage.png') + position = await self.ahk.image_search(str(pathlib.Path('testimage.png').absolute())) assert isinstance(position, tuple) async def test_pixel_search(self): @@ -53,7 +54,7 @@ async def test_pixel_search(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = await self.ahk.image_search('testimage.png') + position = await self.ahk.image_search(str(pathlib.Path('testimage.png').absolute())) assert position is not None x, y = position color = await self.ahk.pixel_get_color(x, y) @@ -71,7 +72,7 @@ async def test_image_search_with_option(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = await self.ahk.image_search('testimage.png', color_variation=50) + position = await self.ahk.image_search(str(pathlib.Path('testimage.png').absolute()), color_variation=50) assert isinstance(position, tuple) # async def test_pixel_get_color(self): diff --git a/tests/_sync/test_screen.py b/tests/_sync/test_screen.py index fb2164e..45e4d5f 100644 --- a/tests/_sync/test_screen.py +++ b/tests/_sync/test_screen.py @@ -1,5 +1,6 @@ import asyncio import os +import pathlib import threading import time from itertools import product @@ -43,7 +44,7 @@ def test_image_search(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = self.ahk.image_search('testimage.png') + position = self.ahk.image_search(str(pathlib.Path('testimage.png').absolute())) assert isinstance(position, tuple) def test_pixel_search(self): @@ -53,7 +54,7 @@ def test_pixel_search(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = self.ahk.image_search('testimage.png') + position = self.ahk.image_search(str(pathlib.Path('testimage.png').absolute())) assert position is not None x, y = position color = self.ahk.pixel_get_color(x, y) @@ -71,7 +72,7 @@ def test_image_search_with_option(self): self._show_in_thread() time.sleep(3) self.im.save('testimage.png') - position = self.ahk.image_search('testimage.png', color_variation=50) + position = self.ahk.image_search(str(pathlib.Path('testimage.png').absolute()), color_variation=50) assert isinstance(position, tuple) # async def test_pixel_get_color(self): From 39669b74818b4c7fec63684a0f302537c0c6f48c Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Tue, 19 Sep 2023 23:47:42 -0700 Subject: [PATCH 31/52] fix base64 decoding for hotkey scripts --- ahk/templates/hotkeys-v2.ahk | 121 +++++++++-------------------------- 1 file changed, 31 insertions(+), 90 deletions(-) diff --git a/ahk/templates/hotkeys-v2.ahk b/ahk/templates/hotkeys-v2.ahk index 9ce3677..e13e746 100644 --- a/ahk/templates/hotkeys-v2.ahk +++ b/ahk/templates/hotkeys-v2.ahk @@ -20,66 +20,8 @@ WriteStdout(s) { Critical "Off" } -; LC_* functions are substantially from Libcrypt -; Modified from https://github.com/ahkscript/libcrypt.ahk -; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 -; Original License: -; The MIT License (MIT) -; -; Copyright (c) 2014 The ahkscript community (ahkscript.org) -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this software and associated documentation files (the "Software"), to deal -; in the Software without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of the Software, and to permit persons to whom the Software is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in all -; copies or substantial portions of the Software. - - -LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") -{ - Bin_ := Buffer(StrPut(Text_, Encoding_)) - LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) - return Base64_ -} - -LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") -{ - Len_ := LC_Base64_Decode(&Bin_, &Text_) - return StrGet(StrPtr(Bin_), Len_, Encoding_) -} - -LC_Base64_Encode(&Out_, &In_, In_Len) -{ - return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) -} - -LC_Base64_Decode(&Out_, &In_) -{ - return LC_Str2Bin(&Out_, &In_, 0x1) -} - -LC_Bin2Str(&Out_, &In_, In_Len, Flags_) -{ - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) - VarSetStrCapacity(&Out_, Out_Len * 2) - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) - return Out_Len -} -LC_Str2Bin(&Out_, &In_, Flags_) -{ - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) - VarSetStrCapacity(&Out_, Out_Len) - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) - return Out_Len -} -; End of libcrypt code - -b64decode(pszString) { +b64decode(&pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. @@ -89,40 +31,39 @@ b64decode(pszString) { ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. - return LC_Base64_Decode_Text(pszString) -; if (pszString = "") { -; return "" -; } -; -; cchString := StrLen(pszString) -; -; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. -; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) ; buff_size := 0 ; The function will write to this variable on our first call -; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero -; pdwFlags := 0 ; We don't need this, so make it null -; -; ; The first call calculates the required size. The result is written to pbBinary -; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success = 0) { -; return "" -; } -; -; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value -; ret := Buffer(buff_size, 0) -;; granted := VarSetStrCapacity(&ret, buff_size) -; -; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to -; -; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success=0) { -; return "" -; } -; -; return StrGet(ret, "UTF-8") + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", &buff_size := 0, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret.Ptr, "UIntP", &buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + return StrGet(ret, "UTF-8") } + {% for hotkey in hotkeys %} {{ hotkey.keyname }}:: @@ -137,7 +78,7 @@ b64decode(pszString) { :{{ hotstring.options }}:{{ hotstring.trigger }}:: hostring_{{ hotstring._id }}_func(hs) { replacement_b64 := "{{ hotstring._replacement_as_b64 }}" - replacement := b64decode(replacement_b64) + replacement := b64decode(&replacement_b64) Send(replacement) } {% else %} From 2054def561ae9a9fae043b45f33ddc5f07a43423 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 06:48:06 +0000 Subject: [PATCH 32/52] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ahk/_constants.py | 121 ++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 90 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 4d7abcb..3599844 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -5791,66 +5791,8 @@ Critical "Off" } -; LC_* functions are substantially from Libcrypt -; Modified from https://github.com/ahkscript/libcrypt.ahk -; Ref: https://www.autohotkey.com/boards/viewtopic.php?t=112821 -; Original License: -; The MIT License (MIT) -; -; Copyright (c) 2014 The ahkscript community (ahkscript.org) -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this software and associated documentation files (the "Software"), to deal -; in the Software without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of the Software, and to permit persons to whom the Software is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in all -; copies or substantial portions of the Software. - - -LC_Base64_Encode_Text(Text_, Encoding_ := "UTF-8") -{ - Bin_ := Buffer(StrPut(Text_, Encoding_)) - LC_Base64_Encode(&Base64_, &Bin_, StrPut(Text_, Bin_, Encoding_) - 1) - return Base64_ -} - -LC_Base64_Decode_Text(Text_, Encoding_ := "UTF-8") -{ - Len_ := LC_Base64_Decode(&Bin_, &Text_) - return StrGet(StrPtr(Bin_), Len_, Encoding_) -} - -LC_Base64_Encode(&Out_, &In_, In_Len) -{ - return LC_Bin2Str(&Out_, &In_, In_Len, 0x40000001) -} - -LC_Base64_Decode(&Out_, &In_) -{ - return LC_Str2Bin(&Out_, &In_, 0x1) -} - -LC_Bin2Str(&Out_, &In_, In_Len, Flags_) -{ - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0) - VarSetStrCapacity(&Out_, Out_Len * 2) - DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", In_, "UInt", In_Len, "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len) - return Out_Len -} -LC_Str2Bin(&Out_, &In_, Flags_) -{ - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Ptr", 0, "UInt*", &Out_Len := 0, "Ptr", 0, "Ptr", 0) - VarSetStrCapacity(&Out_, Out_Len) - DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(In_), "UInt", StrLen(In_), "UInt", Flags_, "Str", Out_, "UInt*", &Out_Len, "Ptr", 0, "Ptr", 0) - return Out_Len -} -; End of libcrypt code - -b64decode(pszString) { +b64decode(&pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. @@ -5860,40 +5802,39 @@ ; [in, out] DWORD *pcbBinary, A pointer to a DWORD variable that, on entry, contains the size, in bytes, of the pbBinary buffer. After the function returns, this variable contains the number of bytes copied to the buffer. If this value is not large enough to contain all of the data, the function fails and GetLastError returns ERROR_MORE_DATA. ; [out] DWORD *pdwSkip, A pointer to a DWORD value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header. If no header is present, then the DWORD is set to zero. This parameter is optional and can be NULL if it is not needed. ; [out] DWORD *pdwFlags A pointer to a DWORD value that receives the flags actually used in the conversion. These are the same flags used for the dwFlags parameter. In many cases, these will be the same flags that were passed in the dwFlags parameter. If dwFlags contains one of the following flags, this value will receive a flag that indicates the actual format of the string. This parameter is optional and can be NULL if it is not needed. - return LC_Base64_Decode_Text(pszString) -; if (pszString = "") { -; return "" -; } -; -; cchString := StrLen(pszString) -; -; dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. -; getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) + + if (pszString = "") { + return "" + } + + cchString := StrLen(pszString) + + dwFlags := 0x00000001 ; CRYPT_STRING_BASE64: Base64, without headers. + getsize := 0 ; When this is NULL, the function returns the required size in bytes (for our first call, which is needed for our subsequent call) ; buff_size := 0 ; The function will write to this variable on our first call -; pdwSkip := 0 ; We don't use any headers or preamble, so this is zero -; pdwFlags := 0 ; We don't need this, so make it null -; -; ; The first call calculates the required size. The result is written to pbBinary -; success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success = 0) { -; return "" -; } -; -; ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value -; ret := Buffer(buff_size, 0) -;; granted := VarSetStrCapacity(&ret, buff_size) -; -; ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to -; -; success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) -; if (success=0) { -; return "" -; } -; -; return StrGet(ret, "UTF-8") + pdwSkip := 0 ; We don't use any headers or preamble, so this is zero + pdwFlags := 0 ; We don't need this, so make it null + + ; The first call calculates the required size. The result is written to pbBinary + success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", &buff_size := 0, "Int", pdwSkip, "Int", pdwFlags ) + if (success = 0) { + return "" + } + + ; We're going to give a pointer to a variable to the next call, but first we want to make the buffer the correct size using VarSetCapacity using the previous return value + ret := Buffer(buff_size) + + ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to + + success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", StrPtr(pszString), "UInt", cchString, "UInt", dwFlags, "Ptr", ret.Ptr, "UIntP", &buff_size, "Int", pdwSkip, "Int", pdwFlags ) + if (success=0) { + return "" + } + return StrGet(ret, "UTF-8") } + {% for hotkey in hotkeys %} {{ hotkey.keyname }}:: @@ -5908,7 +5849,7 @@ :{{ hotstring.options }}:{{ hotstring.trigger }}:: hostring_{{ hotstring._id }}_func(hs) { replacement_b64 := "{{ hotstring._replacement_as_b64 }}" - replacement := b64decode(replacement_b64) + replacement := b64decode(&replacement_b64) Send(replacement) } {% else %} From c6741d85c529ec498afdacb39f4b030e0d8619f8 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 11:57:41 -0700 Subject: [PATCH 33/52] add project urls --- setup.cfg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup.cfg b/setup.cfg index ad170b6..91ecdf0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,6 +8,11 @@ description = A Python wrapper for AHK long_description = file: docs/README.md long_description_content_type = text/markdown url = https://github.com/spyoungtech/ahk +project_urls = + Documentation = https://ahk.readthedocs.io/en/latest/ + Funding = https://github.com/sponsors/spyoungtech/ + Source = https://github.com/spyoungtech/ahk + Tracker = https://github.com/spyoungtech/ahk/issues keywords = ahk autohotkey From 6c5d33e1298b2c508bb9cb15214816866955adf1 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 15:11:46 -0700 Subject: [PATCH 34/52] add AutoHotkey version autodetection --- ahk/_async/engine.py | 6 ++ ahk/_async/transport.py | 137 ++++++++++++++++++-------------- ahk/_sync/engine.py | 6 ++ ahk/_sync/transport.py | 137 +++++++++++++++++--------------- ahk/_utils.py | 96 ++++++++++++++++++++++ buildunasync.py | 3 +- tests/_async/test_hotkeys.py | 2 +- tests/_async/test_versioning.py | 45 +++++++++++ tests/_sync/test_hotkeys.py | 2 +- tests/_sync/test_versioning.py | 45 +++++++++++ 10 files changed, 354 insertions(+), 125 deletions(-) create mode 100644 tests/_async/test_versioning.py create mode 100644 tests/_sync/test_versioning.py diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 8ec6b8c..74a8b09 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -3735,3 +3735,9 @@ async def block_forever(self) -> NoReturn: """ while True: await async_sleep(1) + + async def get_version(self) -> str: + return await self._transport._get_full_version() + + async def get_major_version(self) -> Literal['v1', 'v2']: + return await self._transport._get_major_version() diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 2483066..2daa5d7 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -3,6 +3,7 @@ import asyncio.subprocess import atexit import os +import re import subprocess import sys import tempfile @@ -11,7 +12,6 @@ from abc import ABC from abc import abstractmethod from io import BytesIO -from shutil import which from typing import Any from typing import Callable from typing import Generic @@ -48,11 +48,11 @@ DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, ) +from ahk._utils import _version_detection_script, _resolve_executable_path, _get_executable_major_version from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor -DEFAULT_EXECUTABLE_PATH = r'C:\Program Files\AutoHotkey\AutoHotkey.exe' T_AsyncFuture = TypeVar('T_AsyncFuture') # unasync: remove T_SyncFuture = TypeVar('T_SyncFuture') @@ -216,7 +216,9 @@ class Communicable(Protocol): def communicate(self, input_bytes: Optional[bytes], timeout: Optional[int] = None) -> Tuple[bytes, bytes]: ... - async def acommunicate(self, input_bytes: Optional[bytes], timeout: Optional[int] = None) -> Tuple[bytes, bytes]: + async def acommunicate( # unasync: remove + self, input_bytes: Optional[bytes], timeout: Optional[int] = None + ) -> Tuple[bytes, bytes]: ... @property @@ -274,7 +276,7 @@ def kill(self) -> None: assert self._proc is not None, 'no process to kill' self._proc.kill() - async def acommunicate( + async def acommunicate( # unasync: remove self, input_bytes: Optional[bytes] = None, timeout: Optional[int] = None ) -> Tuple[bytes, bytes]: assert self._proc is not None @@ -298,78 +300,49 @@ def sync_create_process(runargs: List[str]) -> subprocess.Popen[bytes]: return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) -class AhkExecutableNotFoundError(EnvironmentError): - pass - - -def _resolve_executable_path(executable_path: str = '', version: Optional[Literal['v1', 'v2']] = None) -> str: - if not executable_path: - executable_path = ( - os.environ.get('AHK_PATH', '') - or (which('AutoHotkeyV2.exe') if version == 'v2' else '') - or (which('AutoHotkey32.exe') if version == 'v2' else '') - or (which('AutoHotkey64.exe') if version == 'v2' else '') - or which('AutoHotkey.exe') - or (which('AutoHotkeyU64.exe') if version != 'v2' else '') - or (which('AutoHotkeyU32.exe') if version != 'v2' else '') - or (which('AutoHotkeyA32.exe') if version != 'v2' else '') - or '' - ) - - if not executable_path: - if os.path.exists(DEFAULT_EXECUTABLE_PATH): - executable_path = DEFAULT_EXECUTABLE_PATH - - if not executable_path: - raise AhkExecutableNotFoundError( - 'Could not find AutoHotkey.exe on PATH. ' - 'Provide the absolute path with the `executable_path` keyword argument ' - 'or in the AHK_PATH environment variable. ' - 'You may be able to resolve this error by installing the binary extra: pip install "ahk[binary]"' - ) - - if not os.path.exists(executable_path): - raise AhkExecutableNotFoundError(f"executable_path does not seems to exist: '{executable_path}' not found") - - if os.path.isdir(executable_path): - raise AhkExecutableNotFoundError( - f'The path {executable_path} appears to be a directory, but should be a file.' - ' Please specify the *full path* to the autohotkey.exe executable file' - ) - executable_path = str(executable_path) - if not executable_path.endswith('.exe'): - warnings.warn( - 'executable_path does not appear to have a .exe extension. This may be the result of a misconfiguration.' - ) - - return executable_path - - class AsyncTransport(ABC): _started: bool = False def __init__( self, /, - executable_path: str = '', directives: Optional[list[Union[Directive, Type[Directive]]]] = None, - version: Optional[Literal['v1', 'v2']] = None, + version: Optional[Literal['v1', 'v2']] = 'v1', + hotkey_transport: Optional[ThreadedHotkeyTransport] = None, **kwargs: Any, ): - self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) - self._hotkey_transport = ThreadedHotkeyTransport( - executable_path=self._executable_path, directives=directives, version=version - ) + self._hotkey_transport = hotkey_transport self._directives: list[Union[Directive, Type[Directive]]] = directives or [] - self._version: Literal['v1', 'v2'] = version or 'v1' + self._version: Optional[Literal['v1', 'v2']] = version + + async def _get_full_version(self) -> str: + res = await self.run_script(_version_detection_script) + version = res.strip() + assert re.match(r'^\d+\.', version) + return version + + async def _get_major_version(self) -> Literal['v1', 'v2']: + version = await self._get_full_version() + match = re.match(r'^(\d+)\.', version) + if not match: + raise ValueError(f'Unexpected version {version!r}') + major_version = match.group(1) + if major_version == '1': + return 'v1' + elif major_version == '2': + return 'v2' + else: + raise ValueError(f'Unexpected version {version!r}') def on_clipboard_change( self, callback: Callable[[int], Any], ex_handler: Optional[Callable[[int, Exception], Any]] = None ) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.on_clipboard_change(callback, ex_handler) return None def add_hotkey(self, hotkey: Hotkey) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' with warnings.catch_warnings(record=True) as caught_warnings: self._hotkey_transport.add_hotkey(hotkey=hotkey) if caught_warnings: @@ -378,6 +351,7 @@ def add_hotkey(self, hotkey: Hotkey) -> None: return None def add_hotstring(self, hotstring: Hotstring) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' with warnings.catch_warnings(record=True) as caught_warnings: self._hotkey_transport.add_hotstring(hotstring=hotstring) if caught_warnings: @@ -386,31 +360,47 @@ def add_hotstring(self, hotstring: Hotstring) -> None: return None def remove_hotkey(self, hotkey: Hotkey) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.remove_hotkey(hotkey) return None def clear_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.clear_hotkeys() return None def remove_hotstring(self, hotstring: Hotstring) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.remove_hotstring(hotstring) return None def clear_hotstrings(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.clear_hotstrings() return None def start_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' return self._hotkey_transport.start() def stop_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' return self._hotkey_transport.stop() async def init(self) -> None: self._started = True return None + # fmt: off + @overload + async def run_script(self, script_text_or_path: str, /, *, timeout: Optional[int] = None) -> str: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: Literal[False], timeout: Optional[int] = None) -> AsyncFutureResult[str]: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: Literal[True], timeout: Optional[int] = None) -> str: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None) -> Union[str, AsyncFutureResult[str]]: ... + # fmt: on @abstractmethod async def run_script( self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None @@ -676,6 +666,7 @@ def __init__( template: Optional[jinja2.Template] = None, extensions: list[Extension] | None = None, version: Optional[Literal['v1', 'v2']] = None, + skip_version_check: bool = False, ): self._extensions = extensions or [] self._proc: Optional[AsyncAHKProcess] @@ -685,6 +676,14 @@ def __init__( self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() self._a_execution_lock = asyncio.Lock() # unasync: remove + self._executable_path = _resolve_executable_path(executable_path=executable_path, version=version) + if version is None: + try: + version = _get_executable_major_version(self._executable_path) + except Exception as e: + warnings.warn(f'Could not detect AHK version ({e}). Defaulting to v1') + version = 'v1' + skip_version_check = True if version is None or version == 'v1': template_name = 'daemon.ahk' @@ -695,6 +694,13 @@ def __init__( else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') + if not skip_version_check: + detected_version = _get_executable_major_version(self._executable_path) + if version != detected_version: + raise RuntimeError( + f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {self._executable_path}' + ) + if jinja_loader is None: try: loader: jinja2.BaseLoader @@ -721,7 +727,10 @@ def __init__( if extensions: includes = _resolve_includes(extensions) directives = includes + directives - super().__init__(executable_path=executable_path, directives=directives, version=version) + hotkey_transport = ThreadedHotkeyTransport( + executable_path=self._executable_path, directives=directives, version=version + ) + super().__init__(directives=directives, version=version, hotkey_transport=hotkey_transport) @property def template(self) -> jinja2.Template: @@ -911,6 +920,16 @@ def f() -> str: pool.shutdown(wait=False) return FutureResult(fut) + # fmt: off + @overload + async def run_script(self, script_text_or_path: str, /, *, timeout: Optional[int] = None) -> str: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: Literal[False], timeout: Optional[int] = None) -> AsyncFutureResult[str]: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: Literal[True], timeout: Optional[int] = None) -> str: ... + @overload + async def run_script(self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None) -> Union[str, AsyncFutureResult[str]]: ... + # fmt: on async def run_script( self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None ) -> Union[str, AsyncFutureResult[str]]: diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 1a0246e..efe26ca 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -3723,3 +3723,9 @@ def block_forever(self) -> NoReturn: """ while True: sleep(1) + + def get_version(self) -> str: + return self._transport._get_full_version() + + def get_major_version(self) -> Literal['v1', 'v2']: + return self._transport._get_major_version() diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index caaf58c..9d23c0d 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -3,6 +3,7 @@ import asyncio.subprocess import atexit import os +import re import subprocess import sys import tempfile @@ -11,7 +12,6 @@ from abc import ABC from abc import abstractmethod from io import BytesIO -from shutil import which from typing import Any from typing import Callable from typing import Generic @@ -48,11 +48,11 @@ DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, ) +from ahk._utils import _version_detection_script, _resolve_executable_path, _get_executable_major_version from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor -DEFAULT_EXECUTABLE_PATH = r'C:\Program Files\AutoHotkey\AutoHotkey.exe' T_SyncFuture = TypeVar('T_SyncFuture') @@ -208,8 +208,6 @@ class Communicable(Protocol): def communicate(self, input_bytes: Optional[bytes], timeout: Optional[int] = None) -> Tuple[bytes, bytes]: ... - def acommunicate(self, input_bytes: Optional[bytes], timeout: Optional[int] = None) -> Tuple[bytes, bytes]: - ... @property def returncode(self) -> Optional[int]: @@ -261,11 +259,6 @@ def kill(self) -> None: assert self._proc is not None, 'no process to kill' self._proc.kill() - def acommunicate( - self, input_bytes: Optional[bytes] = None, timeout: Optional[int] = None - ) -> Tuple[bytes, bytes]: - assert self._proc is not None - return self._proc.communicate(input=input_bytes) def communicate(self, input_bytes: Optional[bytes] = None, timeout: Optional[int] = None) -> Tuple[bytes, bytes]: assert self._proc is not None @@ -279,76 +272,49 @@ def sync_create_process(runargs: List[str]) -> subprocess.Popen[bytes]: return subprocess.Popen(runargs, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) -class AhkExecutableNotFoundError(EnvironmentError): - pass - - -def _resolve_executable_path(executable_path: str = '', version: Optional[Literal['v1', 'v2']] = None) -> str: - if not executable_path: - executable_path = ( - os.environ.get('AHK_PATH', '') - or (which('AutoHotkeyV2.exe') if version == 'v2' else '') - or (which('AutoHotkey32.exe') if version == 'v2' else '') - or (which('AutoHotkey64.exe') if version == 'v2' else '') - or which('AutoHotkey.exe') - or (which('AutoHotkeyU64.exe') if version != 'v2' else '') - or (which('AutoHotkeyU32.exe') if version != 'v2' else '') - or (which('AutoHotkeyA32.exe') if version != 'v2' else '') - or '' - ) - - if not executable_path: - if os.path.exists(DEFAULT_EXECUTABLE_PATH): - executable_path = DEFAULT_EXECUTABLE_PATH - - if not executable_path: - raise AhkExecutableNotFoundError( - 'Could not find AutoHotkey.exe on PATH. ' - 'Provide the absolute path with the `executable_path` keyword argument ' - 'or in the AHK_PATH environment variable. ' - 'You may be able to resolve this error by installing the binary extra: pip install "ahk[binary]"' - ) - - if not os.path.exists(executable_path): - raise AhkExecutableNotFoundError(f"executable_path does not seems to exist: '{executable_path}' not found") - - if os.path.isdir(executable_path): - raise AhkExecutableNotFoundError( - f'The path {executable_path} appears to be a directory, but should be a file.' - ' Please specify the *full path* to the autohotkey.exe executable file' - ) - executable_path = str(executable_path) - if not executable_path.endswith('.exe'): - warnings.warn( - 'executable_path does not appear to have a .exe extension. This may be the result of a misconfiguration.' - ) - - return executable_path - - class Transport(ABC): _started: bool = False def __init__( self, /, - executable_path: str = '', directives: Optional[list[Union[Directive, Type[Directive]]]] = None, - version: Optional[Literal['v1', 'v2']] = None, + version: Optional[Literal['v1', 'v2']] = 'v1', + hotkey_transport: Optional[ThreadedHotkeyTransport] = None, **kwargs: Any, ): - self._executable_path: str = _resolve_executable_path(executable_path=executable_path, version=version) - self._hotkey_transport = ThreadedHotkeyTransport(executable_path=self._executable_path, directives=directives, version=version) + self._hotkey_transport = hotkey_transport self._directives: list[Union[Directive, Type[Directive]]] = directives or [] - self._version: Literal['v1', 'v2'] = version or 'v1' + self._version: Optional[Literal['v1', 'v2']] = version + + def _get_full_version(self) -> str: + res = self.run_script(_version_detection_script) + version = res.strip() + assert re.match(r'^\d+\.', version) + return version + + def _get_major_version(self) -> Literal['v1', 'v2']: + version = self._get_full_version() + match = re.match(r'^(\d+)\.', version) + if not match: + raise ValueError(f'Unexpected version {version!r}') + major_version = match.group(1) + if major_version == '1': + return 'v1' + elif major_version == '2': + return 'v2' + else: + raise ValueError(f'Unexpected version {version!r}') def on_clipboard_change( self, callback: Callable[[int], Any], ex_handler: Optional[Callable[[int, Exception], Any]] = None ) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.on_clipboard_change(callback, ex_handler) return None def add_hotkey(self, hotkey: Hotkey) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' with warnings.catch_warnings(record=True) as caught_warnings: self._hotkey_transport.add_hotkey(hotkey=hotkey) if caught_warnings: @@ -357,6 +323,7 @@ def add_hotkey(self, hotkey: Hotkey) -> None: return None def add_hotstring(self, hotstring: Hotstring) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' with warnings.catch_warnings(record=True) as caught_warnings: self._hotkey_transport.add_hotstring(hotstring=hotstring) if caught_warnings: @@ -365,31 +332,47 @@ def add_hotstring(self, hotstring: Hotstring) -> None: return None def remove_hotkey(self, hotkey: Hotkey) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.remove_hotkey(hotkey) return None def clear_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.clear_hotkeys() return None def remove_hotstring(self, hotstring: Hotstring) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.remove_hotstring(hotstring) return None def clear_hotstrings(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' self._hotkey_transport.clear_hotstrings() return None def start_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' return self._hotkey_transport.start() def stop_hotkeys(self) -> None: + assert self._hotkey_transport is not None, 'current transport does not support hotkey functionality' return self._hotkey_transport.stop() def init(self) -> None: self._started = True return None + # fmt: off + @overload + def run_script(self, script_text_or_path: str, /, *, timeout: Optional[int] = None) -> str: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: Literal[False], timeout: Optional[int] = None) -> FutureResult[str]: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: Literal[True], timeout: Optional[int] = None) -> str: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None) -> Union[str, FutureResult[str]]: ... + # fmt: on @abstractmethod def run_script( self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None @@ -648,6 +631,7 @@ def __init__( template: Optional[jinja2.Template] = None, extensions: list[Extension] | None = None, version: Optional[Literal['v1', 'v2']] = None, + skip_version_check: bool = False, ): self._extensions = extensions or [] self._proc: Optional[SyncAHKProcess] @@ -656,6 +640,15 @@ def __init__( self.__template: jinja2.Template self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() + self._executable_path = _resolve_executable_path(executable_path=executable_path, version=version) + if version is None: + try: + version = _get_executable_major_version(self._executable_path) + except Exception as e: + warnings.warn(f'Could not detect AHK version ({e}). Defaulting to v1') + version = 'v1' + skip_version_check = True + if version is None or version == 'v1': template_name = 'daemon.ahk' @@ -666,6 +659,11 @@ def __init__( else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') + if not skip_version_check: + detected_version = _get_executable_major_version(self._executable_path) + if version != detected_version: + raise RuntimeError(f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {self._executable_path}') + if jinja_loader is None: try: loader: jinja2.BaseLoader @@ -692,7 +690,10 @@ def __init__( if extensions: includes = _resolve_includes(extensions) directives = includes + directives - super().__init__(executable_path=executable_path, directives=directives, version=version) + hotkey_transport = ThreadedHotkeyTransport( + executable_path=self._executable_path, directives=directives, version=version + ) + super().__init__(directives=directives, version=version, hotkey_transport=hotkey_transport) @property def template(self) -> jinja2.Template: @@ -858,6 +859,16 @@ def f() -> str: pool.shutdown(wait=False) return FutureResult(fut) + # fmt: off + @overload + def run_script(self, script_text_or_path: str, /, *, timeout: Optional[int] = None) -> str: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: Literal[False], timeout: Optional[int] = None) -> FutureResult[str]: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: Literal[True], timeout: Optional[int] = None) -> str: ... + @overload + def run_script(self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None) -> Union[str, FutureResult[str]]: ... + # fmt: on def run_script( self, script_text_or_path: str, /, *, blocking: bool = True, timeout: Optional[int] = None ) -> Union[str, FutureResult[str]]: @@ -870,7 +881,7 @@ def run_script( proc = SyncAHKProcess(runargs) proc.start() if blocking: - stdout, stderr = proc.acommunicate(script_bytes, timeout=timeout) + stdout, stderr = proc.communicate(script_bytes, timeout=timeout) if proc.returncode != 0: assert proc.returncode is not None raise subprocess.CalledProcessError(proc.returncode, proc.runargs, stdout, stderr) diff --git a/ahk/_utils.py b/ahk/_utils.py index 951d434..42c2914 100644 --- a/ahk/_utils.py +++ b/ahk/_utils.py @@ -1,4 +1,11 @@ import enum +import os +import re +import subprocess +import warnings +from shutil import which +from typing import Literal +from typing import Optional HOTKEY_ESCAPE_SEQUENCE_MAP = { '\n': '`n', @@ -71,3 +78,92 @@ class MsgBoxOtherOptions(enum.IntEnum): HELP_BUTTON = 16384 TEXT_RIGHT_JUSTIFIED = 524288 RIGHT_TO_LEFT_READING_ORDER = 1048576 + + +DEFAULT_EXECUTABLE_PATH = r'C:\Program Files\AutoHotkey\AutoHotkey.exe' + + +class AhkExecutableNotFoundError(EnvironmentError): + pass + + +def _resolve_executable_path(executable_path: str = '', version: Optional[Literal['v1', 'v2']] = None) -> str: + if not executable_path: + executable_path = ( + os.environ.get('AHK_PATH', '') + or (which('AutoHotkeyV2.exe') if version == 'v2' else '') + or (which('AutoHotkey32.exe') if version == 'v2' else '') + or (which('AutoHotkey64.exe') if version == 'v2' else '') + or which('AutoHotkey.exe') + or (which('AutoHotkeyU64.exe') if version != 'v2' else '') + or (which('AutoHotkeyU32.exe') if version != 'v2' else '') + or (which('AutoHotkeyA32.exe') if version != 'v2' else '') + or '' + ) + + if not executable_path: + if os.path.exists(DEFAULT_EXECUTABLE_PATH): + executable_path = DEFAULT_EXECUTABLE_PATH + + if not executable_path: + raise AhkExecutableNotFoundError( + 'Could not find AutoHotkey.exe on PATH. ' + 'Provide the absolute path with the `executable_path` keyword argument ' + 'or in the AHK_PATH environment variable. ' + 'You may be able to resolve this error by installing the binary extra: pip install "ahk[binary]"' + ) + + if not os.path.exists(executable_path): + raise AhkExecutableNotFoundError(f"executable_path does not seems to exist: '{executable_path}' not found") + + if os.path.isdir(executable_path): + raise AhkExecutableNotFoundError( + f'The path {executable_path} appears to be a directory, but should be a file.' + ' Please specify the *full path* to the autohotkey.exe executable file' + ) + executable_path = str(executable_path) + if not executable_path.endswith('.exe'): + warnings.warn( + 'executable_path does not appear to have a .exe extension. This may be the result of a misconfiguration.' + ) + + return executable_path + + +_version_detection_script = '''\ +#NoTrayIcon +version := Format("{}", A_AhkVersion) +filename := "*" +encoding := "UTF-8" +mode := "w" +stdout := FileOpen(filename, mode, encoding) +stdout.Write(version) +stdout.Read(0) +''' + + +def _get_executable_version(executable_path: str) -> str: + process = subprocess.Popen( + [executable_path, '/ErrorStdout', '/CP65001', '*'], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + stdout, stderr = process.communicate(_version_detection_script, timeout=2) + assert re.match(r'^\d+\.', stdout) + return stdout.strip() + + +def _get_executable_major_version(executable_path: str) -> Literal['v1', 'v2']: + version = _get_executable_version(executable_path) + match = re.match(r'^(\d+)\.', version) + if not match: + raise ValueError(f'Unexpected version {version!r}') + major_version = match.group(1) + if major_version == '1': + return 'v1' + elif major_version == '2': + return 'v2' + else: + raise ValueError(f'Unexpected version {version!r}') diff --git a/buildunasync.py b/buildunasync.py index 15a2bba..d187ee8 100644 --- a/buildunasync.py +++ b/buildunasync.py @@ -17,7 +17,8 @@ 'a_send_nonblocking': 'send_nonblocking', 'async_sleep': 'sleep', 'AsyncFutureResult': 'FutureResult', - '_async_run_nonblocking': '_sync_run_nonblocking' + '_async_run_nonblocking': '_sync_run_nonblocking', + 'acommunicate': 'communicate' # "__aenter__": "__aenter__", }, ), diff --git a/tests/_async/test_hotkeys.py b/tests/_async/test_hotkeys.py index 462cbe9..6605666 100644 --- a/tests/_async/test_hotkeys.py +++ b/tests/_async/test_hotkeys.py @@ -23,7 +23,7 @@ async def asyncSetUp(self) -> None: async def asyncTearDown(self) -> None: self.ahk.stop_hotkeys() self.ahk._transport._proc.kill() - subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey.exe'], capture_output=True) + subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey*.exe'], capture_output=True) time.sleep(0.2) async def test_hotkey(self): diff --git a/tests/_async/test_versioning.py b/tests/_async/test_versioning.py new file mode 100644 index 0000000..845d44f --- /dev/null +++ b/tests/_async/test_versioning.py @@ -0,0 +1,45 @@ +import shutil +import subprocess +import time +from unittest import IsolatedAsyncioTestCase + +import pytest + +from ahk import AsyncAHK + +V2_EXECUTABLE = shutil.which('AutoHotkeyV2.exe') +V1_EXECUTABLE = shutil.which('AutoHotkey.exe') + + +class TestVersion(IsolatedAsyncioTestCase): + async def asyncTearDown(self) -> None: + subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey*.exe'], capture_output=True) + time.sleep(0.2) + + async def test_default_is_v1(self): + ahk = AsyncAHK() + assert await ahk.get_major_version() == 'v1' + + async def test_v1_explicit(self): + ahk = AsyncAHK(version='v1') + assert await ahk.get_major_version() == 'v1' + + async def test_v2_explicit(self): + ahk = AsyncAHK(version='v2') + assert await ahk.get_major_version() == 'v2' + + async def test_autodetect_v2(self): + ahk = AsyncAHK(executable_path=V2_EXECUTABLE) + assert await ahk.get_major_version() == 'v2' + + async def test_autodetect_v1(self): + ahk = AsyncAHK(executable_path=V1_EXECUTABLE) + assert await ahk.get_major_version() == 'v1' + + async def test_mismatch_autodetect_raises_error_v1_v2(self): + with pytest.raises(RuntimeError): + ahk = AsyncAHK(executable_path=V1_EXECUTABLE, version='v2') + + async def test_mismatch_autodetect_raises_error_v2_v1(self): + with pytest.raises(RuntimeError): + ahk = AsyncAHK(executable_path=V2_EXECUTABLE, version='v1') diff --git a/tests/_sync/test_hotkeys.py b/tests/_sync/test_hotkeys.py index 701c39d..6b1c0a9 100644 --- a/tests/_sync/test_hotkeys.py +++ b/tests/_sync/test_hotkeys.py @@ -20,7 +20,7 @@ def setUp(self) -> None: def tearDown(self) -> None: self.ahk.stop_hotkeys() self.ahk._transport._proc.kill() - subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey.exe'], capture_output=True) + subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey*.exe'], capture_output=True) time.sleep(0.2) def test_hotkey(self): diff --git a/tests/_sync/test_versioning.py b/tests/_sync/test_versioning.py new file mode 100644 index 0000000..0570b93 --- /dev/null +++ b/tests/_sync/test_versioning.py @@ -0,0 +1,45 @@ +import shutil +import subprocess +import time +from unittest import TestCase + +import pytest + +from ahk import AHK + +V2_EXECUTABLE = shutil.which('AutoHotkeyV2.exe') +V1_EXECUTABLE = shutil.which('AutoHotkey.exe') + + +class TestVersion(TestCase): + def tearDown(self) -> None: + subprocess.run(['TASKKILL', '/F', '/IM', 'AutoHotkey*.exe'], capture_output=True) + time.sleep(0.2) + + def test_default_is_v1(self): + ahk = AHK() + assert ahk.get_major_version() == 'v1' + + def test_v1_explicit(self): + ahk = AHK(version='v1') + assert ahk.get_major_version() == 'v1' + + def test_v2_explicit(self): + ahk = AHK(version='v2') + assert ahk.get_major_version() == 'v2' + + def test_autodetect_v2(self): + ahk = AHK(executable_path=V2_EXECUTABLE) + assert ahk.get_major_version() == 'v2' + + def test_autodetect_v1(self): + ahk = AHK(executable_path=V1_EXECUTABLE) + assert ahk.get_major_version() == 'v1' + + def test_mismatch_autodetect_raises_error_v1_v2(self): + with pytest.raises(RuntimeError): + ahk = AHK(executable_path=V1_EXECUTABLE, version='v2') + + def test_mismatch_autodetect_raises_error_v2_v1(self): + with pytest.raises(RuntimeError): + ahk = AHK(executable_path=V2_EXECUTABLE, version='v1') From dce2eaf471761f60ba4a4fdbec5b9bcb93dce4d2 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 16:36:55 -0700 Subject: [PATCH 35/52] support v2 default install location --- ahk/_utils.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ahk/_utils.py b/ahk/_utils.py index 42c2914..15c281d 100644 --- a/ahk/_utils.py +++ b/ahk/_utils.py @@ -81,6 +81,7 @@ class MsgBoxOtherOptions(enum.IntEnum): DEFAULT_EXECUTABLE_PATH = r'C:\Program Files\AutoHotkey\AutoHotkey.exe' +DEFAULT_EXECUTABLE_PATH_V2 = r'C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe' class AhkExecutableNotFoundError(EnvironmentError): @@ -102,15 +103,19 @@ def _resolve_executable_path(executable_path: str = '', version: Optional[Litera ) if not executable_path: - if os.path.exists(DEFAULT_EXECUTABLE_PATH): - executable_path = DEFAULT_EXECUTABLE_PATH + if version == 'v2': + if os.path.exists(DEFAULT_EXECUTABLE_PATH_V2): + executable_path = DEFAULT_EXECUTABLE_PATH_V2 + else: + if os.path.exists(DEFAULT_EXECUTABLE_PATH): + executable_path = DEFAULT_EXECUTABLE_PATH if not executable_path: raise AhkExecutableNotFoundError( 'Could not find AutoHotkey.exe on PATH. ' 'Provide the absolute path with the `executable_path` keyword argument ' 'or in the AHK_PATH environment variable. ' - 'You may be able to resolve this error by installing the binary extra: pip install "ahk[binary]"' + 'You can likely resolve this error simply by installing the binary extra with the following command:\n\tpip install "ahk[binary]"' ) if not os.path.exists(executable_path): From fe0a7551a7b08d332ed0553510f757b420a28e36 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 16:37:15 -0700 Subject: [PATCH 36/52] document v2 support --- docs/README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 136523b..676366e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # ahk -A fully typed Python wrapper around AHK. +A fully typed Python wrapper around AutoHotkey. [![Docs](https://readthedocs.org/projects/ahk/badge/?version=latest)](https://ahk.readthedocs.io/en/latest/?badge=latest) [![Build](https://github.com/spyoungtech/ahk/actions/workflows/test.yaml/badge.svg)](https://github.com/spyoungtech/ahk/actions/workflows/test.yaml) @@ -14,9 +14,10 @@ A fully typed Python wrapper around AHK. ``` pip install ahk ``` + Requires Python 3.8+ -See also [Non-Python dependencies](#deps) +Supports AutoHotkey v1 and v2. See also: [Non-Python dependencies](#deps) # Usage @@ -533,31 +534,75 @@ ahk.run_script(script_path) # Non-Python dependencies -To use this package, you need the [AutoHotkey executable](https://www.autohotkey.com/download/). It's expected to be on PATH by default. +To use this package, you need the [AutoHotkey executable](https://www.autohotkey.com/download/) (e.g., `AutoHotkey.exe`). +It's expected to be on PATH by default OR in a default installation location (`C:\Program Files\AutoHotkey\AutoHotkey.exe` for v1 or `C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe` for v2) -Note: this should be AutoHotkey V1. AutoHotkey V2 is not yet supported. +AutoHotkey v1 is fully supported. AutoHotkey v2 support is available, but is considered to be in beta status. -A convenient way to do this is to install the `binary` extra +The recommended way to supply the AutoHotkey binary (for both v1 and v2) is to install the `binary` extra for this package. This will +provide the necessary executables and help ensure they are correctly placed on PATH. ``` pip install "ahk[binary]" ``` +Alternatively, you may provide the path in code: + +```python +from ahk import AHK + +ahk = AHK(executable_path='C:\\path\\to\\AutoHotkey.exe') +``` + You can also use the `AHK_PATH` environment variable to specify the executable location. ```console set AHK_PATH=C:\Path\To\AutoHotkey.exe +python myscript.py ``` -Alternatively, you may provide the path in code +## Using AHK v2 + +By default, when no `executable_path` parameter (or `AHK_PATH` environment variable) is set, only AutoHotkey v1 binary names +are searched for on PATH or default install locations. This behavior may change in future versions to allow v2 to be used by default. + +To use AutoHotkey version 2, you can do any of the following things: + +1. provide the `executable_path` keyword argument with the location of the AutoHotkey v2 binary +2. set the `AHK_PATH` environment variable with the location of an AutoHotkey v2 binary +3. Provide the `version` keyword argument with the value `v2` which enables finding the executable using AutoHotkey v2 binary names and default install locations. + +For example: ```python from ahk import AHK -ahk = AHK(executable_path='C:\\path\\to\\AutoHotkey.exe') + +ahk = AHK(executable_path=r'C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe') +# OR +ahk = AHK(version='v2') ``` +When you provide the `version` keyword argument (with either `"v1"` or `"v2"`) a check is performed to ensure the provided (or discovered) binary matches the requested version. When +the `version` keyword is omitted, the version is determined automatically from the provided (or discovered) executable binary. + + + +### Differences when using AutoHotkey v1 vs AutoHotkey v2 + +The API of this project is originally designed against AutoHotkey v1 and function signatures are the same, even when using AutoHotkey v2. +While most of the behavior remains the same, some behavior does change when using AutoHotkey v2 compared to v1. This is mostly due to +underlying differences between the two versions. + +Some of the differences that you will experience when using AutoHotkey v2 include: + + +1. Functions that find and return windows will often raise an exception rather than returning `None` (as in AutoHotkey v2, a TargetError is thrown in most cases where the window or control cannot be found) +2. The behavior of `ControlSend` (`ahk.control_send` or `Window.send` or `Control.send`) differs in AutoHotkey v2 when the `control` parameter is not specified. In v1, keys are sent to the topmost controls, which is usually the correct behavior. In v2, keys are sent directly to the window. This means in many cases, you need to specify the control explicitly when using V2. +3. Some functionality is not supported in v2 -- specifically: the `secondstowait` paramater for `TrayTip` (`ahk.show_traytip`) was removed in v2. Specifying this parameter in the Python wrapper will cause a warning to be emitted and the parameter is ignored. +4. Some functionality that is present in v1 is not yet implemented in v2 -- this is expected to change in future versions. Specifically: some [sound functions](https://www.autohotkey.com/docs/v2/lib/Sound.htm) are not implemented. + # Contributing From 71539726a8623039ee0eb264f7423ca8dfc1fc07 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 16:37:34 -0700 Subject: [PATCH 37/52] set binary extra to 2023.9.0 --- .github/workflows/test.yaml | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index bf3e4ce..d1ed71b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,7 +21,7 @@ jobs: python -m pip install -r requirements-dev.txt python -m pip install . python -m pip install tox - python -m pip install "ahk-binary==2023.9.0rc1" + python -m pip install "ahk-binary==2023.9.0" - name: Test with coverage/pytest timeout-minutes: 10 env: diff --git a/setup.cfg b/setup.cfg index 91ecdf0..44c63fd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,7 +50,7 @@ cmdclass = build_py = buildunasync.build_py [options.extras_require] -binary = ahk-binary==1.1.33.9 +binary = ahk-binary==2023.9.0 [options.package_data] ahk = From 2d70afbd3d032e868c40a369f525063a2093124c Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 20 Sep 2023 17:17:49 -0700 Subject: [PATCH 38/52] preload crypt32 --- ahk/_constants.py | 30 ++++++++++++++++++------------ ahk/templates/daemon-v2.ahk | 18 ++++++++++-------- ahk/templates/daemon.ahk | 10 ++++++---- ahk/templates/hotkeys-v2.ahk | 1 + ahk/templates/hotkeys.ahk | 1 + 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 3599844..fecfff5 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2658,8 +2658,10 @@ return ret } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") + + b64decode(ByRef pszString) { - ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. @@ -2682,7 +2684,7 @@ pdwFlags := 0 ; We don't need this, so make it null ; The first call calculates the required size. The result is written to pbBinary - success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + success := DllCall("Crypt32\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags) if (success = 0) { return "" } @@ -2692,7 +2694,7 @@ ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to - success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "Ptr", &ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + success := DllCall("Crypt32\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "Ptr", &ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags) if (success=0) { return "" } @@ -2725,7 +2727,7 @@ ; Now we do the conversion to base64 and rteturn the string - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) + success := DllCall("Crypt32\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) if (success = 0) { msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) throw Exception(msg, -1) @@ -2806,6 +2808,7 @@ KEEPALIVE := Chr(57344) SetTimer, keepalive, 1000 +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") b64decode(ByRef pszString) { ; TODO load DLL globally for performance @@ -3355,13 +3358,14 @@ if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinMaximize(title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinMaximize(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinMaximize %} } @@ -5633,8 +5637,9 @@ return ret } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") + b64decode(&pszString) { - ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. @@ -5791,6 +5796,7 @@ Critical "Off" } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") b64decode(&pszString) { ; TODO load DLL globally for performance diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 2e41cd8..3f4c364 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -460,13 +460,14 @@ AHKWinMaximize(command) { if (detect_hw != "") { DetectHiddenWindows(detect_hw) } - - WinMaximize(title, text, extitle, extext) - - DetectHiddenWindows(current_detect_hw) - SetTitleMatchMode(current_match_mode) - SetTitleMatchMode(current_match_speed) - + try { + WinMaximize(title, text, extitle, extext) + } + finally { + DetectHiddenWindows(current_detect_hw) + SetTitleMatchMode(current_match_mode) + SetTitleMatchMode(current_match_speed) + } return FormatNoValueResponse() {% endblock AHKWinMaximize %} } @@ -2738,8 +2739,9 @@ AHKFileSelectFolder(command) { return ret } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") + b64decode(&pszString) { - ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 83ca10c..83ce0a1 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -2655,8 +2655,10 @@ AHKFileSelectFolder(byRef command) { return ret } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") + + b64decode(ByRef pszString) { - ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw ; [in] LPCSTR pszString, A pointer to a string that contains the formatted string to be converted. ; [in] DWORD cchString, The number of characters of the formatted string to be converted, not including the terminating NULL character. If this parameter is zero, pszString is considered to be a null-terminated string. @@ -2679,7 +2681,7 @@ b64decode(ByRef pszString) { pdwFlags := 0 ; We don't need this, so make it null ; The first call calculates the required size. The result is written to pbBinary - success := DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + success := DllCall("Crypt32\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "UInt", getsize, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags) if (success = 0) { return "" } @@ -2689,7 +2691,7 @@ b64decode(ByRef pszString) { ; Now that we know the buffer size we need and have the variable's capacity set to the proper size, we'll pass a pointer to the variable for the decoded value to be written to - success := DllCall( "Crypt32.dll\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "Ptr", &ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags ) + success := DllCall("Crypt32\CryptStringToBinary", "Ptr", &pszString, "UInt", cchString, "UInt", dwFlags, "Ptr", &ret, "UIntP", buff_size, "Int", pdwSkip, "Int", pdwFlags) if (success=0) { return "" } @@ -2722,7 +2724,7 @@ b64encode(ByRef data) { ; Now we do the conversion to base64 and rteturn the string - success := DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) + success := DllCall("Crypt32\CryptBinaryToString", "Ptr", &data, "UInt", cbBinary, "UInt", dwFlags, "Str", ret, "UIntP", buff_size) if (success = 0) { msg := Format("Problem converting data to base64 when calling CryptBinaryToString ({})", A_LastError) throw Exception(msg, -1) diff --git a/ahk/templates/hotkeys-v2.ahk b/ahk/templates/hotkeys-v2.ahk index e13e746..09667d7 100644 --- a/ahk/templates/hotkeys-v2.ahk +++ b/ahk/templates/hotkeys-v2.ahk @@ -20,6 +20,7 @@ WriteStdout(s) { Critical "Off" } +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") b64decode(&pszString) { ; TODO load DLL globally for performance diff --git a/ahk/templates/hotkeys.ahk b/ahk/templates/hotkeys.ahk index 0857134..43cb2d9 100644 --- a/ahk/templates/hotkeys.ahk +++ b/ahk/templates/hotkeys.ahk @@ -13,6 +13,7 @@ OnClipboardChange("ClipChanged") KEEPALIVE := Chr(57344) SetTimer, keepalive, 1000 +Crypt32 := DllCall("LoadLibrary", "Str", "Crypt32.dll", "Ptr") b64decode(ByRef pszString) { ; TODO load DLL globally for performance From becba02ae5f3ca1b1beaa1650782574f9009394b Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 21 Sep 2023 11:04:52 -0700 Subject: [PATCH 39/52] fix ControlSend in v2 --- ahk/_constants.py | 4 ++-- ahk/templates/daemon-v2.ahk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index fecfff5..15638ed 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -5264,9 +5264,9 @@ try { if (ctrl != "") { - ControlSendText(keys, ctrl, title, text, extitle, extext) + ControlSend(keys, ctrl, title, text, extitle, extext) } else { - ControlSendText(keys,, title, text, extitle, extext) + ControlSend(keys,, title, text, extitle, extext) } } finally { diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 3f4c364..9e52bb7 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -2366,9 +2366,9 @@ AHKControlSend(command) { try { if (ctrl != "") { - ControlSendText(keys, ctrl, title, text, extitle, extext) + ControlSend(keys, ctrl, title, text, extitle, extext) } else { - ControlSendText(keys,, title, text, extitle, extext) + ControlSend(keys,, title, text, extitle, extext) } } finally { From f442c565c5e3f8a8ceeb1686cc96f3a9c9fcab01 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 21 Sep 2023 14:15:22 -0700 Subject: [PATCH 40/52] move version resolution into the engine --- ahk/_async/engine.py | 28 +++++++++++++++++++++++++++- ahk/_async/transport.py | 18 ++---------------- ahk/_sync/engine.py | 28 +++++++++++++++++++++++++++- ahk/_sync/transport.py | 16 +++------------- tests/_async/test_window.py | 7 +++++++ tests/_sync/test_window.py | 7 +++++++ 6 files changed, 73 insertions(+), 31 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 74a8b09..8edaae4 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -22,6 +22,8 @@ from .._hotkey import Hotkey from .._hotkey import Hotstring +from .._utils import _get_executable_major_version +from .._utils import _resolve_executable_path from .._utils import MsgBoxButtons from .._utils import MsgBoxDefaultButton from .._utils import MsgBoxIcon @@ -145,6 +147,27 @@ def __init__( extensions: list[Extension] | None | Literal['auto'] = None, version: Optional[Literal['v1', 'v2']] = None, ): + if version not in (None, 'v1', 'v2'): + raise ValueError(f'Invalid version ({version!r}). Must be one of None, "v1", or "v2"') + executable_path = _resolve_executable_path(executable_path=executable_path, version=version) + skip_version_check = False + if version is None: + try: + version = _get_executable_major_version(executable_path) + except Exception as e: + warnings.warn( + f'Could not detect AHK version ({e}). This is likely caused by a misconfigured AutoHotkey executable and will likely cause a fatal error later on.\nAssuming v1 for now.' + ) + version = 'v1' + skip_version_check = True + + if not skip_version_check: + detected_version = _get_executable_major_version(executable_path) + if version != detected_version: + raise RuntimeError( + f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {executable_path}' + ) + self._version: Literal['v1', 'v2'] = version self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': @@ -162,6 +185,9 @@ def __init__( ) self._transport: AsyncTransport = transport + def __repr__(self) -> str: + return f'<{self.__module__}.{self.__class__.__qualname__} object version={self._version!r}>' + def __getattr__(self, name: str) -> Callable[..., Any]: is_async = False is_async = True # unasync: remove @@ -1332,7 +1358,7 @@ async def show_traytip( if second is None: second = 1.0 else: - if self._transport._version == 'v2': + if self._version == 'v2': warnings.warn( 'supplying seconds is not supported when using AutoHotkey v2. This parameter will be ignored' ) diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 2daa5d7..0e715f9 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -48,7 +48,7 @@ DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, ) -from ahk._utils import _version_detection_script, _resolve_executable_path, _get_executable_major_version +from ahk._utils import _version_detection_script from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor @@ -676,14 +676,7 @@ def __init__( self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() self._a_execution_lock = asyncio.Lock() # unasync: remove - self._executable_path = _resolve_executable_path(executable_path=executable_path, version=version) - if version is None: - try: - version = _get_executable_major_version(self._executable_path) - except Exception as e: - warnings.warn(f'Could not detect AHK version ({e}). Defaulting to v1') - version = 'v1' - skip_version_check = True + self._executable_path = executable_path if version is None or version == 'v1': template_name = 'daemon.ahk' @@ -694,13 +687,6 @@ def __init__( else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') - if not skip_version_check: - detected_version = _get_executable_major_version(self._executable_path) - if version != detected_version: - raise RuntimeError( - f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {self._executable_path}' - ) - if jinja_loader is None: try: loader: jinja2.BaseLoader diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index efe26ca..afe44ca 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -22,6 +22,8 @@ from .._hotkey import Hotkey from .._hotkey import Hotstring +from .._utils import _get_executable_major_version +from .._utils import _resolve_executable_path from .._utils import MsgBoxButtons from .._utils import MsgBoxDefaultButton from .._utils import MsgBoxIcon @@ -141,6 +143,27 @@ def __init__( extensions: list[Extension] | None | Literal['auto'] = None, version: Optional[Literal['v1', 'v2']] = None, ): + if version not in (None, 'v1', 'v2'): + raise ValueError(f'Invalid version ({version!r}). Must be one of None, "v1", or "v2"') + executable_path = _resolve_executable_path(executable_path=executable_path, version=version) + skip_version_check = False + if version is None: + try: + version = _get_executable_major_version(executable_path) + except Exception as e: + warnings.warn( + f'Could not detect AHK version ({e}). This is likely caused by a misconfigured AutoHotkey executable and will likely cause a fatal error later on.\nAssuming v1 for now.' + ) + version = 'v1' + skip_version_check = True + + if not skip_version_check: + detected_version = _get_executable_major_version(executable_path) + if version != detected_version: + raise RuntimeError( + f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {executable_path}' + ) + self._version: Literal['v1', 'v2'] = version self._extension_registry: _ExtensionMethodRegistry self._extensions: list[Extension] if extensions == 'auto': @@ -158,6 +181,9 @@ def __init__( ) self._transport: Transport = transport + def __repr__(self) -> str: + return f'<{self.__module__}.{self.__class__.__qualname__} object version={self._version!r}>' + def __getattr__(self, name: str) -> Callable[..., Any]: is_async = False if is_async: @@ -1320,7 +1346,7 @@ def show_traytip( if second is None: second = 1.0 else: - if self._transport._version == 'v2': + if self._version == 'v2': warnings.warn( 'supplying seconds is not supported when using AutoHotkey v2. This parameter will be ignored' ) diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index 9d23c0d..d5f1df1 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -48,7 +48,7 @@ DAEMON_SCRIPT_TEMPLATE as _DAEMON_SCRIPT_TEMPLATE, DAEMON_SCRIPT_V2_TEMPLATE as _DAEMON_SCRIPT_V2_TEMPLATE, ) -from ahk._utils import _version_detection_script, _resolve_executable_path, _get_executable_major_version +from ahk._utils import _version_detection_script from ahk.directives import Directive from concurrent.futures import Future, ThreadPoolExecutor @@ -640,14 +640,7 @@ def __init__( self.__template: jinja2.Template self._jinja_env: jinja2.Environment self._execution_lock = threading.Lock() - self._executable_path = _resolve_executable_path(executable_path=executable_path, version=version) - if version is None: - try: - version = _get_executable_major_version(self._executable_path) - except Exception as e: - warnings.warn(f'Could not detect AHK version ({e}). Defaulting to v1') - version = 'v1' - skip_version_check = True + self._executable_path = executable_path if version is None or version == 'v1': @@ -659,10 +652,7 @@ def __init__( else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') - if not skip_version_check: - detected_version = _get_executable_major_version(self._executable_path) - if version != detected_version: - raise RuntimeError(f'AutoHotkey {version} was requested but AutoHotkey {detected_version} was detected for executable {self._executable_path}') + if jinja_loader is None: try: diff --git a/tests/_async/test_window.py b/tests/_async/test_window.py index d5ab5d4..f3127bf 100644 --- a/tests/_async/test_window.py +++ b/tests/_async/test_window.py @@ -133,6 +133,13 @@ async def test_type_escape(self): text = await self.win.get_text() assert '!' in text + async def test_send_input_manual_escapes(self): + await self.win.activate() + await self.ahk.send_input('Hello{Enter}World{!}') + time.sleep(0.4) + text = await self.win.get_text() + assert 'Hello\r\nWorld!' in text + async def test_send_literal_tilde_n(self): expected_text = '```nim\nimport std/strformat\n```' await self.win.send(expected_text, control='Edit1') diff --git a/tests/_sync/test_window.py b/tests/_sync/test_window.py index 66ea08a..723ec47 100644 --- a/tests/_sync/test_window.py +++ b/tests/_sync/test_window.py @@ -133,6 +133,13 @@ def test_type_escape(self): text = self.win.get_text() assert '!' in text + def test_send_input_manual_escapes(self): + self.win.activate() + self.ahk.send_input('Hello{Enter}World{!}') + time.sleep(0.4) + text = self.win.get_text() + assert 'Hello\r\nWorld!' in text + def test_send_literal_tilde_n(self): expected_text = '```nim\nimport std/strformat\n```' self.win.send(expected_text, control='Edit1') From ad0f22144fbc0dd0aa5a92ae667ce45de8473e6b Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 21 Sep 2023 14:58:15 -0700 Subject: [PATCH 41/52] use variadic calls --- ahk/_constants.py | 2370 ++++++++++++++++--------------- ahk/templates/daemon-v2.ahk | 1177 +++++++-------- ahk/templates/daemon.ahk | 1193 ++++++++-------- tests/_async/test_extensions.py | 17 +- tests/_sync/test_extensions.py | 17 +- 5 files changed, 2388 insertions(+), 2386 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index 15638ed..a07357b 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -43,18 +43,18 @@ return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } -AHKSetDetectHiddenWindows(ByRef command) { +AHKSetDetectHiddenWindows(args*) { {% block AHKSetDetectHiddenWindows %} - value := command[2] + value := args[1] DetectHiddenWindows, %value% return FormatNoValueResponse() {% endblock AHKSetDetectHiddenWindows %} } -AHKSetTitleMatchMode(ByRef command) { +AHKSetTitleMatchMode(args*) { {% block AHKSetTitleMatchMode %} - val1 := command[2] - val2 := command[3] + val1 := args[1] + val2 := args[2] if (val1 != "") { SetTitleMatchMode, %val1% } @@ -65,45 +65,45 @@ {% endblock AHKSetTitleMatchMode %} } -AHKGetTitleMatchMode(ByRef command) { +AHKGetTitleMatchMode(args*) { {% block AHKGetTitleMatchMode %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } -AHKGetTitleMatchSpeed(ByRef command) { +AHKGetTitleMatchSpeed(args*) { {% block AHKGetTitleMatchSpeed %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } -AHKSetSendLevel(ByRef command) { +AHKSetSendLevel(args*) { {% block AHKSetSendLevel %} - level := command[2] + level := args[1] SendLevel, %level% return FormatNoValueResponse() {% endblock AHKSetSendLevel %} } -AHKGetSendLevel(ByRef command) { +AHKGetSendLevel(args*) { {% block AHKGetSendLevel %} return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } -AHKWinExist(ByRef command) { +AHKWinExist(args*) { {% block AHKWinExist %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -134,16 +134,16 @@ {% endblock AHKWinExist %} } -AHKWinClose(ByRef command) { +AHKWinClose(args*) { {% block AHKWinClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -169,16 +169,16 @@ {% endblock AHKWinClose %} } -AHKWinKill(ByRef command) { +AHKWinKill(args*) { {% block AHKWinKill %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -204,17 +204,17 @@ {% endblock AHKWinKill %} } -AHKWinWait(ByRef command) { +AHKWinWait(args*) { {% block AHKWinWait %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -248,17 +248,17 @@ {% endblock AHKWinWait %} } -AHKWinWaitActive(ByRef command) { +AHKWinWaitActive(args*) { {% block AHKWinWaitActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -292,17 +292,17 @@ {% endblock AHKWinWaitActive %} } -AHKWinWaitNotActive(ByRef command) { +AHKWinWaitNotActive(args*) { {% block AHKWinWaitNotActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -336,17 +336,17 @@ {% endblock AHKWinWaitNotActive %} } -AHKWinWaitClose(ByRef command) { +AHKWinWaitClose(args*) { {% block AHKWinWaitClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -379,15 +379,15 @@ {% endblock AHKWinWaitClose %} } -AHKWinMinimize(ByRef command) { +AHKWinMinimize(args*) { {% block AHKWinMinimize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -413,15 +413,15 @@ {% endblock AHKWinMinimize %} } -AHKWinMaximize(ByRef command) { +AHKWinMaximize(args*) { {% block AHKWinMaximize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -447,15 +447,15 @@ {% endblock AHKWinMaximize %} } -AHKWinRestore(ByRef command) { +AHKWinRestore(args*) { {% block AHKWinRestore %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -481,16 +481,16 @@ {% endblock AHKWinRestore %} } -AHKWinIsActive(ByRef command) { +AHKWinIsActive(args*) { {% block AHKWinIsActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -518,16 +518,16 @@ {% endblock AHKWinIsActive %} } -AHKWinGetID(ByRef command) { +AHKWinGetID(args*) { {% block AHKWinGetID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -557,16 +557,16 @@ {% endblock AHKWinGetID %} } -AHKWinGetTitle(ByRef command) { +AHKWinGetTitle(args*) { {% block AHKWinGetTitle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -592,16 +592,16 @@ {% endblock AHKWinGetTitle %} } -AHKWinGetIDLast(ByRef command) { +AHKWinGetIDLast(args*) { {% block AHKWinGetIDLast %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -631,16 +631,16 @@ {% endblock AHKWinGetIDLast %} } -AHKWinGetPID(ByRef command) { +AHKWinGetPID(args*) { {% block AHKWinGetPID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -670,16 +670,16 @@ {% endblock AHKWinGetPID %} } -AHKWinGetProcessName(ByRef command) { +AHKWinGetProcessName(args*) { {% block AHKWinGetProcessName %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -709,16 +709,16 @@ {% endblock AHKWinGetProcessName %} } -AHKWinGetProcessPath(ByRef command) { +AHKWinGetProcessPath(args*) { {% block AHKWinGetProcessPath %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -748,16 +748,16 @@ {% endblock AHKWinGetProcessPath %} } -AHKWinGetCount(ByRef command) { +AHKWinGetCount(args*) { {% block AHKWinGetCount %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -787,16 +787,16 @@ {% endblock AHKWinGetCount %} } -AHKWinGetMinMax(ByRef command) { +AHKWinGetMinMax(args*) { {% block AHKWinGetMinMax %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -826,16 +826,16 @@ {% endblock AHKWinGetMinMax %} } -AHKWinGetControlList(ByRef command) { +AHKWinGetControlList(args*) { {% block AHKWinGetControlList %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -890,16 +890,16 @@ {% endblock AHKWinGetControlList %} } -AHKWinGetTransparent(ByRef command) { +AHKWinGetTransparent(args*) { {% block AHKWinGetTransparent %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -924,16 +924,16 @@ return response {% endblock AHKWinGetTransparent %} } -AHKWinGetTransColor(ByRef command) { +AHKWinGetTransColor(args*) { {% block AHKWinGetTransColor %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -958,16 +958,16 @@ return response {% endblock AHKWinGetTransColor %} } -AHKWinGetStyle(ByRef command) { +AHKWinGetStyle(args*) { {% block AHKWinGetStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -992,16 +992,16 @@ return response {% endblock AHKWinGetStyle %} } -AHKWinGetExStyle(ByRef command) { +AHKWinGetExStyle(args*) { {% block AHKWinGetExStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1027,16 +1027,16 @@ {% endblock AHKWinGetExStyle %} } -AHKWinGetText(ByRef command) { +AHKWinGetText(args*) { {% block AHKWinGetText %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1067,16 +1067,16 @@ {% endblock AHKWinGetText %} } -AHKWinSetTitle(ByRef command) { +AHKWinSetTitle(args*) { {% block AHKWinSetTitle %} - new_title := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + new_title := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1099,16 +1099,16 @@ {% endblock AHKWinSetTitle %} } -AHKWinSetAlwaysOnTop(ByRef command) { +AHKWinSetAlwaysOnTop(args*) { {% block AHKWinSetAlwaysOnTop %} - toggle := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + toggle := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1132,15 +1132,15 @@ {% endblock AHKWinSetAlwaysOnTop %} } -AHKWinSetBottom(ByRef command) { +AHKWinSetBottom(args*) { {% block AHKWinSetBottom %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1165,15 +1165,15 @@ {% endblock AHKWinSetBottom %} } -AHKWinShow(ByRef command) { +AHKWinShow(args*) { {% block AHKWinShow %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1198,15 +1198,15 @@ {% endblock AHKWinShow %} } -AHKWinHide(ByRef command) { +AHKWinHide(args*) { {% block AHKWinHide %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1231,15 +1231,15 @@ {% endblock AHKWinHide %} } -AHKWinSetTop(ByRef command) { +AHKWinSetTop(args*) { {% block AHKWinSetTop %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1264,15 +1264,15 @@ {% endblock AHKWinSetTop %} } -AHKWinSetEnable(ByRef command) { +AHKWinSetEnable(args*) { {% block AHKWinSetEnable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1297,15 +1297,15 @@ {% endblock AHKWinSetEnable %} } -AHKWinSetDisable(ByRef command) { +AHKWinSetDisable(args*) { {% block AHKWinSetDisable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1330,15 +1330,15 @@ {% endblock AHKWinSetDisable %} } -AHKWinSetRedraw(ByRef command) { +AHKWinSetRedraw(args*) { {% block AHKWinSetRedraw %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1363,17 +1363,17 @@ {% endblock AHKWinSetRedraw %} } -AHKWinSetStyle(ByRef command) { +AHKWinSetStyle(args*) { {% block AHKWinSetStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1402,17 +1402,17 @@ {% endblock AHKWinSetStyle %} } -AHKWinSetExStyle(ByRef command) { +AHKWinSetExStyle(args*) { {% block AHKWinSetExStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1441,17 +1441,17 @@ {% endblock AHKWinSetExStyle %} } -AHKWinSetRegion(ByRef command) { +AHKWinSetRegion(args*) { {% block AHKWinSetRegion %} - options := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + options := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1480,17 +1480,17 @@ {% endblock AHKWinSetRegion %} } -AHKWinSetTransparent(ByRef command) { +AHKWinSetTransparent(args*) { {% block AHKWinSetTransparent %} - transparency := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + transparency := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1514,17 +1514,17 @@ {% endblock AHKWinSetTransparent %} } -AHKWinSetTransColor(ByRef command) { +AHKWinSetTransColor(args*) { {% block AHKWinSetTransColor %} - color := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + color := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1550,15 +1550,15 @@ {% endblock AHKWinSetTransColor %} } -AHKImageSearch(ByRef command) { +AHKImageSearch(args*) { {% block AHKImageSearch %} - imagepath := command[6] - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - coord_mode := command[7] + imagepath := args[5] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + coord_mode := args[6] current_mode := Format("{}", A_CoordModePixel) @@ -1580,7 +1580,7 @@ } if (ErrorLevel = 2) { - s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") + s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the args from conducting the search (such as failure to open the image file or a badly formatted option)") } else if (ErrorLevel = 1) { s := FormatNoValueResponse() } else { @@ -1591,13 +1591,13 @@ {% endblock AHKImageSearch %} } -AHKPixelGetColor(ByRef command) { +AHKPixelGetColor(args*) { {% block AHKPixelGetColor %} - x := command[2] - y := command[3] - coord_mode := command[4] - options := command[5] + x := args[1] + y := args[2] + coord_mode := args[3] + options := args[4] current_mode := Format("{}", A_CoordModePixel) @@ -1616,17 +1616,17 @@ {% endblock AHKPixelGetColor %} } -AHKPixelSearch(ByRef command) { +AHKPixelSearch(args*) { {% block AHKPixelSearch %} - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - color := command[6] - variation := command[7] - options := command[8] - coord_mode := command[9] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + color := args[5] + variation := args[6] + options := args[7] + coord_mode := args[8] current_mode := Format("{}", A_CoordModePixel) @@ -1654,10 +1654,10 @@ {% endblock AHKPixelSearch %} } -AHKMouseGetPos(ByRef command) { +AHKMouseGetPos(args*) { {% block AHKMouseGetPos %} - coord_mode := command[2] + coord_mode := args[1] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { CoordMode, Mouse, %coord_mode% @@ -1675,11 +1675,11 @@ {% endblock AHKMouseGetPos %} } -AHKKeyState(ByRef command) { +AHKKeyState(args*) { {% block AHKKeyState %} - keyname := command[2] - mode := command[3] + keyname := args[1] + mode := args[2] if (mode != "") { state := GetKeyState(keyname, mode) } else{ @@ -1703,12 +1703,12 @@ {% endblock AHKKeyState %} } -AHKMouseMove(ByRef command) { +AHKMouseMove(args*) { {% block AHKMouseMove %} - x := command[2] - y := command[3] - speed := command[4] - relative := command[5] + x := args[1] + y := args[2] + speed := args[3] + relative := args[4] if (relative != "") { MouseMove, %x%, %y%, %speed%, R } else { @@ -1719,15 +1719,15 @@ {% endblock AHKMouseMove %} } -AHKClick(ByRef command) { +AHKClick(args*) { {% block AHKClick %} - x := command[2] - y := command[3] - button := command[4] - click_count := command[5] - direction := command[6] - r := command[7] - relative_to := command[8] + x := args[1] + y := args[2] + button := args[3] + click_count := args[4] + direction := args[5] + r := args[6] + relative_to := args[7] current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { @@ -1745,10 +1745,10 @@ {% endblock AHKClick %} } -AHKGetCoordMode(ByRef command) { +AHKGetCoordMode(args*) { {% block AHKGetCoordMode %} - target := command[2] + target := args[1] if (target = "ToolTip") { return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) @@ -1769,26 +1769,26 @@ {% endblock AHKGetCoordMode %} } -AHKSetCoordMode(ByRef command) { +AHKSetCoordMode(args*) { {% block AHKSetCoordMode %} - target := command[2] - relative_to := command[3] + target := args[1] + relative_to := args[2] CoordMode, %target%, %relative_to% return FormatNoValueResponse() {% endblock AHKSetCoordMode %} } -AHKMouseClickDrag(ByRef command) { +AHKMouseClickDrag(args*) { {% block AHKMouseClickDrag %} - button := command[2] - x1 := command[3] - y1 := command[4] - x2 := command[5] - y2 := command[6] - speed := command[7] - relative := command[8] - relative_to := command[9] + button := args[1] + x1 := args[2] + y1 := args[3] + x2 := args[4] + y2 := args[5] + speed := args[6] + relative := args[7] + relative_to := args[8] current_coord_rel := Format("{}", A_CoordModeMouse) @@ -1807,11 +1807,11 @@ {% endblock AHKMouseClickDrag %} } -AHKRegRead(ByRef command) { +AHKRegRead(args*) { {% block RegRead %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] RegRead, output, %key_name%, %value_name% @@ -1825,13 +1825,13 @@ {% endblock RegRead %} } -AHKRegWrite(ByRef command) { +AHKRegWrite(args*) { {% block RegWrite %} - value_type := command[2] - key_name := command[3] - value_name := command[4] - value := command[5] + value_type := args[1] + key_name := args[2] + value_name := args[3] + value := args[4] RegWrite, %value_type%, %key_name%, %value_name%, %value% if (ErrorLevel = 1) { return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) @@ -1841,11 +1841,11 @@ {% endblock RegWrite %} } -AHKRegDelete(ByRef command) { +AHKRegDelete(args*) { {% block RegDelete %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] RegDelete, %key_name%, %value_name% if (ErrorLevel = 1) { return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) @@ -1855,31 +1855,31 @@ {% endblock RegDelete %} } -AHKKeyWait(ByRef command) { +AHKKeyWait(args*) { {% block AHKKeyWait %} - keyname := command[2] - if (command.Length() = 2) { + keyname := args[1] + if (args.Length() = 2) { KeyWait,% keyname } else { - options := command[3] + options := args[2] KeyWait,% keyname,% options } return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) {% endblock AHKKeyWait %} } -SetKeyDelay(ByRef command) { +SetKeyDelay(args*) { {% block SetKeyDelay %} - SetKeyDelay, command[2], command[3] + SetKeyDelay, args[1], args[2] {% endblock SetKeyDelay %} } -AHKSend(ByRef command) { +AHKSend(args*) { {% block AHKSend %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1896,11 +1896,11 @@ {% endblock AHKSend %} } -AHKSendRaw(ByRef command) { +AHKSendRaw(args*) { {% block AHKSendRaw %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1917,11 +1917,11 @@ {% endblock AHKSendRaw %} } -AHKSendInput(ByRef command) { +AHKSendInput(args*) { {% block AHKSendInput %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1938,11 +1938,11 @@ {% endblock AHKSendInput %} } -AHKSendEvent(ByRef command) { +AHKSendEvent(args*) { {% block AHKSendEvent %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1959,11 +1959,11 @@ {% endblock AHKSendEvent %} } -AHKSendPlay(ByRef command) { +AHKSendPlay(args*) { {% block AHKSendPlay %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelayPlay) current_key_duration := Format("{}", A_KeyDurationPlay) @@ -1980,9 +1980,9 @@ {% endblock AHKSendPlay %} } -AHKSetCapsLockState(ByRef command) { +AHKSetCapsLockState(args*) { {% block AHKSetCapsLockState %} - state := command[2] + state := args[1] if (state = "") { SetCapsLockState % !GetKeyState("CapsLock", "T") } else { @@ -1992,7 +1992,7 @@ {% endblock AHKSetCapsLockState %} } -HideTrayTip(ByRef command) { +HideTrayTip(args*) { {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { @@ -2003,16 +2003,16 @@ {% endblock HideTrayTip %} } -AHKWinGetClass(ByRef command) { +AHKWinGetClass(args*) { {% block AHKWinGetClass %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2043,15 +2043,15 @@ {% endblock AHKWinGetClass %} } -AHKWinActivate(ByRef command) { +AHKWinActivate(args*) { {% block AHKWinActivate %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2078,18 +2078,18 @@ {% endblock AHKWinActivate %} } -AHKWindowList(ByRef command) { +AHKWindowList(args*) { {% block AHKWindowList %} current_detect_hw := Format("{}", A_DetectHiddenWindows) - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2118,20 +2118,20 @@ {% endblock AHKWindowList %} } -AHKControlClick(ByRef command) { +AHKControlClick(args*) { {% block AHKControlClick %} - ctrl := command[2] - title := command[3] - text := command[4] - button := command[5] - click_count := command[6] - options := command[7] - exclude_title := command[8] - exclude_text := command[9] - detect_hw := command[10] - match_mode := command[11] - match_speed := command[12] + ctrl := args[1] + title := args[2] + text := args[3] + button := args[4] + click_count := args[5] + options := args[6] + exclude_title := args[7] + exclude_text := args[8] + detect_hw := args[9] + match_mode := args[10] + match_speed := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2163,17 +2163,17 @@ {% endblock AHKControlClick %} } -AHKControlGetText(ByRef command) { +AHKControlGetText(args*) { {% block AHKControlGetText %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2204,17 +2204,17 @@ {% endblock AHKControlGetText %} } -AHKControlGetPos(ByRef command) { +AHKControlGetPos(args*) { {% block AHKControlGetPos %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2247,17 +2247,17 @@ {% endblock AHKControlGetPos %} } -AHKControlSend(ByRef command) { +AHKControlSend(args*) { {% block AHKControlSend %} - ctrl := command[2] - keys := command[3] - title := command[4] - text := command[5] - extitle := command[6] - extext := command[7] - detect_hw := command[8] - match_mode := command[9] - match_speed := command[10] + ctrl := args[1] + keys := args[2] + title := args[3] + text := args[4] + extitle := args[5] + extext := args[6] + detect_hw := args[7] + match_mode := args[8] + match_speed := args[9] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2280,7 +2280,7 @@ {% endblock AHKControlSend %} } -AHKWinFromMouse(ByRef command) { +AHKWinFromMouse(args*) { {% block AHKWinFromMouse %} MouseGetPos,,, MouseWin @@ -2293,10 +2293,10 @@ {% endblock AHKWinFromMouse %} } -AHKWinIsAlwaysOnTop(ByRef command) { +AHKWinIsAlwaysOnTop(args*) { {% block AHKWinIsAlwaysOnTop %} - title := command[2] + title := args[1] WinGet, ExStyle, ExStyle, %title% if (ExStyle = "") return FormatNoValueResponse() @@ -2308,19 +2308,19 @@ {% endblock AHKWinIsAlwaysOnTop %} } -AHKWinMove(ByRef command) { +AHKWinMove(args*) { {% block AHKWinMove %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - x := command[9] - y := command[10] - width := command[11] - height := command[12] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + x := args[8] + y := args[9] + width := args[10] + height := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2347,16 +2347,16 @@ {% endblock AHKWinMove %} } -AHKWinGetPos(ByRef command) { +AHKWinGetPos(args*) { {% block AHKWinGetPos %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2389,10 +2389,10 @@ {% endblock AHKWinGetPos %} } -AHKGetVolume(ByRef command) { +AHKGetVolume(args*) { {% block AHKGetVolume %} - device_number := command[2] + device_number := args[1] try { SoundGetWaveVolume, retval, %device_number% @@ -2409,21 +2409,21 @@ {% endblock AHKGetVolume %} } -AHKSoundBeep(ByRef command) { +AHKSoundBeep(args*) { {% block AHKSoundBeep %} - freq := command[2] - duration := command[3] + freq := args[1] + duration := args[2] SoundBeep , %freq%, %duration% return FormatNoValueResponse() {% endblock AHKSoundBeep %} } -AHKSoundGet(ByRef command) { +AHKSoundGet(args*) { {% block AHKSoundGet %} - device_number := command[2] - component_type := command[3] - control_type := command[4] + device_number := args[1] + component_type := args[2] + control_type := args[3] SoundGet, retval, %component_type%, %control_type%, %device_number% ; TODO interpret return type @@ -2431,29 +2431,29 @@ {% endblock AHKSoundGet %} } -AHKSoundSet(ByRef command) { +AHKSoundSet(args*) { {% block AHKSoundSet %} - device_number := command[2] - component_type := command[3] - control_type := command[4] - value := command[5] + device_number := args[1] + component_type := args[2] + control_type := args[3] + value := args[4] SoundSet, %value%, %component_type%, %control_type%, %device_number% return FormatNoValueResponse() {% endblock AHKSoundSet %} } -AHKSoundPlay(ByRef command) { +AHKSoundPlay(args*) { {% block AHKSoundPlay %} - filename := command[2] + filename := args[1] SoundPlay, %filename% return FormatNoValueResponse() {% endblock AHKSoundPlay %} } -AHKSetVolume(ByRef command) { +AHKSetVolume(args*) { {% block AHKSetVolume %} - device_number := command[2] - value := command[3] + device_number := args[1] + value := args[2] SoundSetWaveVolume, %value%, %device_number% return FormatNoValueResponse() {% endblock AHKSetVolume %} @@ -2466,71 +2466,71 @@ return count } -AHKEcho(ByRef command) { +AHKEcho(args*) { {% block AHKEcho %} - arg := command[2] + arg := args[1] return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } -AHKTraytip(ByRef command) { +AHKTraytip(args*) { {% block AHKTraytip %} - title := command[2] - text := command[3] - second := command[4] - option := command[5] + title := args[1] + text := args[2] + second := args[3] + option := args[4] TrayTip, %title%, %text%, %second%, %option% return FormatNoValueResponse() {% endblock AHKTraytip %} } -AHKShowToolTip(ByRef command) { +AHKShowToolTip(args*) { {% block AHKShowToolTip %} - text := command[2] - x := command[3] - y := command[4] - which := command[5] + text := args[1] + x := args[2] + y := args[3] + which := args[4] ToolTip, %text%, %x%, %y%, %which% return FormatNoValueResponse() {% endblock AHKShowToolTip %} } -AHKGetClipboard(ByRef command) { +AHKGetClipboard(args*) { {% block AHKGetClipboard %} return FormatResponse("ahk.message.StringResponseMessage", Clipboard) {% endblock AHKGetClipboard %} } -AHKGetClipboardAll(ByRef command) { +AHKGetClipboardAll(args*) { {% block AHKGetClipboardAll %} data := ClipboardAll return FormatBinaryResponse(data) {% endblock AHKGetClipboardAll %} } -AHKSetClipboard(ByRef command) { +AHKSetClipboard(args*) { {% block AHKSetClipboard %} - text := command[2] + text := args[1] Clipboard := text return FormatNoValueResponse() {% endblock AHKSetClipboard %} } -AHKSetClipboardAll(ByRef command) { +AHKSetClipboardAll(args*) { {% block AHKSetClipboardAll %} ; TODO there should be a way for us to accept a base64 string instead - filename := command[2] + filename := args[1] FileRead, Clipboard, %filename% return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } -AHKClipWait(ByRef command) { +AHKClipWait(args*) { - timeout := command[2] - wait_for_any_data := command[3] + timeout := args[1] + wait_for_any_data := args[2] ClipWait, %timeout%, %wait_for_any_data% @@ -2540,45 +2540,45 @@ return FormatNoValueResponse() } -AHKBlockInput(ByRef command) { - value := command[2] +AHKBlockInput(args*) { + value := args[1] BlockInput, %value% return FormatNoValueResponse() } -AHKMenuTrayTip(ByRef command) { - value := command[2] +AHKMenuTrayTip(args*) { + value := args[1] Menu, Tray, Tip, %value% return FormatNoValueResponse() } -AHKMenuTrayShow(ByRef command) { +AHKMenuTrayShow(args*) { Menu, Tray, Icon return FormatNoValueResponse() } -AHKMenuTrayIcon(ByRef command) { - filename := command[2] - icon_number := command[3] - freeze := command[4] +AHKMenuTrayIcon(args*) { + filename := args[1] + icon_number := args[2] + freeze := args[3] Menu, Tray, Icon, %filename%, %icon_number%,%freeze% return FormatNoValueResponse() } -AHKGuiNew(ByRef command) { +AHKGuiNew(args*) { - options := command[2] - title := command[3] + options := args[1] + title := args[2] Gui, New, %options%, %title% return FormatResponse("ahk.message.StringResponseMessage", hwnd) } -AHKMsgBox(ByRef command) { +AHKMsgBox(args*) { - options := command[2] - title := command[3] - text := command[4] - timeout := command[5] + options := args[1] + title := args[2] + text := args[3] + timeout := args[4] MsgBox,% options, %title%, %text%, %timeout% IfMsgBox, Yes ret := FormatResponse("ahk.message.StringResponseMessage", "Yes") @@ -2603,18 +2603,18 @@ return ret } -AHKInputBox(ByRef command) { +AHKInputBox(args*) { - title := command[2] - prompt := command[3] - hide := command[4] - width := command[5] - height := command[6] - x := command[7] - y := command[8] - locale := command[9] - timeout := command[10] - default := command[11] + title := args[1] + prompt := args[2] + hide := args[3] + width := args[4] + height := args[5] + x := args[6] + y := args[7] + locale := args[8] + timeout := args[9] + default := args[10] InputBox, output, %title%, %prompt%, %hide%, %width%, %height%, %x%, %y%, %locale%, %timeout%, %default% if (ErrorLevel = 2) { @@ -2627,12 +2627,12 @@ return ret } -AHKFileSelectFile(byRef command) { +AHKFileSelectFile(byRef args) { - options := command[2] - root := command[3] - title := command[4] - filter := command[5] + options := args[1] + root := args[2] + title := args[3] + filter := args[4] FileSelectFile, output, %options%, %root%, %title%, %filter% if (ErrorLevel = 1) { ret := FormatNoValueResponse() @@ -2642,11 +2642,11 @@ return ret } -AHKFileSelectFolder(byRef command) { +AHKFileSelectFolder(byRef args) { - starting_folder := command[2] - options := command[3] - prompt := command[4] + starting_folder := args[1] + options := args[2] + prompt := args[3] FileSelectFolder, output, %starting_folder%, %options%, %prompt% @@ -2765,12 +2765,13 @@ Loop { query := RTrim(stdin.ReadLine(), "`n") - commandArray := CommandArrayFromQuery(query) + argsArray := CommandArrayFromQuery(query) try { - func := commandArray[1] + func := argsArray[1] + argsArray.RemoveAt(1) {% block before_function %} {% endblock before_function %} - pyresp := %func%(commandArray) + pyresp := %func%(argsArray*) {% block after_function %} {% endblock after_function %} } catch e { @@ -2945,18 +2946,18 @@ return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } -AHKSetDetectHiddenWindows(command) { +AHKSetDetectHiddenWindows(args*) { {% block AHKSetDetectHiddenWindows %} - value := command[2] + value := args[1] DetectHiddenWindows(value) return FormatNoValueResponse() {% endblock AHKSetDetectHiddenWindows %} } -AHKSetTitleMatchMode(command) { +AHKSetTitleMatchMode(args*) { {% block AHKSetTitleMatchMode %} - val1 := command[2] - val2 := command[3] + val1 := args[1] + val2 := args[2] if (val1 != "") { SetTitleMatchMode(val1) } @@ -2967,45 +2968,45 @@ {% endblock AHKSetTitleMatchMode %} } -AHKGetTitleMatchMode(command) { +AHKGetTitleMatchMode(args*) { {% block AHKGetTitleMatchMode %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } -AHKGetTitleMatchSpeed(command) { +AHKGetTitleMatchSpeed(args*) { {% block AHKGetTitleMatchSpeed %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } -AHKSetSendLevel(command) { +AHKSetSendLevel(args*) { {% block AHKSetSendLevel %} - level := command[2] + level := args[1] SendLevel(level) return FormatNoValueResponse() {% endblock AHKSetSendLevel %} } -AHKGetSendLevel(command) { +AHKGetSendLevel(args*) { {% block AHKGetSendLevel %} return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } -AHKWinExist(command) { +AHKWinExist(args*) { {% block AHKWinExist %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3036,16 +3037,16 @@ {% endblock AHKWinExist %} } -AHKWinClose(command) { +AHKWinClose(args*) { {% block AHKWinClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3076,16 +3077,16 @@ {% endblock AHKWinClose %} } -AHKWinKill(command) { +AHKWinKill(args*) { {% block AHKWinKill %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3116,17 +3117,17 @@ {% endblock AHKWinKill %} } -AHKWinWait(command) { +AHKWinWait(args*) { {% block AHKWinWait %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -3162,17 +3163,17 @@ {% endblock AHKWinWait %} } -AHKWinWaitActive(command) { +AHKWinWaitActive(args*) { {% block AHKWinWaitActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -3208,17 +3209,17 @@ {% endblock AHKWinWaitActive %} } -AHKWinWaitNotActive(command) { +AHKWinWaitNotActive(args*) { {% block AHKWinWaitNotActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -3255,17 +3256,17 @@ {% endblock AHKWinWaitNotActive %} } -AHKWinWaitClose(command) { +AHKWinWaitClose(args*) { {% block AHKWinWaitClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -3300,15 +3301,15 @@ {% endblock AHKWinWaitClose %} } -AHKWinMinimize(command) { +AHKWinMinimize(args*) { {% block AHKWinMinimize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3335,15 +3336,15 @@ {% endblock AHKWinMinimize %} } -AHKWinMaximize(command) { +AHKWinMaximize(args*) { {% block AHKWinMaximize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3370,15 +3371,15 @@ {% endblock AHKWinMaximize %} } -AHKWinRestore(command) { +AHKWinRestore(args*) { {% block AHKWinRestore %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3405,16 +3406,16 @@ {% endblock AHKWinRestore %} } -AHKWinIsActive(command) { +AHKWinIsActive(args*) { {% block AHKWinIsActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -3445,16 +3446,16 @@ {% endblock AHKWinIsActive %} } -AHKWinGetID(command) { +AHKWinGetID(args*) { {% block AHKWinGetID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3487,16 +3488,16 @@ {% endblock AHKWinGetID %} } -AHKWinGetTitle(command) { +AHKWinGetTitle(args*) { {% block AHKWinGetTitle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3524,16 +3525,16 @@ {% endblock AHKWinGetTitle %} } -AHKWinGetIDLast(command) { +AHKWinGetIDLast(args*) { {% block AHKWinGetIDLast %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3567,16 +3568,16 @@ {% endblock AHKWinGetIDLast %} } -AHKWinGetPID(command) { +AHKWinGetPID(args*) { {% block AHKWinGetPID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3609,16 +3610,16 @@ {% endblock AHKWinGetPID %} } -AHKWinGetProcessName(command) { +AHKWinGetProcessName(args*) { {% block AHKWinGetProcessName %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3652,16 +3653,16 @@ {% endblock AHKWinGetProcessName %} } -AHKWinGetProcessPath(command) { +AHKWinGetProcessPath(args*) { {% block AHKWinGetProcessPath %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3694,16 +3695,16 @@ {% endblock AHKWinGetProcessPath %} } -AHKWinGetCount(command) { +AHKWinGetCount(args*) { {% block AHKWinGetCount %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3737,16 +3738,16 @@ {% endblock AHKWinGetCount %} } -AHKWinGetMinMax(command) { +AHKWinGetMinMax(args*) { {% block AHKWinGetMinMax %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3780,16 +3781,16 @@ {% endblock AHKWinGetMinMax %} } -AHKWinGetControlList(command) { +AHKWinGetControlList(args*) { {% block AHKWinGetControlList %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3839,16 +3840,16 @@ {% endblock AHKWinGetControlList %} } -AHKWinGetTransparent(command) { +AHKWinGetTransparent(args*) { {% block AHKWinGetTransparent %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3876,16 +3877,16 @@ return response {% endblock AHKWinGetTransparent %} } -AHKWinGetTransColor(command) { +AHKWinGetTransColor(args*) { {% block AHKWinGetTransColor %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3913,16 +3914,16 @@ return response {% endblock AHKWinGetTransColor %} } -AHKWinGetStyle(command) { +AHKWinGetStyle(args*) { {% block AHKWinGetStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3952,16 +3953,16 @@ {% endblock AHKWinGetStyle %} } -AHKWinGetExStyle(command) { +AHKWinGetExStyle(args*) { {% block AHKWinGetExStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -3990,16 +3991,16 @@ {% endblock AHKWinGetExStyle %} } -AHKWinGetText(command) { +AHKWinGetText(args*) { {% block AHKWinGetText %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4029,16 +4030,16 @@ {% endblock AHKWinGetText %} } -AHKWinSetTitle(command) { +AHKWinSetTitle(args*) { {% block AHKWinSetTitle %} - new_title := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + new_title := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4065,16 +4066,16 @@ {% endblock AHKWinSetTitle %} } -AHKWinSetAlwaysOnTop(command) { +AHKWinSetAlwaysOnTop(args*) { {% block AHKWinSetAlwaysOnTop %} - toggle := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + toggle := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4110,15 +4111,15 @@ {% endblock AHKWinSetAlwaysOnTop %} } -AHKWinSetBottom(command) { +AHKWinSetBottom(args*) { {% block AHKWinSetBottom %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4146,15 +4147,15 @@ {% endblock AHKWinSetBottom %} } -AHKWinShow(command) { +AHKWinShow(args*) { {% block AHKWinShow %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4182,15 +4183,15 @@ {% endblock AHKWinShow %} } -AHKWinHide(command) { +AHKWinHide(args*) { {% block AHKWinHide %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4218,15 +4219,15 @@ {% endblock AHKWinHide %} } -AHKWinSetTop(command) { +AHKWinSetTop(args*) { {% block AHKWinSetTop %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4254,15 +4255,15 @@ {% endblock AHKWinSetTop %} } -AHKWinSetEnable(command) { +AHKWinSetEnable(args*) { {% block AHKWinSetEnable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4290,15 +4291,15 @@ {% endblock AHKWinSetEnable %} } -AHKWinSetDisable(command) { +AHKWinSetDisable(args*) { {% block AHKWinSetDisable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4326,15 +4327,15 @@ {% endblock AHKWinSetDisable %} } -AHKWinSetRedraw(command) { +AHKWinSetRedraw(args*) { {% block AHKWinSetRedraw %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4362,17 +4363,17 @@ {% endblock AHKWinSetRedraw %} } -AHKWinSetStyle(command) { +AHKWinSetStyle(args*) { {% block AHKWinSetStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4399,17 +4400,17 @@ {% endblock AHKWinSetStyle %} } -AHKWinSetExStyle(command) { +AHKWinSetExStyle(args*) { {% block AHKWinSetExStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4437,17 +4438,17 @@ {% endblock AHKWinSetExStyle %} } -AHKWinSetRegion(command) { +AHKWinSetRegion(args*) { {% block AHKWinSetRegion %} - options := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + options := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4474,17 +4475,17 @@ {% endblock AHKWinSetRegion %} } -AHKWinSetTransparent(command) { +AHKWinSetTransparent(args*) { {% block AHKWinSetTransparent %} - transparency := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + transparency := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4511,17 +4512,17 @@ {% endblock AHKWinSetTransparent %} } -AHKWinSetTransColor(command) { +AHKWinSetTransColor(args*) { {% block AHKWinSetTransColor %} - color := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + color := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -4548,15 +4549,15 @@ {% endblock AHKWinSetTransColor %} } -AHKImageSearch(command) { +AHKImageSearch(args*) { {% block AHKImageSearch %} - imagepath := command[6] - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - coord_mode := command[7] + imagepath := args[5] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + coord_mode := args[6] current_mode := Format("{}", A_CoordModePixel) @@ -4588,13 +4589,13 @@ {% endblock AHKImageSearch %} } -AHKPixelGetColor(command) { +AHKPixelGetColor(args*) { {% block AHKPixelGetColor %} - x := command[2] - y := command[3] - coord_mode := command[4] - options := command[5] + x := args[1] + y := args[2] + coord_mode := args[3] + options := args[4] current_mode := Format("{}", A_CoordModePixel) @@ -4615,17 +4616,17 @@ {% endblock AHKPixelGetColor %} } -AHKPixelSearch(command) { +AHKPixelSearch(args*) { {% block AHKPixelSearch %} - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - color := command[6] - variation := command[7] - options := command[8] - coord_mode := command[9] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + color := args[5] + variation := args[6] + options := args[7] + coord_mode := args[8] current_mode := Format("{}", A_CoordModePixel) @@ -4651,10 +4652,10 @@ {% endblock AHKPixelSearch %} } -AHKMouseGetPos(command) { +AHKMouseGetPos(args*) { {% block AHKMouseGetPos %} - coord_mode := command[2] + coord_mode := args[1] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { CoordMode("Mouse", coord_mode) @@ -4672,11 +4673,11 @@ {% endblock AHKMouseGetPos %} } -AHKKeyState(command) { +AHKKeyState(args*) { {% block AHKKeyState %} - keyname := command[2] - mode := command[3] + keyname := args[1] + mode := args[2] if (mode != "") { state := GetKeyState(keyname, mode) } else{ @@ -4701,12 +4702,12 @@ {% endblock AHKKeyState %} } -AHKMouseMove(command) { +AHKMouseMove(args*) { {% block AHKMouseMove %} - x := command[2] - y := command[3] - speed := command[4] - relative := command[5] + x := args[1] + y := args[2] + speed := args[3] + relative := args[4] if (relative != "") { MouseMove(x, y, speed, "R") } else { @@ -4717,15 +4718,15 @@ {% endblock AHKMouseMove %} } -AHKClick(command) { +AHKClick(args*) { {% block AHKClick %} - x := command[2] - y := command[3] - button := command[4] - click_count := command[5] - direction := command[6] - r := command[7] - relative_to := command[8] + x := args[1] + y := args[2] + button := args[3] + click_count := args[4] + direction := args[5] + r := args[6] + relative_to := args[7] current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { @@ -4743,10 +4744,10 @@ {% endblock AHKClick %} } -AHKGetCoordMode(command) { +AHKGetCoordMode(args*) { {% block AHKGetCoordMode %} - target := command[2] + target := args[1] if (target = "ToolTip") { return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) @@ -4767,26 +4768,26 @@ {% endblock AHKGetCoordMode %} } -AHKSetCoordMode(command) { +AHKSetCoordMode(args*) { {% block AHKSetCoordMode %} - target := command[2] - relative_to := command[3] + target := args[1] + relative_to := args[2] CoordMode(target, relative_to) return FormatNoValueResponse() {% endblock AHKSetCoordMode %} } -AHKMouseClickDrag(command) { +AHKMouseClickDrag(args*) { {% block AHKMouseClickDrag %} - button := command[2] - x1 := command[3] - y1 := command[4] - x2 := command[5] - y2 := command[6] - speed := command[7] - relative := command[8] - relative_to := command[9] + button := args[1] + x1 := args[2] + y1 := args[3] + x2 := args[4] + y2 := args[5] + speed := args[6] + relative := args[7] + relative_to := args[8] current_coord_rel := Format("{}", A_CoordModeMouse) @@ -4805,11 +4806,11 @@ {% endblock AHKMouseClickDrag %} } -AHKRegRead(command) { +AHKRegRead(args*) { {% block RegRead %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] output := RegRead(key_name, value_name) resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) @@ -4817,12 +4818,12 @@ {% endblock RegRead %} } -AHKRegWrite(command) { +AHKRegWrite(args*) { {% block RegWrite %} - value_type := command[2] - key_name := command[3] - value_name := command[4] - value := command[5] + value_type := args[1] + key_name := args[2] + value_name := args[3] + value := args[4] ; RegWrite(value_type, key_name, value_name, value) if (value_name != "") { RegWrite(value, value_type, key_name, value_name) @@ -4833,11 +4834,11 @@ {% endblock RegWrite %} } -AHKRegDelete(command) { +AHKRegDelete(args*) { {% block RegDelete %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] if (value_name != "") { RegDelete(key_name, value_name) } else { @@ -4848,31 +4849,31 @@ {% endblock RegDelete %} } -AHKKeyWait(command) { +AHKKeyWait(args*) { {% block AHKKeyWait %} - keyname := command[2] - if (command.Length = 2) { + keyname := args[1] + if (args.Length = 2) { ret := KeyWait(keyname) } else { - options := command[3] + options := args[2] ret := KeyWait(keyname, options) } return FormatResponse("ahk.message.IntegerResponseMessage", ret) {% endblock AHKKeyWait %} } -;SetKeyDelay(command) { +;SetKeyDelay(args*) { ; {% block SetKeyDelay %} -; SetKeyDelay(command[2], command[3]) +; SetKeyDelay(args[1], args[2]) ; {% endblock SetKeyDelay %} ;} -AHKSend(command) { +AHKSend(args*) { {% block AHKSend %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -4890,11 +4891,11 @@ {% endblock AHKSend %} } -AHKSendRaw(command) { +AHKSendRaw(args*) { {% block AHKSendRaw %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -4911,11 +4912,11 @@ {% endblock AHKSendRaw %} } -AHKSendInput(command) { +AHKSendInput(args*) { {% block AHKSendInput %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -4932,11 +4933,11 @@ {% endblock AHKSendInput %} } -AHKSendEvent(command) { +AHKSendEvent(args*) { {% block AHKSendEvent %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -4953,11 +4954,11 @@ {% endblock AHKSendEvent %} } -AHKSendPlay(command) { +AHKSendPlay(args*) { {% block AHKSendPlay %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelayPlay) current_key_duration := Format("{}", A_KeyDurationPlay) @@ -4974,9 +4975,9 @@ {% endblock AHKSendPlay %} } -AHKSetCapsLockState(command) { +AHKSetCapsLockState(args*) { {% block AHKSetCapsLockState %} - state := command[2] + state := args[1] if (state = "") { SetCapsLockState(!GetKeyState("CapsLock", "T")) } else { @@ -4986,7 +4987,7 @@ {% endblock AHKSetCapsLockState %} } -HideTrayTip(command) { +HideTrayTip(args*) { {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { @@ -4997,16 +4998,16 @@ {% endblock HideTrayTip %} } -AHKWinGetClass(command) { +AHKWinGetClass(args*) { {% block AHKWinGetClass %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5035,15 +5036,15 @@ {% endblock AHKWinGetClass %} } -AHKWinActivate(command) { +AHKWinActivate(args*) { {% block AHKWinActivate %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5072,18 +5073,18 @@ {% endblock AHKWinActivate %} } -AHKWindowList(command) { +AHKWindowList(args*) { {% block AHKWindowList %} current_detect_hw := Format("{}", A_DetectHiddenWindows) - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5114,20 +5115,20 @@ {% endblock AHKWindowList %} } -AHKControlClick(command) { +AHKControlClick(args*) { {% block AHKControlClick %} - ctrl := command[2] - title := command[3] - text := command[4] - button := command[5] - click_count := command[6] - options := command[7] - exclude_title := command[8] - exclude_text := command[9] - detect_hw := command[10] - match_mode := command[11] - match_speed := command[12] + ctrl := args[1] + title := args[2] + text := args[3] + button := args[4] + click_count := args[5] + options := args[6] + exclude_title := args[7] + exclude_text := args[8] + detect_hw := args[9] + match_mode := args[10] + match_speed := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5156,17 +5157,17 @@ {% endblock AHKControlClick %} } -AHKControlGetText(command) { +AHKControlGetText(args*) { {% block AHKControlGetText %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5196,17 +5197,17 @@ {% endblock AHKControlGetText %} } -AHKControlGetPos(command) { +AHKControlGetPos(args*) { {% block AHKControlGetPos %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5236,17 +5237,17 @@ {% endblock AHKControlGetPos %} } -AHKControlSend(command) { +AHKControlSend(args*) { {% block AHKControlSend %} - ctrl := command[2] - keys := command[3] - title := command[4] - text := command[5] - extitle := command[6] - extext := command[7] - detect_hw := command[8] - match_mode := command[9] - match_speed := command[10] + ctrl := args[1] + keys := args[2] + title := args[3] + text := args[4] + extitle := args[5] + extext := args[6] + detect_hw := args[7] + match_mode := args[8] + match_speed := args[9] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5278,7 +5279,7 @@ {% endblock AHKControlSend %} } -AHKWinFromMouse(command) { +AHKWinFromMouse(args*) { {% block AHKWinFromMouse %} MouseGetPos(,, &MouseWin) @@ -5291,10 +5292,10 @@ {% endblock AHKWinFromMouse %} } -AHKWinIsAlwaysOnTop(command) { +AHKWinIsAlwaysOnTop(args*) { {% block AHKWinIsAlwaysOnTop %} ; TODO: detect hidden windows / etc? - title := command[2] + title := args[1] ExStyle := WinGetExStyle(title) if (ExStyle = "") return FormatNoValueResponse() @@ -5306,19 +5307,19 @@ {% endblock AHKWinIsAlwaysOnTop %} } -AHKWinMove(command) { +AHKWinMove(args*) { {% block AHKWinMove %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - x := command[9] - y := command[10] - width := command[11] - height := command[12] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + x := args[8] + y := args[9] + width := args[10] + height := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5347,16 +5348,16 @@ {% endblock AHKWinMove %} } -AHKWinGetPos(command) { +AHKWinGetPos(args*) { {% block AHKWinGetPos %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -5387,10 +5388,10 @@ {% endblock AHKWinGetPos %} } -AHKGetVolume(command) { +AHKGetVolume(args*) { {% block AHKGetVolume %} - device_number := command[2] + device_number := args[1] retval := SoundGetVolume(,device_number) response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) @@ -5398,111 +5399,111 @@ {% endblock AHKGetVolume %} } -AHKSoundBeep(command) { +AHKSoundBeep(args*) { {% block AHKSoundBeep %} - freq := command[2] - duration := command[3] + freq := args[1] + duration := args[2] SoundBeep(freq, duration) return FormatNoValueResponse() {% endblock AHKSoundBeep %} } -AHKSoundGet(command) { +AHKSoundGet(args*) { {% block AHKSoundGet %} return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundGet is not supported in ahk v2") {% endblock AHKSoundGet %} } -AHKSoundSet(command) { +AHKSoundSet(args*) { {% block AHKSoundSet %} return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundSet is not supported in ahk v2") {% endblock AHKSoundSet %} } -AHKSoundPlay(command) { +AHKSoundPlay(args*) { {% block AHKSoundPlay %} - filename := command[2] + filename := args[1] SoundPlay(filename) return FormatNoValueResponse() {% endblock AHKSoundPlay %} } -AHKSetVolume(command) { +AHKSetVolume(args*) { {% block AHKSetVolume %} - device_number := command[2] - value := command[3] + device_number := args[1] + value := args[2] SoundSetVolume(value,,device_number) return FormatNoValueResponse() {% endblock AHKSetVolume %} } -AHKEcho(command) { +AHKEcho(args*) { {% block AHKEcho %} - arg := command[2] + arg := args[1] return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } -AHKTraytip(command) { +AHKTraytip(args*) { {% block AHKTraytip %} - title := command[2] - text := command[3] - second := command[4] - option := command[5] + title := args[1] + text := args[2] + second := args[3] + option := args[4] TrayTip(title, text, option) return FormatNoValueResponse() {% endblock AHKTraytip %} } -AHKShowToolTip(command) { +AHKShowToolTip(args*) { {% block AHKShowToolTip %} - text := command[2] - x := command[3] - y := command[4] - which := command[5] + text := args[1] + x := args[2] + y := args[3] + which := args[4] ToolTip(text, x, y, which) return FormatNoValueResponse() {% endblock AHKShowToolTip %} } -AHKGetClipboard(command) { +AHKGetClipboard(args*) { {% block AHKGetClipboard %} return FormatResponse("ahk.message.StringResponseMessage", A_Clipboard) {% endblock AHKGetClipboard %} } -AHKGetClipboardAll(command) { +AHKGetClipboardAll(args*) { {% block AHKGetClipboardAll %} data := ClipboardAll() return FormatBinaryResponse(&data) {% endblock AHKGetClipboardAll %} } -AHKSetClipboard(command) { +AHKSetClipboard(args*) { {% block AHKSetClipboard %} - text := command[2] + text := args[1] A_Clipboard := text return FormatNoValueResponse() {% endblock AHKSetClipboard %} } -AHKSetClipboardAll(command) { +AHKSetClipboardAll(args*) { {% block AHKSetClipboardAll %} ; TODO there should be a way for us to accept a base64 string instead - filename := command[2] + filename := args[1] contents := FileRead(filename, "RAW") A_Clipboard := ClipboardAll(contents) return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } -AHKClipWait(command) { +AHKClipWait(args*) { - timeout := command[2] - wait_for_any_data := command[3] + timeout := args[1] + wait_for_any_data := args[2] if ClipWait(timeout, wait_for_any_data) return FormatNoValueResponse() @@ -5511,45 +5512,45 @@ return FormatNoValueResponse() } -AHKBlockInput(command) { - value := command[2] +AHKBlockInput(args*) { + value := args[1] BlockInput(value) return FormatNoValueResponse() } -AHKMenuTrayTip(command) { - value := command[2] +AHKMenuTrayTip(args*) { + value := args[1] A_IconTip := value return FormatNoValueResponse() } -AHKMenuTrayShow(command) { +AHKMenuTrayShow(args*) { A_IconHidden := 0 return FormatNoValueResponse() } -AHKMenuTrayIcon(command) { - filename := command[2] - icon_number := command[3] - freeze := command[4] +AHKMenuTrayIcon(args*) { + filename := args[1] + icon_number := args[2] + freeze := args[3] TraySetIcon(filename, icon_number, freeze) return FormatNoValueResponse() } -;AHKGuiNew(command) { +;AHKGuiNew(args*) { ; -; options := command[2] -; title := command[3] +; options := args[1] +; title := args[2] ; Gui(New, options, title) ; return FormatResponse("ahk.message.StringResponseMessage", hwnd) ;} -AHKMsgBox(command) { +AHKMsgBox(args*) { - options := command[2] - title := command[3] - text := command[4] - timeout := command[5] + options := args[1] + title := args[2] + text := args[3] + timeout := args[4] if (timeout != "") { options := "" options " T" timeout } @@ -5562,18 +5563,18 @@ return ret } -AHKInputBox(command) { +AHKInputBox(args*) { - title := command[2] - prompt := command[3] - hide := command[4] - width := command[5] - height := command[6] - x := command[7] - y := command[8] - locale := command[9] - timeout := command[10] - default := command[11] + title := args[1] + prompt := args[2] + hide := args[3] + width := args[4] + height := args[5] + x := args[6] + y := args[7] + locale := args[8] + timeout := args[9] + default := args[10] ; TODO: support options correctly options := "" @@ -5591,12 +5592,12 @@ return ret } -AHKFileSelectFile(command) { +AHKFileSelectFile(args*) { - options := command[2] - root := command[3] - title := command[4] - filter := command[5] + options := args[1] + root := args[2] + title := args[3] + filter := args[4] output := FileSelect(options, root, title, filter) if (output = "") { ret := FormatNoValueResponse() @@ -5621,11 +5622,11 @@ return ret } -AHKFileSelectFolder(command) { +AHKFileSelectFolder(args*) { - starting_folder := command[2] - options := command[3] - prompt := command[4] + starting_folder := args[1] + options := args[2] + prompt := args[3] output := DirSelect(starting_folder, options, prompt) @@ -5743,12 +5744,13 @@ Loop { query := RTrim(stdin.ReadLine(), "`n") - commandArray := CommandArrayFromQuery(query) + argsArray := CommandArrayFromQuery(query) try { - func_name := commandArray[1] + func_name := argsArray[1] + argsArray.RemoveAt(1) {% block before_function %} {% endblock before_function %} - pyresp := %func_name%(commandArray) + pyresp := %func_name%(argsArray*) {% block after_function %} {% endblock after_function %} } catch Any as e { diff --git a/ahk/templates/daemon-v2.ahk b/ahk/templates/daemon-v2.ahk index 9e52bb7..e9ca86a 100644 --- a/ahk/templates/daemon-v2.ahk +++ b/ahk/templates/daemon-v2.ahk @@ -47,18 +47,18 @@ FormatBinaryResponse(bin) { return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } -AHKSetDetectHiddenWindows(command) { +AHKSetDetectHiddenWindows(args*) { {% block AHKSetDetectHiddenWindows %} - value := command[2] + value := args[1] DetectHiddenWindows(value) return FormatNoValueResponse() {% endblock AHKSetDetectHiddenWindows %} } -AHKSetTitleMatchMode(command) { +AHKSetTitleMatchMode(args*) { {% block AHKSetTitleMatchMode %} - val1 := command[2] - val2 := command[3] + val1 := args[1] + val2 := args[2] if (val1 != "") { SetTitleMatchMode(val1) } @@ -69,45 +69,45 @@ AHKSetTitleMatchMode(command) { {% endblock AHKSetTitleMatchMode %} } -AHKGetTitleMatchMode(command) { +AHKGetTitleMatchMode(args*) { {% block AHKGetTitleMatchMode %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } -AHKGetTitleMatchSpeed(command) { +AHKGetTitleMatchSpeed(args*) { {% block AHKGetTitleMatchSpeed %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } -AHKSetSendLevel(command) { +AHKSetSendLevel(args*) { {% block AHKSetSendLevel %} - level := command[2] + level := args[1] SendLevel(level) return FormatNoValueResponse() {% endblock AHKSetSendLevel %} } -AHKGetSendLevel(command) { +AHKGetSendLevel(args*) { {% block AHKGetSendLevel %} return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } -AHKWinExist(command) { +AHKWinExist(args*) { {% block AHKWinExist %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -138,16 +138,16 @@ AHKWinExist(command) { {% endblock AHKWinExist %} } -AHKWinClose(command) { +AHKWinClose(args*) { {% block AHKWinClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -178,16 +178,16 @@ AHKWinClose(command) { {% endblock AHKWinClose %} } -AHKWinKill(command) { +AHKWinKill(args*) { {% block AHKWinKill %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -218,17 +218,17 @@ AHKWinKill(command) { {% endblock AHKWinKill %} } -AHKWinWait(command) { +AHKWinWait(args*) { {% block AHKWinWait %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -264,17 +264,17 @@ AHKWinWait(command) { {% endblock AHKWinWait %} } -AHKWinWaitActive(command) { +AHKWinWaitActive(args*) { {% block AHKWinWaitActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -310,17 +310,17 @@ AHKWinWaitActive(command) { {% endblock AHKWinWaitActive %} } -AHKWinWaitNotActive(command) { +AHKWinWaitNotActive(args*) { {% block AHKWinWaitNotActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -357,17 +357,17 @@ AHKWinWaitNotActive(command) { {% endblock AHKWinWaitNotActive %} } -AHKWinWaitClose(command) { +AHKWinWaitClose(args*) { {% block AHKWinWaitClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -402,15 +402,15 @@ AHKWinWaitClose(command) { {% endblock AHKWinWaitClose %} } -AHKWinMinimize(command) { +AHKWinMinimize(args*) { {% block AHKWinMinimize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -437,15 +437,15 @@ AHKWinMinimize(command) { {% endblock AHKWinMinimize %} } -AHKWinMaximize(command) { +AHKWinMaximize(args*) { {% block AHKWinMaximize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -472,15 +472,15 @@ AHKWinMaximize(command) { {% endblock AHKWinMaximize %} } -AHKWinRestore(command) { +AHKWinRestore(args*) { {% block AHKWinRestore %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -507,16 +507,16 @@ AHKWinRestore(command) { {% endblock AHKWinRestore %} } -AHKWinIsActive(command) { +AHKWinIsActive(args*) { {% block AHKWinIsActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -547,16 +547,16 @@ AHKWinIsActive(command) { {% endblock AHKWinIsActive %} } -AHKWinGetID(command) { +AHKWinGetID(args*) { {% block AHKWinGetID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -589,16 +589,16 @@ AHKWinGetID(command) { {% endblock AHKWinGetID %} } -AHKWinGetTitle(command) { +AHKWinGetTitle(args*) { {% block AHKWinGetTitle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -626,16 +626,16 @@ AHKWinGetTitle(command) { {% endblock AHKWinGetTitle %} } -AHKWinGetIDLast(command) { +AHKWinGetIDLast(args*) { {% block AHKWinGetIDLast %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -669,16 +669,16 @@ AHKWinGetIDLast(command) { {% endblock AHKWinGetIDLast %} } -AHKWinGetPID(command) { +AHKWinGetPID(args*) { {% block AHKWinGetPID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -711,16 +711,16 @@ AHKWinGetPID(command) { {% endblock AHKWinGetPID %} } -AHKWinGetProcessName(command) { +AHKWinGetProcessName(args*) { {% block AHKWinGetProcessName %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -754,16 +754,16 @@ AHKWinGetProcessName(command) { {% endblock AHKWinGetProcessName %} } -AHKWinGetProcessPath(command) { +AHKWinGetProcessPath(args*) { {% block AHKWinGetProcessPath %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -796,16 +796,16 @@ AHKWinGetProcessPath(command) { {% endblock AHKWinGetProcessPath %} } -AHKWinGetCount(command) { +AHKWinGetCount(args*) { {% block AHKWinGetCount %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -839,16 +839,16 @@ AHKWinGetCount(command) { {% endblock AHKWinGetCount %} } -AHKWinGetMinMax(command) { +AHKWinGetMinMax(args*) { {% block AHKWinGetMinMax %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -882,16 +882,16 @@ AHKWinGetMinMax(command) { {% endblock AHKWinGetMinMax %} } -AHKWinGetControlList(command) { +AHKWinGetControlList(args*) { {% block AHKWinGetControlList %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -941,16 +941,16 @@ AHKWinGetControlList(command) { {% endblock AHKWinGetControlList %} } -AHKWinGetTransparent(command) { +AHKWinGetTransparent(args*) { {% block AHKWinGetTransparent %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -978,16 +978,16 @@ AHKWinGetTransparent(command) { return response {% endblock AHKWinGetTransparent %} } -AHKWinGetTransColor(command) { +AHKWinGetTransColor(args*) { {% block AHKWinGetTransColor %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1015,16 +1015,16 @@ AHKWinGetTransColor(command) { return response {% endblock AHKWinGetTransColor %} } -AHKWinGetStyle(command) { +AHKWinGetStyle(args*) { {% block AHKWinGetStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1054,16 +1054,16 @@ AHKWinGetStyle(command) { {% endblock AHKWinGetStyle %} } -AHKWinGetExStyle(command) { +AHKWinGetExStyle(args*) { {% block AHKWinGetExStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1092,16 +1092,16 @@ AHKWinGetExStyle(command) { {% endblock AHKWinGetExStyle %} } -AHKWinGetText(command) { +AHKWinGetText(args*) { {% block AHKWinGetText %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1131,16 +1131,16 @@ AHKWinGetText(command) { {% endblock AHKWinGetText %} } -AHKWinSetTitle(command) { +AHKWinSetTitle(args*) { {% block AHKWinSetTitle %} - new_title := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + new_title := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1167,16 +1167,16 @@ AHKWinSetTitle(command) { {% endblock AHKWinSetTitle %} } -AHKWinSetAlwaysOnTop(command) { +AHKWinSetAlwaysOnTop(args*) { {% block AHKWinSetAlwaysOnTop %} - toggle := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + toggle := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1212,15 +1212,15 @@ AHKWinSetAlwaysOnTop(command) { {% endblock AHKWinSetAlwaysOnTop %} } -AHKWinSetBottom(command) { +AHKWinSetBottom(args*) { {% block AHKWinSetBottom %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1248,15 +1248,15 @@ AHKWinSetBottom(command) { {% endblock AHKWinSetBottom %} } -AHKWinShow(command) { +AHKWinShow(args*) { {% block AHKWinShow %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1284,15 +1284,15 @@ AHKWinShow(command) { {% endblock AHKWinShow %} } -AHKWinHide(command) { +AHKWinHide(args*) { {% block AHKWinHide %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1320,15 +1320,15 @@ AHKWinHide(command) { {% endblock AHKWinHide %} } -AHKWinSetTop(command) { +AHKWinSetTop(args*) { {% block AHKWinSetTop %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1356,15 +1356,15 @@ AHKWinSetTop(command) { {% endblock AHKWinSetTop %} } -AHKWinSetEnable(command) { +AHKWinSetEnable(args*) { {% block AHKWinSetEnable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1392,15 +1392,15 @@ AHKWinSetEnable(command) { {% endblock AHKWinSetEnable %} } -AHKWinSetDisable(command) { +AHKWinSetDisable(args*) { {% block AHKWinSetDisable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1428,15 +1428,15 @@ AHKWinSetDisable(command) { {% endblock AHKWinSetDisable %} } -AHKWinSetRedraw(command) { +AHKWinSetRedraw(args*) { {% block AHKWinSetRedraw %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1464,17 +1464,17 @@ AHKWinSetRedraw(command) { {% endblock AHKWinSetRedraw %} } -AHKWinSetStyle(command) { +AHKWinSetStyle(args*) { {% block AHKWinSetStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1501,17 +1501,17 @@ AHKWinSetStyle(command) { {% endblock AHKWinSetStyle %} } -AHKWinSetExStyle(command) { +AHKWinSetExStyle(args*) { {% block AHKWinSetExStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1539,17 +1539,17 @@ AHKWinSetExStyle(command) { {% endblock AHKWinSetExStyle %} } -AHKWinSetRegion(command) { +AHKWinSetRegion(args*) { {% block AHKWinSetRegion %} - options := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + options := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1576,17 +1576,17 @@ AHKWinSetRegion(command) { {% endblock AHKWinSetRegion %} } -AHKWinSetTransparent(command) { +AHKWinSetTransparent(args*) { {% block AHKWinSetTransparent %} - transparency := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + transparency := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1613,17 +1613,17 @@ AHKWinSetTransparent(command) { {% endblock AHKWinSetTransparent %} } -AHKWinSetTransColor(command) { +AHKWinSetTransColor(args*) { {% block AHKWinSetTransColor %} - color := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + color := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1650,15 +1650,15 @@ AHKWinSetTransColor(command) { {% endblock AHKWinSetTransColor %} } -AHKImageSearch(command) { +AHKImageSearch(args*) { {% block AHKImageSearch %} - imagepath := command[6] - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - coord_mode := command[7] + imagepath := args[5] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + coord_mode := args[6] current_mode := Format("{}", A_CoordModePixel) @@ -1690,13 +1690,13 @@ AHKImageSearch(command) { {% endblock AHKImageSearch %} } -AHKPixelGetColor(command) { +AHKPixelGetColor(args*) { {% block AHKPixelGetColor %} - x := command[2] - y := command[3] - coord_mode := command[4] - options := command[5] + x := args[1] + y := args[2] + coord_mode := args[3] + options := args[4] current_mode := Format("{}", A_CoordModePixel) @@ -1717,17 +1717,17 @@ AHKPixelGetColor(command) { {% endblock AHKPixelGetColor %} } -AHKPixelSearch(command) { +AHKPixelSearch(args*) { {% block AHKPixelSearch %} - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - color := command[6] - variation := command[7] - options := command[8] - coord_mode := command[9] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + color := args[5] + variation := args[6] + options := args[7] + coord_mode := args[8] current_mode := Format("{}", A_CoordModePixel) @@ -1753,10 +1753,10 @@ AHKPixelSearch(command) { {% endblock AHKPixelSearch %} } -AHKMouseGetPos(command) { +AHKMouseGetPos(args*) { {% block AHKMouseGetPos %} - coord_mode := command[2] + coord_mode := args[1] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { CoordMode("Mouse", coord_mode) @@ -1774,11 +1774,11 @@ AHKMouseGetPos(command) { {% endblock AHKMouseGetPos %} } -AHKKeyState(command) { +AHKKeyState(args*) { {% block AHKKeyState %} - keyname := command[2] - mode := command[3] + keyname := args[1] + mode := args[2] if (mode != "") { state := GetKeyState(keyname, mode) } else{ @@ -1803,12 +1803,12 @@ AHKKeyState(command) { {% endblock AHKKeyState %} } -AHKMouseMove(command) { +AHKMouseMove(args*) { {% block AHKMouseMove %} - x := command[2] - y := command[3] - speed := command[4] - relative := command[5] + x := args[1] + y := args[2] + speed := args[3] + relative := args[4] if (relative != "") { MouseMove(x, y, speed, "R") } else { @@ -1819,15 +1819,15 @@ AHKMouseMove(command) { {% endblock AHKMouseMove %} } -AHKClick(command) { +AHKClick(args*) { {% block AHKClick %} - x := command[2] - y := command[3] - button := command[4] - click_count := command[5] - direction := command[6] - r := command[7] - relative_to := command[8] + x := args[1] + y := args[2] + button := args[3] + click_count := args[4] + direction := args[5] + r := args[6] + relative_to := args[7] current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { @@ -1845,10 +1845,10 @@ AHKClick(command) { {% endblock AHKClick %} } -AHKGetCoordMode(command) { +AHKGetCoordMode(args*) { {% block AHKGetCoordMode %} - target := command[2] + target := args[1] if (target = "ToolTip") { return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) @@ -1869,26 +1869,26 @@ AHKGetCoordMode(command) { {% endblock AHKGetCoordMode %} } -AHKSetCoordMode(command) { +AHKSetCoordMode(args*) { {% block AHKSetCoordMode %} - target := command[2] - relative_to := command[3] + target := args[1] + relative_to := args[2] CoordMode(target, relative_to) return FormatNoValueResponse() {% endblock AHKSetCoordMode %} } -AHKMouseClickDrag(command) { +AHKMouseClickDrag(args*) { {% block AHKMouseClickDrag %} - button := command[2] - x1 := command[3] - y1 := command[4] - x2 := command[5] - y2 := command[6] - speed := command[7] - relative := command[8] - relative_to := command[9] + button := args[1] + x1 := args[2] + y1 := args[3] + x2 := args[4] + y2 := args[5] + speed := args[6] + relative := args[7] + relative_to := args[8] current_coord_rel := Format("{}", A_CoordModeMouse) @@ -1907,11 +1907,11 @@ AHKMouseClickDrag(command) { {% endblock AHKMouseClickDrag %} } -AHKRegRead(command) { +AHKRegRead(args*) { {% block RegRead %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] output := RegRead(key_name, value_name) resp := FormatResponse("ahk.message.StringResponseMessage", Format("{}", output)) @@ -1919,12 +1919,12 @@ AHKRegRead(command) { {% endblock RegRead %} } -AHKRegWrite(command) { +AHKRegWrite(args*) { {% block RegWrite %} - value_type := command[2] - key_name := command[3] - value_name := command[4] - value := command[5] + value_type := args[1] + key_name := args[2] + value_name := args[3] + value := args[4] ; RegWrite(value_type, key_name, value_name, value) if (value_name != "") { RegWrite(value, value_type, key_name, value_name) @@ -1935,11 +1935,11 @@ AHKRegWrite(command) { {% endblock RegWrite %} } -AHKRegDelete(command) { +AHKRegDelete(args*) { {% block RegDelete %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] if (value_name != "") { RegDelete(key_name, value_name) } else { @@ -1950,31 +1950,31 @@ AHKRegDelete(command) { {% endblock RegDelete %} } -AHKKeyWait(command) { +AHKKeyWait(args*) { {% block AHKKeyWait %} - keyname := command[2] - if (command.Length = 2) { + keyname := args[1] + if (args.Length = 2) { ret := KeyWait(keyname) } else { - options := command[3] + options := args[2] ret := KeyWait(keyname, options) } return FormatResponse("ahk.message.IntegerResponseMessage", ret) {% endblock AHKKeyWait %} } -;SetKeyDelay(command) { +;SetKeyDelay(args*) { ; {% block SetKeyDelay %} -; SetKeyDelay(command[2], command[3]) +; SetKeyDelay(args[1], args[2]) ; {% endblock SetKeyDelay %} ;} -AHKSend(command) { +AHKSend(args*) { {% block AHKSend %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1992,11 +1992,11 @@ AHKSend(command) { {% endblock AHKSend %} } -AHKSendRaw(command) { +AHKSendRaw(args*) { {% block AHKSendRaw %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -2013,11 +2013,11 @@ AHKSendRaw(command) { {% endblock AHKSendRaw %} } -AHKSendInput(command) { +AHKSendInput(args*) { {% block AHKSendInput %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -2034,11 +2034,11 @@ AHKSendInput(command) { {% endblock AHKSendInput %} } -AHKSendEvent(command) { +AHKSendEvent(args*) { {% block AHKSendEvent %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -2055,11 +2055,11 @@ AHKSendEvent(command) { {% endblock AHKSendEvent %} } -AHKSendPlay(command) { +AHKSendPlay(args*) { {% block AHKSendPlay %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelayPlay) current_key_duration := Format("{}", A_KeyDurationPlay) @@ -2076,9 +2076,9 @@ AHKSendPlay(command) { {% endblock AHKSendPlay %} } -AHKSetCapsLockState(command) { +AHKSetCapsLockState(args*) { {% block AHKSetCapsLockState %} - state := command[2] + state := args[1] if (state = "") { SetCapsLockState(!GetKeyState("CapsLock", "T")) } else { @@ -2088,7 +2088,7 @@ AHKSetCapsLockState(command) { {% endblock AHKSetCapsLockState %} } -HideTrayTip(command) { +HideTrayTip(args*) { {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { @@ -2099,16 +2099,16 @@ HideTrayTip(command) { {% endblock HideTrayTip %} } -AHKWinGetClass(command) { +AHKWinGetClass(args*) { {% block AHKWinGetClass %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2137,15 +2137,15 @@ AHKWinGetClass(command) { {% endblock AHKWinGetClass %} } -AHKWinActivate(command) { +AHKWinActivate(args*) { {% block AHKWinActivate %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2174,18 +2174,18 @@ AHKWinActivate(command) { {% endblock AHKWinActivate %} } -AHKWindowList(command) { +AHKWindowList(args*) { {% block AHKWindowList %} current_detect_hw := Format("{}", A_DetectHiddenWindows) - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2216,20 +2216,20 @@ AHKWindowList(command) { {% endblock AHKWindowList %} } -AHKControlClick(command) { +AHKControlClick(args*) { {% block AHKControlClick %} - ctrl := command[2] - title := command[3] - text := command[4] - button := command[5] - click_count := command[6] - options := command[7] - exclude_title := command[8] - exclude_text := command[9] - detect_hw := command[10] - match_mode := command[11] - match_speed := command[12] + ctrl := args[1] + title := args[2] + text := args[3] + button := args[4] + click_count := args[5] + options := args[6] + exclude_title := args[7] + exclude_text := args[8] + detect_hw := args[9] + match_mode := args[10] + match_speed := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2258,17 +2258,17 @@ AHKControlClick(command) { {% endblock AHKControlClick %} } -AHKControlGetText(command) { +AHKControlGetText(args*) { {% block AHKControlGetText %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2298,17 +2298,17 @@ AHKControlGetText(command) { {% endblock AHKControlGetText %} } -AHKControlGetPos(command) { +AHKControlGetPos(args*) { {% block AHKControlGetPos %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2338,17 +2338,17 @@ AHKControlGetPos(command) { {% endblock AHKControlGetPos %} } -AHKControlSend(command) { +AHKControlSend(args*) { {% block AHKControlSend %} - ctrl := command[2] - keys := command[3] - title := command[4] - text := command[5] - extitle := command[6] - extext := command[7] - detect_hw := command[8] - match_mode := command[9] - match_speed := command[10] + ctrl := args[1] + keys := args[2] + title := args[3] + text := args[4] + extitle := args[5] + extext := args[6] + detect_hw := args[7] + match_mode := args[8] + match_speed := args[9] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2380,7 +2380,7 @@ AHKControlSend(command) { {% endblock AHKControlSend %} } -AHKWinFromMouse(command) { +AHKWinFromMouse(args*) { {% block AHKWinFromMouse %} MouseGetPos(,, &MouseWin) @@ -2393,10 +2393,10 @@ AHKWinFromMouse(command) { {% endblock AHKWinFromMouse %} } -AHKWinIsAlwaysOnTop(command) { +AHKWinIsAlwaysOnTop(args*) { {% block AHKWinIsAlwaysOnTop %} ; TODO: detect hidden windows / etc? - title := command[2] + title := args[1] ExStyle := WinGetExStyle(title) if (ExStyle = "") return FormatNoValueResponse() @@ -2408,19 +2408,19 @@ AHKWinIsAlwaysOnTop(command) { {% endblock AHKWinIsAlwaysOnTop %} } -AHKWinMove(command) { +AHKWinMove(args*) { {% block AHKWinMove %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - x := command[9] - y := command[10] - width := command[11] - height := command[12] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + x := args[8] + y := args[9] + width := args[10] + height := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2449,16 +2449,16 @@ AHKWinMove(command) { {% endblock AHKWinMove %} } -AHKWinGetPos(command) { +AHKWinGetPos(args*) { {% block AHKWinGetPos %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2489,10 +2489,10 @@ AHKWinGetPos(command) { {% endblock AHKWinGetPos %} } -AHKGetVolume(command) { +AHKGetVolume(args*) { {% block AHKGetVolume %} - device_number := command[2] + device_number := args[1] retval := SoundGetVolume(,device_number) response := FormatResponse("ahk.message.FloatResponseMessage", Format("{}", retval)) @@ -2500,111 +2500,111 @@ AHKGetVolume(command) { {% endblock AHKGetVolume %} } -AHKSoundBeep(command) { +AHKSoundBeep(args*) { {% block AHKSoundBeep %} - freq := command[2] - duration := command[3] + freq := args[1] + duration := args[2] SoundBeep(freq, duration) return FormatNoValueResponse() {% endblock AHKSoundBeep %} } -AHKSoundGet(command) { +AHKSoundGet(args*) { {% block AHKSoundGet %} return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundGet is not supported in ahk v2") {% endblock AHKSoundGet %} } -AHKSoundSet(command) { +AHKSoundSet(args*) { {% block AHKSoundSet %} return FormatResponse("ahk.message.ExceptionResponseMessage", "SoundSet is not supported in ahk v2") {% endblock AHKSoundSet %} } -AHKSoundPlay(command) { +AHKSoundPlay(args*) { {% block AHKSoundPlay %} - filename := command[2] + filename := args[1] SoundPlay(filename) return FormatNoValueResponse() {% endblock AHKSoundPlay %} } -AHKSetVolume(command) { +AHKSetVolume(args*) { {% block AHKSetVolume %} - device_number := command[2] - value := command[3] + device_number := args[1] + value := args[2] SoundSetVolume(value,,device_number) return FormatNoValueResponse() {% endblock AHKSetVolume %} } -AHKEcho(command) { +AHKEcho(args*) { {% block AHKEcho %} - arg := command[2] + arg := args[1] return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } -AHKTraytip(command) { +AHKTraytip(args*) { {% block AHKTraytip %} - title := command[2] - text := command[3] - second := command[4] - option := command[5] + title := args[1] + text := args[2] + second := args[3] + option := args[4] TrayTip(title, text, option) return FormatNoValueResponse() {% endblock AHKTraytip %} } -AHKShowToolTip(command) { +AHKShowToolTip(args*) { {% block AHKShowToolTip %} - text := command[2] - x := command[3] - y := command[4] - which := command[5] + text := args[1] + x := args[2] + y := args[3] + which := args[4] ToolTip(text, x, y, which) return FormatNoValueResponse() {% endblock AHKShowToolTip %} } -AHKGetClipboard(command) { +AHKGetClipboard(args*) { {% block AHKGetClipboard %} return FormatResponse("ahk.message.StringResponseMessage", A_Clipboard) {% endblock AHKGetClipboard %} } -AHKGetClipboardAll(command) { +AHKGetClipboardAll(args*) { {% block AHKGetClipboardAll %} data := ClipboardAll() return FormatBinaryResponse(&data) {% endblock AHKGetClipboardAll %} } -AHKSetClipboard(command) { +AHKSetClipboard(args*) { {% block AHKSetClipboard %} - text := command[2] + text := args[1] A_Clipboard := text return FormatNoValueResponse() {% endblock AHKSetClipboard %} } -AHKSetClipboardAll(command) { +AHKSetClipboardAll(args*) { {% block AHKSetClipboardAll %} ; TODO there should be a way for us to accept a base64 string instead - filename := command[2] + filename := args[1] contents := FileRead(filename, "RAW") A_Clipboard := ClipboardAll(contents) return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } -AHKClipWait(command) { +AHKClipWait(args*) { - timeout := command[2] - wait_for_any_data := command[3] + timeout := args[1] + wait_for_any_data := args[2] if ClipWait(timeout, wait_for_any_data) return FormatNoValueResponse() @@ -2613,45 +2613,45 @@ AHKClipWait(command) { return FormatNoValueResponse() } -AHKBlockInput(command) { - value := command[2] +AHKBlockInput(args*) { + value := args[1] BlockInput(value) return FormatNoValueResponse() } -AHKMenuTrayTip(command) { - value := command[2] +AHKMenuTrayTip(args*) { + value := args[1] A_IconTip := value return FormatNoValueResponse() } -AHKMenuTrayShow(command) { +AHKMenuTrayShow(args*) { A_IconHidden := 0 return FormatNoValueResponse() } -AHKMenuTrayIcon(command) { - filename := command[2] - icon_number := command[3] - freeze := command[4] +AHKMenuTrayIcon(args*) { + filename := args[1] + icon_number := args[2] + freeze := args[3] TraySetIcon(filename, icon_number, freeze) return FormatNoValueResponse() } -;AHKGuiNew(command) { +;AHKGuiNew(args*) { ; -; options := command[2] -; title := command[3] +; options := args[1] +; title := args[2] ; Gui(New, options, title) ; return FormatResponse("ahk.message.StringResponseMessage", hwnd) ;} -AHKMsgBox(command) { +AHKMsgBox(args*) { - options := command[2] - title := command[3] - text := command[4] - timeout := command[5] + options := args[1] + title := args[2] + text := args[3] + timeout := args[4] if (timeout != "") { options := "" options " T" timeout } @@ -2664,18 +2664,18 @@ AHKMsgBox(command) { return ret } -AHKInputBox(command) { +AHKInputBox(args*) { - title := command[2] - prompt := command[3] - hide := command[4] - width := command[5] - height := command[6] - x := command[7] - y := command[8] - locale := command[9] - timeout := command[10] - default := command[11] + title := args[1] + prompt := args[2] + hide := args[3] + width := args[4] + height := args[5] + x := args[6] + y := args[7] + locale := args[8] + timeout := args[9] + default := args[10] ; TODO: support options correctly options := "" @@ -2693,12 +2693,12 @@ AHKInputBox(command) { return ret } -AHKFileSelectFile(command) { +AHKFileSelectFile(args*) { - options := command[2] - root := command[3] - title := command[4] - filter := command[5] + options := args[1] + root := args[2] + title := args[3] + filter := args[4] output := FileSelect(options, root, title, filter) if (output = "") { ret := FormatNoValueResponse() @@ -2723,11 +2723,11 @@ AHKFileSelectFile(command) { return ret } -AHKFileSelectFolder(command) { +AHKFileSelectFolder(args*) { - starting_folder := command[2] - options := command[3] - prompt := command[4] + starting_folder := args[1] + options := args[2] + prompt := args[3] output := DirSelect(starting_folder, options, prompt) @@ -2845,12 +2845,13 @@ pyresp := "" Loop { query := RTrim(stdin.ReadLine(), "`n") - commandArray := CommandArrayFromQuery(query) + argsArray := CommandArrayFromQuery(query) try { - func_name := commandArray[1] + func_name := argsArray[1] + argsArray.RemoveAt(1) {% block before_function %} {% endblock before_function %} - pyresp := %func_name%(commandArray) + pyresp := %func_name%(argsArray*) {% block after_function %} {% endblock after_function %} } catch Any as e { diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 83ce0a1..358c008 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -40,18 +40,18 @@ FormatBinaryResponse(ByRef bin) { return FormatResponse("ahk.message.B64BinaryResponseMessage", b64) } -AHKSetDetectHiddenWindows(ByRef command) { +AHKSetDetectHiddenWindows(args*) { {% block AHKSetDetectHiddenWindows %} - value := command[2] + value := args[1] DetectHiddenWindows, %value% return FormatNoValueResponse() {% endblock AHKSetDetectHiddenWindows %} } -AHKSetTitleMatchMode(ByRef command) { +AHKSetTitleMatchMode(args*) { {% block AHKSetTitleMatchMode %} - val1 := command[2] - val2 := command[3] + val1 := args[1] + val2 := args[2] if (val1 != "") { SetTitleMatchMode, %val1% } @@ -62,45 +62,45 @@ AHKSetTitleMatchMode(ByRef command) { {% endblock AHKSetTitleMatchMode %} } -AHKGetTitleMatchMode(ByRef command) { +AHKGetTitleMatchMode(args*) { {% block AHKGetTitleMatchMode %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchMode) {% endblock AHKGetTitleMatchMode %} } -AHKGetTitleMatchSpeed(ByRef command) { +AHKGetTitleMatchSpeed(args*) { {% block AHKGetTitleMatchSpeed %} return FormatResponse("ahk.message.StringResponseMessage", A_TitleMatchModeSpeed) {% endblock AHKGetTitleMatchSpeed %} } -AHKSetSendLevel(ByRef command) { +AHKSetSendLevel(args*) { {% block AHKSetSendLevel %} - level := command[2] + level := args[1] SendLevel, %level% return FormatNoValueResponse() {% endblock AHKSetSendLevel %} } -AHKGetSendLevel(ByRef command) { +AHKGetSendLevel(args*) { {% block AHKGetSendLevel %} return FormatResponse("ahk.message.IntegerResponseMessage", A_SendLevel) {% endblock AHKGetSendLevel %} } -AHKWinExist(ByRef command) { +AHKWinExist(args*) { {% block AHKWinExist %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -131,16 +131,16 @@ AHKWinExist(ByRef command) { {% endblock AHKWinExist %} } -AHKWinClose(ByRef command) { +AHKWinClose(args*) { {% block AHKWinClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -166,16 +166,16 @@ AHKWinClose(ByRef command) { {% endblock AHKWinClose %} } -AHKWinKill(ByRef command) { +AHKWinKill(args*) { {% block AHKWinKill %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - secondstowait := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + secondstowait := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -201,17 +201,17 @@ AHKWinKill(ByRef command) { {% endblock AHKWinKill %} } -AHKWinWait(ByRef command) { +AHKWinWait(args*) { {% block AHKWinWait %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -245,17 +245,17 @@ AHKWinWait(ByRef command) { {% endblock AHKWinWait %} } -AHKWinWaitActive(ByRef command) { +AHKWinWaitActive(args*) { {% block AHKWinWaitActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -289,17 +289,17 @@ AHKWinWaitActive(ByRef command) { {% endblock AHKWinWaitActive %} } -AHKWinWaitNotActive(ByRef command) { +AHKWinWaitNotActive(args*) { {% block AHKWinWaitNotActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -333,17 +333,17 @@ AHKWinWaitNotActive(ByRef command) { {% endblock AHKWinWaitNotActive %} } -AHKWinWaitClose(ByRef command) { +AHKWinWaitClose(args*) { {% block AHKWinWaitClose %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - timeout := command[9] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + timeout := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -376,15 +376,15 @@ AHKWinWaitClose(ByRef command) { {% endblock AHKWinWaitClose %} } -AHKWinMinimize(ByRef command) { +AHKWinMinimize(args*) { {% block AHKWinMinimize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -410,15 +410,15 @@ AHKWinMinimize(ByRef command) { {% endblock AHKWinMinimize %} } -AHKWinMaximize(ByRef command) { +AHKWinMaximize(args*) { {% block AHKWinMaximize %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -444,15 +444,15 @@ AHKWinMaximize(ByRef command) { {% endblock AHKWinMaximize %} } -AHKWinRestore(ByRef command) { +AHKWinRestore(args*) { {% block AHKWinRestore %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -478,16 +478,16 @@ AHKWinRestore(ByRef command) { {% endblock AHKWinRestore %} } -AHKWinIsActive(ByRef command) { +AHKWinIsActive(args*) { {% block AHKWinIsActive %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) if (match_mode != "") { @@ -515,16 +515,16 @@ AHKWinIsActive(ByRef command) { {% endblock AHKWinIsActive %} } -AHKWinGetID(ByRef command) { +AHKWinGetID(args*) { {% block AHKWinGetID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -554,16 +554,16 @@ AHKWinGetID(ByRef command) { {% endblock AHKWinGetID %} } -AHKWinGetTitle(ByRef command) { +AHKWinGetTitle(args*) { {% block AHKWinGetTitle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -589,16 +589,16 @@ AHKWinGetTitle(ByRef command) { {% endblock AHKWinGetTitle %} } -AHKWinGetIDLast(ByRef command) { +AHKWinGetIDLast(args*) { {% block AHKWinGetIDLast %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -628,16 +628,16 @@ AHKWinGetIDLast(ByRef command) { {% endblock AHKWinGetIDLast %} } -AHKWinGetPID(ByRef command) { +AHKWinGetPID(args*) { {% block AHKWinGetPID %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -667,16 +667,16 @@ AHKWinGetPID(ByRef command) { {% endblock AHKWinGetPID %} } -AHKWinGetProcessName(ByRef command) { +AHKWinGetProcessName(args*) { {% block AHKWinGetProcessName %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -706,16 +706,16 @@ AHKWinGetProcessName(ByRef command) { {% endblock AHKWinGetProcessName %} } -AHKWinGetProcessPath(ByRef command) { +AHKWinGetProcessPath(args*) { {% block AHKWinGetProcessPath %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -745,16 +745,16 @@ AHKWinGetProcessPath(ByRef command) { {% endblock AHKWinGetProcessPath %} } -AHKWinGetCount(ByRef command) { +AHKWinGetCount(args*) { {% block AHKWinGetCount %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -784,16 +784,16 @@ AHKWinGetCount(ByRef command) { {% endblock AHKWinGetCount %} } -AHKWinGetMinMax(ByRef command) { +AHKWinGetMinMax(args*) { {% block AHKWinGetMinMax %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -823,16 +823,16 @@ AHKWinGetMinMax(ByRef command) { {% endblock AHKWinGetMinMax %} } -AHKWinGetControlList(ByRef command) { +AHKWinGetControlList(args*) { {% block AHKWinGetControlList %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -887,16 +887,16 @@ AHKWinGetControlList(ByRef command) { {% endblock AHKWinGetControlList %} } -AHKWinGetTransparent(ByRef command) { +AHKWinGetTransparent(args*) { {% block AHKWinGetTransparent %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -921,16 +921,16 @@ AHKWinGetTransparent(ByRef command) { return response {% endblock AHKWinGetTransparent %} } -AHKWinGetTransColor(ByRef command) { +AHKWinGetTransColor(args*) { {% block AHKWinGetTransColor %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -955,16 +955,16 @@ AHKWinGetTransColor(ByRef command) { return response {% endblock AHKWinGetTransColor %} } -AHKWinGetStyle(ByRef command) { +AHKWinGetStyle(args*) { {% block AHKWinGetStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -989,16 +989,16 @@ AHKWinGetStyle(ByRef command) { return response {% endblock AHKWinGetStyle %} } -AHKWinGetExStyle(ByRef command) { +AHKWinGetExStyle(args*) { {% block AHKWinGetExStyle %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1024,16 +1024,16 @@ AHKWinGetExStyle(ByRef command) { {% endblock AHKWinGetExStyle %} } -AHKWinGetText(ByRef command) { +AHKWinGetText(args*) { {% block AHKWinGetText %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1064,16 +1064,16 @@ AHKWinGetText(ByRef command) { {% endblock AHKWinGetText %} } -AHKWinSetTitle(ByRef command) { +AHKWinSetTitle(args*) { {% block AHKWinSetTitle %} - new_title := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + new_title := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1096,16 +1096,16 @@ AHKWinSetTitle(ByRef command) { {% endblock AHKWinSetTitle %} } -AHKWinSetAlwaysOnTop(ByRef command) { +AHKWinSetAlwaysOnTop(args*) { {% block AHKWinSetAlwaysOnTop %} - toggle := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + toggle := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1129,15 +1129,15 @@ AHKWinSetAlwaysOnTop(ByRef command) { {% endblock AHKWinSetAlwaysOnTop %} } -AHKWinSetBottom(ByRef command) { +AHKWinSetBottom(args*) { {% block AHKWinSetBottom %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1162,15 +1162,15 @@ AHKWinSetBottom(ByRef command) { {% endblock AHKWinSetBottom %} } -AHKWinShow(ByRef command) { +AHKWinShow(args*) { {% block AHKWinShow %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1195,15 +1195,15 @@ AHKWinShow(ByRef command) { {% endblock AHKWinShow %} } -AHKWinHide(ByRef command) { +AHKWinHide(args*) { {% block AHKWinHide %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1228,15 +1228,15 @@ AHKWinHide(ByRef command) { {% endblock AHKWinHide %} } -AHKWinSetTop(ByRef command) { +AHKWinSetTop(args*) { {% block AHKWinSetTop %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1261,15 +1261,15 @@ AHKWinSetTop(ByRef command) { {% endblock AHKWinSetTop %} } -AHKWinSetEnable(ByRef command) { +AHKWinSetEnable(args*) { {% block AHKWinSetEnable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1294,15 +1294,15 @@ AHKWinSetEnable(ByRef command) { {% endblock AHKWinSetEnable %} } -AHKWinSetDisable(ByRef command) { +AHKWinSetDisable(args*) { {% block AHKWinSetDisable %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1327,15 +1327,15 @@ AHKWinSetDisable(ByRef command) { {% endblock AHKWinSetDisable %} } -AHKWinSetRedraw(ByRef command) { +AHKWinSetRedraw(args*) { {% block AHKWinSetRedraw %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1360,17 +1360,17 @@ AHKWinSetRedraw(ByRef command) { {% endblock AHKWinSetRedraw %} } -AHKWinSetStyle(ByRef command) { +AHKWinSetStyle(args*) { {% block AHKWinSetStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1399,17 +1399,17 @@ AHKWinSetStyle(ByRef command) { {% endblock AHKWinSetStyle %} } -AHKWinSetExStyle(ByRef command) { +AHKWinSetExStyle(args*) { {% block AHKWinSetExStyle %} - style := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + style := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1438,17 +1438,17 @@ AHKWinSetExStyle(ByRef command) { {% endblock AHKWinSetExStyle %} } -AHKWinSetRegion(ByRef command) { +AHKWinSetRegion(args*) { {% block AHKWinSetRegion %} - options := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + options := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1477,17 +1477,17 @@ AHKWinSetRegion(ByRef command) { {% endblock AHKWinSetRegion %} } -AHKWinSetTransparent(ByRef command) { +AHKWinSetTransparent(args*) { {% block AHKWinSetTransparent %} - transparency := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + transparency := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1511,17 +1511,17 @@ AHKWinSetTransparent(ByRef command) { {% endblock AHKWinSetTransparent %} } -AHKWinSetTransColor(ByRef command) { +AHKWinSetTransColor(args*) { {% block AHKWinSetTransColor %} - color := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + color := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -1547,15 +1547,15 @@ AHKWinSetTransColor(ByRef command) { {% endblock AHKWinSetTransColor %} } -AHKImageSearch(ByRef command) { +AHKImageSearch(args*) { {% block AHKImageSearch %} - imagepath := command[6] - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - coord_mode := command[7] + imagepath := args[5] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + coord_mode := args[6] current_mode := Format("{}", A_CoordModePixel) @@ -1577,7 +1577,7 @@ AHKImageSearch(ByRef command) { } if (ErrorLevel = 2) { - s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the command from conducting the search (such as failure to open the image file or a badly formatted option)") + s := FormatResponse("ahk.message.ExceptionResponseMessage", "there was a problem that prevented the args from conducting the search (such as failure to open the image file or a badly formatted option)") } else if (ErrorLevel = 1) { s := FormatNoValueResponse() } else { @@ -1588,13 +1588,13 @@ AHKImageSearch(ByRef command) { {% endblock AHKImageSearch %} } -AHKPixelGetColor(ByRef command) { +AHKPixelGetColor(args*) { {% block AHKPixelGetColor %} - x := command[2] - y := command[3] - coord_mode := command[4] - options := command[5] + x := args[1] + y := args[2] + coord_mode := args[3] + options := args[4] current_mode := Format("{}", A_CoordModePixel) @@ -1613,17 +1613,17 @@ AHKPixelGetColor(ByRef command) { {% endblock AHKPixelGetColor %} } -AHKPixelSearch(ByRef command) { +AHKPixelSearch(args*) { {% block AHKPixelSearch %} - x1 := command[2] - y1 := command[3] - x2 := command[4] - y2 := command[5] - color := command[6] - variation := command[7] - options := command[8] - coord_mode := command[9] + x1 := args[1] + y1 := args[2] + x2 := args[3] + y2 := args[4] + color := args[5] + variation := args[6] + options := args[7] + coord_mode := args[8] current_mode := Format("{}", A_CoordModePixel) @@ -1651,10 +1651,10 @@ AHKPixelSearch(ByRef command) { {% endblock AHKPixelSearch %} } -AHKMouseGetPos(ByRef command) { +AHKMouseGetPos(args*) { {% block AHKMouseGetPos %} - coord_mode := command[2] + coord_mode := args[1] current_coord_mode := Format("{}", A_CoordModeMouse) if (coord_mode != "") { CoordMode, Mouse, %coord_mode% @@ -1672,11 +1672,11 @@ AHKMouseGetPos(ByRef command) { {% endblock AHKMouseGetPos %} } -AHKKeyState(ByRef command) { +AHKKeyState(args*) { {% block AHKKeyState %} - keyname := command[2] - mode := command[3] + keyname := args[1] + mode := args[2] if (mode != "") { state := GetKeyState(keyname, mode) } else{ @@ -1700,12 +1700,12 @@ AHKKeyState(ByRef command) { {% endblock AHKKeyState %} } -AHKMouseMove(ByRef command) { +AHKMouseMove(args*) { {% block AHKMouseMove %} - x := command[2] - y := command[3] - speed := command[4] - relative := command[5] + x := args[1] + y := args[2] + speed := args[3] + relative := args[4] if (relative != "") { MouseMove, %x%, %y%, %speed%, R } else { @@ -1716,15 +1716,15 @@ AHKMouseMove(ByRef command) { {% endblock AHKMouseMove %} } -AHKClick(ByRef command) { +AHKClick(args*) { {% block AHKClick %} - x := command[2] - y := command[3] - button := command[4] - click_count := command[5] - direction := command[6] - r := command[7] - relative_to := command[8] + x := args[1] + y := args[2] + button := args[3] + click_count := args[4] + direction := args[5] + r := args[6] + relative_to := args[7] current_coord_rel := Format("{}", A_CoordModeMouse) if (relative_to != "") { @@ -1742,10 +1742,10 @@ AHKClick(ByRef command) { {% endblock AHKClick %} } -AHKGetCoordMode(ByRef command) { +AHKGetCoordMode(args*) { {% block AHKGetCoordMode %} - target := command[2] + target := args[1] if (target = "ToolTip") { return FormatResponse("ahk.message.StringResponseMessage", A_CoordModeToolTip) @@ -1766,26 +1766,26 @@ AHKGetCoordMode(ByRef command) { {% endblock AHKGetCoordMode %} } -AHKSetCoordMode(ByRef command) { +AHKSetCoordMode(args*) { {% block AHKSetCoordMode %} - target := command[2] - relative_to := command[3] + target := args[1] + relative_to := args[2] CoordMode, %target%, %relative_to% return FormatNoValueResponse() {% endblock AHKSetCoordMode %} } -AHKMouseClickDrag(ByRef command) { +AHKMouseClickDrag(args*) { {% block AHKMouseClickDrag %} - button := command[2] - x1 := command[3] - y1 := command[4] - x2 := command[5] - y2 := command[6] - speed := command[7] - relative := command[8] - relative_to := command[9] + button := args[1] + x1 := args[2] + y1 := args[3] + x2 := args[4] + y2 := args[5] + speed := args[6] + relative := args[7] + relative_to := args[8] current_coord_rel := Format("{}", A_CoordModeMouse) @@ -1804,11 +1804,11 @@ AHKMouseClickDrag(ByRef command) { {% endblock AHKMouseClickDrag %} } -AHKRegRead(ByRef command) { +AHKRegRead(args*) { {% block RegRead %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] RegRead, output, %key_name%, %value_name% @@ -1822,13 +1822,13 @@ AHKRegRead(ByRef command) { {% endblock RegRead %} } -AHKRegWrite(ByRef command) { +AHKRegWrite(args*) { {% block RegWrite %} - value_type := command[2] - key_name := command[3] - value_name := command[4] - value := command[5] + value_type := args[1] + key_name := args[2] + value_name := args[3] + value := args[4] RegWrite, %value_type%, %key_name%, %value_name%, %value% if (ErrorLevel = 1) { return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) @@ -1838,11 +1838,11 @@ AHKRegWrite(ByRef command) { {% endblock RegWrite %} } -AHKRegDelete(ByRef command) { +AHKRegDelete(args*) { {% block RegDelete %} - key_name := command[2] - value_name := command[3] + key_name := args[1] + value_name := args[2] RegDelete, %key_name%, %value_name% if (ErrorLevel = 1) { return FormatResponse("ahk.message.ExceptionResponseMessage", Format("registry error: {}", A_LastError)) @@ -1852,31 +1852,31 @@ AHKRegDelete(ByRef command) { {% endblock RegDelete %} } -AHKKeyWait(ByRef command) { +AHKKeyWait(args*) { {% block AHKKeyWait %} - keyname := command[2] - if (command.Length() = 2) { + keyname := args[1] + if (args.Length() = 2) { KeyWait,% keyname } else { - options := command[3] + options := args[2] KeyWait,% keyname,% options } return FormatResponse("ahk.message.IntegerResponseMessage", ErrorLevel) {% endblock AHKKeyWait %} } -SetKeyDelay(ByRef command) { +SetKeyDelay(args*) { {% block SetKeyDelay %} - SetKeyDelay, command[2], command[3] + SetKeyDelay, args[1], args[2] {% endblock SetKeyDelay %} } -AHKSend(ByRef command) { +AHKSend(args*) { {% block AHKSend %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1893,11 +1893,11 @@ AHKSend(ByRef command) { {% endblock AHKSend %} } -AHKSendRaw(ByRef command) { +AHKSendRaw(args*) { {% block AHKSendRaw %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1914,11 +1914,11 @@ AHKSendRaw(ByRef command) { {% endblock AHKSendRaw %} } -AHKSendInput(ByRef command) { +AHKSendInput(args*) { {% block AHKSendInput %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1935,11 +1935,11 @@ AHKSendInput(ByRef command) { {% endblock AHKSendInput %} } -AHKSendEvent(ByRef command) { +AHKSendEvent(args*) { {% block AHKSendEvent %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelay) current_key_duration := Format("{}", A_KeyDuration) @@ -1956,11 +1956,11 @@ AHKSendEvent(ByRef command) { {% endblock AHKSendEvent %} } -AHKSendPlay(ByRef command) { +AHKSendPlay(args*) { {% block AHKSendPlay %} - str := command[2] - key_delay := command[3] - key_press_duration := command[4] + str := args[1] + key_delay := args[2] + key_press_duration := args[3] current_delay := Format("{}", A_KeyDelayPlay) current_key_duration := Format("{}", A_KeyDurationPlay) @@ -1977,9 +1977,9 @@ AHKSendPlay(ByRef command) { {% endblock AHKSendPlay %} } -AHKSetCapsLockState(ByRef command) { +AHKSetCapsLockState(args*) { {% block AHKSetCapsLockState %} - state := command[2] + state := args[1] if (state = "") { SetCapsLockState % !GetKeyState("CapsLock", "T") } else { @@ -1989,7 +1989,7 @@ AHKSetCapsLockState(ByRef command) { {% endblock AHKSetCapsLockState %} } -HideTrayTip(ByRef command) { +HideTrayTip(args*) { {% block HideTrayTip %} TrayTip ; Attempt to hide it the normal way. if SubStr(A_OSVersion,1,3) = "10." { @@ -2000,16 +2000,16 @@ HideTrayTip(ByRef command) { {% endblock HideTrayTip %} } -AHKWinGetClass(ByRef command) { +AHKWinGetClass(args*) { {% block AHKWinGetClass %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2040,15 +2040,15 @@ AHKWinGetClass(ByRef command) { {% endblock AHKWinGetClass %} } -AHKWinActivate(ByRef command) { +AHKWinActivate(args*) { {% block AHKWinActivate %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2075,18 +2075,18 @@ AHKWinActivate(ByRef command) { {% endblock AHKWinActivate %} } -AHKWindowList(ByRef command) { +AHKWindowList(args*) { {% block AHKWindowList %} current_detect_hw := Format("{}", A_DetectHiddenWindows) - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2115,20 +2115,20 @@ AHKWindowList(ByRef command) { {% endblock AHKWindowList %} } -AHKControlClick(ByRef command) { +AHKControlClick(args*) { {% block AHKControlClick %} - ctrl := command[2] - title := command[3] - text := command[4] - button := command[5] - click_count := command[6] - options := command[7] - exclude_title := command[8] - exclude_text := command[9] - detect_hw := command[10] - match_mode := command[11] - match_speed := command[12] + ctrl := args[1] + title := args[2] + text := args[3] + button := args[4] + click_count := args[5] + options := args[6] + exclude_title := args[7] + exclude_text := args[8] + detect_hw := args[9] + match_mode := args[10] + match_speed := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2160,17 +2160,17 @@ AHKControlClick(ByRef command) { {% endblock AHKControlClick %} } -AHKControlGetText(ByRef command) { +AHKControlGetText(args*) { {% block AHKControlGetText %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2201,17 +2201,17 @@ AHKControlGetText(ByRef command) { {% endblock AHKControlGetText %} } -AHKControlGetPos(ByRef command) { +AHKControlGetPos(args*) { {% block AHKControlGetPos %} - ctrl := command[2] - title := command[3] - text := command[4] - extitle := command[5] - extext := command[6] - detect_hw := command[7] - match_mode := command[8] - match_speed := command[9] + ctrl := args[1] + title := args[2] + text := args[3] + extitle := args[4] + extext := args[5] + detect_hw := args[6] + match_mode := args[7] + match_speed := args[8] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2244,17 +2244,17 @@ AHKControlGetPos(ByRef command) { {% endblock AHKControlGetPos %} } -AHKControlSend(ByRef command) { +AHKControlSend(args*) { {% block AHKControlSend %} - ctrl := command[2] - keys := command[3] - title := command[4] - text := command[5] - extitle := command[6] - extext := command[7] - detect_hw := command[8] - match_mode := command[9] - match_speed := command[10] + ctrl := args[1] + keys := args[2] + title := args[3] + text := args[4] + extitle := args[5] + extext := args[6] + detect_hw := args[7] + match_mode := args[8] + match_speed := args[9] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2277,7 +2277,7 @@ AHKControlSend(ByRef command) { {% endblock AHKControlSend %} } -AHKWinFromMouse(ByRef command) { +AHKWinFromMouse(args*) { {% block AHKWinFromMouse %} MouseGetPos,,, MouseWin @@ -2290,10 +2290,10 @@ AHKWinFromMouse(ByRef command) { {% endblock AHKWinFromMouse %} } -AHKWinIsAlwaysOnTop(ByRef command) { +AHKWinIsAlwaysOnTop(args*) { {% block AHKWinIsAlwaysOnTop %} - title := command[2] + title := args[1] WinGet, ExStyle, ExStyle, %title% if (ExStyle = "") return FormatNoValueResponse() @@ -2305,19 +2305,19 @@ AHKWinIsAlwaysOnTop(ByRef command) { {% endblock AHKWinIsAlwaysOnTop %} } -AHKWinMove(ByRef command) { +AHKWinMove(args*) { {% block AHKWinMove %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] - x := command[9] - y := command[10] - width := command[11] - height := command[12] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] + x := args[8] + y := args[9] + width := args[10] + height := args[11] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2344,16 +2344,16 @@ AHKWinMove(ByRef command) { {% endblock AHKWinMove %} } -AHKWinGetPos(ByRef command) { +AHKWinGetPos(args*) { {% block AHKWinGetPos %} - title := command[2] - text := command[3] - extitle := command[4] - extext := command[5] - detect_hw := command[6] - match_mode := command[7] - match_speed := command[8] + title := args[1] + text := args[2] + extitle := args[3] + extext := args[4] + detect_hw := args[5] + match_mode := args[6] + match_speed := args[7] current_match_mode := Format("{}", A_TitleMatchMode) current_match_speed := Format("{}", A_TitleMatchModeSpeed) @@ -2386,10 +2386,10 @@ AHKWinGetPos(ByRef command) { {% endblock AHKWinGetPos %} } -AHKGetVolume(ByRef command) { +AHKGetVolume(args*) { {% block AHKGetVolume %} - device_number := command[2] + device_number := args[1] try { SoundGetWaveVolume, retval, %device_number% @@ -2406,21 +2406,21 @@ AHKGetVolume(ByRef command) { {% endblock AHKGetVolume %} } -AHKSoundBeep(ByRef command) { +AHKSoundBeep(args*) { {% block AHKSoundBeep %} - freq := command[2] - duration := command[3] + freq := args[1] + duration := args[2] SoundBeep , %freq%, %duration% return FormatNoValueResponse() {% endblock AHKSoundBeep %} } -AHKSoundGet(ByRef command) { +AHKSoundGet(args*) { {% block AHKSoundGet %} - device_number := command[2] - component_type := command[3] - control_type := command[4] + device_number := args[1] + component_type := args[2] + control_type := args[3] SoundGet, retval, %component_type%, %control_type%, %device_number% ; TODO interpret return type @@ -2428,29 +2428,29 @@ AHKSoundGet(ByRef command) { {% endblock AHKSoundGet %} } -AHKSoundSet(ByRef command) { +AHKSoundSet(args*) { {% block AHKSoundSet %} - device_number := command[2] - component_type := command[3] - control_type := command[4] - value := command[5] + device_number := args[1] + component_type := args[2] + control_type := args[3] + value := args[4] SoundSet, %value%, %component_type%, %control_type%, %device_number% return FormatNoValueResponse() {% endblock AHKSoundSet %} } -AHKSoundPlay(ByRef command) { +AHKSoundPlay(args*) { {% block AHKSoundPlay %} - filename := command[2] + filename := args[1] SoundPlay, %filename% return FormatNoValueResponse() {% endblock AHKSoundPlay %} } -AHKSetVolume(ByRef command) { +AHKSetVolume(args*) { {% block AHKSetVolume %} - device_number := command[2] - value := command[3] + device_number := args[1] + value := args[2] SoundSetWaveVolume, %value%, %device_number% return FormatNoValueResponse() {% endblock AHKSetVolume %} @@ -2463,71 +2463,71 @@ CountNewlines(ByRef s) { return count } -AHKEcho(ByRef command) { +AHKEcho(args*) { {% block AHKEcho %} - arg := command[2] + arg := args[1] return FormatResponse("ahk.message.StringResponseMessage", arg) {% endblock AHKEcho %} } -AHKTraytip(ByRef command) { +AHKTraytip(args*) { {% block AHKTraytip %} - title := command[2] - text := command[3] - second := command[4] - option := command[5] + title := args[1] + text := args[2] + second := args[3] + option := args[4] TrayTip, %title%, %text%, %second%, %option% return FormatNoValueResponse() {% endblock AHKTraytip %} } -AHKShowToolTip(ByRef command) { +AHKShowToolTip(args*) { {% block AHKShowToolTip %} - text := command[2] - x := command[3] - y := command[4] - which := command[5] + text := args[1] + x := args[2] + y := args[3] + which := args[4] ToolTip, %text%, %x%, %y%, %which% return FormatNoValueResponse() {% endblock AHKShowToolTip %} } -AHKGetClipboard(ByRef command) { +AHKGetClipboard(args*) { {% block AHKGetClipboard %} return FormatResponse("ahk.message.StringResponseMessage", Clipboard) {% endblock AHKGetClipboard %} } -AHKGetClipboardAll(ByRef command) { +AHKGetClipboardAll(args*) { {% block AHKGetClipboardAll %} data := ClipboardAll return FormatBinaryResponse(data) {% endblock AHKGetClipboardAll %} } -AHKSetClipboard(ByRef command) { +AHKSetClipboard(args*) { {% block AHKSetClipboard %} - text := command[2] + text := args[1] Clipboard := text return FormatNoValueResponse() {% endblock AHKSetClipboard %} } -AHKSetClipboardAll(ByRef command) { +AHKSetClipboardAll(args*) { {% block AHKSetClipboardAll %} ; TODO there should be a way for us to accept a base64 string instead - filename := command[2] + filename := args[1] FileRead, Clipboard, %filename% return FormatNoValueResponse() {% endblock AHKSetClipboardAll %} } -AHKClipWait(ByRef command) { +AHKClipWait(args*) { - timeout := command[2] - wait_for_any_data := command[3] + timeout := args[1] + wait_for_any_data := args[2] ClipWait, %timeout%, %wait_for_any_data% @@ -2537,45 +2537,45 @@ AHKClipWait(ByRef command) { return FormatNoValueResponse() } -AHKBlockInput(ByRef command) { - value := command[2] +AHKBlockInput(args*) { + value := args[1] BlockInput, %value% return FormatNoValueResponse() } -AHKMenuTrayTip(ByRef command) { - value := command[2] +AHKMenuTrayTip(args*) { + value := args[1] Menu, Tray, Tip, %value% return FormatNoValueResponse() } -AHKMenuTrayShow(ByRef command) { +AHKMenuTrayShow(args*) { Menu, Tray, Icon return FormatNoValueResponse() } -AHKMenuTrayIcon(ByRef command) { - filename := command[2] - icon_number := command[3] - freeze := command[4] +AHKMenuTrayIcon(args*) { + filename := args[1] + icon_number := args[2] + freeze := args[3] Menu, Tray, Icon, %filename%, %icon_number%,%freeze% return FormatNoValueResponse() } -AHKGuiNew(ByRef command) { +AHKGuiNew(args*) { - options := command[2] - title := command[3] + options := args[1] + title := args[2] Gui, New, %options%, %title% return FormatResponse("ahk.message.StringResponseMessage", hwnd) } -AHKMsgBox(ByRef command) { +AHKMsgBox(args*) { - options := command[2] - title := command[3] - text := command[4] - timeout := command[5] + options := args[1] + title := args[2] + text := args[3] + timeout := args[4] MsgBox,% options, %title%, %text%, %timeout% IfMsgBox, Yes ret := FormatResponse("ahk.message.StringResponseMessage", "Yes") @@ -2600,18 +2600,18 @@ AHKMsgBox(ByRef command) { return ret } -AHKInputBox(ByRef command) { +AHKInputBox(args*) { - title := command[2] - prompt := command[3] - hide := command[4] - width := command[5] - height := command[6] - x := command[7] - y := command[8] - locale := command[9] - timeout := command[10] - default := command[11] + title := args[1] + prompt := args[2] + hide := args[3] + width := args[4] + height := args[5] + x := args[6] + y := args[7] + locale := args[8] + timeout := args[9] + default := args[10] InputBox, output, %title%, %prompt%, %hide%, %width%, %height%, %x%, %y%, %locale%, %timeout%, %default% if (ErrorLevel = 2) { @@ -2624,12 +2624,12 @@ AHKInputBox(ByRef command) { return ret } -AHKFileSelectFile(byRef command) { +AHKFileSelectFile(byRef args) { - options := command[2] - root := command[3] - title := command[4] - filter := command[5] + options := args[1] + root := args[2] + title := args[3] + filter := args[4] FileSelectFile, output, %options%, %root%, %title%, %filter% if (ErrorLevel = 1) { ret := FormatNoValueResponse() @@ -2639,11 +2639,11 @@ AHKFileSelectFile(byRef command) { return ret } -AHKFileSelectFolder(byRef command) { +AHKFileSelectFolder(byRef args) { - starting_folder := command[2] - options := command[3] - prompt := command[4] + starting_folder := args[1] + options := args[2] + prompt := args[3] FileSelectFolder, output, %starting_folder%, %options%, %prompt% @@ -2762,12 +2762,13 @@ pyresp := "" Loop { query := RTrim(stdin.ReadLine(), "`n") - commandArray := CommandArrayFromQuery(query) + argsArray := CommandArrayFromQuery(query) try { - func := commandArray[1] + func := argsArray[1] + argsArray.RemoveAt(1) {% block before_function %} {% endblock before_function %} - pyresp := %func%(commandArray) + pyresp := %func%(argsArray*) {% block after_function %} {% endblock after_function %} } catch e { diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index 11430eb..ff09c5d 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -17,9 +17,8 @@ function_name = 'AAHKDoSomething' # unasync: remove ext_text = f'''\ -{function_name}(command) {{ - arg := command[2] - return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) +{function_name}(first, second) {{ + return FormatResponse("ahk.message.StringResponseMessage", Format("{{}} and {{}}", first, second)) }} ''' @@ -27,8 +26,8 @@ @async_extension.register -async def do_something(ahk, arg: str) -> str: - res = await ahk.function_call(function_name, [arg]) +async def do_something(ahk, first: str, second: str) -> str: + res = await ahk.function_call(function_name, [first, second]) return res @@ -41,8 +40,8 @@ async def asyncTearDown(self) -> None: time.sleep(0.2) async def test_ext_explicit(self): - res = await self.ahk.do_something('foo') - assert res == 'testfoo' + res = await self.ahk.do_something('foo', 'bar') + assert res == 'foo and bar' class TestExtensionsAuto(unittest.IsolatedAsyncioTestCase): @@ -54,8 +53,8 @@ async def asyncTearDown(self) -> None: time.sleep(0.2) async def test_ext_auto(self): - res = await self.ahk.do_something('foo') - assert res == 'testfoo' + res = await self.ahk.do_something('foo', 'bar') + assert res == 'foo and bar' class TestNoExtensions(unittest.IsolatedAsyncioTestCase): diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index e74f41f..3fb960f 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -15,9 +15,8 @@ function_name = 'AHKDoSomething' ext_text = f'''\ -{function_name}(command) {{ - arg := command[2] - return FormatResponse("ahk.message.StringResponseMessage", Format("test{{}}", arg)) +{function_name}(first, second) {{ + return FormatResponse("ahk.message.StringResponseMessage", Format("{{}} and {{}}", first, second)) }} ''' @@ -25,8 +24,8 @@ @async_extension.register -def do_something(ahk, arg: str) -> str: - res = ahk.function_call(function_name, [arg]) +def do_something(ahk, first: str, second: str) -> str: + res = ahk.function_call(function_name, [first, second]) return res @@ -39,8 +38,8 @@ def tearDown(self) -> None: time.sleep(0.2) def test_ext_explicit(self): - res = self.ahk.do_something('foo') - assert res == 'testfoo' + res = self.ahk.do_something('foo', 'bar') + assert res == 'foo and bar' class TestExtensionsAuto(unittest.TestCase): @@ -52,8 +51,8 @@ def tearDown(self) -> None: time.sleep(0.2) def test_ext_auto(self): - res = self.ahk.do_something('foo') - assert res == 'testfoo' + res = self.ahk.do_something('foo', 'bar') + assert res == 'foo and bar' class TestNoExtensions(unittest.TestCase): From 32e9e9ff95876c09432413a99087dc0b8a233d4b Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 21 Sep 2023 15:51:40 -0700 Subject: [PATCH 42/52] extension documentation and tests --- docs/extending.rst | 125 +++++++++++++++++++++++--------- tests/_async/test_extensions.py | 35 +++++++++ tests/_sync/test_extensions.py | 34 +++++++++ 3 files changed, 160 insertions(+), 34 deletions(-) diff --git a/docs/extending.rst b/docs/extending.rst index ed3badb..1b47cd0 100644 --- a/docs/extending.rst +++ b/docs/extending.rst @@ -31,7 +31,7 @@ First, a little background is necessary into the inner mechanisms of how ``ahk`` extension authors to understand these key points: - Python calls AHK functions by name and can pass any number of strings as parameters. -- Functions written in AHK (v1) accept exactly one argument (an array of zero or more strings) and must return responses in a specific message format (we'll discuss these specifics later) +- Functions written in AHK accept zero or more string arguments and must return a string in a specific message format (we'll discuss these specifics later) - The message returned from AHK to Python indicates the type of the return value so Python can parse the response message into an appropriate Python type. There are several predefined message types available in the :py:mod:`ahk.message` module. Extension authors may also create their own message types (discussed later). @@ -42,8 +42,8 @@ Writing an extension The basics of writing an extension requires two key components: -- A function written in AHK (v1) that conforms to the required spec (accepts one argument of an array of strings and returns a formatted message). -- A python function that accepts an instance of `AHK` (or `AsyncAHK for `async` functions) as its first parameter (think of it like a method of the `AHK` class). It may also accept any additional parameters. +- A function written in AHK that conforms to the required spec (accepts zero or more arguments and returns a formatted message). +- A python function that accepts an instance of ``AHK`` (or ``AsyncAHK`` for ``async`` functions) as its first parameter (think of it like a method of the ``AHK`` class). It may also accept any additional parameters. Example @@ -62,23 +62,18 @@ When complete, the interface will look something like this: Let's begin writing the extension. -First, we'll start with the AutoHotkey code. This will be an AHK (v1) function that accepts a single argument, which -is an array containing the arguments of the function passed by Python. These start at index 2. +First, we'll start with the AutoHotkey code. This will be an AHK function that, in this case, accepts 3 arguments. -Ultimately, the function will perform some operation utilizing these inputs and will return a formatted response -(using the ``FormatResponse`` function which is already defined for you. It accepts two arguments: the messaage type name -and the raw payload. - -.. code-block:: +Ultimately, the function will perform some operation utilizing these inputs and will return a formatted response. We use +the ``FormatResponse`` function (which is available by default) to do this. ``FormatResponse`` accepts two arguments: the message type name +and the raw payload as a string. By default, message type names are the fully qualified name of the Python class that +implements the message type (more on message types later). - SimpleMath(ByRef command) { +.. code-block:: - ; `command` is an array with passed arguments, starting at index 2 - lhs := command[2] - rhs := command[3] - operator := command[4] + SimpleMath(lhs, rhs, operator) { if (operator = "+") { result := (lhs + rhs) } else if (operator = "*") { @@ -86,13 +81,10 @@ and the raw payload. } else { ; invalid operator argument return FormatResponse("ahk.message.ExceptionResponseMessage", Format("Invalid operator: {}", operator)) } - return FormatResponse("ahk.message.IntegerResponseMessage", result) } -Note that the ``FormatResponse`` function is already implemented for you! - Next, we'll create the Python components of our extension: a Python function and the extension itself. The extension itself is an instance of the ``Extension`` class and it accepts an argument ``script_text`` which will be a string @@ -161,6 +153,83 @@ In addition to supplying AutoHotkey extension code via ``script_text``, you may from ahk.extensions import Extension my_extension = Extension(includes=['myscript.ahk']) # equivalent to "#Include myscript.ahk" +AsyncIO considerations +^^^^^^^^^^^^^^^^^^^^^^ + +When registering an extension function, if the decorated function is a coroutine function (``async def function_name(...):``) +then it will be made available only when the Async API (via ``AsyncAHK()``) is used. Conversely, normal non-async functions will only be available +when the sync API (via ``AHK()``). + +To provide your extension functionality to both the Sync and Async APIs, you will need to provide your function + + +AutoHotkey V1 vs V2 compatibility +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Because extensions involve the inclusion of AutoHotkey source code, it is often the case that extensions are sensitive +to the version of AutoHotkey being used. Extensions can specify their compatibility with different AutoHotkey versions +by providing the ``requires_autohotkey`` keyword argument with a value of ``v1`` or ``v2``. If an extension omits this +keyword argument, it is assumed that the extension is compatible with both V1 and V2. + +When an AutoHotkey class is instantiated with ``extensions='auto'`` extensions are automatically filtered by version compatibility. + +That is to say, you may need multiple ``Extension`` objects to fully support users of both versions of AutoHotkey. However, this +doesn't necessarily mean you need multiple Python functions -- you can register multiple extensions to the same Python function. + +.. code-block:: + + my_extension_v1 = Extension(..., requires_autohotkey='v1') + my_extension_v2 = Extension(..., requires_autohotkey='v1') + + @my_extension_v1.register + @my_extension_v2.register + def my_extension_function(ahk: AHK, foo, bar, baz) -> Any: + ... + + +Extension dependencies +^^^^^^^^^^^^^^^^^^^^^^ + +Extensions can declare explicit dependencies on other extensions. This allows extension authors to re-use other extensions +and end-users do not need to specify your extension's dependencies when explicitly providing the ``extensions`` keyword argument. + +To specify dependencies, provide a list of ``Extension`` instance objects in the ``dependencies`` keyword argument. + +.. code-block:: + + from ahk_json import JXON # pip install ahk-json + my_extension_script = '''\ + MyAHKFunction(one, two) { + val := Array(one, two) + ret := Jxon_Dump(val) ; `Jxon_Dump` is provided by the dependent extension! + return FormatResponse("ahk_json.message.JsonResponseMessage", ret) ; this message type is also part of the extension + } + ''' + MY_EXTENSION = Extension(script_text=my_extension_script, dependencies=[JXON]) + + @MY_EXTENSION.register + def my_function(ahk: AHK, one: str, two: str) -> list[str]: + args = [one, two] + return ahk.function_call('MyAHKFunction', args) + +Then users may use such an extension simply as follows, and both ``JXON`` and ``MY_EXTENSION`` will be used. + +.. code-block:: + + from ahk import AHK + from my_extension import MY_EXTENSION + + ahk = AHK(extensions=[MY_EXTENSION]) # same effect as extensions=[JXON, MY_EXTENSION] + +Best practices for extension authors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some conventions that authors are recommended to follow: + +- Extension functions should use namespaced naming conventions to avoid collisions (both in AutoHotkey code and Python function names); avoid generic function names like "load" or similar that may collide with other extensions +- Do not start AutoHotkey function names with ``AHK`` -- as it may conflict with functions implemented by this package. +- Extension packages published on PyPI should be named with a convention like so: ``ahk-`` + Available Message Types ^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,24 +303,12 @@ For example, suppose you want your method to return a datetime object, you might return datetime.datetime.fromtimestamp(val) In AHK code, you can reference custom response messages by the their fully qualified name, including the namespace. -(if you're not sure what this means, you can see this value by calling ``DateTimeResponseMessage.fqn()``) +(if you're not sure what this means, you can see this value by calling the ``fqn()`` method, e.g. ``DateTimeResponseMessage.fqn()``) Notes ^^^^^ - AHK functions MUST always return a message. Failing to return a message will result in an exception being raised. If the function should return nothing, use ``return FormatNoValueResponse()`` which will translate to ``None`` in Python. -- You cannot define hotkeys, hotstrings, or write any AutoHotkey code that would cause the end of autoexecution -- Extensions must be imported *before* instantiating the ``AHK`` instance -- Although extensions can be declared explicitly, using ``extensions='auto'`` is the recommended method for enabling extensions - - -Packaging -^^^^^^^^^ - -Coming soon. - - -Extending with jinja -^^^^^^^^^^^^^^^^^^^^ - -Coming soon. +- You cannot define hotkeys, hotstrings, or write any AutoHotkey code that would cause the end of the `auto-execute section `_ +- Extensions must be imported (anywhere, at least once) *before* instantiating the ``AHK`` instance +- Although extensions can be declared explicitly, using ``extensions='auto'`` is generally the easiest method for enabling all available extensions diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index ff09c5d..f058deb 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -3,6 +3,7 @@ import string import time import unittest +from typing import Literal import pytest @@ -22,7 +23,33 @@ }} ''' +math_function_name = 'SimpleMath' +math_function_name = 'ASimpleMath' # unasync: remove + +math_test = rf''' +{math_function_name}(lhs, rhs, operator) {{ + if (operator = "+") {{ + result := (lhs + rhs) + }} else if (operator = "*") {{ + result := (lhs * rhs) + }} else {{ ; invalid operator argument + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("Invalid operator: {{}}", operator)) + }} + return FormatResponse("ahk.message.IntegerResponseMessage", result) +}} +''' + async_extension = Extension(script_text=ext_text) +async_math_extension = Extension(script_text=math_test) + + +@async_math_extension.register +async def simple_math(ahk: AsyncAHK, lhs: int, rhs: int, operator: Literal['+', '*']) -> int: + assert isinstance(lhs, int) + assert isinstance(rhs, int) + args = [str(lhs), str(rhs), operator] # all args must be strings + result = await ahk.function_call(math_function_name, args, blocking=True) + return result @async_extension.register @@ -56,6 +83,14 @@ async def test_ext_auto(self): res = await self.ahk.do_something('foo', 'bar') assert res == 'foo and bar' + async def test_math_example(self): + res = await self.ahk.simple_math(1, 2, '+') + assert res == 3 + + async def test_math_example_exception(self): + with pytest.raises(Exception): + res = await self.ahk.simple_math(1, 2, 'x') + class TestNoExtensions(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self) -> None: diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 3fb960f..47e8396 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -3,6 +3,7 @@ import string import time import unittest +from typing import Literal import pytest @@ -20,7 +21,32 @@ }} ''' +math_function_name = 'SimpleMath' + +math_test = rf''' +{math_function_name}(lhs, rhs, operator) {{ + if (operator = "+") {{ + result := (lhs + rhs) + }} else if (operator = "*") {{ + result := (lhs * rhs) + }} else {{ ; invalid operator argument + return FormatResponse("ahk.message.ExceptionResponseMessage", Format("Invalid operator: {{}}", operator)) + }} + return FormatResponse("ahk.message.IntegerResponseMessage", result) +}} +''' + async_extension = Extension(script_text=ext_text) +async_math_extension = Extension(script_text=math_test) + + +@async_math_extension.register +def simple_math(ahk: AHK, lhs: int, rhs: int, operator: Literal['+', '*']) -> int: + assert isinstance(lhs, int) + assert isinstance(rhs, int) + args = [str(lhs), str(rhs), operator] # all args must be strings + result = ahk.function_call(math_function_name, args, blocking=True) + return result @async_extension.register @@ -54,6 +80,14 @@ def test_ext_auto(self): res = self.ahk.do_something('foo', 'bar') assert res == 'foo and bar' + def test_math_example(self): + res = self.ahk.simple_math(1, 2, '+') + assert res == 3 + + def test_math_example_exception(self): + with pytest.raises(Exception): + res = self.ahk.simple_math(1, 2, 'x') + class TestNoExtensions(unittest.TestCase): def setUp(self) -> None: From 5e4a5bcaa827db13af479cc96489ef598d661276 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Sun, 24 Sep 2023 15:00:23 -0700 Subject: [PATCH 43/52] more extension documentation --- docs/extending.rst | 13 ++++++++++++- requirements-dev.txt | 1 + tests/_async/test_extensions.py | 28 +++++++++++++++++++++++++++- tests/_sync/test_extensions.py | 27 ++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/docs/extending.rst b/docs/extending.rst index 1b47cd0..9737bd5 100644 --- a/docs/extending.rst +++ b/docs/extending.rst @@ -160,7 +160,18 @@ When registering an extension function, if the decorated function is a coroutine then it will be made available only when the Async API (via ``AsyncAHK()``) is used. Conversely, normal non-async functions will only be available when the sync API (via ``AHK()``). -To provide your extension functionality to both the Sync and Async APIs, you will need to provide your function +To provide your extension functionality to both the Sync and Async APIs, you will need to provide both a synchronous and async version of your function. + +.. code-block:: + + + @my_extension.register + def my_function(ahk: AHK, foo, bar): + ... + + @my_extension.register + async def my_function(ahk: AsyncAHK, foo, bar): + ... AutoHotkey V1 vs V2 compatibility diff --git a/requirements-dev.txt b/requirements-dev.txt index f321754..e897cac 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,3 +8,4 @@ mypy typing_extensions jinja2 pytest-rerunfailures +ahk-json diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index f058deb..989ed2a 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -39,6 +39,28 @@ }} ''' +from ahk_json import JXON + +dependency_func_name = 'MyFunc' +dependency_func_name = 'AMyFunc' # unasync: remove + +dependency_test_script = f'''\ +{dependency_func_name}(one, two) {{ + val := Array(one, two) + ret := Jxon_Dump(val) ; `Jxon_Dump` is provided by the dependent extension! + return FormatResponse("ahk_json.message.JsonResponseMessage", ret) ; this message type is also part of the extension +}} +''' + +dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON]) + + +@dependency_extension.register +def my_function(ahk, one: str, two: str) -> list[str]: + args = [one, two] + return ahk.function_call(dependency_func_name, args) + + async_extension = Extension(script_text=ext_text) async_math_extension = Extension(script_text=math_test) @@ -60,7 +82,7 @@ async def do_something(ahk, first: str, second: str) -> str: class TestExtensions(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self) -> None: - self.ahk = AsyncAHK(extensions=[async_extension]) + self.ahk = AsyncAHK(extensions=[async_extension, dependency_extension]) async def asyncTearDown(self) -> None: self.ahk._transport._proc.kill() @@ -70,6 +92,10 @@ async def test_ext_explicit(self): res = await self.ahk.do_something('foo', 'bar') assert res == 'foo and bar' + async def test_dep_extension(self): + res = await self.ahk.my_function('foo', 'bar') + assert res == ['foo', 'bar'] + class TestExtensionsAuto(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self) -> None: diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 47e8396..5bbb4a0 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -36,6 +36,27 @@ }} ''' +from ahk_json import JXON + +dependency_func_name = 'MyFunc' + +dependency_test_script = f'''\ +{dependency_func_name}(one, two) {{ + val := Array(one, two) + ret := Jxon_Dump(val) ; `Jxon_Dump` is provided by the dependent extension! + return FormatResponse("ahk_json.message.JsonResponseMessage", ret) ; this message type is also part of the extension +}} +''' + +dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON]) + + +@dependency_extension.register +def my_function(ahk, one: str, two: str) -> list[str]: + args = [one, two] + return ahk.function_call(dependency_func_name, args) + + async_extension = Extension(script_text=ext_text) async_math_extension = Extension(script_text=math_test) @@ -57,7 +78,7 @@ def do_something(ahk, first: str, second: str) -> str: class TestExtensions(unittest.TestCase): def setUp(self) -> None: - self.ahk = AHK(extensions=[async_extension]) + self.ahk = AHK(extensions=[async_extension, dependency_extension]) def tearDown(self) -> None: self.ahk._transport._proc.kill() @@ -67,6 +88,10 @@ def test_ext_explicit(self): res = self.ahk.do_something('foo', 'bar') assert res == 'foo and bar' + def test_dep_extension(self): + res = self.ahk.my_function('foo', 'bar') + assert res == ['foo', 'bar'] + class TestExtensionsAuto(unittest.TestCase): def setUp(self) -> None: From c5898ab324866a0e0bec109146df480116c29087 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Sun, 24 Sep 2023 15:27:07 -0700 Subject: [PATCH 44/52] more extension documentation --- docs/extending.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/extending.rst b/docs/extending.rst index 9737bd5..3b3f898 100644 --- a/docs/extending.rst +++ b/docs/extending.rst @@ -216,7 +216,7 @@ To specify dependencies, provide a list of ``Extension`` instance objects in the return FormatResponse("ahk_json.message.JsonResponseMessage", ret) ; this message type is also part of the extension } ''' - MY_EXTENSION = Extension(script_text=my_extension_script, dependencies=[JXON]) + MY_EXTENSION = Extension(script_text=my_extension_script, dependencies=[JXON], requires_autohotkey='v1') @MY_EXTENSION.register def my_function(ahk: AHK, one: str, two: str) -> list[str]: @@ -230,7 +230,7 @@ Then users may use such an extension simply as follows, and both ``JXON`` and `` from ahk import AHK from my_extension import MY_EXTENSION - ahk = AHK(extensions=[MY_EXTENSION]) # same effect as extensions=[JXON, MY_EXTENSION] + ahk = AHK(extensions=[MY_EXTENSION], version='v1') # same effect as extensions=[JXON, MY_EXTENSION] Best practices for extension authors ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 67d2432b933198ffe02f51845c22d10d596c6298 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Sun, 24 Sep 2023 15:54:06 -0700 Subject: [PATCH 45/52] extension compatibility checks --- ahk/_async/engine.py | 5 +++++ ahk/_sync/engine.py | 5 +++++ tests/_async/test_extensions.py | 28 +++++++++++++++++++++++----- tests/_sync/test_extensions.py | 24 +++++++++++++++++++++--- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 8edaae4..f46ef53 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -174,6 +174,11 @@ def __init__( self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)] else: self._extensions = _resolve_extensions(extensions) if extensions else [] + for ext in self._extensions: + if ext._requires not in (None, version): + raise ValueError( + f'Incompatible extension detected. Extension requires AutoHotkey {ext._requires} but current version is {version}' + ) self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) for ext in self._extensions: self._method_registry.merge(ext._extension_method_registry) diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index afe44ca..b0d7ca1 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -170,6 +170,11 @@ def __init__( self._extensions = [ext for ext in _extension_registry if ext._requires in (None, version)] else: self._extensions = _resolve_extensions(extensions) if extensions else [] + for ext in self._extensions: + if ext._requires not in (None, version): + raise ValueError( + f'Incompatible extension detected. Extension requires AutoHotkey {ext._requires} but current version is {version}' + ) self._method_registry = _ExtensionMethodRegistry(sync_methods={}, async_methods={}) for ext in self._extensions: self._method_registry.merge(ext._extension_method_registry) diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index 989ed2a..f2fdeb5 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -52,13 +52,13 @@ }} ''' -dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON]) +dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON], requires_autohotkey='v1') @dependency_extension.register -def my_function(ahk, one: str, two: str) -> list[str]: +async def my_function(ahk, one: str, two: str) -> list[str]: args = [one, two] - return ahk.function_call(dependency_func_name, args) + return await ahk.function_call(dependency_func_name, args) async_extension = Extension(script_text=ext_text) @@ -85,7 +85,10 @@ async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(extensions=[async_extension, dependency_extension]) async def asyncTearDown(self) -> None: - self.ahk._transport._proc.kill() + try: + self.ahk._transport._proc.kill() + except: + pass time.sleep(0.2) async def test_ext_explicit(self): @@ -102,7 +105,10 @@ async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(extensions='auto') async def asyncTearDown(self) -> None: - self.ahk._transport._proc.kill() + try: + self.ahk._transport._proc.kill() + except: + pass time.sleep(0.2) async def test_ext_auto(self): @@ -135,6 +141,9 @@ class TestExtensionsV2(TestExtensions): async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(extensions=[async_extension], version='v2') + async def test_dep_extension(self): + pytest.skip('this test does not run on v2') + class TestExtensionsAutoV2(TestExtensionsAuto): async def asyncSetUp(self) -> None: @@ -145,3 +154,12 @@ class TestNoExtensionsV2(TestNoExtensions): async def asyncSetUp(self) -> None: self.ahk = AsyncAHK(version='v2') await self.ahk.get_mouse_position() # cause daemon to start + + async def test_dep_extension(self): + pytest.skip('this test does not run on v2') + + +class TestExtensionCompatibility(unittest.IsolatedAsyncioTestCase): + def test_ext_incompatible(self): + with pytest.raises(ValueError): + AsyncAHK(version='v2', extensions=[dependency_extension]) diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 5bbb4a0..2694854 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -48,7 +48,7 @@ }} ''' -dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON]) +dependency_extension = Extension(script_text=dependency_test_script, dependencies=[JXON], requires_autohotkey='v1') @dependency_extension.register @@ -81,7 +81,10 @@ def setUp(self) -> None: self.ahk = AHK(extensions=[async_extension, dependency_extension]) def tearDown(self) -> None: - self.ahk._transport._proc.kill() + try: + self.ahk._transport._proc.kill() + except: + pass time.sleep(0.2) def test_ext_explicit(self): @@ -98,7 +101,10 @@ def setUp(self) -> None: self.ahk = AHK(extensions='auto') def tearDown(self) -> None: - self.ahk._transport._proc.kill() + try: + self.ahk._transport._proc.kill() + except: + pass time.sleep(0.2) def test_ext_auto(self): @@ -131,6 +137,9 @@ class TestExtensionsV2(TestExtensions): def setUp(self) -> None: self.ahk = AHK(extensions=[async_extension], version='v2') + def test_dep_extension(self): + pytest.skip('this test does not run on v2') + class TestExtensionsAutoV2(TestExtensionsAuto): def setUp(self) -> None: @@ -141,3 +150,12 @@ class TestNoExtensionsV2(TestNoExtensions): def setUp(self) -> None: self.ahk = AHK(version='v2') self.ahk.get_mouse_position() # cause daemon to start + + def test_dep_extension(self): + pytest.skip('this test does not run on v2') + + +class TestExtensionCompatibility(unittest.TestCase): + def test_ext_incompatible(self): + with pytest.raises(ValueError): + AHK(version='v2', extensions=[dependency_extension]) From c83358724975608fcf7c4d7851edce170fc0d989 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Sun, 24 Sep 2023 16:25:07 -0700 Subject: [PATCH 46/52] fix python3.8 compatibility in tests --- tests/_async/test_extensions.py | 2 ++ tests/_sync/test_extensions.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/_async/test_extensions.py b/tests/_async/test_extensions.py index f2fdeb5..c61e712 100644 --- a/tests/_async/test_extensions.py +++ b/tests/_async/test_extensions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio import random import string diff --git a/tests/_sync/test_extensions.py b/tests/_sync/test_extensions.py index 2694854..d983e0f 100644 --- a/tests/_sync/test_extensions.py +++ b/tests/_sync/test_extensions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio import random import string From d634432a0a72059c5b71b32ba7966e464dec59c4 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Sun, 24 Sep 2023 16:49:21 -0700 Subject: [PATCH 47/52] 1.4.0rc2 :package: --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 44c63fd..76ca2f2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = ahk -version = 1.4.0rc1 +version = 1.4.0rc2 author_email = spencer.young@spyoung.com author = Spencer Young description = A Python wrapper for AHK From 1fcce26a4b42169156486f9ec7967c00a5dc99f8 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 27 Sep 2023 19:07:41 -0700 Subject: [PATCH 48/52] fix bug in win_get_position --- ahk/_constants.py | 4 ++-- ahk/templates/daemon.ahk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ahk/_constants.py b/ahk/_constants.py index a07357b..0e8b631 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2374,8 +2374,8 @@ WinGetPos, x, y, w, h, %title%, %text%, %extitle%, %extext% - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") + if (x = "") { + response := FormatNoValueResponse() } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) response := FormatResponse("ahk.message.PositionResponseMessage", result) diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index 358c008..6a3ead5 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -2371,8 +2371,8 @@ AHKWinGetPos(args*) { WinGetPos, x, y, w, h, %title%, %text%, %extitle%, %extext% - if (ErrorLevel = 1) { - response := FormatResponse("ahk.message.ExceptionResponseMessage", "There was a problem getting the position") + if (x = "") { + response := FormatNoValueResponse() } else { result := Format("({1:i}, {2:i}, {3:i}, {4:i})", x, y, w, h) response := FormatResponse("ahk.message.PositionResponseMessage", result) From f63d0623b8b6c306791372dd231ce1c28e2169b4 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Thu, 28 Sep 2023 17:32:14 -0700 Subject: [PATCH 49/52] initial generic version typing --- ahk/__init__.py | 2 +- ahk/_async/engine.py | 144 ++++++++++++++++++++++++++++---------- ahk/_async/transport.py | 148 ++++++++++++++++++++-------------------- ahk/_async/window.py | 19 ++++-- ahk/_sync/engine.py | 144 ++++++++++++++++++++++++++++---------- ahk/_sync/transport.py | 147 +++++++++++++++++++-------------------- ahk/_sync/window.py | 23 ++++--- ahk/extensions.py | 2 +- ahk/message.py | 6 +- 9 files changed, 394 insertions(+), 241 deletions(-) diff --git a/ahk/__init__.py b/ahk/__init__.py index 7fdd704..8ae34b5 100644 --- a/ahk/__init__.py +++ b/ahk/__init__.py @@ -25,7 +25,7 @@ 'MsgBoxModality', ] -_global_instance: Optional[AHK] = None +_global_instance: Optional[AHK[None]] = None def __getattr__(name: str) -> Any: diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index f46ef53..0aa064d 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -11,6 +11,7 @@ from typing import Awaitable from typing import Callable from typing import Coroutine +from typing import Generic from typing import List from typing import Literal from typing import NoReturn @@ -18,6 +19,7 @@ from typing import overload from typing import Tuple from typing import Type +from typing import TypeVar from typing import Union from .._hotkey import Hotkey @@ -137,9 +139,22 @@ def _resolve_button(button: Union[str, int]) -> str: return resolved_button -class AsyncAHK: +T_AHKVersion = TypeVar('T_AHKVersion', bound=Optional[Literal['v1', 'v2']]) + + +class AsyncAHK(Generic[T_AHKVersion]): + # fmt: off + @overload + def __init__(self: AsyncAHK[None], *, TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None): ... + @overload + def __init__(self: AsyncAHK[None], *, TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: None): ... + @overload + def __init__(self: AsyncAHK[Literal['v2']], *, TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: Literal['v2']): ... + @overload + def __init__(self: AsyncAHK[Literal['v1']], *, TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: Literal['v1']): ... + # fmt: on def __init__( - self, + self: AsyncAHK[Optional[Literal['v1', 'v2']]], *, TransportClass: Optional[Type[AsyncTransport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, @@ -810,8 +825,8 @@ async def get_active_window(self, blocking: Literal[False]) -> AsyncFutureResult async def get_active_window(self, blocking: bool = True) -> Union[Optional[AsyncWindow], AsyncFutureResult[Optional[AsyncWindow]]]: ... # fmt: on async def get_active_window( - self, blocking: bool = True - ) -> Union[Optional[AsyncWindow], AsyncFutureResult[Optional[AsyncWindow]]]: + self: AsyncAHK[Any], blocking: bool = True + ) -> Union[Optional[AsyncWindow], AsyncFutureResult[Optional[AsyncWindow]], AsyncFutureResult[AsyncWindow]]: """ Gets the currently active window. """ @@ -1337,14 +1352,25 @@ async def set_volume( return await self._transport.function_call('AHKSetVolume', args, blocking=blocking) # fmt: off + + # in v2 the "second" parameter is not supported + @overload + async def show_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - async def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... + async def show_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + async def show_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - async def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + async def show_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + + @overload + async def show_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + async def show_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + async def show_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + async def show_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... # fmt: on async def show_traytip( self, @@ -1374,19 +1400,29 @@ async def show_traytip( # fmt: off @overload - async def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + async def show_error_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + async def show_error_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + @overload + async def show_error_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - async def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + async def show_error_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + + @overload + async def show_error_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + async def show_error_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + async def show_error_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - async def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + async def show_error_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + # fmt: on async def show_error_traytip( - self, + self: AsyncAHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1401,19 +1437,28 @@ async def show_error_traytip( # fmt: off @overload - async def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + async def show_info_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - async def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + async def show_info_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + async def show_info_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - async def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + async def show_info_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + + @overload + async def show_info_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + async def show_info_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + @overload + async def show_info_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + async def show_info_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... # fmt: on async def show_info_traytip( - self, + self: AsyncAHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1428,19 +1473,28 @@ async def show_info_traytip( # fmt: off @overload - async def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + async def show_warning_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + async def show_warning_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + @overload + async def show_warning_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + async def show_warning_traytip(self: AsyncAHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + + @overload + async def show_warning_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - async def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... + async def show_warning_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> AsyncFutureResult[None]: ... @overload - async def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + async def show_warning_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - async def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... + async def show_warning_traytip(self: AsyncAHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... # fmt: on async def show_warning_traytip( - self, + self: AsyncAHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1593,13 +1647,22 @@ async def sound_set( # fmt: off @overload - async def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[AsyncWindow, None]: ... + async def win_get(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> AsyncWindow: ... + @overload + async def win_get(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[AsyncWindow]: ... + @overload + async def win_get(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> AsyncWindow: ... + @overload + async def win_get(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... + + @overload + async def win_get(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[AsyncWindow, None]: ... @overload - async def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[Union[AsyncWindow, None]]: ... + async def win_get(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[Union[AsyncWindow, None]]: ... @overload - async def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[AsyncWindow, None]: ... + async def win_get(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[AsyncWindow, None]: ... @overload - async def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[AsyncWindow, None, AsyncFutureResult[Union[None, AsyncWindow]]]: ... + async def win_get(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[AsyncWindow, None, AsyncFutureResult[Union[None, AsyncWindow]], AsyncFutureResult[AsyncWindow]]: ... # fmt: on async def win_get( self, @@ -1611,7 +1674,7 @@ async def win_get( title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True, - ) -> Union[AsyncWindow, None, AsyncFutureResult[Union[None, AsyncWindow]]]: + ) -> Union[AsyncWindow, None, AsyncFutureResult[Union[None, AsyncWindow]], AsyncFutureResult[AsyncWindow]]: """ Analog for `WinGet `_ """ @@ -1727,13 +1790,22 @@ async def win_get_class( # fmt: off @overload - async def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Position, None]: ... + async def win_get_position(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Position: ... + @overload + async def win_get_position(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[Position]: ... + @overload + async def win_get_position(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Position: ... + @overload + async def win_get_position(self: AsyncAHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, AsyncFutureResult[Position]]: ... + + @overload + async def win_get_position(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Position, None]: ... @overload - async def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[Union[Position, None]]: ... + async def win_get_position(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> AsyncFutureResult[Union[Position, None]]: ... @overload - async def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Position, None]: ... + async def win_get_position(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Position, None]: ... @overload - async def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, None, AsyncFutureResult[Union[Position, None]]]: ... + async def win_get_position(self: AsyncAHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, None, AsyncFutureResult[Union[Position, None]]]: ... # fmt: on async def win_get_position( self, @@ -1745,7 +1817,7 @@ async def win_get_position( title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True, - ) -> Union[Position, None, AsyncFutureResult[Union[Position, None]]]: + ) -> Union[Position, None, AsyncFutureResult[Union[Position, None]], AsyncFutureResult[Position]]: """ Analog for `WinGetPos `_ """ diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 0e715f9..69b7e1e 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -409,119 +409,119 @@ async def run_script( # fmt: off @overload - async def function_call(self, function_name: Literal['AHKWinExist'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[bool, AsyncFutureResult[bool]]: ... + async def function_call(self, function_name: Literal['AHKWinExist'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[bool, AsyncFutureResult[bool]]: ... @overload - async def function_call(self, function_name: Literal['AHKImageSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Tuple[int, int], None, AsyncFutureResult[Union[Tuple[int, int], None]]]: ... + async def function_call(self, function_name: Literal['AHKImageSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Tuple[int, int], None, AsyncFutureResult[Union[Tuple[int, int], None]]]: ... @overload - async def function_call(self, function_name: Literal['AHKPixelGetColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[str, AsyncFutureResult[str]]: ... + async def function_call(self, function_name: Literal['AHKPixelGetColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[str, AsyncFutureResult[str]]: ... @overload - async def function_call(self, function_name: Literal['AHKPixelSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Optional[Tuple[int, int]], AsyncFutureResult[Optional[Tuple[int, int]]]]: ... + async def function_call(self, function_name: Literal['AHKPixelSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Optional[Tuple[int, int]], AsyncFutureResult[Optional[Tuple[int, int]]]]: ... @overload - async def function_call(self, function_name: Literal['AHKMouseGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Tuple[int, int], AsyncFutureResult[Tuple[int, int]]]: ... + async def function_call(self, function_name: Literal['AHKMouseGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Tuple[int, int], AsyncFutureResult[Tuple[int, int]]]: ... @overload - async def function_call(self, function_name: Literal['AHKKeyState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[int, float, str, None, AsyncFutureResult[None], AsyncFutureResult[str], AsyncFutureResult[int], AsyncFutureResult[float]]: ... + async def function_call(self, function_name: Literal['AHKKeyState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[int, float, str, None, AsyncFutureResult[None], AsyncFutureResult[str], AsyncFutureResult[int], AsyncFutureResult[float]]: ... @overload - async def function_call(self, function_name: Literal['AHKMouseMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKMouseMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKClick'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKClick'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKMouseClickDrag'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKMouseClickDrag'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKKeyWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[int, AsyncFutureResult[int]]: ... + async def function_call(self, function_name: Literal['AHKKeyWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[int, AsyncFutureResult[int]]: ... @overload - async def function_call(self, function_name: Literal['SetKeyDelay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['SetKeyDelay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSendRaw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSendRaw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSendInput'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSendInput'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSendEvent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSendEvent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSendPlay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSendPlay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKSetCapsLockState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKSetCapsLockState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetTitle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[str, AsyncFutureResult[str]]: ... + async def function_call(self, function_name: Literal['AHKWinGetTitle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[str, AsyncFutureResult[str]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetClass'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[str, AsyncFutureResult[str]]: ... + async def function_call(self, function_name: Literal['AHKWinGetClass'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[str, AsyncFutureResult[str]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetText'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[str, AsyncFutureResult[str]]: ... + async def function_call(self, function_name: Literal['AHKWinGetText'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[str, AsyncFutureResult[str]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinActivate'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinActivate'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['WinActivateBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['WinActivateBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinKill'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinKill'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinMaximize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinMaximize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinMinimize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinMinimize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinRestore'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinRestore'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWindowList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[List[AsyncWindow], AsyncFutureResult[List[AsyncWindow]]]: ... + async def function_call(self, function_name: Literal['AHKWindowList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[List[AsyncWindow], AsyncFutureResult[List[AsyncWindow]]]: ... @overload - async def function_call(self, function_name: Literal['AHKControlSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKControlSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinFromMouse'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Optional[AsyncWindow], AsyncFutureResult[Optional[AsyncWindow]]]: ... + async def function_call(self, function_name: Literal['AHKWinFromMouse'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Optional[AsyncWindow], AsyncFutureResult[Optional[AsyncWindow]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinIsAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Optional[bool], AsyncFutureResult[Optional[bool]]]: ... + async def function_call(self, function_name: Literal['AHKWinIsAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Optional[bool], AsyncFutureResult[Optional[bool]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[Position, None], AsyncFutureResult[Union[None, Position]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[Position, None], AsyncFutureResult[Union[None, Position]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, AsyncWindow], AsyncFutureResult[Union[None, AsyncWindow]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, AsyncWindow], AsyncFutureResult[Union[None, AsyncWindow]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetIDLast'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, AsyncWindow], AsyncFutureResult[Union[None, AsyncWindow]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetIDLast'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, AsyncWindow], AsyncFutureResult[Union[None, AsyncWindow]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetPID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[int, None], AsyncFutureResult[Union[int, None]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetPID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[int, None], AsyncFutureResult[Union[int, None]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetProcessName'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetProcessName'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetProcessPath'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetProcessPath'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetCount'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[int, AsyncFutureResult[int]]: ... + async def function_call(self, function_name: Literal['AHKWinGetCount'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[int, AsyncFutureResult[int]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[List[AsyncWindow], AsyncFutureResult[List[AsyncWindow]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[List[AsyncWindow], AsyncFutureResult[List[AsyncWindow]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetMinMax'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, int], AsyncFutureResult[Union[None, int]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetMinMax'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, int], AsyncFutureResult[Union[None, int]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetControlList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[List[AsyncControl], None, AsyncFutureResult[Union[List[AsyncControl], None]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetControlList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[List[AsyncControl], None, AsyncFutureResult[Union[List[AsyncControl], None]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, int], AsyncFutureResult[Union[None, int]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, int], AsyncFutureResult[Union[None, int]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinGetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... + async def function_call(self, function_name: Literal['AHKWinGetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[Union[None, str], AsyncFutureResult[Union[None, str]]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetDisable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetDisable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetEnable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetEnable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetRedraw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetRedraw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[bool, AsyncFutureResult[bool]]: ... + async def function_call(self, function_name: Literal['AHKWinSetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[bool, AsyncFutureResult[bool]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[bool, AsyncFutureResult[bool]]: ... + async def function_call(self, function_name: Literal['AHKWinSetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[bool, AsyncFutureResult[bool]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetRegion'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[bool, AsyncFutureResult[bool]]: ... + async def function_call(self, function_name: Literal['AHKWinSetRegion'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[bool, AsyncFutureResult[bool]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinSetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinSetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload async def function_call(self, function_name: Literal['AHKSetDetectHiddenWindows'], args: Optional[List[str]] = None) -> None: ... @overload @@ -533,7 +533,7 @@ async def function_call(self, function_name: Literal['AHKGetTitleMatchMode']) -> @overload async def function_call(self, function_name: Literal['AHKGetTitleMatchSpeed']) -> str: ... @overload - async def function_call(self, function_name: Literal['AHKControlGetText'], args: Optional[List[str]] = None, *, engine: Optional[AsyncAHK] = None, blocking: bool = True) -> Union[str, AsyncFutureResult[str]]: ... + async def function_call(self, function_name: Literal['AHKControlGetText'], args: Optional[List[str]] = None, *, engine: Optional[AsyncAHK[Any]] = None, blocking: bool = True) -> Union[str, AsyncFutureResult[str]]: ... @overload async def function_call(self, function_name: Literal['AHKControlClick'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... @overload @@ -547,18 +547,18 @@ async def function_call(self, function_name: Literal['AHKGetSendLevel']) -> int: @overload async def function_call(self, function_name: Literal['AHKSetSendLevel'], args: List[str]) -> None: ... @overload - async def function_call(self, function_name: Literal['AHKWinWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... + async def function_call(self, function_name: Literal['AHKWinWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinWaitActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... + async def function_call(self, function_name: Literal['AHKWinWaitActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinWaitNotActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... + async def function_call(self, function_name: Literal['AHKWinWaitNotActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[AsyncWindow, AsyncFutureResult[AsyncWindow]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinShow'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinShow'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinHide'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinHide'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKWinIsActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[bool, AsyncFutureResult[bool]]: ... + async def function_call(self, function_name: Literal['AHKWinIsActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[bool, AsyncFutureResult[bool]]: ... @overload async def function_call(self, function_name: Literal['AHKGetVolume'], args: Optional[List[str]] = None) -> float: ... @overload @@ -591,7 +591,7 @@ async def function_call(self, function_name: Literal['AHKClipWait'], args: Optio # @overload # async def function_call(self, function_name: Literal['HideTrayTip'], args: Optional[List[str]] = None) -> None: ... @overload - async def function_call(self, function_name: Literal['AHKWinWaitClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK] = None) -> Union[None, AsyncFutureResult[None]]: ... + async def function_call(self, function_name: Literal['AHKWinWaitClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AsyncAHK[Any]] = None) -> Union[None, AsyncFutureResult[None]]: ... @overload async def function_call(self, function_name: Literal['AHKRegRead'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, AsyncFutureResult[str]]: ... @overload @@ -605,7 +605,7 @@ async def function_call(self, function_name: Literal['AHKMenuTrayIcon'], args: O @overload async def function_call(self, function_name: Literal['AHKMenuTrayShow'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[None, AsyncFutureResult[None]]: ... @overload - async def function_call(self, function_name: Literal['AHKGuiNew'], args: List[str], *, engine: AsyncAHK) -> str: ... + async def function_call(self, function_name: Literal['AHKGuiNew'], args: List[str], *, engine: AsyncAHK[Any]) -> str: ... @overload async def function_call(self, function_name: Literal['AHKMsgBox'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, AsyncFutureResult[str]]: ... @overload @@ -621,7 +621,7 @@ async def function_call( function_name: FunctionName, args: Optional[List[str]] = None, blocking: bool = True, - engine: Optional[AsyncAHK] = None, + engine: Optional[AsyncAHK[Any]] = None, ) -> Any: if not self._started: with warnings.catch_warnings(record=True) as caught_warnings: @@ -637,13 +637,13 @@ async def function_call( @abstractmethod async def send( - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]]: return NotImplemented @abstractmethod # unasync: remove async def a_send_nonblocking( # unasync: remove - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> AsyncFutureResult[ Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]] ]: @@ -651,7 +651,7 @@ async def a_send_nonblocking( # unasync: remove @abstractmethod def send_nonblocking( - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> FutureResult[Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]]]: return NotImplemented @@ -784,7 +784,7 @@ async def _create_process( return proc async def _send_nonblocking( - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]]: msg = request.format() proc = await self._create_process() @@ -820,7 +820,7 @@ async def _send_nonblocking( return response.unpack() # type: ignore async def a_send_nonblocking( # unasync: remove - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> AsyncFutureResult[ Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]] ]: @@ -829,7 +829,7 @@ async def a_send_nonblocking( # unasync: remove return AsyncFutureResult(task) def send_nonblocking( - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> FutureResult[Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]]]: # this is only used by the sync implementation pool = ThreadPoolExecutor(max_workers=1) @@ -841,7 +841,7 @@ def send_nonblocking( return FutureResult(fut) async def send( - self, request: RequestMessage, engine: Optional[AsyncAHK] = None + self, request: RequestMessage, engine: Optional[AsyncAHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, AsyncWindow, List[AsyncWindow], List[AsyncControl]]: msg = request.format() assert self._proc is not None diff --git a/ahk/_async/window.py b/ahk/_async/window.py index 08229b0..d308083 100644 --- a/ahk/_async/window.py +++ b/ahk/_async/window.py @@ -10,6 +10,7 @@ from typing import Sequence from typing import Tuple from typing import TYPE_CHECKING +from typing import TypeVar from typing import Union from ahk.message import Position @@ -45,10 +46,12 @@ class WindowNotFoundException(Exception): 'Use of the {0} property setter is not supported in the async API. Use the set_{0} instead.' ) +T_EngineVersion = TypeVar('T_EngineVersion', bound=Optional[Literal['v1', 'v2']]) + class AsyncWindow: - def __init__(self, engine: AsyncAHK, ahk_id: str): - self._engine: AsyncAHK = engine + def __init__(self, engine: AsyncAHK[T_EngineVersion], ahk_id: str): + self._engine: AsyncAHK[T_EngineVersion] = engine if not ahk_id: raise ValueError(f'Invalid ahk_id: {ahk_id!r}') self._ahk_id: str = ahk_id @@ -381,10 +384,12 @@ async def get_position(self, *, blocking: Literal[False]) -> AsyncFutureResult[O @overload async def get_position(self, *, blocking: Literal[True]) -> Position: ... @overload - async def get_position(self, *, blocking: bool = True) -> Union[Position, AsyncFutureResult[Optional[Position]]]: ... + async def get_position(self, *, blocking: bool = True) -> Union[Position, AsyncFutureResult[Optional[Position]], AsyncFutureResult[Position]]: ... # fmt: on - async def get_position(self, *, blocking: bool = True) -> Union[Position, AsyncFutureResult[Optional[Position]]]: - resp = await self._engine.win_get_position( + async def get_position( + self, *, blocking: bool = True + ) -> Union[Position, AsyncFutureResult[Optional[Position]], AsyncFutureResult[Position]]: + resp = await self._engine.win_get_position( # type: ignore[misc] # this appears to be a mypy bug title=f'ahk_id {self._ahk_id}', blocking=blocking, detect_hidden_windows=True, @@ -652,11 +657,11 @@ async def move( ) @classmethod - async def from_pid(cls, engine: AsyncAHK, pid: int) -> Optional[AsyncWindow]: + async def from_pid(cls, engine: AsyncAHK[Any], pid: int) -> Optional[AsyncWindow]: return await engine.win_get(title=f'ahk_pid {pid}') @classmethod - async def from_mouse_position(cls, engine: AsyncAHK) -> Optional[AsyncWindow]: + async def from_mouse_position(cls, engine: AsyncAHK[Any]) -> Optional[AsyncWindow]: return await engine.win_get_from_mouse_position() diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index b0d7ca1..57505a9 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -11,6 +11,7 @@ from typing import Awaitable from typing import Callable from typing import Coroutine +from typing import Generic from typing import List from typing import Literal from typing import NoReturn @@ -18,6 +19,7 @@ from typing import overload from typing import Tuple from typing import Type +from typing import TypeVar from typing import Union from .._hotkey import Hotkey @@ -133,9 +135,22 @@ def _resolve_button(button: Union[str, int]) -> str: return resolved_button -class AHK: +T_AHKVersion = TypeVar('T_AHKVersion', bound=Optional[Literal['v1', 'v2']]) + + +class AHK(Generic[T_AHKVersion]): + # fmt: off + @overload + def __init__(self: AHK[None], *, TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None): ... + @overload + def __init__(self: AHK[None], *, TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: None): ... + @overload + def __init__(self: AHK[Literal['v2']], *, TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: Literal['v2']): ... + @overload + def __init__(self: AHK[Literal['v1']], *, TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, executable_path: str = '', extensions: list[Extension] | None | Literal['auto'] = None, version: Literal['v1']): ... + # fmt: on def __init__( - self, + self: AHK[Optional[Literal['v1', 'v2']]], *, TransportClass: Optional[Type[Transport]] = None, directives: Optional[list[Directive | Type[Directive]]] = None, @@ -801,8 +816,8 @@ def get_active_window(self, blocking: Literal[False]) -> FutureResult[Optional[W def get_active_window(self, blocking: bool = True) -> Union[Optional[Window], FutureResult[Optional[Window]]]: ... # fmt: on def get_active_window( - self, blocking: bool = True - ) -> Union[Optional[Window], FutureResult[Optional[Window]]]: + self: AHK[Any], blocking: bool = True + ) -> Union[Optional[Window], FutureResult[Optional[Window]], FutureResult[Window]]: """ Gets the currently active window. """ @@ -1325,14 +1340,25 @@ def set_volume( return self._transport.function_call('AHKSetVolume', args, blocking=blocking) # fmt: off + + # in v2 the "second" parameter is not supported + @overload + def show_traytip(self: AHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... + def show_traytip(self: AHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + def show_traytip(self: AHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + def show_traytip(self: AHK[Literal['v2']], title: str, text: str, second: None = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + + @overload + def show_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + def show_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def show_traytip(self, title: str, text: str, second: float = 1.0, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + def show_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + def show_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, type_id: int = 1, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... # fmt: on def show_traytip( self, @@ -1362,19 +1388,29 @@ def show_traytip( # fmt: off @overload - def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + def show_error_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + def show_error_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + @overload + def show_error_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + def show_error_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + + @overload + def show_error_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + def show_error_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + def show_error_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - def show_error_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + def show_error_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + # fmt: on def show_error_traytip( - self, + self: AHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1389,19 +1425,28 @@ def show_error_traytip( # fmt: off @overload - def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + def show_info_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + def show_info_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + def show_info_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - def show_info_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + def show_info_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + + @overload + def show_info_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + def show_info_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + @overload + def show_info_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + def show_info_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... # fmt: on def show_info_traytip( - self, + self: AHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1416,19 +1461,28 @@ def show_info_traytip( # fmt: off @overload - def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False) -> None: ... + def show_warning_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False) -> None: ... + @overload + def show_warning_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + @overload + def show_warning_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + @overload + def show_warning_traytip(self: AHK[Literal['v2']], title: str, text: str, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + + @overload + def show_warning_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False) -> None: ... @overload - def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... + def show_warning_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[False]) -> FutureResult[None]: ... @overload - def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... + def show_warning_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: Literal[True]) -> None: ... @overload - def show_warning_traytip(self, title: str, text: str, second: float = 1.0, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... + def show_warning_traytip(self: AHK[Optional[Literal['v1']]], title: str, text: str, second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, blocking: bool = True) -> Union[None, FutureResult[None]]: ... # fmt: on def show_warning_traytip( - self, + self: AHK[Any], title: str, text: str, - second: float = 1.0, + second: Optional[float] = None, *, silent: bool = False, large_icon: bool = False, @@ -1581,13 +1635,22 @@ def sound_set( # fmt: off @overload - def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Window, None]: ... + def win_get(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Window: ... + @overload + def win_get(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Window]: ... + @overload + def win_get(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Window: ... + @overload + def win_get(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Window, FutureResult[Window]]: ... + + @overload + def win_get(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Window, None]: ... @overload - def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Union[Window, None]]: ... + def win_get(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Union[Window, None]]: ... @overload - def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Window, None]: ... + def win_get(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Window, None]: ... @overload - def win_get(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Window, None, FutureResult[Union[None, Window]]]: ... + def win_get(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Window, None, FutureResult[Union[None, Window]], FutureResult[Window]]: ... # fmt: on def win_get( self, @@ -1599,7 +1662,7 @@ def win_get( title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True, - ) -> Union[Window, None, FutureResult[Union[None, Window]]]: + ) -> Union[Window, None, FutureResult[Union[None, Window]], FutureResult[Window]]: """ Analog for `WinGet `_ """ @@ -1715,13 +1778,22 @@ def win_get_class( # fmt: off @overload - def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Position, None]: ... + def win_get_position(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Position: ... + @overload + def win_get_position(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Position]: ... + @overload + def win_get_position(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Position: ... + @overload + def win_get_position(self: AHK[Literal['v2']], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, FutureResult[Position]]: ... + + @overload + def win_get_position(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None) -> Union[Position, None]: ... @overload - def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Union[Position, None]]: ... + def win_get_position(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[False]) -> FutureResult[Union[Position, None]]: ... @overload - def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Position, None]: ... + def win_get_position(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: Literal[True]) -> Union[Position, None]: ... @overload - def win_get_position(self, title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, None, FutureResult[Union[Position, None]]]: ... + def win_get_position(self: AHK[Optional[Literal['v1']]], title: str = '', text: str = '', exclude_title: str = '', exclude_text: str = '', *, title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True) -> Union[Position, None, FutureResult[Union[Position, None]]]: ... # fmt: on def win_get_position( self, @@ -1733,7 +1805,7 @@ def win_get_position( title_match_mode: Optional[TitleMatchMode] = None, detect_hidden_windows: Optional[bool] = None, blocking: bool = True, - ) -> Union[Position, None, FutureResult[Union[Position, None]]]: + ) -> Union[Position, None, FutureResult[Union[Position, None]], FutureResult[Position]]: """ Analog for `WinGetPos `_ """ diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index d5f1df1..0766491 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -381,119 +381,119 @@ def run_script( # fmt: off @overload - def function_call(self, function_name: Literal['AHKWinExist'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[bool, FutureResult[bool]]: ... + def function_call(self, function_name: Literal['AHKWinExist'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[bool, FutureResult[bool]]: ... @overload - def function_call(self, function_name: Literal['AHKImageSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Tuple[int, int], None, FutureResult[Union[Tuple[int, int], None]]]: ... + def function_call(self, function_name: Literal['AHKImageSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Tuple[int, int], None, FutureResult[Union[Tuple[int, int], None]]]: ... @overload - def function_call(self, function_name: Literal['AHKPixelGetColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[str, FutureResult[str]]: ... + def function_call(self, function_name: Literal['AHKPixelGetColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[str, FutureResult[str]]: ... @overload - def function_call(self, function_name: Literal['AHKPixelSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Optional[Tuple[int, int]], FutureResult[Optional[Tuple[int, int]]]]: ... + def function_call(self, function_name: Literal['AHKPixelSearch'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Optional[Tuple[int, int]], FutureResult[Optional[Tuple[int, int]]]]: ... @overload - def function_call(self, function_name: Literal['AHKMouseGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Tuple[int, int], FutureResult[Tuple[int, int]]]: ... + def function_call(self, function_name: Literal['AHKMouseGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Tuple[int, int], FutureResult[Tuple[int, int]]]: ... @overload - def function_call(self, function_name: Literal['AHKKeyState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[int, float, str, None, FutureResult[None], FutureResult[str], FutureResult[int], FutureResult[float]]: ... + def function_call(self, function_name: Literal['AHKKeyState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[int, float, str, None, FutureResult[None], FutureResult[str], FutureResult[int], FutureResult[float]]: ... @overload - def function_call(self, function_name: Literal['AHKMouseMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKMouseMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKClick'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKClick'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKMouseClickDrag'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKMouseClickDrag'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKKeyWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[int, FutureResult[int]]: ... + def function_call(self, function_name: Literal['AHKKeyWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[int, FutureResult[int]]: ... @overload - def function_call(self, function_name: Literal['SetKeyDelay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['SetKeyDelay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSendRaw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSendRaw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSendInput'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSendInput'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSendEvent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSendEvent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSendPlay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSendPlay'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKSetCapsLockState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKSetCapsLockState'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetTitle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[str, FutureResult[str]]: ... + def function_call(self, function_name: Literal['AHKWinGetTitle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[str, FutureResult[str]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetClass'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[str, FutureResult[str]]: ... + def function_call(self, function_name: Literal['AHKWinGetClass'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[str, FutureResult[str]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetText'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[str, FutureResult[str]]: ... + def function_call(self, function_name: Literal['AHKWinGetText'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[str, FutureResult[str]]: ... @overload - def function_call(self, function_name: Literal['AHKWinActivate'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinActivate'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['WinActivateBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['WinActivateBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinKill'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinKill'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinMaximize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinMaximize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinMinimize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinMinimize'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinRestore'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinRestore'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWindowList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[List[Window], FutureResult[List[Window]]]: ... + def function_call(self, function_name: Literal['AHKWindowList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[List[Window], FutureResult[List[Window]]]: ... @overload - def function_call(self, function_name: Literal['AHKControlSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKControlSend'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinFromMouse'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Optional[Window], FutureResult[Optional[Window]]]: ... + def function_call(self, function_name: Literal['AHKWinFromMouse'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Optional[Window], FutureResult[Optional[Window]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinIsAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Optional[bool], FutureResult[Optional[bool]]]: ... + def function_call(self, function_name: Literal['AHKWinIsAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Optional[bool], FutureResult[Optional[bool]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinMove'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[Position, None], FutureResult[Union[None, Position]]]: ... + def function_call(self, function_name: Literal['AHKWinGetPos'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[Position, None], FutureResult[Union[None, Position]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, Window], FutureResult[Union[None, Window]]]: ... + def function_call(self, function_name: Literal['AHKWinGetID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, Window], FutureResult[Union[None, Window]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetIDLast'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, Window], FutureResult[Union[None, Window]]]: ... + def function_call(self, function_name: Literal['AHKWinGetIDLast'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, Window], FutureResult[Union[None, Window]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetPID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[int, None], FutureResult[Union[int, None]]]: ... + def function_call(self, function_name: Literal['AHKWinGetPID'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[int, None], FutureResult[Union[int, None]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetProcessName'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... + def function_call(self, function_name: Literal['AHKWinGetProcessName'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetProcessPath'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... + def function_call(self, function_name: Literal['AHKWinGetProcessPath'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetCount'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[int, FutureResult[int]]: ... + def function_call(self, function_name: Literal['AHKWinGetCount'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[int, FutureResult[int]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[List[Window], FutureResult[List[Window]]]: ... + def function_call(self, function_name: Literal['AHKWinGetList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[List[Window], FutureResult[List[Window]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetMinMax'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, int], FutureResult[Union[None, int]]]: ... + def function_call(self, function_name: Literal['AHKWinGetMinMax'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, int], FutureResult[Union[None, int]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetControlList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[List[Control], None, FutureResult[Union[List[Control], None]]]: ... + def function_call(self, function_name: Literal['AHKWinGetControlList'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[List[Control], None, FutureResult[Union[List[Control], None]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, int], FutureResult[Union[None, int]]]: ... + def function_call(self, function_name: Literal['AHKWinGetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, int], FutureResult[Union[None, int]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... + def function_call(self, function_name: Literal['AHKWinGetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... + def function_call(self, function_name: Literal['AHKWinGetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinGetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... + def function_call(self, function_name: Literal['AHKWinGetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Union[None, str], FutureResult[Union[None, str]]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetAlwaysOnTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetBottom'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetTop'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetDisable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetDisable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetEnable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetEnable'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetRedraw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetRedraw'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[bool, FutureResult[bool]]: ... + def function_call(self, function_name: Literal['AHKWinSetStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[bool, FutureResult[bool]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[bool, FutureResult[bool]]: ... + def function_call(self, function_name: Literal['AHKWinSetExStyle'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[bool, FutureResult[bool]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetRegion'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[bool, FutureResult[bool]]: ... + def function_call(self, function_name: Literal['AHKWinSetRegion'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[bool, FutureResult[bool]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetTransparent'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinSetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinSetTransColor'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload def function_call(self, function_name: Literal['AHKSetDetectHiddenWindows'], args: Optional[List[str]] = None) -> None: ... @overload @@ -505,7 +505,7 @@ def function_call(self, function_name: Literal['AHKGetTitleMatchMode']) -> str: @overload def function_call(self, function_name: Literal['AHKGetTitleMatchSpeed']) -> str: ... @overload - def function_call(self, function_name: Literal['AHKControlGetText'], args: Optional[List[str]] = None, *, engine: Optional[AHK] = None, blocking: bool = True) -> Union[str, FutureResult[str]]: ... + def function_call(self, function_name: Literal['AHKControlGetText'], args: Optional[List[str]] = None, *, engine: Optional[AHK[Any]] = None, blocking: bool = True) -> Union[str, FutureResult[str]]: ... @overload def function_call(self, function_name: Literal['AHKControlClick'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[None, FutureResult[None]]: ... @overload @@ -519,18 +519,18 @@ def function_call(self, function_name: Literal['AHKGetSendLevel']) -> int: ... @overload def function_call(self, function_name: Literal['AHKSetSendLevel'], args: List[str]) -> None: ... @overload - def function_call(self, function_name: Literal['AHKWinWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Window, FutureResult[Window]]: ... + def function_call(self, function_name: Literal['AHKWinWait'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Window, FutureResult[Window]]: ... @overload - def function_call(self, function_name: Literal['AHKWinWaitActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Window, FutureResult[Window]]: ... + def function_call(self, function_name: Literal['AHKWinWaitActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Window, FutureResult[Window]]: ... @overload - def function_call(self, function_name: Literal['AHKWinWaitNotActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[Window, FutureResult[Window]]: ... + def function_call(self, function_name: Literal['AHKWinWaitNotActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[Window, FutureResult[Window]]: ... @overload - def function_call(self, function_name: Literal['AHKWinShow'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinShow'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinHide'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinHide'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKWinIsActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[bool, FutureResult[bool]]: ... + def function_call(self, function_name: Literal['AHKWinIsActive'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[bool, FutureResult[bool]]: ... @overload def function_call(self, function_name: Literal['AHKGetVolume'], args: Optional[List[str]] = None) -> float: ... @overload @@ -563,7 +563,7 @@ def function_call(self, function_name: Literal['AHKClipWait'], args: Optional[Li # @overload # async def function_call(self, function_name: Literal['HideTrayTip'], args: Optional[List[str]] = None) -> None: ... @overload - def function_call(self, function_name: Literal['AHKWinWaitClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK] = None) -> Union[None, FutureResult[None]]: ... + def function_call(self, function_name: Literal['AHKWinWaitClose'], args: Optional[List[str]] = None, *, blocking: bool = True, engine: Optional[AHK[Any]] = None) -> Union[None, FutureResult[None]]: ... @overload def function_call(self, function_name: Literal['AHKRegRead'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, FutureResult[str]]: ... @overload @@ -577,7 +577,7 @@ def function_call(self, function_name: Literal['AHKMenuTrayIcon'], args: Optiona @overload def function_call(self, function_name: Literal['AHKMenuTrayShow'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[None, FutureResult[None]]: ... @overload - def function_call(self, function_name: Literal['AHKGuiNew'], args: List[str], *, engine: AHK) -> str: ... + def function_call(self, function_name: Literal['AHKGuiNew'], args: List[str], *, engine: AHK[Any]) -> str: ... @overload def function_call(self, function_name: Literal['AHKMsgBox'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, FutureResult[str]]: ... @overload @@ -593,7 +593,7 @@ def function_call( function_name: FunctionName, args: Optional[List[str]] = None, blocking: bool = True, - engine: Optional[AHK] = None, + engine: Optional[AHK[Any]] = None, ) -> Any: if not self._started: with warnings.catch_warnings(record=True) as caught_warnings: @@ -609,14 +609,14 @@ def function_call( @abstractmethod def send( - self, request: RequestMessage, engine: Optional[AHK] = None + self, request: RequestMessage, engine: Optional[AHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, Window, List[Window], List[Control]]: return NotImplemented @abstractmethod def send_nonblocking( - self, request: RequestMessage, engine: Optional[AHK] = None + self, request: RequestMessage, engine: Optional[AHK[Any]] = None ) -> FutureResult[Union[None, Tuple[int, int], int, str, bool, Window, List[Window], List[Control]]]: return NotImplemented @@ -642,7 +642,6 @@ def __init__( self._execution_lock = threading.Lock() self._executable_path = executable_path - if version is None or version == 'v1': template_name = 'daemon.ahk' const_script = _DAEMON_SCRIPT_TEMPLATE @@ -652,8 +651,6 @@ def __init__( else: raise ValueError(f'Invalid version {version!r} - must be one of "v1" or "v2"') - - if jinja_loader is None: try: loader: jinja2.BaseLoader @@ -750,7 +747,7 @@ def _create_process( return proc def _send_nonblocking( - self, request: RequestMessage, engine: Optional[AHK] = None + self, request: RequestMessage, engine: Optional[AHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, Window, List[Window], List[Control]]: msg = request.format() proc = self._create_process() @@ -787,7 +784,7 @@ def _send_nonblocking( def send_nonblocking( - self, request: RequestMessage, engine: Optional[AHK] = None + self, request: RequestMessage, engine: Optional[AHK[Any]] = None ) -> FutureResult[Union[None, Tuple[int, int], int, str, bool, Window, List[Window], List[Control]]]: # this is only used by the sync implementation pool = ThreadPoolExecutor(max_workers=1) @@ -799,7 +796,7 @@ def send_nonblocking( return FutureResult(fut) def send( - self, request: RequestMessage, engine: Optional[AHK] = None + self, request: RequestMessage, engine: Optional[AHK[Any]] = None ) -> Union[None, Tuple[int, int], int, str, bool, Window, List[Window], List[Control]]: msg = request.format() assert self._proc is not None diff --git a/ahk/_sync/window.py b/ahk/_sync/window.py index baaed41..7c6f6f6 100644 --- a/ahk/_sync/window.py +++ b/ahk/_sync/window.py @@ -10,6 +10,7 @@ from typing import Sequence from typing import Tuple from typing import TYPE_CHECKING +from typing import TypeVar from typing import Union from ahk.message import Position @@ -41,10 +42,12 @@ class WindowNotFoundException(Exception): 'Use of the {0} property setter is not supported in the async API. Use the set_{0} instead.' ) +T_EngineVersion = TypeVar('T_EngineVersion', bound=Optional[Literal['v1', 'v2']]) + class Window: - def __init__(self, engine: AHK, ahk_id: str): - self._engine: AHK = engine + def __init__(self, engine: AHK[T_EngineVersion], ahk_id: str): + self._engine: AHK[T_EngineVersion] = engine if not ahk_id: raise ValueError(f'Invalid ahk_id: {ahk_id!r}') self._ahk_id: str = ahk_id @@ -289,7 +292,9 @@ def send(self, keys: str, control: str = '', *, blocking: Literal[True]) -> None @overload def send(self, keys: str, control: str = '', *, blocking: bool = True) -> Union[None, FutureResult[None]]: ... # fmt: on - def send(self, keys: str, control: str = '', *, blocking: bool = True) -> Union[None, FutureResult[None]]: + def send( + self, keys: str, control: str = '', *, blocking: bool = True + ) -> Union[None, FutureResult[None]]: return self._engine.control_send( keys=keys, control=control, @@ -358,10 +363,12 @@ def get_position(self, *, blocking: Literal[False]) -> FutureResult[Optional[Pos @overload def get_position(self, *, blocking: Literal[True]) -> Position: ... @overload - def get_position(self, *, blocking: bool = True) -> Union[Position, FutureResult[Optional[Position]]]: ... + def get_position(self, *, blocking: bool = True) -> Union[Position, FutureResult[Optional[Position]], FutureResult[Position]]: ... # fmt: on - def get_position(self, *, blocking: bool = True) -> Union[Position, FutureResult[Optional[Position]]]: - resp = self._engine.win_get_position( + def get_position( + self, *, blocking: bool = True + ) -> Union[Position, FutureResult[Optional[Position]], FutureResult[Position]]: + resp = self._engine.win_get_position( # type: ignore[misc] # this appears to be a mypy bug title=f'ahk_id {self._ahk_id}', blocking=blocking, detect_hidden_windows=True, @@ -629,11 +636,11 @@ def move( ) @classmethod - def from_pid(cls, engine: AHK, pid: int) -> Optional[Window]: + def from_pid(cls, engine: AHK[Any], pid: int) -> Optional[Window]: return engine.win_get(title=f'ahk_pid {pid}') @classmethod - def from_mouse_position(cls, engine: AHK) -> Optional[Window]: + def from_mouse_position(cls, engine: AHK[Any]) -> Optional[Window]: return engine.win_get_from_mouse_position() diff --git a/ahk/extensions.py b/ahk/extensions.py index 88b387d..3677e30 100644 --- a/ahk/extensions.py +++ b/ahk/extensions.py @@ -34,7 +34,7 @@ class _ExtensionEntry: if typing.TYPE_CHECKING: from ahk import AHK, AsyncAHK - TAHK = TypeVar('TAHK', bound=typing.Union[AHK, AsyncAHK]) + TAHK = TypeVar('TAHK', bound=typing.Union[AHK[Any], AsyncAHK[Any]]) @dataclass diff --git a/ahk/message.py b/ahk/message.py index 3a0f131..a78206c 100644 --- a/ahk/message.py +++ b/ahk/message.py @@ -114,9 +114,9 @@ def __init_subclass__(cls: Type[T_ResponseMessageType], **kwargs: Any) -> None: _message_registry[tom] = cls super().__init_subclass__(**kwargs) - def __init__(self, raw_content: bytes, engine: Optional[Union[AsyncAHK, AHK]] = None): + def __init__(self, raw_content: bytes, engine: Optional[Union[AsyncAHK[Any], AHK[Any]]] = None): self._raw_content: bytes = raw_content - self._engine: Optional[Union[AsyncAHK, AHK]] = engine + self._engine: Optional[Union[AsyncAHK[Any], AHK[Any]]] = engine def __repr__(self) -> str: return f'ResponseMessage' @@ -130,7 +130,7 @@ def _tom_lookup(tom: bytes) -> 'ResponseMessageClassTypes': @classmethod def from_bytes( - cls: Type[T_ResponseMessageType], b: bytes, engine: Optional[Union[AsyncAHK, AHK]] = None + cls: Type[T_ResponseMessageType], b: bytes, engine: Optional[Union[AsyncAHK[Any], AHK[Any]]] = None ) -> 'ResponseMessageTypes': tom, _, message_bytes = b.split(b'\n', 2) klass = cls._tom_lookup(tom) From f7fbbe7d3bf3be2e9be7d1a8cca3460ff260c232 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 20:13:09 +0000 Subject: [PATCH 50/52] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) - [github.com/psf/black: 23.9.1 → 23.11.0](https://github.com/psf/black/compare/23.9.1...23.11.0) - [github.com/asottile/reorder-python-imports: v3.10.0 → v3.12.0](https://github.com/asottile/reorder-python-imports/compare/v3.10.0...v3.12.0) - [github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.7.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.1...v1.7.0) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 01b9d4f..3492172 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: files: ^(ahk/daemon\.ahk|ahk/_constants\.py) - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: mixed-line-ending args: ["-f", "lf"] @@ -31,7 +31,7 @@ repos: - id: trailing-whitespace - id: double-quote-string-fixer - repo: https://github.com/psf/black - rev: '23.9.1' + rev: '23.11.0' hooks: - id: black args: @@ -40,12 +40,12 @@ repos: - "120" exclude: ^(ahk/_sync/.*\.py) - repo: https://github.com/asottile/reorder-python-imports - rev: v3.10.0 + rev: v3.12.0 hooks: - id: reorder-python-imports - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.5.1' + rev: 'v1.7.0' hooks: - id: mypy args: From 5e35f632696ef35712adb3a82e51477c2ac3156a Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 22 Nov 2023 22:17:43 -0800 Subject: [PATCH 51/52] update actions --- .github/workflows/release.yaml | 2 +- .github/workflows/test.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6c4bb05..b23911c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -19,7 +19,7 @@ jobs: - name: build shell: bash run: | - python -m pip install --upgrade wheel setuptools build unasync tokenize-rt + python -m pip install --upgrade wheel setuptools build python -m build - name: Release PyPI shell: bash diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d1ed71b..78b50d4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -33,4 +33,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | pip install --upgrade coveralls - coveralls --service=github + coveralls --service=github-actions From ea22dcccfa3651df8918187255b79f4c1b5c99d7 Mon Sep 17 00:00:00 2001 From: Spencer Phillip Young Date: Wed, 22 Nov 2023 22:44:47 -0800 Subject: [PATCH 52/52] coveralls parallel --- .github/workflows/test.yaml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 78b50d4..d4de6f9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -31,6 +31,18 @@ jobs: - name: Coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_PARALLEL: "true" + COVERALLS_SERVICE_JOB_ID: ${{ github.run_id }} run: | pip install --upgrade coveralls - coveralls --service=github-actions + coveralls --service=github + finish: + runs-on: ubuntu-latest + needs: build + steps: + - name: finish coveralls + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + pip install --upgrade coveralls + coveralls --service=github --finish