[codex] fix Windows bridge worker popups (#1203)
* fix windows bridge worker popups * scope worker hiding to desktop
This commit is contained in:
@@ -66,19 +66,43 @@ def _positive_int(value: str | None) -> int | None:
|
|||||||
return parsed if parsed > 0 else None
|
return parsed if parsed > 0 else None
|
||||||
|
|
||||||
|
|
||||||
def _hidden_subprocess_kwargs() -> dict[str, int]:
|
def _hidden_subprocess_kwargs() -> dict[str, Any]:
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
return {}
|
return {}
|
||||||
return {"creationflags": getattr(subprocess, "CREATE_NO_WINDOW", 0)}
|
if os.environ.get("HERMES_DESKTOP", "").strip().lower() != "true":
|
||||||
|
return {}
|
||||||
|
create_no_window = getattr(subprocess, "CREATE_NO_WINDOW", 0) or 0x08000000
|
||||||
|
kwargs: dict[str, Any] = {"creationflags": create_no_window}
|
||||||
|
try:
|
||||||
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
startupinfo.dwFlags |= getattr(subprocess, "STARTF_USESHOWWINDOW", 1)
|
||||||
|
startupinfo.wShowWindow = getattr(subprocess, "SW_HIDE", 0)
|
||||||
|
kwargs["startupinfo"] = startupinfo
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
def _add_hidden_creationflags(kwargs: dict[str, Any], create_no_window: int) -> None:
|
def _add_hidden_process_options(kwargs: dict[str, Any], create_no_window: int) -> None:
|
||||||
flags = kwargs.get("creationflags", 0) or 0
|
flags = kwargs.get("creationflags", 0) or 0
|
||||||
try:
|
try:
|
||||||
kwargs["creationflags"] = int(flags) | create_no_window
|
kwargs["creationflags"] = int(flags) | create_no_window
|
||||||
except Exception:
|
except Exception:
|
||||||
kwargs["creationflags"] = create_no_window
|
kwargs["creationflags"] = create_no_window
|
||||||
|
|
||||||
|
startupinfo = kwargs.get("startupinfo")
|
||||||
|
if startupinfo is None:
|
||||||
|
try:
|
||||||
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
kwargs["startupinfo"] = startupinfo
|
||||||
|
try:
|
||||||
|
startupinfo.dwFlags |= getattr(subprocess, "STARTF_USESHOWWINDOW", 1)
|
||||||
|
startupinfo.wShowWindow = getattr(subprocess, "SW_HIDE", 0)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _install_windows_hidden_subprocess_defaults() -> None:
|
def _install_windows_hidden_subprocess_defaults() -> None:
|
||||||
"""Hide console windows for subprocesses launched inside desktop bridge runs.
|
"""Hide console windows for subprocesses launched inside desktop bridge runs.
|
||||||
@@ -102,15 +126,15 @@ def _install_windows_hidden_subprocess_defaults() -> None:
|
|||||||
|
|
||||||
class HiddenPopen(original_popen): # type: ignore[misc, valid-type]
|
class HiddenPopen(original_popen): # type: ignore[misc, valid-type]
|
||||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
_add_hidden_creationflags(kwargs, create_no_window)
|
_add_hidden_process_options(kwargs, create_no_window)
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
async def hidden_create_subprocess_exec(*args: Any, **kwargs: Any) -> Any:
|
async def hidden_create_subprocess_exec(*args: Any, **kwargs: Any) -> Any:
|
||||||
_add_hidden_creationflags(kwargs, create_no_window)
|
_add_hidden_process_options(kwargs, create_no_window)
|
||||||
return await original_create_subprocess_exec(*args, **kwargs)
|
return await original_create_subprocess_exec(*args, **kwargs)
|
||||||
|
|
||||||
async def hidden_create_subprocess_shell(*args: Any, **kwargs: Any) -> Any:
|
async def hidden_create_subprocess_shell(*args: Any, **kwargs: Any) -> Any:
|
||||||
_add_hidden_creationflags(kwargs, create_no_window)
|
_add_hidden_process_options(kwargs, create_no_window)
|
||||||
return await original_create_subprocess_shell(*args, **kwargs)
|
return await original_create_subprocess_shell(*args, **kwargs)
|
||||||
|
|
||||||
subprocess.Popen = HiddenPopen # type: ignore[assignment]
|
subprocess.Popen = HiddenPopen # type: ignore[assignment]
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ original_popen = bridge.subprocess.Popen
|
|||||||
original_async_exec = bridge.asyncio.create_subprocess_exec
|
original_async_exec = bridge.asyncio.create_subprocess_exec
|
||||||
original_async_shell = bridge.asyncio.create_subprocess_shell
|
original_async_shell = bridge.asyncio.create_subprocess_shell
|
||||||
original_create_no_window = getattr(bridge.subprocess, "CREATE_NO_WINDOW", None)
|
original_create_no_window = getattr(bridge.subprocess, "CREATE_NO_WINDOW", None)
|
||||||
|
original_startupinfo = getattr(bridge.subprocess, "STARTUPINFO", None)
|
||||||
|
original_startf = getattr(bridge.subprocess, "STARTF_USESHOWWINDOW", None)
|
||||||
|
original_sw_hide = getattr(bridge.subprocess, "SW_HIDE", None)
|
||||||
original_installed = getattr(bridge.subprocess, "_hermes_hidden_defaults_installed", None)
|
original_installed = getattr(bridge.subprocess, "_hermes_hidden_defaults_installed", None)
|
||||||
|
|
||||||
class FakePopen:
|
class FakePopen:
|
||||||
@@ -142,6 +145,11 @@ async def fake_create_subprocess_shell(*args, **kwargs):
|
|||||||
async_calls.append({"kind": "shell", "args": args, "kwargs": kwargs})
|
async_calls.append({"kind": "shell", "args": args, "kwargs": kwargs})
|
||||||
return {"kind": "shell"}
|
return {"kind": "shell"}
|
||||||
|
|
||||||
|
class FakeStartupInfo:
|
||||||
|
def __init__(self):
|
||||||
|
self.dwFlags = 0
|
||||||
|
self.wShowWindow = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bridge.os.name = "nt"
|
bridge.os.name = "nt"
|
||||||
bridge.os.environ["HERMES_DESKTOP"] = "true"
|
bridge.os.environ["HERMES_DESKTOP"] = "true"
|
||||||
@@ -149,16 +157,22 @@ try:
|
|||||||
bridge.asyncio.create_subprocess_exec = fake_create_subprocess_exec
|
bridge.asyncio.create_subprocess_exec = fake_create_subprocess_exec
|
||||||
bridge.asyncio.create_subprocess_shell = fake_create_subprocess_shell
|
bridge.asyncio.create_subprocess_shell = fake_create_subprocess_shell
|
||||||
bridge.subprocess.CREATE_NO_WINDOW = 0x08000000
|
bridge.subprocess.CREATE_NO_WINDOW = 0x08000000
|
||||||
|
bridge.subprocess.STARTUPINFO = FakeStartupInfo
|
||||||
|
bridge.subprocess.STARTF_USESHOWWINDOW = 0x00000001
|
||||||
|
bridge.subprocess.SW_HIDE = 0
|
||||||
if hasattr(bridge.subprocess, "_hermes_hidden_defaults_installed"):
|
if hasattr(bridge.subprocess, "_hermes_hidden_defaults_installed"):
|
||||||
delattr(bridge.subprocess, "_hermes_hidden_defaults_installed")
|
delattr(bridge.subprocess, "_hermes_hidden_defaults_installed")
|
||||||
|
|
||||||
bridge._install_windows_hidden_subprocess_defaults()
|
bridge._install_windows_hidden_subprocess_defaults()
|
||||||
bridge.subprocess.Popen(["git", "status"], creationflags=0x00000200)
|
bridge.subprocess.Popen(["git", "status"], creationflags=0x00000200)
|
||||||
flags = FakePopen.calls[0]["kwargs"]["creationflags"]
|
flags = FakePopen.calls[0]["kwargs"]["creationflags"]
|
||||||
|
startupinfo = FakePopen.calls[0]["kwargs"]["startupinfo"]
|
||||||
bridge.asyncio.run(bridge.asyncio.create_subprocess_exec("git", "status", creationflags=0x00000400))
|
bridge.asyncio.run(bridge.asyncio.create_subprocess_exec("git", "status", creationflags=0x00000400))
|
||||||
bridge.asyncio.run(bridge.asyncio.create_subprocess_shell("git status"))
|
bridge.asyncio.run(bridge.asyncio.create_subprocess_shell("git status"))
|
||||||
async_exec_flags = async_calls[0]["kwargs"]["creationflags"]
|
async_exec_flags = async_calls[0]["kwargs"]["creationflags"]
|
||||||
|
async_exec_startupinfo = async_calls[0]["kwargs"]["startupinfo"]
|
||||||
async_shell_flags = async_calls[1]["kwargs"]["creationflags"]
|
async_shell_flags = async_calls[1]["kwargs"]["creationflags"]
|
||||||
|
async_shell_startupinfo = async_calls[1]["kwargs"]["startupinfo"]
|
||||||
finally:
|
finally:
|
||||||
bridge.os.name = original_os_name
|
bridge.os.name = original_os_name
|
||||||
bridge.subprocess.Popen = original_popen
|
bridge.subprocess.Popen = original_popen
|
||||||
@@ -171,6 +185,18 @@ finally:
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
bridge.subprocess.CREATE_NO_WINDOW = original_create_no_window
|
bridge.subprocess.CREATE_NO_WINDOW = original_create_no_window
|
||||||
|
for name, original in [
|
||||||
|
("STARTUPINFO", original_startupinfo),
|
||||||
|
("STARTF_USESHOWWINDOW", original_startf),
|
||||||
|
("SW_HIDE", original_sw_hide),
|
||||||
|
]:
|
||||||
|
if original is None:
|
||||||
|
try:
|
||||||
|
delattr(bridge.subprocess, name)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
setattr(bridge.subprocess, name, original)
|
||||||
if original_installed is None:
|
if original_installed is None:
|
||||||
try:
|
try:
|
||||||
delattr(bridge.subprocess, "_hermes_hidden_defaults_installed")
|
delattr(bridge.subprocess, "_hermes_hidden_defaults_installed")
|
||||||
@@ -183,11 +209,14 @@ print(json.dumps({
|
|||||||
"flags": flags,
|
"flags": flags,
|
||||||
"has_create_no_window": bool(flags & 0x08000000),
|
"has_create_no_window": bool(flags & 0x08000000),
|
||||||
"kept_existing_flag": bool(flags & 0x00000200),
|
"kept_existing_flag": bool(flags & 0x00000200),
|
||||||
|
"startupinfo_hidden": bool(startupinfo.dwFlags & 0x00000001) and startupinfo.wShowWindow == 0,
|
||||||
"async_exec_flags": async_exec_flags,
|
"async_exec_flags": async_exec_flags,
|
||||||
"async_exec_has_create_no_window": bool(async_exec_flags & 0x08000000),
|
"async_exec_has_create_no_window": bool(async_exec_flags & 0x08000000),
|
||||||
"async_exec_kept_existing_flag": bool(async_exec_flags & 0x00000400),
|
"async_exec_kept_existing_flag": bool(async_exec_flags & 0x00000400),
|
||||||
|
"async_exec_startupinfo_hidden": bool(async_exec_startupinfo.dwFlags & 0x00000001) and async_exec_startupinfo.wShowWindow == 0,
|
||||||
"async_shell_flags": async_shell_flags,
|
"async_shell_flags": async_shell_flags,
|
||||||
"async_shell_has_create_no_window": bool(async_shell_flags & 0x08000000),
|
"async_shell_has_create_no_window": bool(async_shell_flags & 0x08000000),
|
||||||
|
"async_shell_startupinfo_hidden": bool(async_shell_startupinfo.dwFlags & 0x00000001) and async_shell_startupinfo.wShowWindow == 0,
|
||||||
}))
|
}))
|
||||||
`)
|
`)
|
||||||
|
|
||||||
@@ -195,11 +224,14 @@ print(json.dumps({
|
|||||||
flags: 0x08000200,
|
flags: 0x08000200,
|
||||||
has_create_no_window: true,
|
has_create_no_window: true,
|
||||||
kept_existing_flag: true,
|
kept_existing_flag: true,
|
||||||
|
startupinfo_hidden: true,
|
||||||
async_exec_flags: 0x08000400,
|
async_exec_flags: 0x08000400,
|
||||||
async_exec_has_create_no_window: true,
|
async_exec_has_create_no_window: true,
|
||||||
async_exec_kept_existing_flag: true,
|
async_exec_kept_existing_flag: true,
|
||||||
|
async_exec_startupinfo_hidden: true,
|
||||||
async_shell_flags: 0x08000000,
|
async_shell_flags: 0x08000000,
|
||||||
async_shell_has_create_no_window: true,
|
async_shell_has_create_no_window: true,
|
||||||
|
async_shell_startupinfo_hidden: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user