diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-26 07:26:13 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-26 07:27:56 +0300 |
commit | 44b80a27509a5afa8763bd31b1d28883dbe43e10 (patch) | |
tree | 43621cf528630d375e725795675205b1b464ff6e /src | |
parent | b6c2742f6beb0bc162ea9fdc43050e14c784eb33 (diff) |
Root: Crash when closing split view
Some deleted widgets were kept around in the root's onTop list.
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/root.c | 4 | ||||
-rw-r--r-- | src/ui/util.c | 6 | ||||
-rw-r--r-- | src/ui/widget.c | 22 | ||||
-rw-r--r-- | src/ui/window.c | 2 |
4 files changed, 27 insertions, 7 deletions
diff --git a/src/ui/root.c b/src/ui/root.c index 90c0c6e4..c014ffa8 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -244,6 +244,8 @@ void init_Root(iRoot *d) { | |||
244 | 244 | ||
245 | void deinit_Root(iRoot *d) { | 245 | void deinit_Root(iRoot *d) { |
246 | iReleasePtr(&d->widget); | 246 | iReleasePtr(&d->widget); |
247 | delete_PtrArray(d->onTop); | ||
248 | delete_PtrSet(d->pendingDestruction); | ||
247 | } | 249 | } |
248 | 250 | ||
249 | void setCurrent_Root(iRoot *root) { | 251 | void setCurrent_Root(iRoot *root) { |
@@ -284,7 +286,7 @@ void destroyPending_Root(iRoot *d) { | |||
284 | if (widget->parent) { | 286 | if (widget->parent) { |
285 | removeChild_Widget(widget->parent, widget); | 287 | removeChild_Widget(widget->parent, widget); |
286 | } | 288 | } |
287 | iAssert(widget->parent == NULL); | 289 | iAssert(widget->parent == NULL); |
288 | iRelease(widget); | 290 | iRelease(widget); |
289 | remove_PtrSetIterator(&i); | 291 | remove_PtrSetIterator(&i); |
290 | } | 292 | } |
diff --git a/src/ui/util.c b/src/ui/util.c index 53478cba..244eb24d 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -1028,6 +1028,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
1028 | iRoot *oldRoot = current_Root(); | 1028 | iRoot *oldRoot = current_Root(); |
1029 | setFlags_Widget(d, keepOnTop_WidgetFlag, iFalse); | 1029 | setFlags_Widget(d, keepOnTop_WidgetFlag, iFalse); |
1030 | setUserData_Object(d, parent_Widget(d)); | 1030 | setUserData_Object(d, parent_Widget(d)); |
1031 | iAssert(userData_Object(d)); | ||
1031 | removeChild_Widget(parent_Widget(d), d); /* we'll borrow the widget for a while */ | 1032 | removeChild_Widget(parent_Widget(d), d); /* we'll borrow the widget for a while */ |
1032 | const float pixelRatio = get_Window()->pixelRatio; | 1033 | const float pixelRatio = get_Window()->pixelRatio; |
1033 | iInt2 menuPos = add_I2(get_MainWindow()->place.normalRect.pos, | 1034 | iInt2 menuPos = add_I2(get_MainWindow()->place.normalRect.pos, |
@@ -1040,10 +1041,9 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, iBool postCommands) { | |||
1040 | menuPos.x = iMin(menuPos.x, displayRect.x + displayRect.w - menuSize.x); | 1041 | menuPos.x = iMin(menuPos.x, displayRect.x + displayRect.w - menuSize.x); |
1041 | menuPos.y = iMin(menuPos.y, displayRect.y + displayRect.h - menuSize.y); | 1042 | menuPos.y = iMin(menuPos.y, displayRect.y + displayRect.h - menuSize.y); |
1042 | } | 1043 | } |
1043 | // SDL_GetGlobalMouseState(&mousePos.x, &mousePos.y); | 1044 | iWindow *win = newPopup_Window(menuPos, d); /* window takes the widget */ |
1044 | iWindow *win = newPopup_Window(menuPos, d); | ||
1045 | SDL_SetWindowTitle(win->win, "Menu"); | 1045 | SDL_SetWindowTitle(win->win, "Menu"); |
1046 | addPopup_App(win); /* window takes the widget */ | 1046 | addPopup_App(win); |
1047 | SDL_ShowWindow(win->win); | 1047 | SDL_ShowWindow(win->win); |
1048 | draw_Window(win); | 1048 | draw_Window(win); |
1049 | setCurrent_Window(mainWindow_App()); | 1049 | setCurrent_Window(mainWindow_App()); |
diff --git a/src/ui/widget.c b/src/ui/widget.c index 6b9ee11d..bdc5f090 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -105,7 +105,12 @@ static void printInfo_Widget_(const iWidget *); | |||
105 | 105 | ||
106 | void releaseChildren_Widget(iWidget *d) { | 106 | void releaseChildren_Widget(iWidget *d) { |
107 | iForEach(ObjectList, i, d->children) { | 107 | iForEach(ObjectList, i, d->children) { |
108 | ((iWidget *) i.object)->parent = NULL; /* the actual reference being held */ | 108 | iWidget *child = i.object; |
109 | child->parent = NULL; /* the actual reference being held */ | ||
110 | if (child->flags & keepOnTop_WidgetFlag) { | ||
111 | removeOne_PtrArray(onTop_Root(child->root), child); | ||
112 | child->flags &= ~keepOnTop_WidgetFlag; | ||
113 | } | ||
109 | } | 114 | } |
110 | iReleasePtr(&d->children); | 115 | iReleasePtr(&d->children); |
111 | } | 116 | } |
@@ -318,6 +323,13 @@ void setCommandHandler_Widget(iWidget *d, iBool (*handler)(iWidget *, const char | |||
318 | } | 323 | } |
319 | 324 | ||
320 | void setRoot_Widget(iWidget *d, iRoot *root) { | 325 | void setRoot_Widget(iWidget *d, iRoot *root) { |
326 | if (d->flags & keepOnTop_WidgetFlag) { | ||
327 | iAssert(indexOf_PtrArray(onTop_Root(root), d) == iInvalidPos); | ||
328 | /* Move it over the new root's onTop list. */ | ||
329 | removeOne_PtrArray(onTop_Root(d->root), d); | ||
330 | iAssert(indexOf_PtrArray(onTop_Root(d->root), d) == iInvalidPos); | ||
331 | pushBack_PtrArray(onTop_Root(root), d); | ||
332 | } | ||
321 | d->root = root; | 333 | d->root = root; |
322 | iForEach(ObjectList, i, d->children) { | 334 | iForEach(ObjectList, i, d->children) { |
323 | setRoot_Widget(i.object, root); | 335 | setRoot_Widget(i.object, root); |
@@ -1667,7 +1679,13 @@ iAny *removeChild_Widget(iWidget *d, iAnyObject *child) { | |||
1667 | } | 1679 | } |
1668 | } | 1680 | } |
1669 | iAssert(found); | 1681 | iAssert(found); |
1670 | ((iWidget *) child)->parent = NULL; | 1682 | iWidget *childWidget = child; |
1683 | // if (childWidget->flags & keepOnTop_WidgetFlag) { | ||
1684 | // removeOne_PtrArray(onTop_Root(childWidget->root), childWidget); | ||
1685 | // iAssert(indexOf_PtrArray(onTop_Root(childWidget->root), childWidget) == iInvalidPos); | ||
1686 | // } | ||
1687 | // printf("%s:%d [%p] parent = NULL\n", __FILE__, __LINE__, d); | ||
1688 | childWidget->parent = NULL; | ||
1671 | postRefresh_App(); | 1689 | postRefresh_App(); |
1672 | return child; | 1690 | return child; |
1673 | } | 1691 | } |
diff --git a/src/ui/window.c b/src/ui/window.c index fb55bb52..77e49dbb 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -1597,7 +1597,7 @@ iWindow *newPopup_Window(iInt2 screenPos, iWidget *rootWidget) { | |||
1597 | SDL_WINDOW_POPUP_MENU | | 1597 | SDL_WINDOW_POPUP_MENU | |
1598 | SDL_WINDOW_SKIP_TASKBAR); | 1598 | SDL_WINDOW_SKIP_TASKBAR); |
1599 | #if defined (iPlatformAppleDesktop) | 1599 | #if defined (iPlatformAppleDesktop) |
1600 | hideTitleBar_MacOS(win); /* make it a borderless window */ | 1600 | hideTitleBar_MacOS(win); /* make it a borderless window, but retain shadow */ |
1601 | #endif | 1601 | #endif |
1602 | iRoot *root = new_Root(); | 1602 | iRoot *root = new_Root(); |
1603 | win->roots[0] = root; | 1603 | win->roots[0] = root; |