summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-07 21:00:39 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-07 21:00:39 +0200
commit824da6cbec4a6a28d0fde710777b2bbf771006a0 (patch)
tree991e976de02b48b9e6dcd814aadeb94e3e4e8368
parent71e149f463b18193a0a9e27822390708a2cca83c (diff)
Document-specific palettes
Manage a color palette separately for each GmDocument, and activate one of them globally whenever a document is being drawn. Palettes are cached in memory.
-rw-r--r--src/gmdocument.c8
-rw-r--r--src/gmutil.c11
-rw-r--r--src/gmutil.h2
-rw-r--r--src/history.c50
-rw-r--r--src/history.h5
-rw-r--r--src/ui/documentwidget.c116
6 files changed, 125 insertions, 67 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 884f8c07..e3c06d49 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -1710,9 +1710,12 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
1710} 1710}
1711 1711
1712void makePaletteGlobal_GmDocument(const iGmDocument *d) { 1712void makePaletteGlobal_GmDocument(const iGmDocument *d) {
1713 if (d->isPaletteValid) { 1713 if (!d->isPaletteValid) {
1714 memcpy(get_Root()->tmPalette, d->palette, sizeof(d->palette)); 1714 /* Recompute the palette since it's needed now. */
1715 setThemeSeed_GmDocument((iGmDocument *) d, urlThemeSeed_String(&d->url));
1715 } 1716 }
1717 iAssert(d->isPaletteValid);
1718 memcpy(get_Root()->tmPalette, d->palette, sizeof(d->palette));
1716} 1719}
1717 1720
1718void invalidatePalette_GmDocument(iGmDocument *d) { 1721void invalidatePalette_GmDocument(iGmDocument *d) {
@@ -1885,6 +1888,7 @@ static void normalize_GmDocument(iGmDocument *d) {
1885void setUrl_GmDocument(iGmDocument *d, const iString *url) { 1888void setUrl_GmDocument(iGmDocument *d, const iString *url) {
1886 url = canonicalUrl_String(url); 1889 url = canonicalUrl_String(url);
1887 set_String(&d->url, url); 1890 set_String(&d->url, url);
1891 setThemeSeed_GmDocument(d, urlThemeSeed_String(url));
1888 iUrl parts; 1892 iUrl parts;
1889 init_Url(&parts, url); 1893 init_Url(&parts, url);
1890 setRange_String(&d->localHost, parts.host); 1894 setRange_String(&d->localHost, parts.host);
diff --git a/src/gmutil.c b/src/gmutil.c
index 643fbea7..79462e41 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -253,6 +253,17 @@ iRangecc urlRoot_String(const iString *d) {
253 return (iRangecc){ constBegin_String(d), rootEnd }; 253 return (iRangecc){ constBegin_String(d), rootEnd };
254} 254}
255 255
256const iBlock *urlThemeSeed_String(const iString *url) {
257 if (equalCase_Rangecc(urlScheme_String(url), "file")) {
258 return collect_Block(new_Block(0));
259 }
260 const iRangecc user = urlUser_String(url);
261 if (isEmpty_Range(&user)) {
262 return collect_Block(newRange_Block(urlHost_String(url)));
263 }
264 return collect_Block(newRange_Block(user));
265}
266
256static iBool isAbsolutePath_(iRangecc path) { 267static iBool isAbsolutePath_(iRangecc path) {
257 return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path))))); 268 return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path)))));
258} 269}
diff --git a/src/gmutil.h b/src/gmutil.h
index 6b10b444..35a7ee0d 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -117,6 +117,8 @@ iRangecc urlHost_String (const iString *);
117uint16_t urlPort_String (const iString *); 117uint16_t urlPort_String (const iString *);
118iRangecc urlUser_String (const iString *); 118iRangecc urlUser_String (const iString *);
119iRangecc urlRoot_String (const iString *); 119iRangecc urlRoot_String (const iString *);
120const iBlock * urlThemeSeed_String (const iString *);
121
120const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); 122const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative);
121iBool isLikelyUrl_String (const iString *); 123iBool isLikelyUrl_String (const iString *);
122iBool isKnownScheme_Rangecc (iRangecc scheme); /* any URI scheme */ 124iBool isKnownScheme_Rangecc (iRangecc scheme); /* any URI scheme */
diff --git a/src/history.c b/src/history.c
index 7185912f..8c268ec0 100644
--- a/src/history.c
+++ b/src/history.c
@@ -110,6 +110,14 @@ iHistory *copy_History(const iHistory *d) {
110 return copy; 110 return copy;
111} 111}
112 112
113void lock_History(iHistory *d) {
114 lock_Mutex(d->mtx);
115}
116
117void unlock_History(iHistory *d) {
118 unlock_Mutex(d->mtx);
119}
120
113iMemInfo memoryUsage_History(const iHistory *d) { 121iMemInfo memoryUsage_History(const iHistory *d) {
114 iMemInfo mem = { 0, 0 }; 122 iMemInfo mem = { 0, 0 };
115 iConstForEach(Array, i, &d->recent) { 123 iConstForEach(Array, i, &d->recent) {
@@ -297,20 +305,22 @@ void add_History(iHistory *d, const iString *url) {
297 unlock_Mutex(d->mtx); 305 unlock_Mutex(d->mtx);
298} 306}
299 307
300iBool preceding_History(iHistory *d, iRecentUrl *recent_out) { 308iRecentUrl *precedingLocked_History(iHistory *d) {
309 /* NOTE: Manual lock and unlock are required when using this; returning an internal pointer. */
301 iBool ok = iFalse; 310 iBool ok = iFalse;
302 lock_Mutex(d->mtx); 311 //lock_Mutex(d->mtx);
303 if (!isEmpty_Array(&d->recent) && d->recentPos < size_Array(&d->recent) - 1) { 312 const size_t lastIndex = size_Array(&d->recent) - 1;
304 const iRecentUrl *recent = constAt_Array(&d->recent, size_Array(&d->recent) - 1 - 313 if (!isEmpty_Array(&d->recent) && d->recentPos < lastIndex) {
305 (d->recentPos + 1)); 314 return at_Array(&d->recent, lastIndex - (d->recentPos + 1));
306 set_String(&recent_out->url, &recent->url); 315// set_String(&recent_out->url, &recent->url);
307 recent_out->normScrollY = recent->normScrollY; 316// recent_out->normScrollY = recent->normScrollY;
308 iChangeRef(recent_out->cachedDoc, recent->cachedDoc); 317// iChangeRef(recent_out->cachedDoc, recent->cachedDoc);
309 /* Cached response is not returned, would involve a deep copy. */ 318 /* Cached response is not returned, would involve a deep copy. */
310 ok = iTrue; 319// ok = iTrue;
311 } 320 }
312 unlock_Mutex(d->mtx); 321 //unlock_Mutex(d->mtx);
313 return ok; 322// return ok;
323 return NULL;
314} 324}
315 325
316#if 0 326#if 0
@@ -395,12 +405,20 @@ void setCachedDocument_History(iHistory *d, iGmDocument *doc, iBool openedFromSi
395 lock_Mutex(d->mtx); 405 lock_Mutex(d->mtx);
396 iRecentUrl *item = mostRecentUrl_History(d); 406 iRecentUrl *item = mostRecentUrl_History(d);
397 if (item) { 407 if (item) {
398 iAssert(equal_String(url_GmDocument(doc), &item->url)); 408 if (equal_String(url_GmDocument(doc), &item->url)) {
399 item->flags.openedFromSidebar = openedFromSidebar; 409 item->flags.openedFromSidebar = openedFromSidebar;
400 if (item->cachedDoc != doc) { 410 if (item->cachedDoc != doc) {
401 iRelease(item->cachedDoc); 411 iRelease(item->cachedDoc);
402 item->cachedDoc = ref_Object(doc); 412 item->cachedDoc = ref_Object(doc);
413 }
414 }
415#if !defined (NDEBUG)
416 else {
417 printf("[History] Not updating cached document; expecting {%s} but document URL is {%s}\n",
418 cstr_String(&item->url),
419 cstr_String(url_GmDocument(doc)));
403 } 420 }
421#endif
404 } 422 }
405 unlock_Mutex(d->mtx); 423 unlock_Mutex(d->mtx);
406} 424}
diff --git a/src/history.h b/src/history.h
index d3daae80..0c07759b 100644
--- a/src/history.h
+++ b/src/history.h
@@ -58,6 +58,8 @@ iDeclareTypeConstruction(History)
58iDeclareTypeSerialization(History) 58iDeclareTypeSerialization(History)
59 59
60iHistory * copy_History (const iHistory *); 60iHistory * copy_History (const iHistory *);
61void lock_History (iHistory *);
62void unlock_History (iHistory *);
61 63
62void clear_History (iHistory *); 64void clear_History (iHistory *);
63void add_History (iHistory *, const iString *url); 65void add_History (iHistory *, const iString *url);
@@ -66,8 +68,7 @@ void setCachedResponse_History (iHistory *, const iGmResponse *response
66void setCachedDocument_History (iHistory *, iGmDocument *doc, iBool openedFromSidebar); 68void setCachedDocument_History (iHistory *, iGmDocument *doc, iBool openedFromSidebar);
67iBool goBack_History (iHistory *); 69iBool goBack_History (iHistory *);
68iBool goForward_History (iHistory *); 70iBool goForward_History (iHistory *);
69iBool preceding_History (iHistory *d, iRecentUrl *recent_out); 71iRecentUrl *precedingLocked_History (iHistory *); /* requires manual lock/unlock! */
70//iBool following_History (iHistory *d, iRecentUrl *recent_out);
71iRecentUrl *recentUrl_History (iHistory *, size_t pos); 72iRecentUrl *recentUrl_History (iHistory *, size_t pos);
72iRecentUrl *mostRecentUrl_History (iHistory *); 73iRecentUrl *mostRecentUrl_History (iHistory *);
73iRecentUrl *findUrl_History (iHistory *, const iString *url); 74iRecentUrl *findUrl_History (iHistory *, const iString *url);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 1760be9e..1c861b8f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -330,7 +330,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
330 } 330 }
331 init_PersistentDocumentState(&d->mod); 331 init_PersistentDocumentState(&d->mod);
332 d->flags = 0; 332 d->flags = 0;
333 d->phoneToolbar = NULL; 333 d->phoneToolbar = findWidget_App("toolbar");
334 d->footerButtons = NULL; 334 d->footerButtons = NULL;
335 iZap(d->certExpiry); 335 iZap(d->certExpiry);
336 d->certFingerprint = new_Block(0); 336 d->certFingerprint = new_Block(0);
@@ -961,7 +961,8 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
961 animateMedia_DocumentWidget_(d); 961 animateMedia_DocumentWidget_(d);
962 /* Remember scroll positions of recently visited pages. */ { 962 /* Remember scroll positions of recently visited pages. */ {
963 iRecentUrl *recent = mostRecentUrl_History(d->mod.history); 963 iRecentUrl *recent = mostRecentUrl_History(d->mod.history);
964 if (recent && docSize && d->state == ready_RequestState) { 964 if (recent && docSize && d->state == ready_RequestState &&
965 equal_String(&recent->url, d->mod.url)) {
965 recent->normScrollY = normScrollPos_DocumentWidget_(d); 966 recent->normScrollY = normScrollPos_DocumentWidget_(d);
966 } 967 }
967 } 968 }
@@ -1162,27 +1163,14 @@ static void replaceDocument_DocumentWidget_(iDocumentWidget *d, iGmDocument *new
1162} 1163}
1163 1164
1164static void updateBanner_DocumentWidget_(iDocumentWidget *d) { 1165static void updateBanner_DocumentWidget_(iDocumentWidget *d) {
1165 /* TODO: Set width. */
1166 setSite_Banner(d->banner, siteText_DocumentWidget_(d), siteIcon_GmDocument(d->doc)); 1166 setSite_Banner(d->banner, siteText_DocumentWidget_(d), siteIcon_GmDocument(d->doc));
1167} 1167}
1168 1168
1169static void updateTheme_DocumentWidget_(iDocumentWidget *d) { 1169static void updateTheme_DocumentWidget_(iDocumentWidget *d) {
1170 if (document_App() != d || category_GmStatusCode(d->sourceStatus) == categoryInput_GmStatusCode) { 1170 if (document_App() != d || category_GmStatusCode(d->sourceStatus) == categoryInput_GmStatusCode) {
1171 return; 1171 return;
1172 } 1172 }
1173 if (equalCase_Rangecc(urlScheme_String(d->mod.url), "file")) { 1173// setThemeSeed_GmDocument(d->doc, urlThemeSeed_String(d->mod.url)); /* theme palette and icon */
1174 iBlock empty;
1175 init_Block(&empty, 0);
1176 setThemeSeed_GmDocument(d->doc, &empty);
1177 deinit_Block(&empty);
1178 }
1179 else if (isEmpty_String(d->titleUser)) {
1180 setThemeSeed_GmDocument(d->doc,
1181 collect_Block(newRange_Block(urlHost_String(d->mod.url))));
1182 }
1183 else {
1184 setThemeSeed_GmDocument(d->doc, &d->titleUser->chars);
1185 }
1186 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag; 1174 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag;
1187 updateBanner_DocumentWidget_(d); 1175 updateBanner_DocumentWidget_(d);
1188} 1176}
@@ -2616,6 +2604,7 @@ static void swap_DocumentWidget_(iDocumentWidget *d, iGmDocument *doc,
2616 iAssert(isInstance_Object(doc, &Class_GmDocument)); 2604 iAssert(isInstance_Object(doc, &Class_GmDocument));
2617 replaceDocument_DocumentWidget_(d, doc); 2605 replaceDocument_DocumentWidget_(d, doc);
2618 d->scrollY = swapBuffersWith->scrollY; 2606 d->scrollY = swapBuffersWith->scrollY;
2607 d->scrollY.widget = as_Widget(d);
2619 iSwap(iBanner *, d->banner, swapBuffersWith->banner); 2608 iSwap(iBanner *, d->banner, swapBuffersWith->banner);
2620 setOwner_Banner(d->banner, d); 2609 setOwner_Banner(d->banner, d);
2621 setOwner_Banner(swapBuffersWith->banner, swapBuffersWith); 2610 setOwner_Banner(swapBuffersWith->banner, swapBuffersWith);
@@ -2631,6 +2620,14 @@ static iWidget *swipeParent_DocumentWidget_(iDocumentWidget *d) {
2631 return findChild_Widget(as_Widget(d)->root->widget, "doctabs"); 2620 return findChild_Widget(as_Widget(d)->root->widget, "doctabs");
2632} 2621}
2633 2622
2623static void setUrl_DocumentWidget_(iDocumentWidget *d, const iString *url) {
2624 url = canonicalUrl_String(url);
2625 if (!equal_String(d->mod.url, url)) {
2626 d->flags |= urlChanged_DocumentWidgetFlag;
2627 set_String(d->mod.url, url);
2628 }
2629}
2630
2634static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 2631static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2635 iWidget *w = as_Widget(d); 2632 iWidget *w = as_Widget(d);
2636 /* Swipe animations are rather complex and utilize both cached GmDocument content 2633 /* Swipe animations are rather complex and utilize both cached GmDocument content
@@ -2658,18 +2655,31 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2658 swipeIn->widget.rect.size = d->widget.rect.size; 2655 swipeIn->widget.rect.size = d->widget.rect.size;
2659 swipeIn->widget.offsetRef = parent_Widget(w); 2656 swipeIn->widget.offsetRef = parent_Widget(w);
2660 /* Use a cached document for the layer underneath. */ { 2657 /* Use a cached document for the layer underneath. */ {
2661 iRecentUrl *recent = new_RecentUrl(); 2658// iRecentUrl *recent = new_RecentUrl();
2662 preceding_History(d->mod.history, recent); 2659 lock_History(d->mod.history);
2663 if (recent->cachedDoc) { 2660 iRecentUrl *recent = precedingLocked_History(d->mod.history);
2661 if (recent && recent->cachedResponse) {
2662 /*
2664 iChangeRef(swipeIn->doc, recent->cachedDoc); 2663 iChangeRef(swipeIn->doc, recent->cachedDoc);
2665 updateBanner_DocumentWidget_(swipeIn); 2664 updateBanner_DocumentWidget_(swipeIn);
2666 updateScrollMax_DocumentWidget_(d); 2665 updateScrollMax_DocumentWidget_(d);
2667 setValue_Anim(&swipeIn->scrollY.pos, 2666 setValue_Anim(&swipeIn->scrollY.pos,
2668 pageHeight_DocumentWidget_(d) * recent->normScrollY, 0); 2667 pageHeight_DocumentWidget_(d) * recent->normScrollY, 0);
2669 updateVisible_DocumentWidget_(swipeIn); 2668 updateVisible_DocumentWidget_(swipeIn);
2670 swipeIn->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; 2669 swipeIn->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag;*/
2670 setUrl_DocumentWidget_(swipeIn, &recent->url);
2671 updateFromCachedResponse_DocumentWidget_(swipeIn,
2672 recent->normScrollY,
2673 recent->cachedResponse,
2674 recent->cachedDoc);
2671 } 2675 }
2672 delete_RecentUrl(recent); 2676 else {
2677 setUrlAndSource_DocumentWidget(swipeIn, &recent->url,
2678 collectNewCStr_String("text/gemini"),
2679 collect_Block(new_Block(0)));
2680 }
2681// delete_RecentUrl(recent);
2682 unlock_History(d->mod.history);
2673 } 2683 }
2674 addChildPos_Widget(swipeParent, iClob(swipeIn), front_WidgetAddPos); 2684 addChildPos_Widget(swipeParent, iClob(swipeIn), front_WidgetAddPos);
2675 } 2685 }
@@ -2677,8 +2687,7 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2677 if (side == 2) { /* right edge */ 2687 if (side == 2) { /* right edge */
2678 if (offset < -get_Window()->pixelRatio * 10) { 2688 if (offset < -get_Window()->pixelRatio * 10) {
2679 int animSpan = 10; 2689 int animSpan = 10;
2680 if (!atLatest_History(d->mod.history) && 2690 if (!atLatest_History(d->mod.history) && ~flags_Widget(w) & dragged_WidgetFlag) {
2681 ~flags_Widget(w) & dragged_WidgetFlag) {
2682 animSpan = 0; 2691 animSpan = 0;
2683 postCommand_Widget(d, "navigate.forward"); 2692 postCommand_Widget(d, "navigate.forward");
2684 setFlags_Widget(w, dragged_WidgetFlag, iTrue); 2693 setFlags_Widget(w, dragged_WidgetFlag, iTrue);
@@ -2695,6 +2704,13 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2695 setFlags_Widget(as_Widget(target), refChildrenOffset_WidgetFlag, iTrue); 2704 setFlags_Widget(as_Widget(target), refChildrenOffset_WidgetFlag, iTrue);
2696 as_Widget(target)->offsetRef = parent_Widget(w); 2705 as_Widget(target)->offsetRef = parent_Widget(w);
2697 destroy_Widget(as_Widget(target)); /* will be actually deleted after animation finishes */ 2706 destroy_Widget(as_Widget(target)); /* will be actually deleted after animation finishes */
2707 /* The `d` document will now navigate forward and be replaced with a cached
2708 copy. However, if a cached response isn't available, we'll need to show a
2709 blank page. */
2710 setUrlAndSource_DocumentWidget(d,
2711 collectNewCStr_String("about:blank"),
2712 collectNewCStr_String("text/gemini"),
2713 collect_Block(new_Block(0)));
2698 } 2714 }
2699 if (flags_Widget(w) & dragged_WidgetFlag) { 2715 if (flags_Widget(w) & dragged_WidgetFlag) {
2700 setVisualOffset_Widget(w, width_Widget(w) + 2716 setVisualOffset_Widget(w, width_Widget(w) +
@@ -2718,10 +2734,19 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2718 } 2734 }
2719 if (equal_Command(cmd, "edgeswipe.ended") && argLabel_Command(cmd, "side") == 1) { 2735 if (equal_Command(cmd, "edgeswipe.ended") && argLabel_Command(cmd, "side") == 1) {
2720 iWidget *swipeParent = swipeParent_DocumentWidget_(d); 2736 iWidget *swipeParent = swipeParent_DocumentWidget_(d);
2721 iWidget *swipeIn = findChild_Widget(swipeParent, "swipein"); 2737 iDocumentWidget *swipeIn = findChild_Widget(swipeParent, "swipein");
2738// iDocumentWidget *swipeInDoc = (iDocumentWidget *) swipeIn;
2739 /* "swipe.back" will soon follow. The `d` document will do the actual back navigation,
2740 switching immediately to a cached page. However, if one is not available, we'll need
2741 to show a blank page for a while. */
2722 if (swipeIn) { 2742 if (swipeIn) {
2723 swipeIn->offsetRef = NULL; 2743 setUrlAndSource_DocumentWidget(d,
2724 destroy_Widget(swipeIn); 2744 swipeIn->mod.url,
2745 collectNewCStr_String("text/gemini"),
2746 collect_Block(new_Block(0)));
2747 //swap_DocumentWidget_(d, swipeIn->doc, swipeIn);
2748 as_Widget(swipeIn)->offsetRef = NULL;
2749 destroy_Widget(as_Widget(swipeIn));
2725 } 2750 }
2726 } 2751 }
2727 if (equal_Command(cmd, "swipe.back")) { 2752 if (equal_Command(cmd, "swipe.back")) {
@@ -2824,14 +2849,16 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2824 else if (equal_Command(cmd, "window.mouse.exited")) { 2849 else if (equal_Command(cmd, "window.mouse.exited")) {
2825 return iFalse; 2850 return iFalse;
2826 } 2851 }
2827 else if (equal_Command(cmd, "theme.changed") && document_App() == d) { 2852 else if (equal_Command(cmd, "theme.changed")) {
2828// invalidateTheme_History(d->mod.history); /* cached colors */ 2853 invalidateTheme_History(d->mod.history); /* forget cached color palettes */
2829 updateTheme_DocumentWidget_(d); 2854 if (document_App() == d) {
2830 updateVisible_DocumentWidget_(d); 2855 updateTheme_DocumentWidget_(d);
2831 updateTrust_DocumentWidget_(d, NULL); 2856 updateVisible_DocumentWidget_(d);
2832 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag; 2857 updateTrust_DocumentWidget_(d, NULL);
2833 invalidate_DocumentWidget_(d); 2858 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
2834 refresh_Widget(w); 2859 invalidate_DocumentWidget_(d);
2860 refresh_Widget(w);
2861 }
2835 } 2862 }
2836 else if (equal_Command(cmd, "document.layout.changed") && document_Root(get_Root()) == d) { 2863 else if (equal_Command(cmd, "document.layout.changed") && document_Root(get_Root()) == d) {
2837 if (argLabel_Command(cmd, "redo")) { 2864 if (argLabel_Command(cmd, "redo")) {
@@ -5047,6 +5074,7 @@ static void prerender_DocumentWidget_(iAny *context) {
5047 }; 5074 };
5048// printf("%u prerendering\n", SDL_GetTicks()); 5075// printf("%u prerendering\n", SDL_GetTicks());
5049 if (d->visBuf->buffers[0].texture) { 5076 if (d->visBuf->buffers[0].texture) {
5077 makePaletteGlobal_GmDocument(d->doc);
5050 if (render_DocumentWidget_(d, &ctx, iTrue /* just fill up progressively */)) { 5078 if (render_DocumentWidget_(d, &ctx, iTrue /* just fill up progressively */)) {
5051 /* Something was drawn, should check if there is still more to do. */ 5079 /* Something was drawn, should check if there is still more to do. */
5052 addTicker_App(prerender_DocumentWidget_, context); 5080 addTicker_App(prerender_DocumentWidget_, context);
@@ -5062,10 +5090,11 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
5062 if (width_Rect(bounds) <= 0) { 5090 if (width_Rect(bounds) <= 0) {
5063 return; 5091 return;
5064 } 5092 }
5065 /* TODO: Come up with a better palette caching system. 5093 /* Each document has its own palette, but the drawing routines rely on a global one.
5066 It should be able to recompute cached colors in `History` when the theme has changed. 5094 As we're now drawing a document, ensure that the right palette is in effect.
5067 Cache the theme seed in `GmDocument`? */ 5095 Document theme colors can be used elsewhere, too, but first a document's palette
5068// makePaletteGlobal_GmDocument(d->doc); 5096 must be made global. */
5097 makePaletteGlobal_GmDocument(d->doc);
5069 if (d->drawBufs->flags & updateTimestampBuf_DrawBufsFlag) { 5098 if (d->drawBufs->flags & updateTimestampBuf_DrawBufsFlag) {
5070 updateTimestampBuf_DocumentWidget_(d); 5099 updateTimestampBuf_DocumentWidget_(d);
5071 } 5100 }
@@ -5319,14 +5348,6 @@ void deserializeState_DocumentWidget(iDocumentWidget *d, iStream *ins) {
5319 updateFromHistory_DocumentWidget_(d); 5348 updateFromHistory_DocumentWidget_(d);
5320} 5349}
5321 5350
5322static void setUrl_DocumentWidget_(iDocumentWidget *d, const iString *url) {
5323 url = canonicalUrl_String(url);
5324 if (!equal_String(d->mod.url, url)) {
5325 d->flags |= urlChanged_DocumentWidgetFlag;
5326 set_String(d->mod.url, url);
5327 }
5328}
5329
5330void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) { 5351void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) {
5331 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag, 5352 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag,
5332 (setUrlFlags & openedFromSidebar_DocumentWidgetSetUrlFlag) != 0); 5353 (setUrlFlags & openedFromSidebar_DocumentWidgetSetUrlFlag) != 0);
@@ -5352,6 +5373,7 @@ void setUrlAndSource_DocumentWidget(iDocumentWidget *d, const iString *url, cons
5352 set_String(&resp->meta, mime); 5373 set_String(&resp->meta, mime);
5353 set_Block(&resp->body, source); 5374 set_Block(&resp->body, source);
5354 updateFromCachedResponse_DocumentWidget_(d, 0, resp, NULL); 5375 updateFromCachedResponse_DocumentWidget_(d, 0, resp, NULL);
5376 updateBanner_DocumentWidget_(d);
5355 delete_GmResponse(resp); 5377 delete_GmResponse(resp);
5356} 5378}
5357 5379