diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-27 12:56:09 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-27 12:56:09 +0300 |
commit | 3846778c99d9efca609b7cb216cb71c675f036b0 (patch) | |
tree | cb126b07588036c24c5922c5c460d30be2204791 | |
parent | 9a7aa34e63132edb5906914ff99b861e64ee9099 (diff) |
Keeping track of current UI root
The current UI root should always be set explicitly before the UI
is accessed.
-rw-r--r-- | src/app.c | 8 | ||||
-rw-r--r-- | src/periodic.c | 3 | ||||
-rw-r--r-- | src/ui/root.c | 3 | ||||
-rw-r--r-- | src/ui/window.c | 19 |
4 files changed, 26 insertions, 7 deletions
@@ -392,6 +392,7 @@ static iBool loadState_App_(iApp *d) { | |||
392 | printf("%s: unsupported version\n", cstr_String(path_File(f))); | 392 | printf("%s: unsupported version\n", cstr_String(path_File(f))); |
393 | return iFalse; | 393 | return iFalse; |
394 | } | 394 | } |
395 | setCurrent_Root(&d->window->root); | ||
395 | setVersion_Stream(stream_File(f), version); | 396 | setVersion_Stream(stream_File(f), version); |
396 | iDocumentWidget *doc = document_App(); | 397 | iDocumentWidget *doc = document_App(); |
397 | iDocumentWidget *current = NULL; | 398 | iDocumentWidget *current = NULL; |
@@ -409,10 +410,12 @@ static iBool loadState_App_(iApp *d) { | |||
409 | } | 410 | } |
410 | else { | 411 | else { |
411 | printf("%s: unrecognized data\n", cstr_String(path_File(f))); | 412 | printf("%s: unrecognized data\n", cstr_String(path_File(f))); |
413 | setCurrent_Root(NULL); | ||
412 | return iFalse; | 414 | return iFalse; |
413 | } | 415 | } |
414 | } | 416 | } |
415 | postCommandf_App("tabs.switch page:%p", current); | 417 | postCommandf_App("tabs.switch page:%p", current); |
418 | setCurrent_Root(NULL); | ||
416 | return iTrue; | 419 | return iTrue; |
417 | } | 420 | } |
418 | return iFalse; | 421 | return iFalse; |
@@ -436,12 +439,14 @@ static void saveState_App_(const iApp *d) { | |||
436 | if (open_File(f, writeOnly_FileMode)) { | 439 | if (open_File(f, writeOnly_FileMode)) { |
437 | writeData_File(f, magicState_App_, 4); | 440 | writeData_File(f, magicState_App_, 4); |
438 | writeU32_File(f, latest_FileVersion); /* version */ | 441 | writeU32_File(f, latest_FileVersion); /* version */ |
442 | setCurrent_Root(&d->window->root); | ||
439 | iConstForEach(ObjectList, i, iClob(listDocuments_App())) { | 443 | iConstForEach(ObjectList, i, iClob(listDocuments_App())) { |
440 | iAssert(isInstance_Object(i.object, &Class_DocumentWidget)); | 444 | iAssert(isInstance_Object(i.object, &Class_DocumentWidget)); |
441 | writeData_File(f, magicTabDocument_App_, 4); | 445 | writeData_File(f, magicTabDocument_App_, 4); |
442 | write8_File(f, document_App() == i.object ? 1 : 0); | 446 | write8_File(f, document_App() == i.object ? 1 : 0); |
443 | serializeState_DocumentWidget(i.object, stream_File(f)); | 447 | serializeState_DocumentWidget(i.object, stream_File(f)); |
444 | } | 448 | } |
449 | setCurrent_Root(NULL); | ||
445 | } | 450 | } |
446 | else { | 451 | else { |
447 | fprintf(stderr, "[App] failed to save state: %s\n", strerror(errno)); | 452 | fprintf(stderr, "[App] failed to save state: %s\n", strerror(errno)); |
@@ -1082,12 +1087,14 @@ static void runTickers_App_(iApp *d) { | |||
1082 | iSortedArray *pending = copy_SortedArray(&d->tickers); | 1087 | iSortedArray *pending = copy_SortedArray(&d->tickers); |
1083 | clear_SortedArray(&d->tickers); | 1088 | clear_SortedArray(&d->tickers); |
1084 | postRefresh_App(); | 1089 | postRefresh_App(); |
1090 | setCurrent_Root(&d->window->root); /* TODO: Each ticker has its own root. */ | ||
1085 | iConstForEach(Array, i, &pending->values) { | 1091 | iConstForEach(Array, i, &pending->values) { |
1086 | const iTicker *ticker = i.value; | 1092 | const iTicker *ticker = i.value; |
1087 | if (ticker->callback) { | 1093 | if (ticker->callback) { |
1088 | ticker->callback(ticker->context); | 1094 | ticker->callback(ticker->context); |
1089 | } | 1095 | } |
1090 | } | 1096 | } |
1097 | setCurrent_Root(NULL); | ||
1091 | delete_SortedArray(pending); | 1098 | delete_SortedArray(pending); |
1092 | if (isEmpty_SortedArray(&d->tickers)) { | 1099 | if (isEmpty_SortedArray(&d->tickers)) { |
1093 | d->lastTickerTime = 0; | 1100 | d->lastTickerTime = 0; |
@@ -1121,6 +1128,7 @@ static int run_App_(iApp *d) { | |||
1121 | #endif | 1128 | #endif |
1122 | while (d->isRunning) { | 1129 | while (d->isRunning) { |
1123 | processEvents_App(waitForNewEvents_AppEventMode); | 1130 | processEvents_App(waitForNewEvents_AppEventMode); |
1131 | setCurrent_Root(NULL); | ||
1124 | runTickers_App_(d); | 1132 | runTickers_App_(d); |
1125 | refresh_App(); | 1133 | refresh_App(); |
1126 | recycle_Garbage(); | 1134 | recycle_Garbage(); |
diff --git a/src/periodic.c b/src/periodic.c index 9e9dfdba..ab3b66e6 100644 --- a/src/periodic.c +++ b/src/periodic.c | |||
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #include "periodic.h" | 23 | #include "periodic.h" |
24 | #include "ui/widget.h" | 24 | #include "ui/widget.h" |
25 | #include "ui/window.h" | ||
25 | #include "app.h" | 26 | #include "app.h" |
26 | 27 | ||
27 | #include <the_Foundation/string.h> | 28 | #include <the_Foundation/string.h> |
@@ -64,6 +65,7 @@ iBool dispatchCommands_Periodic(iPeriodic *d) { | |||
64 | d->lastPostTime = now; | 65 | d->lastPostTime = now; |
65 | iBool wasPosted = iFalse; | 66 | iBool wasPosted = iFalse; |
66 | lock_Mutex(d->mutex); | 67 | lock_Mutex(d->mutex); |
68 | setCurrent_Root(&get_Window()->root); | ||
67 | iConstForEach(Array, i, &d->commands.values) { | 69 | iConstForEach(Array, i, &d->commands.values) { |
68 | const iPeriodicCommand *pc = i.value; | 70 | const iPeriodicCommand *pc = i.value; |
69 | const SDL_UserEvent ev = { | 71 | const SDL_UserEvent ev = { |
@@ -75,6 +77,7 @@ iBool dispatchCommands_Periodic(iPeriodic *d) { | |||
75 | dispatchEvent_Widget(pc->context, (const SDL_Event *) &ev); | 77 | dispatchEvent_Widget(pc->context, (const SDL_Event *) &ev); |
76 | wasPosted = iTrue; | 78 | wasPosted = iTrue; |
77 | } | 79 | } |
80 | setCurrent_Root(NULL); | ||
78 | unlock_Mutex(d->mutex); | 81 | unlock_Mutex(d->mutex); |
79 | return wasPosted; | 82 | return wasPosted; |
80 | } | 83 | } |
diff --git a/src/ui/root.c b/src/ui/root.c index 1fa36851..bd7d07a1 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -251,10 +251,12 @@ void setCurrent_Root(iRoot *root) { | |||
251 | } | 251 | } |
252 | 252 | ||
253 | iRoot *get_Root(void) { | 253 | iRoot *get_Root(void) { |
254 | iAssert(activeRoot_); | ||
254 | return activeRoot_; | 255 | return activeRoot_; |
255 | } | 256 | } |
256 | 257 | ||
257 | void destroyPending_Root(iRoot *d) { | 258 | void destroyPending_Root(iRoot *d) { |
259 | setCurrent_Root(d); | ||
258 | iForEach(PtrSet, i, d->pendingDestruction) { | 260 | iForEach(PtrSet, i, d->pendingDestruction) { |
259 | iWidget *widget = *i.value; | 261 | iWidget *widget = *i.value; |
260 | if (!isFinished_Anim(&widget->visualOffset)) { | 262 | if (!isFinished_Anim(&widget->visualOffset)) { |
@@ -267,6 +269,7 @@ void destroyPending_Root(iRoot *d) { | |||
267 | iRelease(widget); | 269 | iRelease(widget); |
268 | remove_PtrSetIterator(&i); | 270 | remove_PtrSetIterator(&i); |
269 | } | 271 | } |
272 | setCurrent_Root(NULL); | ||
270 | } | 273 | } |
271 | 274 | ||
272 | iPtrArray *onTop_Root(iRoot *d) { | 275 | iPtrArray *onTop_Root(iRoot *d) { |
diff --git a/src/ui/window.c b/src/ui/window.c index 627f16b1..1e98b167 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -167,6 +167,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
167 | #endif | 167 | #endif |
168 | setCurrent_Root(&d->root); | 168 | setCurrent_Root(&d->root); |
169 | createUserInterface_Root(&d->root); | 169 | createUserInterface_Root(&d->root); |
170 | setCurrent_Root(NULL); | ||
170 | } | 171 | } |
171 | 172 | ||
172 | static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { | 173 | static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { |
@@ -449,19 +450,21 @@ void init_Window(iWindow *d, iRect rect) { | |||
449 | } | 450 | } |
450 | 451 | ||
451 | void deinit_Window(iWindow *d) { | 452 | void deinit_Window(iWindow *d) { |
453 | setCurrent_Root(&d->root); | ||
452 | iRecycle(); | 454 | iRecycle(); |
453 | if (theWindow_ == d) { | 455 | if (theWindow_ == d) { |
454 | theWindow_ = NULL; | 456 | theWindow_ = NULL; |
455 | } | 457 | } |
458 | deinit_Root(&d->root); | ||
459 | setCurrent_Root(NULL); | ||
460 | deinit_Text(); | ||
461 | SDL_DestroyRenderer(d->render); | ||
462 | SDL_DestroyWindow(d->win); | ||
456 | iForIndices(i, d->cursors) { | 463 | iForIndices(i, d->cursors) { |
457 | if (d->cursors[i]) { | 464 | if (d->cursors[i]) { |
458 | SDL_FreeCursor(d->cursors[i]); | 465 | SDL_FreeCursor(d->cursors[i]); |
459 | } | 466 | } |
460 | } | 467 | } |
461 | deinit_Root(&d->root); | ||
462 | deinit_Text(); | ||
463 | SDL_DestroyRenderer(d->render); | ||
464 | SDL_DestroyWindow(d->win); | ||
465 | } | 468 | } |
466 | 469 | ||
467 | SDL_Renderer *renderer_Window(const iWindow *d) { | 470 | SDL_Renderer *renderer_Window(const iWindow *d) { |
@@ -766,6 +769,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
766 | event.button.x = pos.x; | 769 | event.button.x = pos.x; |
767 | event.button.y = pos.y; | 770 | event.button.y = pos.y; |
768 | } | 771 | } |
772 | setCurrent_Root(&d->root); | ||
769 | iWidget *widget = d->root.widget; | 773 | iWidget *widget = d->root.widget; |
770 | if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEWHEEL || | 774 | if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEWHEEL || |
771 | event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) { | 775 | event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) { |
@@ -866,10 +870,11 @@ void draw_Window(iWindow *d) { | |||
866 | /* Draw widgets. */ | 870 | /* Draw widgets. */ |
867 | d->frameTime = SDL_GetTicks(); | 871 | d->frameTime = SDL_GetTicks(); |
868 | if (isExposed_Window(d)) { | 872 | if (isExposed_Window(d)) { |
873 | setCurrent_Root(&d->root); | ||
869 | draw_Widget(d->root.widget); | 874 | draw_Widget(d->root.widget); |
870 | #if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) | 875 | #if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) |
871 | /* App icon. */ | 876 | /* App icon. */ |
872 | const iWidget *appIcon = findChild_Widget(d->root, "winbar.icon"); | 877 | const iWidget *appIcon = findChild_Widget(d->root.widget, "winbar.icon"); |
873 | if (isVisible_Widget(appIcon)) { | 878 | if (isVisible_Widget(appIcon)) { |
874 | const int size = appIconSize_(); | 879 | const int size = appIconSize_(); |
875 | const iRect rect = bounds_Widget(appIcon); | 880 | const iRect rect = bounds_Widget(appIcon); |
@@ -885,11 +890,11 @@ void draw_Window(iWindow *d) { | |||
885 | &(SDL_Rect){ left_Rect(rect) + gap_UI * 1.25f, mid.y - size / 2, size, size }); | 890 | &(SDL_Rect){ left_Rect(rect) + gap_UI * 1.25f, mid.y - size / 2, size, size }); |
886 | } | 891 | } |
887 | #endif | 892 | #endif |
893 | setCurrent_Root(NULL); | ||
888 | } | 894 | } |
889 | #if 0 | 895 | #if 0 |
890 | /* Text cache debugging. */ { | 896 | /* Text cache debugging. */ { |
891 | SDL_Texture *cache = glyphCache_Text(); | 897 | SDL_Rect rect = { d->root.widget->rect.size.x - 640, 0, 640, 2.5 * 640 }; |
892 | SDL_Rect rect = { d->root->rect.size.x - 640, 0, 640, 2.5 * 640 }; | ||
893 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); | 898 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); |
894 | SDL_RenderFillRect(d->render, &rect); | 899 | SDL_RenderFillRect(d->render, &rect); |
895 | SDL_RenderCopy(d->render, glyphCache_Text(), NULL, &rect); | 900 | SDL_RenderCopy(d->render, glyphCache_Text(), NULL, &rect); |