M6: fix 2-GUI khi mở VST FX native (mastering) — một plugin chỉ một GUI
Bug .24: mastering panel load VST FX → 1 floating native (FX slot N) + 1 embed
cùng lúc; floating không đóng được qua UI.
Backend (/fx-gui):
- native branch terminate bridge fx-gui fallback cũ cùng plugin_path trước
ed.open (loại instance VST thứ 2 + window rời)
- fallback spawn chặn khi editor native đang mở ở session sống → trả native
(không spawn embed/float thứ 2)
- _terminate_fx_gui_for_path dùng chung cho /fx-gui/close
Frontend (M6 — xử lý r.native):
- openMasterVstGui/openVstGui/auto-open/reopen: nhánh native → state
{path, url:null, native:true} (không còn toast 'Không mở được GUI embed'),
marker gui_open_path/vstGuiOpenPath giữ như embed
- closeMasterGui/closeFxGui native → SonicAPI.closeFxGui (engine capture preset
+ ed.close); unmount/hide panel → SonicAPI.hideFxGui
- panel render: GUI native mở = indicator + nút Đóng GUI (thay VstGuiEmbed)
- api.js: closeFxGui/hideFxGui/showFxGui endpoints
This commit is contained in:
+38
-9
@@ -722,6 +722,12 @@ async def open_fx_gui(req: FxGuiRequest, current_user: dict = Depends(get_curren
|
||||
if _sess is not None and _sess.alive():
|
||||
_slot = _sess.chain_slot_for_path(plugin_path)
|
||||
if _slot is not None:
|
||||
# Bug 2-GUI: fallback bridge fx-gui (embed/float) còn sống cho cùng
|
||||
# plugin — instance VST THỨ 2 + window riêng; mở native phải loại nó
|
||||
# trước, nếu không 1 plugin hiện 2 GUI (1 floating native + 1 embed)
|
||||
# và floating không tắt được qua UI. Terminate proc cũ → frontend
|
||||
# embed panel của nó onDead → tự đóng.
|
||||
_terminate_fx_gui_for_path(plugin_path)
|
||||
_already = fx_realtime.editor_find(plugin_path)
|
||||
_same = _already is not None and _already[0] == _sess.name
|
||||
_sess.send_editor_cmd("open", slot=_slot)
|
||||
@@ -729,6 +735,15 @@ async def open_fx_gui(req: FxGuiRequest, current_user: dict = Depends(get_curren
|
||||
return {"success": True, "started": not _same,
|
||||
"already_running": bool(_same), "native": True,
|
||||
"embed_url": None, "session_id": _sess.name, "slot": _slot}
|
||||
# Tránh mở 2 GUI cùng plugin: editor NATIVE (instance DSP trong session
|
||||
# fxrt) của plugin này đang mở ở session SỐNG → KHÔNG spawn instance 2 /
|
||||
# bridge fx-gui nữa (nguồn CPU 100% + 2 GUI); trả native để frontend hiện
|
||||
# đúng trạng thái cửa sổ ngoài (M6).
|
||||
_nsess, _nslot = _fxrt_native_editor(plugin_path)
|
||||
if _nsess is not None:
|
||||
return {"success": True, "started": False, "already_running": True,
|
||||
"native": True, "embed_url": None,
|
||||
"session_id": _nsess.name, "slot": _nslot}
|
||||
# Tránh mở 2 GUI cùng plugin: nếu tiến trình bridge fx-gui cho plugin này
|
||||
# đang chạy → trả started=False (frontend có thể focus window cũ).
|
||||
for proc in _FX_GUI_PROCESSES:
|
||||
@@ -842,15 +857,8 @@ async def close_fx_gui(req: FxGuiCloseRequest, current_user: dict = Depends(get_
|
||||
return {"success": True, "closed": True, "native": True,
|
||||
"preset_b64": _preset}
|
||||
# session đã chết — rơi xuống spawn fallback (đóng bridge fx-gui cũ nếu có)
|
||||
for proc in _FX_GUI_PROCESSES:
|
||||
if proc is not None and proc.poll() is None and getattr(proc, "_sf_plugin_path", None) == plugin_path:
|
||||
proc.terminate()
|
||||
try:
|
||||
proc.wait(timeout=5)
|
||||
except Exception:
|
||||
proc.kill()
|
||||
_prune_fx_gui_processes()
|
||||
return {"success": True, "closed": True}
|
||||
if _terminate_fx_gui_for_path(plugin_path):
|
||||
return {"success": True, "closed": True}
|
||||
return {"success": True, "closed": False}
|
||||
|
||||
|
||||
@@ -908,6 +916,27 @@ def _prune_fx_gui_processes():
|
||||
global _FX_GUI_PROCESSES
|
||||
_FX_GUI_PROCESSES = [p for p in _FX_GUI_PROCESSES if p is not None and p.poll() is None]
|
||||
|
||||
def _terminate_fx_gui_for_path(plugin_path):
|
||||
"""Terminate MỌI bridge fx-gui (embed/float fallback) còn sống cho plugin.
|
||||
Dùng khi mở native editor thay thế fallback — tránh 2 instance VST + 2 GUI
|
||||
cùng 1 plugin (Bug 2-GUI). Trả True nếu có proc đã bị chấm dứt."""
|
||||
_prune_fx_gui_processes()
|
||||
killed = False
|
||||
for proc in list(_FX_GUI_PROCESSES):
|
||||
if proc.poll() is None and getattr(proc, "_sf_plugin_path", None) == plugin_path:
|
||||
try:
|
||||
proc.terminate()
|
||||
try:
|
||||
proc.wait(timeout=5)
|
||||
except Exception:
|
||||
proc.kill()
|
||||
killed = True
|
||||
except Exception:
|
||||
pass
|
||||
if killed:
|
||||
_prune_fx_gui_processes()
|
||||
return killed
|
||||
|
||||
|
||||
|
||||
@router.post("/preview")
|
||||
|
||||
Reference in New Issue
Block a user