summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-09-26 07:26:13 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-09-26 07:27:56 +0300
commit44b80a27509a5afa8763bd31b1d28883dbe43e10 (patch)
tree43621cf528630d375e725795675205b1b464ff6e /src
parentb6c2742f6beb0bc162ea9fdc43050e14c784eb33 (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.c4
-rw-r--r--src/ui/util.c6
-rw-r--r--src/ui/widget.c22
-rw-r--r--src/ui/window.c2
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
245void deinit_Root(iRoot *d) { 245void 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
249void setCurrent_Root(iRoot *root) { 251void 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
106void releaseChildren_Widget(iWidget *d) { 106void 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
320void setRoot_Widget(iWidget *d, iRoot *root) { 325void 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;