Maximize GUI app window and fix input forwarding
- After window discovery, activate, move to (0,0), and resize to fill the 1280x1024 Xvfb display so the app is fullscreen - Add windowactivate --sync before click events so the window receives focus in X11 before mouse input - Add windowfocus --sync before key events so keyboard input goes to the correct window - Make canvas fill the entire app panel area (width/height 100%) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1467d07bc4
commit
12c10d69f0
2 changed files with 31 additions and 5 deletions
|
|
@ -187,6 +187,8 @@ class ManagedGuiApp:
|
||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Maximize the window to fill the Xvfb display and activate it
|
||||||
|
await self._maximize_window()
|
||||||
log.info("Capture loop started for app %s window %d", self.app_id, self.window_id)
|
log.info("Capture loop started for app %s window %d", self.app_id, self.window_id)
|
||||||
|
|
||||||
while self.alive:
|
while self.alive:
|
||||||
|
|
@ -357,6 +359,25 @@ class ManagedGuiApp:
|
||||||
grandchildren.extend(ManagedGuiApp._get_descendant_pids(cpid))
|
grandchildren.extend(ManagedGuiApp._get_descendant_pids(cpid))
|
||||||
return children + grandchildren
|
return children + grandchildren
|
||||||
|
|
||||||
|
async def _maximize_window(self):
|
||||||
|
"""Activate the window, resize it to fill the Xvfb display, and move to origin."""
|
||||||
|
if not self.window_id or not XDOTOOL_BIN:
|
||||||
|
return
|
||||||
|
env = self._display_env()
|
||||||
|
wid = str(self.window_id)
|
||||||
|
try:
|
||||||
|
# Activate (focus) the window
|
||||||
|
await self._xdotool("windowactivate", "--sync", wid, env=env)
|
||||||
|
# Move to origin
|
||||||
|
await self._xdotool("windowmove", "--sync", wid, "0", "0", env=env)
|
||||||
|
# Resize to fill display (Xvfb is 1280x1024)
|
||||||
|
await self._xdotool("windowsize", "--sync", wid, "1280", "1024", env=env)
|
||||||
|
# Some apps need a moment to redraw after resize
|
||||||
|
await asyncio.sleep(0.3)
|
||||||
|
log.debug("Maximized window %s to 1280x1024 for %s", wid, self.app_id)
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("Failed to maximize window %s: %s", wid, e)
|
||||||
|
|
||||||
async def _xdotool_search(self, *args, env=None) -> Optional[int]:
|
async def _xdotool_search(self, *args, env=None) -> Optional[int]:
|
||||||
"""Run xdotool search and return first window ID, or None."""
|
"""Run xdotool search and return first window ID, or None."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -399,6 +420,7 @@ class ManagedGuiApp:
|
||||||
if action == "click":
|
if action == "click":
|
||||||
btn = str(msg.get("button", 1))
|
btn = str(msg.get("button", 1))
|
||||||
await self._xdotool(
|
await self._xdotool(
|
||||||
|
"windowactivate", "--sync", wid,
|
||||||
"mousemove", "--window", wid, x, y,
|
"mousemove", "--window", wid, x, y,
|
||||||
"click", "--window", wid, btn,
|
"click", "--window", wid, btn,
|
||||||
env=env,
|
env=env,
|
||||||
|
|
@ -406,6 +428,7 @@ class ManagedGuiApp:
|
||||||
elif action == "dblclick":
|
elif action == "dblclick":
|
||||||
btn = str(msg.get("button", 1))
|
btn = str(msg.get("button", 1))
|
||||||
await self._xdotool(
|
await self._xdotool(
|
||||||
|
"windowactivate", "--sync", wid,
|
||||||
"mousemove", "--window", wid, x, y,
|
"mousemove", "--window", wid, x, y,
|
||||||
"click", "--window", wid, "--repeat", "2", btn,
|
"click", "--window", wid, "--repeat", "2", btn,
|
||||||
env=env,
|
env=env,
|
||||||
|
|
@ -449,7 +472,11 @@ class ManagedGuiApp:
|
||||||
|
|
||||||
wid = str(self.window_id)
|
wid = str(self.window_id)
|
||||||
if action == "press":
|
if action == "press":
|
||||||
await self._xdotool("key", "--window", wid, xkey, env=env)
|
await self._xdotool(
|
||||||
|
"windowfocus", "--sync", wid,
|
||||||
|
"key", "--window", wid, xkey,
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
# release events handled implicitly by xdotool key
|
# release events handled implicitly by xdotool key
|
||||||
|
|
||||||
async def _xdotool(self, *args, env=None):
|
async def _xdotool(self, *args, env=None):
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,17 @@
|
||||||
.gui-canvas-wrap {
|
.gui-canvas-wrap {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gui-canvas {
|
.gui-canvas {
|
||||||
max-width: 100%;
|
width: 100%;
|
||||||
max-height: 100%;
|
height: 100%;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
outline: none;
|
outline: none;
|
||||||
image-rendering: auto;
|
image-rendering: auto;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Status overlays */
|
/* Status overlays */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue