diff --git a/DouYinSparkFlow/login_desktop_server.py b/DouYinSparkFlow/login_desktop_server.py
index 6cbcac6..7933af0 100644
--- a/DouYinSparkFlow/login_desktop_server.py
+++ b/DouYinSparkFlow/login_desktop_server.py
@@ -135,6 +135,8 @@ class LoginDesktopManager:
"--disable-dev-shm-usage",
"--no-sandbox",
"--start-maximized",
+ "--window-position=0,0",
+ "--window-size=1600,1000",
"--disable-gpu",
"--disable-gpu-compositing",
"--disable-software-rasterizer",
diff --git a/DouYinSparkFlow/tests/test_deployment_contract.py b/DouYinSparkFlow/tests/test_deployment_contract.py
index d8f4daa..b9dceba 100644
--- a/DouYinSparkFlow/tests/test_deployment_contract.py
+++ b/DouYinSparkFlow/tests/test_deployment_contract.py
@@ -122,6 +122,7 @@ class DeploymentContractTests(unittest.TestCase):
self.assertIn("mem_limit: ${LOGIN_DESKTOP_MEMORY_LIMIT:-1200m}", compose)
self.assertIn("pids_limit: ${LOGIN_DESKTOP_PIDS_LIMIT:-256}", compose)
self.assertIn("-nap -wait 50 -defer 50", start_script)
+ self.assertIn("--window-size=1600,1000", server)
self.assertIn("start_idle_monitor", server)
self.assertIn("schedule_stop_after_export", server)
self.assertIn('reduced_motion="reduce"', server)
diff --git a/DouYinSparkFlow/tests/test_webui_safety.py b/DouYinSparkFlow/tests/test_webui_safety.py
index 4f22ea7..a94113f 100644
--- a/DouYinSparkFlow/tests/test_webui_safety.py
+++ b/DouYinSparkFlow/tests/test_webui_safety.py
@@ -250,12 +250,15 @@ class WebUiSafetyTests(unittest.TestCase):
self.assertIn("data-refresh-login-qr", dashboard)
self.assertIn("/login-desktop/qr", dashboard)
- def test_mobile_login_popup_opens_before_async_request(self):
+ def test_login_workspace_loads_inside_dashboard_frame(self):
script = (Path(app_module.STATIC_DIR) / "app.js").read_text(encoding="utf-8")
block_start = script.index('document.querySelectorAll(".login-desktop-open")')
block_end = script.index('document.querySelectorAll(".login-desktop-save")', block_start)
block = script[block_start:block_end]
- self.assertLess(block.index('window.open("about:blank"'), block.index('postForm("/login-desktop/open"'))
+ self.assertLess(block.index('postForm("/login-desktop/open"'), block.index("loadFrame(true)"))
+ self.assertNotIn('window.open("about:blank"', block)
+ self.assertNotIn("popup.location", block)
+ self.assertIn("new URL(configuredPublicUrl, window.location.href).href", script)
self.assertIn("refreshLoginQr(500)", block)
self.assertIn('data.state === "queued"', block)
self.assertIn("renderWorkspace(data.workspace)", block)
diff --git a/DouYinSparkFlow/webui/static/app.js b/DouYinSparkFlow/webui/static/app.js
index 5f1b07e..59bc3f9 100644
--- a/DouYinSparkFlow/webui/static/app.js
+++ b/DouYinSparkFlow/webui/static/app.js
@@ -338,7 +338,15 @@
if (!root) return;
const section = document.getElementById("interactive-login-section");
const csrfToken = root.dataset.csrfToken || "";
- const publicUrl = root.dataset.publicUrl || "";
+ const configuredPublicUrl = root.dataset.publicUrl || "";
+ const publicUrl = (() => {
+ if (!configuredPublicUrl) return "";
+ try {
+ return new URL(configuredPublicUrl, window.location.href).href;
+ } catch {
+ return configuredPublicUrl;
+ }
+ })();
const runtimeState = document.getElementById("login-desktop-runtime-state");
const statusText = document.getElementById("login-desktop-status-text");
const frame = document.querySelector("[data-login-frame]");
@@ -472,7 +480,6 @@
document.querySelectorAll(".login-desktop-open").forEach((button) => {
button.addEventListener("click", async () => {
if (section) section.open = true;
- const popup = publicUrl ? window.open("about:blank", "_blank", "noopener") : null;
try {
const reloginUniqueId = button.dataset.reloginUniqueId || "";
const mode = button.dataset.loginMode || (reloginUniqueId ? "relogin" : "add");
@@ -481,16 +488,11 @@
...(reloginUniqueId ? { relogin_unique_id: reloginUniqueId } : {}),
});
renderWorkspace(data.workspace);
- if (data.state === "queued") {
- if (popup && !popup.closed) popup.close();
- return;
- }
- if (popup && !popup.closed) popup.location.href = publicUrl;
+ if (data.state === "queued") return;
loadFrame(true);
refreshLoginQr(500);
- if (!popup && frame) frame.scrollIntoView({ behavior: "smooth", block: "start" });
+ if (frame) frame.scrollIntoView({ behavior: "smooth", block: "start" });
} catch (error) {
- if (popup && !popup.closed) popup.close();
setStatus(`申请登录工作区失败:${error.message}`, "danger");
}
});
diff --git a/DouYinSparkFlow/webui/templates/base.html b/DouYinSparkFlow/webui/templates/base.html
index 3683737..5087abe 100644
--- a/DouYinSparkFlow/webui/templates/base.html
+++ b/DouYinSparkFlow/webui/templates/base.html
@@ -139,7 +139,7 @@
-
+
{% block scripts %}{% endblock %}