Fix up focusorstart, especially on systems without recent libxdo
This commit is contained in:
		
							parent
							
								
									d7a4df8b31
								
							
						
					
					
						commit
						99c7158b98
					
				
							
								
								
									
										123
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										123
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							| @ -15,11 +15,44 @@ optional = false | ||||
| python-versions = ">=3.5" | ||||
| 
 | ||||
| [package.extras] | ||||
| dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] | ||||
| docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] | ||||
| tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] | ||||
| dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope-interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] | ||||
| docs = ["furo", "sphinx", "zope-interface", "sphinx-notfound-page"] | ||||
| tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope-interface", "cloudpickle"] | ||||
| tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "black" | ||||
| version = "22.6.0" | ||||
| description = "The uncompromising code formatter." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6.2" | ||||
| 
 | ||||
| [package.dependencies] | ||||
| click = ">=8.0.0" | ||||
| mypy-extensions = ">=0.4.3" | ||||
| pathspec = ">=0.9.0" | ||||
| platformdirs = ">=2" | ||||
| tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} | ||||
| typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} | ||||
| 
 | ||||
| [package.extras] | ||||
| colorama = ["colorama (>=0.4.3)"] | ||||
| d = ["aiohttp (>=3.7.4)"] | ||||
| jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] | ||||
| uvloop = ["uvloop (>=0.15.2)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "click" | ||||
| version = "8.1.3" | ||||
| description = "Composable command line interface toolkit" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| 
 | ||||
| [package.dependencies] | ||||
| colorama = {version = "*", markers = "platform_system == \"Windows\""} | ||||
| 
 | ||||
| [[package]] | ||||
| name = "colorama" | ||||
| version = "0.4.5" | ||||
| @ -28,6 +61,20 @@ category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "isort" | ||||
| version = "5.10.1" | ||||
| description = "A Python utility / library to sort Python imports." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6.1,<4.0" | ||||
| 
 | ||||
| [package.extras] | ||||
| pipfile_deprecated_finder = ["pipreqs", "requirementslib"] | ||||
| requirements_deprecated_finder = ["pipreqs", "pip-api"] | ||||
| colors = ["colorama (>=0.4.3,<0.5.0)"] | ||||
| plugins = ["setuptools"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "more-itertools" | ||||
| version = "8.14.0" | ||||
| @ -36,6 +83,14 @@ category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.5" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mypy-extensions" | ||||
| version = "0.4.3" | ||||
| description = "Experimental type system extensions for programs checked with the mypy typechecker." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "packaging" | ||||
| version = "21.3" | ||||
| @ -47,6 +102,26 @@ python-versions = ">=3.6" | ||||
| [package.dependencies] | ||||
| pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pathspec" | ||||
| version = "0.9.0" | ||||
| description = "Utility library for gitignore style pattern matching of file paths." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "platformdirs" | ||||
| version = "2.5.2" | ||||
| description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| 
 | ||||
| [package.extras] | ||||
| docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] | ||||
| test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pluggy" | ||||
| version = "0.13.1" | ||||
| @ -129,6 +204,22 @@ category = "main" | ||||
| optional = false | ||||
| python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tomli" | ||||
| version = "2.0.1" | ||||
| description = "A lil' TOML parser" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "typing-extensions" | ||||
| version = "4.3.0" | ||||
| description = "Backported and Experimental Type Hints for Python 3.7+" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wcwidth" | ||||
| version = "0.2.5" | ||||
| @ -140,19 +231,39 @@ python-versions = "*" | ||||
| [metadata] | ||||
| lock-version = "1.1" | ||||
| python-versions = "^3.8" | ||||
| content-hash = "ce2bd3695095025e5af2cf1f12ed4c584ae8e7ab7306c563cfb8288fbae071e4" | ||||
| content-hash = "30f692b01424a60c3313628f24ff7782340fc55fd34bd6220fa878cb88c4f117" | ||||
| 
 | ||||
| [metadata.files] | ||||
| atomicwrites = [] | ||||
| attrs = [] | ||||
| black = [] | ||||
| click = [] | ||||
| colorama = [] | ||||
| isort = [] | ||||
| more-itertools = [] | ||||
| packaging = [] | ||||
| mypy-extensions = [ | ||||
|     {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, | ||||
|     {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, | ||||
| ] | ||||
| packaging = [ | ||||
|     {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, | ||||
|     {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, | ||||
| ] | ||||
| pathspec = [ | ||||
|     {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, | ||||
|     {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, | ||||
| ] | ||||
| platformdirs = [] | ||||
| pluggy = [] | ||||
| psutil = [] | ||||
| py = [] | ||||
| pyparsing = [] | ||||
| pytest = [] | ||||
| python-libxdo-ng = [] | ||||
| six = [] | ||||
| six = [ | ||||
|     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, | ||||
|     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, | ||||
| ] | ||||
| tomli = [] | ||||
| typing-extensions = [] | ||||
| wcwidth = [] | ||||
|  | ||||
| @ -9,6 +9,10 @@ python = "^3.8" | ||||
| python-libxdo-ng = "^0.1.4" | ||||
| psutil = "^5.9.1" | ||||
| 
 | ||||
| [tool.poetry.group.dev.dependencies] | ||||
| black = "^22.6.0" | ||||
| isort = "^5.10.1" | ||||
| 
 | ||||
| [tool.poetry.dev-dependencies] | ||||
| pytest = "^5.2" | ||||
| 
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| __version__ = '0.1.0' | ||||
| __version__ = "0.1.0" | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| import subprocess | ||||
| import sys | ||||
| from time import sleep | ||||
| from typing import List | ||||
| 
 | ||||
| import psutil | ||||
| from xdo import Xdo | ||||
| @ -14,7 +16,14 @@ In old versions, `search_windows` won't return anything here... | ||||
| 
 | ||||
| def focus_window_of_process(pid: int) -> None: | ||||
|     x = Xdo() | ||||
|     window_ids = x.search_windows(pid=pid) | ||||
| 
 | ||||
|     # Broken for old libxdos, use xdotool as workaround | ||||
|     # window_ids = x.search_windows(pid=pid) | ||||
|     window_ids = [ | ||||
|         wid | ||||
|         for wid in _workaround_get_windows_for_pid(pid) | ||||
|         if _check_window_not_dropdown(wid) | ||||
|     ] | ||||
|     if not window_ids: | ||||
|         raise ValueError("No windows for application!") | ||||
| 
 | ||||
| @ -24,8 +33,30 @@ def focus_window_of_process(pid: int) -> None: | ||||
|     current_desktop = x.get_current_desktop() | ||||
|     window_id = window_ids[0] | ||||
|     x.set_desktop_for_window(window_id, current_desktop) | ||||
|     x.raise_window(window_id) | ||||
|     x.focus_window(window_id) | ||||
|     x.activate_window(window_id) | ||||
| 
 | ||||
| 
 | ||||
| def _workaround_get_windows_for_pid(pid: int) -> List[int]: | ||||
|     return [ | ||||
|         int(line.strip()) | ||||
|         for line in subprocess.check_output( | ||||
|             ["xdotool", "search", "--pid", str(pid)] | ||||
|         ).splitlines() | ||||
|         if line.strip() | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| def _check_window_not_dropdown(window_id: int) -> bool: | ||||
|     xprop_output = subprocess.check_output(["xprop", "-id", str(window_id)]) | ||||
| 
 | ||||
|     if ( | ||||
|         b"_WM_WINDOW_TYPE_DROPDOWN_MENU" in xprop_output | ||||
|         or b"_WM_WINDOW_TYPE_POPUP_MENU" in xprop_output | ||||
|     ): | ||||
|         print("Ignoring dropdown/popup type window") | ||||
|         return False | ||||
| 
 | ||||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def main() -> None: | ||||
| @ -35,11 +66,11 @@ def main() -> None: | ||||
|         process_name = process.name().split()[0] | ||||
|         if process_name == application_name: | ||||
|             focus_window_of_process(process.pid) | ||||
|             break | ||||
|             return | ||||
| 
 | ||||
|     # Launch the process, since we didn't find it. | ||||
|     subprocess.Popen(application_name) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
|  | ||||
							
								
								
									
										6
									
								
								scripts-dev/lint.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								scripts-dev/lint.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,6 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| isort . | ||||
| black . | ||||
| #mypy | ||||
| 
 | ||||
| @ -2,4 +2,4 @@ from rei_dotools import __version__ | ||||
| 
 | ||||
| 
 | ||||
| def test_version(): | ||||
|     assert __version__ == '0.1.0' | ||||
|     assert __version__ == "0.1.0" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user