diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/documentwidget.c | 116 |
1 files changed, 69 insertions, 47 deletions
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 | ||
1164 | static void updateBanner_DocumentWidget_(iDocumentWidget *d) { | 1165 | static 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 | ||
1169 | static void updateTheme_DocumentWidget_(iDocumentWidget *d) { | 1169 | static 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 | ||
2623 | static 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 | |||
2634 | static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 2631 | static 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 | ||
5322 | static 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 | |||
5330 | void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) { | 5351 | void 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 | ||