From 526e9b81ead10cf66f010b8e556d08753b9b368c Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 6 May 2015 00:52:24 -0400 Subject: [PATCH] Fixed bin destruction handling on the Windows backend. --- uipriv.h | 2 +- windows/bin.c | 4 +++- windows/tab.c | 6 +++++- windows/window.c | 3 ++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/uipriv.h b/uipriv.h index f37ca174..e4f94259 100644 --- a/uipriv.h +++ b/uipriv.h @@ -22,7 +22,7 @@ struct ptrArray { uintmax_t cap; }; struct ptrArray *newPtrArray(void); -void ptrArrayDestroy(sstruct ptrArray *); +void ptrArrayDestroy(struct ptrArray *); void ptrArrayAppend(struct ptrArray *, void *); void ptrArrayInsertBefore(struct ptrArray *, uintmax_t, void *); void ptrArrayDelete(struct ptrArray *, uintmax_t); diff --git a/windows/bin.c b/windows/bin.c index 7062ad2c..359d0ab5 100644 --- a/windows/bin.c +++ b/windows/bin.c @@ -18,7 +18,7 @@ static void binDestroy(uiControl *c) // ensure clean removal by making sure the bin has no OS parent hwnd = (HWND) uiControlHandle(uiControl(b)); - if (GetAncestor(hwnd, GA_PARENT) != NULL) + if (GetAncestor(hwnd, GA_PARENT) != initialParent) complain("attempt to destroy bin %p while it has an OS parent", b); // don't chain up to base here; we need to destroy children ourselves first if (b->mainControl != NULL) { @@ -119,6 +119,8 @@ void binSetParent(uiContainer *c, uintptr_t osParent) HWND newParent = (HWND) osParent; hwnd = (HWND) uiControlHandle(uiControl(b)); + if (newParent == NULL) + newParent = initialParent; if (SetParent(hwnd, newParent) == 0) logLastError("error changing bin's parent in binSetParent()"); } diff --git a/windows/tab.c b/windows/tab.c index 499fb43e..3760f9a0 100644 --- a/windows/tab.c +++ b/windows/tab.c @@ -54,8 +54,11 @@ static void onDestroy(void *data) ShowWindow(t->hwnd, SW_HIDE); // because the pages don't have by a libui paent, we can simply destroy them // we don't have to worry about the Windows tab control holding a reference to our bin; there is no reference holding anyway - for (i = 0; i < t->len; i++) + for (i = 0; i < t->len; i++) { + // we do have to remove the page from the tab control, though + binSetParent(t->pages[i], 0); uiControlDestroy(uiControl(t->pages[i])); + } // and finally destroy ourselves uiFree(t->pages); uiFree(t->margined); @@ -243,6 +246,7 @@ static void tabDeletePage(uiTab *tt, uintmax_t n) binSetMainControl(page, NULL); // see tabDestroy() above for details + binSetParent(page, 0); uiControlDestroy(uiControl(page)); } diff --git a/windows/window.c b/windows/window.c index 757f23a2..bfbe0e77 100644 --- a/windows/window.c +++ b/windows/window.c @@ -84,7 +84,8 @@ static void windowDestroy(uiControl *c) // first hide ourselves ShowWindow(w->hwnd, SW_HIDE); // now destroy the bin - // the bin has no parent, so we can just call uiControlDestroy() + // we need to remove the OS parent first + binSetParent(w->bin, 0); uiControlDestroy(uiControl(w->bin)); // now free the menubar, if any if (w->menubar != NULL)