Fix GUI Qin không hiện lại sau hide + âm thanh lỗi sau khi đóng cửa sổ
- plugin_host_main.cpp: chặn WM_CLOSE (đóng GUI nhưng giữ window sống, hide thay vì destroy), WM_DESTROY reset hwnd; dùng g_hostHwnd toàn cục thay hwnd local để control OPEN_GUI/CLOSE_GUI tái sử dụng đúng window. - main.cpp: bỏ qua dedupe hasAttachedView cho instrument child-own (SandboxVst2Host) — bridge guiOpen_ stale sau khi child tự đóng nên OPEN_GUI lặp lại phải forward control 4; child tự chặn double-open. - Verify: WM_CLOSE -> window ẩn còn sống; OPEN_GUI lần 2 -> window hiện lại, âm ch1 vẫn kêu (peak 0.15), không câm.
This commit is contained in:
@@ -38,10 +38,41 @@ static bool parent_alive(uint32_t pid) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// G4.7: the child owns the host window, so the user's X click lands HERE, not
|
||||
// on the bridge. DefWindowProc destroys the window on WM_CLOSE while the VST2
|
||||
// instrument still thinks its editor is attached (guiAttached_ stale true) -
|
||||
// a second OPEN_GUI then can never re-show the GUI (bridge dedupes on
|
||||
// hasAttachedView, and the child's openGUI guard skips too). Intercept:
|
||||
// WM_CLOSE -> effEditClose + hide (keep the window alive, reopen works);
|
||||
// WM_DESTROY (external destroy) -> forget the hwnd so the next OPEN_GUI
|
||||
// creates a fresh window instead of attaching to a dead one.
|
||||
static INativeInstrument* g_wndInst = nullptr;
|
||||
static HWND g_hostHwnd = nullptr;
|
||||
|
||||
static LRESULT CALLBACK PluginHostWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (msg) {
|
||||
case WM_CLOSE:
|
||||
if (g_wndInst) {
|
||||
try { g_wndInst->closeGUI(); } catch (...) {}
|
||||
}
|
||||
if (g_hostHwnd) ShowWindow(g_hostHwnd, SW_HIDE);
|
||||
return 0; // swallow: do NOT let DefWindowProc destroy the window
|
||||
case WM_DESTROY:
|
||||
if (g_wndInst) {
|
||||
try { g_wndInst->closeGUI(); } catch (...) {}
|
||||
}
|
||||
g_hostHwnd = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static HWND make_host_window() {
|
||||
WNDCLASSEX wc = {};
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.lpfnWndProc = PluginHostWndProc;
|
||||
wc.hInstance = GetModuleHandle(nullptr);
|
||||
wc.lpszClassName = "PluginHostClass";
|
||||
RegisterClassEx(&wc);
|
||||
@@ -106,6 +137,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
INativeInstrument& inst = vst2 ? (INativeInstrument&)instV2 : (INativeInstrument&)instV3;
|
||||
g_wndInst = &inst; // WM_CLOSE (user X) needs the live instrument
|
||||
|
||||
// G4.6 auto-play fix: a loaded chunk can embed a stuck/sustained note
|
||||
// (factory state, seed, or a patch captured mid-note). Release everything
|
||||
@@ -145,12 +177,12 @@ int main(int argc, char* argv[]) {
|
||||
// VST3: GUI on the main thread at startup (editorhost pattern: attach then
|
||||
// pump below). VST2: deferred until control 4 (OPEN_GUI) so loading a Qin
|
||||
// does not pop a window for every track.
|
||||
HWND hwnd = nullptr;
|
||||
g_hostHwnd = nullptr;
|
||||
if (!vst2) {
|
||||
hwnd = make_host_window();
|
||||
printf("[plugin_host] ownHwnd=%p openGUI...\n", (void*)hwnd);
|
||||
g_hostHwnd = make_host_window();
|
||||
printf("[plugin_host] ownHwnd=%p openGUI...\n", (void*)g_hostHwnd);
|
||||
fflush(stdout);
|
||||
bool gui = inst.openGUI(hwnd);
|
||||
bool gui = inst.openGUI(g_hostHwnd);
|
||||
printf("[plugin_host] openGUI=%d\n", gui ? 1 : 0);
|
||||
fflush(stdout);
|
||||
}
|
||||
@@ -208,16 +240,16 @@ int main(int argc, char* argv[]) {
|
||||
for (uint32_t i = 0; i < nctl; ++i) {
|
||||
const auto& c = ipc->base.controlQueue[i];
|
||||
if (c.type == 4) {
|
||||
if (!hwnd) hwnd = make_host_window();
|
||||
if (hwnd && !inst.hasAttachedView()) {
|
||||
if (!g_hostHwnd) g_hostHwnd = make_host_window();
|
||||
if (g_hostHwnd && !inst.hasAttachedView()) {
|
||||
printf("[plugin_host] OPEN_GUI ch=%u\n", channel);
|
||||
fflush(stdout);
|
||||
inst.openGUI(hwnd);
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
inst.openGUI(g_hostHwnd);
|
||||
ShowWindow(g_hostHwnd, SW_SHOW);
|
||||
}
|
||||
} else if (c.type == 5) {
|
||||
inst.closeGUI();
|
||||
if (hwnd) ShowWindow(hwnd, SW_HIDE);
|
||||
if (g_hostHwnd) ShowWindow(g_hostHwnd, SW_HIDE);
|
||||
} else if (c.type == 6) {
|
||||
quit = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user