summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
commit347b4c1cb3482fd43251bf4d4ab7807360bbb938 (patch)
treea3a1ad51b392891f87ebd6ef438a1d16c5dd376e
parent6cbaa38d4ebf5a911e908b72bf721985bde87e44 (diff)
Highlight links opened in other tabs
The primary purpose is to aid navigation in split view, so one can see exactly which links have been opened.
-rw-r--r--src/app.c16
-rw-r--r--src/app.h2
-rw-r--r--src/gmdocument.c42
-rw-r--r--src/gmdocument.h2
-rw-r--r--src/ui/color.h4
-rw-r--r--src/ui/documentwidget.c67
6 files changed, 117 insertions, 16 deletions
diff --git a/src/app.c b/src/app.c
index f909c251..4872799b 100644
--- a/src/app.c
+++ b/src/app.c
@@ -2109,6 +2109,7 @@ iBool handleCommand_App(const char *cmd) {
2109 iBool wasCurrent = (doc == (iWidget *) document_App()); 2109 iBool wasCurrent = (doc == (iWidget *) document_App());
2110 size_t index = tabPageIndex_Widget(tabs, doc); 2110 size_t index = tabPageIndex_Widget(tabs, doc);
2111 iBool wasClosed = iFalse; 2111 iBool wasClosed = iFalse;
2112 postCommand_App("document.openurls.changed");
2112 if (argLabel_Command(cmd, "toright")) { 2113 if (argLabel_Command(cmd, "toright")) {
2113 while (tabCount_Widget(tabs) > index + 1) { 2114 while (tabCount_Widget(tabs) > index + 1) {
2114 destroy_Widget(removeTabPage_Widget(tabs, index + 1)); 2115 destroy_Widget(removeTabPage_Widget(tabs, index + 1));
@@ -2314,6 +2315,11 @@ iBool handleCommand_App(const char *cmd) {
2314 save_Visited(d->visited, dataDir_App_()); 2315 save_Visited(d->visited, dataDir_App_());
2315 return iFalse; 2316 return iFalse;
2316 } 2317 }
2318 else if (equal_Command(cmd, "document.changed")) {
2319 /* Set of open tabs has changed. */
2320 postCommand_App("document.openurls.changed");
2321 return iFalse;
2322 }
2317 else if (equal_Command(cmd, "ident.new")) { 2323 else if (equal_Command(cmd, "ident.new")) {
2318 iWidget *dlg = makeIdentityCreation_Widget(); 2324 iWidget *dlg = makeIdentityCreation_Widget();
2319 setFocus_Widget(findChild_Widget(dlg, "ident.until")); 2325 setFocus_Widget(findChild_Widget(dlg, "ident.until"));
@@ -2472,3 +2478,13 @@ iObjectList *listDocuments_App(const iRoot *rootOrNull) {
2472 } 2478 }
2473 return docs; 2479 return docs;
2474} 2480}
2481
2482iStringSet *listOpenURLs_App(void) {
2483 iStringSet *set = new_StringSet();
2484 iObjectList *docs = listDocuments_App(NULL);
2485 iConstForEach(ObjectList, i, docs) {
2486 insert_StringSet(set, withSpacesEncoded_String(url_DocumentWidget(i.object)));
2487 }
2488 iRelease(docs);
2489 return set;
2490}
diff --git a/src/app.h b/src/app.h
index 952688a4..c8f0f1c2 100644
--- a/src/app.h
+++ b/src/app.h
@@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 26
27#include <the_Foundation/objectlist.h> 27#include <the_Foundation/objectlist.h>
28#include <the_Foundation/string.h> 28#include <the_Foundation/string.h>
29#include <the_Foundation/stringset.h>
29#include <the_Foundation/time.h> 30#include <the_Foundation/time.h>
30 31
31#include "prefs.h" 32#include "prefs.h"
@@ -90,6 +91,7 @@ iMimeHooks * mimeHooks_App (void);
90iPeriodic * periodic_App (void); 91iPeriodic * periodic_App (void);
91iDocumentWidget * document_App (void); 92iDocumentWidget * document_App (void);
92iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */ 93iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */
94iStringSet * listOpenURLs_App (void); /* all tabs */
93iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); 95iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew);
94void trimCache_App (void); 96void trimCache_App (void);
95 97
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 47f629bd..b64e9ea7 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33 33
34#include <the_Foundation/ptrarray.h> 34#include <the_Foundation/ptrarray.h>
35#include <the_Foundation/regexp.h> 35#include <the_Foundation/regexp.h>
36#include <the_Foundation/stringset.h>
36 37
37#include <ctype.h> 38#include <ctype.h>
38 39
@@ -87,6 +88,7 @@ struct Impl_GmDocument {
87 uint32_t themeSeed; 88 uint32_t themeSeed;
88 iChar siteIcon; 89 iChar siteIcon;
89 iMedia * media; 90 iMedia * media;
91 iStringSet *openURLs; /* currently open URLs for highlighting links */
90}; 92};
91 93
92iDefineObjectConstruction(GmDocument) 94iDefineObjectConstruction(GmDocument)
@@ -229,6 +231,9 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li
229 if (isValid_Time(&link->when)) { 231 if (isValid_Time(&link->when)) {
230 link->flags |= visited_GmLinkFlag; 232 link->flags |= visited_GmLinkFlag;
231 } 233 }
234 if (contains_StringSet(d->openURLs, &link->url)) {
235 link->flags |= isOpen_GmLinkFlag;
236 }
232 } 237 }
233 } 238 }
234 pushBack_PtrArray(&d->links, link); 239 pushBack_PtrArray(&d->links, link);
@@ -340,6 +345,13 @@ static void alignDecoration_GmRun_(iGmRun *run, iBool isCentered) {
340 run->visBounds.size.x -= xAdjust; 345 run->visBounds.size.x -= xAdjust;
341} 346}
342 347
348static void updateOpenURLs_GmDocument_(iGmDocument *d) {
349 if (d->openURLs) {
350 iReleasePtr(&d->openURLs);
351 }
352 d->openURLs = listOpenURLs_App();
353}
354
343static void doLayout_GmDocument_(iGmDocument *d) { 355static void doLayout_GmDocument_(iGmDocument *d) {
344 const iPrefs *prefs = prefs_App(); 356 const iPrefs *prefs = prefs_App();
345 const iBool isMono = isForcedMonospace_GmDocument_(d); 357 const iBool isMono = isForcedMonospace_GmDocument_(d);
@@ -405,6 +417,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
405 if (d->size.x <= 0 || isEmpty_String(&d->source)) { 417 if (d->size.x <= 0 || isEmpty_String(&d->source)) {
406 return; 418 return;
407 } 419 }
420 updateOpenURLs_GmDocument_(d);
408 const iRangecc content = range_String(&d->source); 421 const iRangecc content = range_String(&d->source);
409 iRangecc contentLine = iNullRange; 422 iRangecc contentLine = iNullRange;
410 iInt2 pos = zero_I2(); 423 iInt2 pos = zero_I2();
@@ -861,9 +874,11 @@ void init_GmDocument(iGmDocument *d) {
861 d->themeSeed = 0; 874 d->themeSeed = 0;
862 d->siteIcon = 0; 875 d->siteIcon = 0;
863 d->media = new_Media(); 876 d->media = new_Media();
877 d->openURLs = NULL;
864} 878}
865 879
866void deinit_GmDocument(iGmDocument *d) { 880void deinit_GmDocument(iGmDocument *d) {
881 iReleasePtr(&d->openURLs);
867 delete_Media(d->media); 882 delete_Media(d->media);
868 deinit_String(&d->bannerText); 883 deinit_String(&d->bannerText);
869 deinit_String(&d->title); 884 deinit_String(&d->title);
@@ -900,10 +915,15 @@ static void setDerivedThemeColors_(enum iGmDocumentTheme theme) {
900 set_Color(tmQuoteIcon_ColorId, 915 set_Color(tmQuoteIcon_ColorId,
901 mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); 916 mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f));
902 set_Color(tmBannerSideTitle_ColorId, 917 set_Color(tmBannerSideTitle_ColorId,
903 mix_Color(get_Color(tmBannerTitle_ColorId), get_Color(tmBackground_ColorId), 918 mix_Color(get_Color(tmBannerTitle_ColorId),
919 get_Color(tmBackground_ColorId),
904 theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); 920 theme == colorfulDark_GmDocumentTheme ? 0.55f : 0));
905 set_Color(tmAltTextBackground_ColorId, mix_Color(get_Color(tmQuoteIcon_ColorId), 921 set_Color(tmBackgroundAltText_ColorId,
906 get_Color(tmBackground_ColorId), 0.85f)); 922 mix_Color(get_Color(tmQuoteIcon_ColorId), get_Color(tmBackground_ColorId), 0.85f));
923 set_Color(tmBackgroundOpenLink_ColorId,
924 mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.92f));
925 set_Color(tmFrameOpenLink_ColorId,
926 mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.78f));
907 if (theme == colorfulDark_GmDocumentTheme) { 927 if (theme == colorfulDark_GmDocumentTheme) {
908 /* Ensure paragraph text and link text aren't too similarly colored. */ 928 /* Ensure paragraph text and link text aren't too similarly colored. */
909 if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { 929 if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) {
@@ -1381,6 +1401,22 @@ void redoLayout_GmDocument(iGmDocument *d) {
1381 doLayout_GmDocument_(d); 1401 doLayout_GmDocument_(d);
1382} 1402}
1383 1403
1404iBool updateOpenURLs_GmDocument(iGmDocument *d) {
1405 iBool wasChanged = iFalse;
1406 updateOpenURLs_GmDocument_(d);
1407 iForEach(PtrArray, i, &d->links) {
1408 iGmLink *link = i.ptr;
1409 if (!equal_String(&link->url, &d->url)) {
1410 const iBool isOpen = contains_StringSet(d->openURLs, &link->url);
1411 if (isOpen ^ ((link->flags & isOpen_GmLinkFlag) != 0)) {
1412 iChangeFlags(link->flags, isOpen_GmLinkFlag, isOpen);
1413 wasChanged = iTrue;
1414 }
1415 }
1416 }
1417 return wasChanged;
1418}
1419
1384iLocalDef iBool isNormalizableSpace_(char ch) { 1420iLocalDef iBool isNormalizableSpace_(char ch) {
1385 return ch == ' ' || ch == '\t'; 1421 return ch == ' ' || ch == '\t';
1386} 1422}
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 5d34dbaf..574f0acf 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -83,6 +83,7 @@ enum iGmLinkFlags {
83 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ 83 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */
84 query_GmLinkFlag = iBit(16), /* Gopher query link */ 84 query_GmLinkFlag = iBit(16), /* Gopher query link */
85 iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */ 85 iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */
86 isOpen_GmLinkFlag = iBit(18), /* currently open in a tab */
86}; 87};
87 88
88struct Impl_GmHeading { 89struct Impl_GmHeading {
@@ -164,6 +165,7 @@ void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format);
164void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type); 165void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type);
165void setWidth_GmDocument (iGmDocument *, int width); 166void setWidth_GmDocument (iGmDocument *, int width);
166void redoLayout_GmDocument (iGmDocument *); 167void redoLayout_GmDocument (iGmDocument *);
168iBool updateOpenURLs_GmDocument(iGmDocument *);
167void setUrl_GmDocument (iGmDocument *, const iString *url); 169void setUrl_GmDocument (iGmDocument *, const iString *url);
168void setSource_GmDocument (iGmDocument *, const iString *source, int width); 170void setSource_GmDocument (iGmDocument *, const iString *source, int width);
169void foldPre_GmDocument (iGmDocument *, uint16_t preId); 171void foldPre_GmDocument (iGmDocument *, uint16_t preId);
diff --git a/src/ui/color.h b/src/ui/color.h
index c0db4382..d2fa3c00 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -132,7 +132,9 @@ enum iColorId {
132 tmBannerIcon_ColorId, 132 tmBannerIcon_ColorId,
133 tmBannerSideTitle_ColorId, 133 tmBannerSideTitle_ColorId,
134 tmInlineContentMetadata_ColorId, 134 tmInlineContentMetadata_ColorId,
135 tmAltTextBackground_ColorId, /* derived from other theme colors */ 135 tmBackgroundAltText_ColorId, /* derived from other theme colors */
136 tmBackgroundOpenLink_ColorId, /* derived from other theme colors */
137 tmFrameOpenLink_ColorId, /* derived from other theme colors */
136 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */ 138 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */
137 tmBadLink_ColorId, 139 tmBadLink_ColorId,
138 140
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 16d2a84a..6a44fd5f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -286,7 +286,7 @@ struct Impl_DocumentWidget {
286 iWidget * playerMenu; 286 iWidget * playerMenu;
287 iWidget * copyMenu; 287 iWidget * copyMenu;
288 iVisBuf * visBuf; 288 iVisBuf * visBuf;
289 iGmRunRange * visBufMeta; 289 iVisBufMeta * visBufMeta;
290 iPtrSet * invalidRuns; 290 iPtrSet * invalidRuns;
291 iDrawBufs * drawBufs; /* dynamic state for drawing */ 291 iDrawBufs * drawBufs; /* dynamic state for drawing */
292 iTranslation * translation; 292 iTranslation * translation;
@@ -1881,7 +1881,15 @@ static iBool handlePinch_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1881 1881
1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1883 iWidget *w = as_Widget(d); 1883 iWidget *w = as_Widget(d);
1884 if (equal_Command(cmd, "document.render")) /* Periodic makes direct dispatch to here */ { 1884 if (equal_Command(cmd, "document.openurls.changed")) {
1885 /* When any tab changes its document URL, update the open link indicators. */
1886 if (updateOpenURLs_GmDocument(d->doc)) {
1887 invalidate_DocumentWidget_(d);
1888 refresh_Widget(d);
1889 }
1890 return iFalse;
1891 }
1892 if (equal_Command(cmd, "document.render")) /* `Periodic` makes direct dispatch to here */ {
1885// printf("%u: document.render\n", SDL_GetTicks()); 1893// printf("%u: document.render\n", SDL_GetTicks());
1886 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) { 1894 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) {
1887 remove_Periodic(periodic_App(), d); 1895 remove_Periodic(periodic_App(), d);
@@ -3486,15 +3494,18 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3486 /* Media UIs are drawn afterwards as a dynamic overlay. */ 3494 /* Media UIs are drawn afterwards as a dynamic overlay. */
3487 return; 3495 return;
3488 } 3496 }
3489// printf(" drawRun: {%s}\n", cstr_Rangecc(run->text)); 3497 enum iColorId fg = run->color;
3490 enum iColorId fg = run->color; 3498 const iGmDocument *doc = d->widget->doc;
3491 const iGmDocument *doc = d->widget->doc; 3499 const int linkFlags = linkFlags_GmDocument(doc, run->linkId);
3492 iBool isHover = 3500 /* Hover state of a link. */
3501 iBool isHover =
3493 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId && 3502 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId &&
3494 ~run->flags & decoration_GmRunFlag); 3503 ~run->flags & decoration_GmRunFlag);
3504 /* Visible (scrolled) position of the run. */
3495 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin), 3505 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin),
3496 /* Preformatted runs can be scrolled. */ 3506 /* Preformatted runs can be scrolled. */
3497 runOffset_DocumentWidget_(d->widget, run)); 3507 runOffset_DocumentWidget_(d->widget, run));
3508 const iRect visRect = { visPos, run->visBounds.size };
3498 if (run->flags & footer_GmRunFlag) { 3509 if (run->flags & footer_GmRunFlag) {
3499 iRect footerBack = 3510 iRect footerBack =
3500 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) }; 3511 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) };
@@ -3502,16 +3513,48 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3502 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId); 3513 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId);
3503 return; 3514 return;
3504 } 3515 }
3505 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId); 3516 /* Fill the background. */ {
3517 if (run->linkId && linkFlags & isOpen_GmLinkFlag) {
3518 /* Open links get a highlighted background. */
3519 int bg = tmBackgroundOpenLink_ColorId;
3520 const int frame = tmFrameOpenLink_ColorId;
3521 iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y),
3522 init_I2(width_Rect(d->widgetBounds) +
3523 width_Widget(d->widget->scroll),
3524 height_Rect(run->visBounds)) };
3525 /* The first line is composed of two runs that may be drawn in either order, so
3526 only draw half of the background. */
3527 if (run->flags & decoration_GmRunFlag) {
3528 wideRect.size.x = right_Rect(visRect) - left_Rect(wideRect);
3529 }
3530 else if (run->flags & startOfLine_GmRunFlag) {
3531 wideRect.size.x = right_Rect(wideRect) - left_Rect(visRect);
3532 wideRect.pos.x = left_Rect(visRect);
3533 }
3534 fillRect_Paint(&d->paint, wideRect, bg);
3535 if (run->flags & (startOfLine_GmRunFlag | decoration_GmRunFlag)) {
3536 drawHLine_Paint(&d->paint, topLeft_Rect(wideRect), width_Rect(wideRect), frame);
3537 }
3538 /* TODO: The decoration is not marked as endOfLine, so it lacks the bottom line. */
3539// if (run->flags & endOfLine_GmRunFlag) {
3540// drawHLine_Paint(
3541// &d->paint, addY_I2(bottomLeft_Rect(wideRect), -1), width_Rect(wideRect), frame);
3542// }
3543 }
3544 else {
3545 /* Normal background for other runs. */
3546 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId);
3547 }
3548 }
3506 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3549 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3507 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart); 3550 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart);
3508 if (linkFlags_GmDocument(doc, run->linkId) & content_GmLinkFlag) { 3551 if (linkFlags & content_GmLinkFlag) {
3509 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */ 3552 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */
3510 } 3553 }
3511 } 3554 }
3512 if (run->flags & altText_GmRunFlag) { 3555 if (run->flags & altText_GmRunFlag) {
3513 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId); 3556 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId);
3514 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmAltTextBackground_ColorId); 3557 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackgroundAltText_ColorId);
3515 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId); 3558 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId);
3516 drawWrapRange_Text(run->font, add_I2(visPos, margin), 3559 drawWrapRange_Text(run->font, add_I2(visPos, margin),
3517 run->visBounds.size.x - 2 * margin.x, run->color, run->text); 3560 run->visBounds.size.x - 2 * margin.x, run->color, run->text);
@@ -3552,7 +3595,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3552 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3595 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3553 const int metaFont = paragraph_FontId; 3596 const int metaFont = paragraph_FontId;
3554 /* TODO: Show status of an ongoing media request. */ 3597 /* TODO: Show status of an ongoing media request. */
3555 const int flags = linkFlags_GmDocument(doc, run->linkId); 3598 const int flags = linkFlags;
3556 const iRect linkRect = moved_Rect(run->visBounds, origin); 3599 const iRect linkRect = moved_Rect(run->visBounds, origin);
3557 iMediaRequest *mr = NULL; 3600 iMediaRequest *mr = NULL;
3558 /* Show metadata about inline content. */ 3601 /* Show metadata about inline content. */
@@ -3614,7 +3657,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3614 else if (isHover) { 3657 else if (isHover) {
3615 const iGmLinkId linkId = d->widget->hoverLink->linkId; 3658 const iGmLinkId linkId = d->widget->hoverLink->linkId;
3616 const iString * url = linkUrl_GmDocument(doc, linkId); 3659 const iString * url = linkUrl_GmDocument(doc, linkId);
3617 const int flags = linkFlags_GmDocument(doc, linkId); 3660 const int flags = linkFlags;
3618 iUrl parts; 3661 iUrl parts;
3619 init_Url(&parts, url); 3662 init_Url(&parts, url);
3620 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart); 3663 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart);
@@ -4122,7 +4165,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4122 if (altTextOpacity < 1) { 4165 if (altTextOpacity < 1) {
4123 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND); 4166 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
4124 } 4167 }
4125 fillRect_Paint(&ctx.paint, altRect, tmAltTextBackground_ColorId); 4168 fillRect_Paint(&ctx.paint, altRect, tmBackgroundAltText_ColorId);
4126 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId); 4169 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId);
4127 setOpacity_Text(altTextOpacity); 4170 setOpacity_Text(altTextOpacity);
4128 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap, 4171 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap,