summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-27 12:56:09 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-27 12:56:09 +0300
commit3846778c99d9efca609b7cb216cb71c675f036b0 (patch)
treecb126b07588036c24c5922c5c460d30be2204791
parent9a7aa34e63132edb5906914ff99b861e64ee9099 (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.c8
-rw-r--r--src/periodic.c3
-rw-r--r--src/ui/root.c3
-rw-r--r--src/ui/window.c19
4 files changed, 26 insertions, 7 deletions
diff --git a/src/app.c b/src/app.c
index cefb707d..675edf4c 100644
--- a/src/app.c
+++ b/src/app.c
@@ -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
253iRoot *get_Root(void) { 253iRoot *get_Root(void) {
254 iAssert(activeRoot_);
254 return activeRoot_; 255 return activeRoot_;
255} 256}
256 257
257void destroyPending_Root(iRoot *d) { 258void 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
272iPtrArray *onTop_Root(iRoot *d) { 275iPtrArray *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
172static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) { 173static void updateRootSize_Window_(iWindow *d, iBool notifyAlways) {
@@ -449,19 +450,21 @@ void init_Window(iWindow *d, iRect rect) {
449} 450}
450 451
451void deinit_Window(iWindow *d) { 452void 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
467SDL_Renderer *renderer_Window(const iWindow *d) { 470SDL_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);