Skip to content

Commit 81868bf

Browse files
committed
fix windows child chromium processes
1 parent 4ce0cce commit 81868bf

1 file changed

Lines changed: 29 additions & 6 deletions

File tree

frontend/chromium_manager.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ def launch_window(self, window_name, url, monitor, index):
8888
print(f"[Chromium] Launching '{window_name}' on monitor {index} "
8989
f"({monitor.width}x{monitor.height} at {monitor.x},{monitor.y})")
9090

91-
proc = subprocess.Popen(args, env=env)
91+
# Launch in its own process group so we can kill the entire tree on shutdown
92+
# (Chromium spawns renderers, GPU, zygote children that must all be killed)
93+
popen_kwargs = dict(env=env)
94+
if platform.system() != "Windows":
95+
popen_kwargs['start_new_session'] = True
96+
97+
proc = subprocess.Popen(args, **popen_kwargs)
9298
self._processes.append((window_name, proc, user_data_dir))
9399
return proc
94100

@@ -128,16 +134,33 @@ def launch_all_windows(self, iniconfig, base_url="http://127.0.0.1"):
128134

129135
print(f"[Chromium] Launched {len(self._processes)} browser windows")
130136

137+
def _kill_process_tree(self, proc, window_name, force=False):
138+
"""Kill a Chromium process and all its children (renderers, GPU, zygote)."""
139+
if platform.system() == "Windows":
140+
# taskkill /T kills the entire process tree, /F forces it
141+
try:
142+
subprocess.call(
143+
['taskkill', '/F', '/T', '/PID', str(proc.pid)],
144+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
145+
)
146+
except Exception as e:
147+
print(f"[Chromium] taskkill failed for '{window_name}': {e}")
148+
else:
149+
sig = signal.SIGKILL if force else signal.SIGTERM
150+
try:
151+
os.killpg(proc.pid, sig)
152+
except ProcessLookupError:
153+
pass
154+
except Exception as e:
155+
print(f"[Chromium] killpg failed for '{window_name}': {e}")
156+
131157
def terminate_all(self):
132158
"""Terminate all Chromium processes gracefully."""
133159
print("[Chromium] Terminating all browser windows...")
134160
for window_name, proc, temp_dir in self._processes:
135161
try:
136162
if proc.poll() is None: # still running
137-
if platform.system() == "Windows":
138-
proc.terminate()
139-
else:
140-
proc.send_signal(signal.SIGTERM)
163+
self._kill_process_tree(proc, window_name)
141164
except Exception as e:
142165
print(f"[Chromium] Error terminating '{window_name}': {e}")
143166

@@ -147,7 +170,7 @@ def terminate_all(self):
147170
proc.wait(timeout=5)
148171
except subprocess.TimeoutExpired:
149172
print(f"[Chromium] Force killing '{window_name}'")
150-
proc.kill()
173+
self._kill_process_tree(proc, window_name, force=True)
151174

152175
self._processes.clear()
153176
self._exit_event.set()

0 commit comments

Comments
 (0)