diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..0321d12 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,35 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + apt_packages: + - inkscape + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +formats: +# - epub +# - pdf + - htmlzip + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + # Install this package first, then doc/en/requirements.txt. + # This order is important to honor any pins in doc/en/requirements.txt + # when the pinned library is also a dependency of this package. + - method: pip + path: . + - requirements: docs/requirements.txt diff --git a/README.rst b/README.rst index fb40db9..036c964 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ Use cases - Tracks the focused window and its process - Tracks windows that capture the mouse or keyboard input -- Tracks which process is causing your fullscreen game to lose focus (Kevin Turner's initial motivation for his gist) +- Tracks which process is causing your fullscreen game to lose focus (Kevin Turner's initial motivation for the gist) - ... (there are lots of UI Automation related events that could be useful) Since the standard HWND and PID are readily available, you can utilize diff --git a/docs/conf.py b/docs/conf.py index 6d08eba..9654837 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,7 @@ import sphinx_rtd_theme import os import sys +import typing sys.path.insert(0, os.path.abspath('..')) @@ -8,6 +9,35 @@ # See NamedInt.FORCE_HEX_STR os.environ['SPHINX_NAMED_INT_FORCE_HEX_REPR'] = 'ON' + +# Mock types to enable doc generation on Linux and provide type name that the developer use. +class MockWithDocName(typing.NewType): + """Mock ctypes package as readthedocs.org only provides Linux machine for build, and ctypes.windll is not available. + + This also fix ctypes.wintypes.HANDLE being documented as ctypes.c_void_p, and similar for DWORD... + """ + + def __getattr__(self, name): + if name not in self.__dict__: + value = MockWithDocName(self.__name__ + '.' + name, typing.Any) + setattr(self, name, value) + return value + return super().__getattribute__(name) + + def __repr__(self): + return self.__name__ + + +def win_func_type(restype, *argtypes): + return typing.Callable[argtypes, restype] + + +import ctypes + +ctypes.wintypes = MockWithDocName('wintypes', typing.Any) +ctypes.windll = MockWithDocName('windll', typing.Any) +ctypes.WINFUNCTYPE = win_func_type + # Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: @@ -50,6 +80,12 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "sphinx_rtd_theme" -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -html_static_path = ['_static'] +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'classic' + +#html_static_path = ['_static'] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'win32_window_monitor' + diff --git a/docs/index.rst b/docs/index.rst index 7d5b982..70eb7f2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,7 @@ .. toctree:: :maxdepth: 2 - :caption: Contents: + :caption: API Reference api diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..5c43e5b --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,109 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --all-extras --output-file='E:\prg\prj\win32_window_monitor\docs\requirements.txt' pyproject.toml +# +alabaster==0.7.13 + # via sphinx +babel==2.12.1 + # via sphinx +build==1.0.3 + # via pip-tools +certifi==2023.7.22 + # via requests +charset-normalizer==3.2.0 + # via requests +click==8.1.7 + # via pip-tools +colorama==0.4.6 + # via + # build + # click + # pytest + # sphinx +coverage==7.3.1 + # via win32-window-monitor (pyproject.toml) +docutils==0.18.1 + # via + # myst-parser + # sphinx + # sphinx-rtd-theme +idna==3.4 + # via requests +imagesize==1.4.1 + # via sphinx +iniconfig==2.0.0 + # via pytest +jinja2==3.1.2 + # via + # myst-parser + # sphinx +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.3 + # via jinja2 +mdit-py-plugins==0.4.0 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +myst-parser==2.0.0 + # via win32-window-monitor (pyproject.toml) +packaging==23.1 + # via + # build + # pytest + # sphinx +pip-tools==7.3.0 + # via win32-window-monitor (pyproject.toml) +pluggy==1.3.0 + # via pytest +pygments==2.16.1 + # via sphinx +pyproject-hooks==1.0.0 + # via build +pytest==7.3.2 + # via win32-window-monitor (pyproject.toml) +pyyaml==6.0.1 + # via myst-parser +requests==2.31.0 + # via sphinx +snowballstemmer==2.2.0 + # via sphinx +sphinx==7.2.5 + # via + # myst-parser + # sphinx-rtd-theme + # sphinxcontrib-applehelp + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-jquery + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml + # win32-window-monitor (pyproject.toml) +sphinx-rtd-theme==1.3.0 + # via win32-window-monitor (pyproject.toml) +sphinxcontrib-applehelp==1.0.7 + # via sphinx +sphinxcontrib-devhelp==1.0.5 + # via sphinx +sphinxcontrib-htmlhelp==2.0.4 + # via sphinx +sphinxcontrib-jquery==4.1 + # via sphinx-rtd-theme +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.6 + # via sphinx +sphinxcontrib-serializinghtml==1.1.9 + # via sphinx +urllib3==2.0.4 + # via requests +wheel==0.41.2 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools diff --git a/docs/requirements_update.bat b/docs/requirements_update.bat new file mode 100644 index 0000000..2bcf8b0 --- /dev/null +++ b/docs/requirements_update.bat @@ -0,0 +1 @@ +pip-compile --output-file=%~dp0requirements.txt --all-extras --no-strip-extras pyproject.toml diff --git a/pyproject.toml b/pyproject.toml index 2d17059..d1acb49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ Home = "https://github.com/blep/win32_window_monitor" Source = "https://github.com/blep/win32_window_monitor" Issues = "https://github.com/blep/win32_window_monitor/issues" -#Documentation = "https://?" +Documentation = "http://win32-window-monitor.readthedocs.io/" [project.scripts] log_focused_window = "win32_window_monitor.main:main" @@ -44,6 +44,7 @@ doc = [ "sphinx ~= 7.2.3", "sphinx-rtd-theme ~= 1.3.0", "myst-parser ~= 2.0.0", + "pip-tools ~= 7.3.0", ] [tool.pytest.ini_options] diff --git a/win32_window_monitor/win32api.py b/win32_window_monitor/win32api.py index 4ef254f..1a5017a 100644 --- a/win32_window_monitor/win32api.py +++ b/win32_window_monitor/win32api.py @@ -150,7 +150,7 @@ def unhook(self): handle = self.handle if not handle: return # already unhook - unhook_win_event(handle) + _unhook_win_event(handle) with self.lock: self.handle = None self.proc = None @@ -190,7 +190,7 @@ def set_win_event_hook(on_event_func: EventHookFuncType, event_type: Union[int, UnhookWinEvent.restype = wintypes.BOOL -def unhook_win_event(win_event_hook_handle: HWINEVENTHOOK) -> bool: +def _unhook_win_event(win_event_hook_handle: HWINEVENTHOOK) -> bool: """Removes the hook set by set_win_event_hook().""" return UnhookWinEvent(win_event_hook_handle) != 0