diff options
-rw-r--r-- | res/about/version.gmi | 5 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 22 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 4 | ||||
-rw-r--r-- | src/ui/text.c | 23 |
5 files changed, 34 insertions, 27 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi index 5141a4b1..35c730c1 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi | |||
@@ -10,6 +10,11 @@ | |||
10 | * Added support for viewing WebP images. The libwebp library is an optional dependency and will be included in the build if found via pkg-config. | 10 | * Added support for viewing WebP images. The libwebp library is an optional dependency and will be included in the build if found via pkg-config. |
11 | * Added a footer action to view `application/octet-stream` content depending on recognized file extensions. | 11 | * Added a footer action to view `application/octet-stream` content depending on recognized file extensions. |
12 | 12 | ||
13 | ## 1.6.5 | ||
14 | * Audio init errors are no longer fatal. SDL's error message will still be printed. | ||
15 | * Fixed a cursor position regression in input fields related to handling of variation selectors (codepoint clusters). Moving the cursor to the start of a wrapped line segment put the cursor in the wrong place. | ||
16 | * Fixed right-clicking on sidebar tab buttons. It was showing the wrong context menu when the list had been scrolled down. | ||
17 | |||
13 | ## 1.6.4 | 18 | ## 1.6.4 |
14 | * Local files containing UTF-8 text can be viewed regardless of their file extension. | 19 | * Local files containing UTF-8 text can be viewed regardless of their file extension. |
15 | * Fixed input field cursor positioning and insertion problems around Emoji variation selectors. | 20 | * Fixed input field cursor positioning and insertion problems around Emoji variation selectors. |
@@ -68,10 +68,13 @@ int main(int argc, char **argv) { | |||
68 | "DHE-RSA-AES256-GCM-SHA384"); | 68 | "DHE-RSA-AES256-GCM-SHA384"); |
69 | SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); | 69 | SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); |
70 | SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1"); | 70 | SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1"); |
71 | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { | 71 | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) { |
72 | fprintf(stderr, "SDL init failed: %s\n", SDL_GetError()); | 72 | fprintf(stderr, "[SDL] init failed: %s\n", SDL_GetError()); |
73 | return -1; | 73 | return -1; |
74 | } | 74 | } |
75 | if (SDL_Init(SDL_INIT_AUDIO)) { | ||
76 | fprintf(stderr, "[SDL] audio init failed: %s\n", SDL_GetError()); | ||
77 | } | ||
75 | run_App(argc, argv); | 78 | run_App(argc, argv); |
76 | SDL_Quit(); | 79 | SDL_Quit(); |
77 | #if defined (LAGRANGE_ENABLE_MPG123) | 80 | #if defined (LAGRANGE_ENABLE_MPG123) |
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index e0272a5d..fa65cf3c 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -59,7 +59,7 @@ static void enableEditorKeysInMenus_(iBool enable) { | |||
59 | /*----------------------------------------------------------------------------------------------*/ | 59 | /*----------------------------------------------------------------------------------------------*/ |
60 | 60 | ||
61 | iDeclareType(InputLine) | 61 | iDeclareType(InputLine) |
62 | 62 | ||
63 | struct Impl_InputLine { | 63 | struct Impl_InputLine { |
64 | iString text; | 64 | iString text; |
65 | iRanges range; /* byte offset inside the entire content; for marking */ | 65 | iRanges range; /* byte offset inside the entire content; for marking */ |
@@ -157,7 +157,7 @@ static void mergeLines_(const iArray *inputLines, iString *merged) { | |||
157 | } | 157 | } |
158 | 158 | ||
159 | iDefineTypeConstruction(InputLine) | 159 | iDefineTypeConstruction(InputLine) |
160 | 160 | ||
161 | /*----------------------------------------------------------------------------------------------*/ | 161 | /*----------------------------------------------------------------------------------------------*/ |
162 | 162 | ||
163 | iDeclareType(InputUndo) | 163 | iDeclareType(InputUndo) |
@@ -227,7 +227,7 @@ struct Impl_InputWidget { | |||
227 | }; | 227 | }; |
228 | 228 | ||
229 | iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen) | 229 | iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen) |
230 | 230 | ||
231 | static void updateMetrics_InputWidget_(iInputWidget *); | 231 | static void updateMetrics_InputWidget_(iInputWidget *); |
232 | 232 | ||
233 | static void restoreBackup_InputWidget_(iInputWidget *d) { | 233 | static void restoreBackup_InputWidget_(iInputWidget *d) { |
@@ -610,7 +610,7 @@ static uint32_t cursorTimer_(uint32_t interval, void *w) { | |||
610 | 610 | ||
611 | static void startOrStopCursorTimer_InputWidget_(iInputWidget *d, iBool doStart) { | 611 | static void startOrStopCursorTimer_InputWidget_(iInputWidget *d, iBool doStart) { |
612 | if (doStart && !d->timer) { | 612 | if (doStart && !d->timer) { |
613 | d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); | 613 | d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); |
614 | } | 614 | } |
615 | else if (!doStart && d->timer) { | 615 | else if (!doStart && d->timer) { |
616 | SDL_RemoveTimer(d->timer); | 616 | SDL_RemoveTimer(d->timer); |
@@ -679,7 +679,7 @@ void deinit_InputWidget(iInputWidget *d) { | |||
679 | delete_TextBuf(d->buffered); | 679 | delete_TextBuf(d->buffered); |
680 | clearUndo_InputWidget_(d); | 680 | clearUndo_InputWidget_(d); |
681 | deinit_Array(&d->undoStack); | 681 | deinit_Array(&d->undoStack); |
682 | startOrStopCursorTimer_InputWidget_(d, iFalse); | 682 | startOrStopCursorTimer_InputWidget_(d, iFalse); |
683 | deinit_String(&d->srcHint); | 683 | deinit_String(&d->srcHint); |
684 | deinit_String(&d->hint); | 684 | deinit_String(&d->hint); |
685 | deinit_String(&d->oldText); | 685 | deinit_String(&d->oldText); |
@@ -708,7 +708,7 @@ static iBool popUndo_InputWidget_(iInputWidget *d) { | |||
708 | splitToLines_(&undo->text, &d->lines); | 708 | splitToLines_(&undo->text, &d->lines); |
709 | d->cursor = undo->cursor; | 709 | d->cursor = undo->cursor; |
710 | deinit_InputUndo_(undo); | 710 | deinit_InputUndo_(undo); |
711 | popBack_Array(&d->undoStack); | 711 | popBack_Array(&d->undoStack); |
712 | iZap(d->mark); | 712 | iZap(d->mark); |
713 | updateAllLinesAndResizeHeight_InputWidget_(d); | 713 | updateAllLinesAndResizeHeight_InputWidget_(d); |
714 | return iTrue; | 714 | return iTrue; |
@@ -836,7 +836,7 @@ static iRangei visibleLineRange_InputWidget_(const iInputWidget *d) { | |||
836 | static void updateBuffered_InputWidget_(iInputWidget *d) { | 836 | static void updateBuffered_InputWidget_(iInputWidget *d) { |
837 | invalidateBuffered_InputWidget_(d); | 837 | invalidateBuffered_InputWidget_(d); |
838 | if (isHintVisible_InputWidget_(d)) { | 838 | if (isHintVisible_InputWidget_(d)) { |
839 | d->buffered = newRange_TextBuf(d->font, uiAnnotation_ColorId, range_String(&d->hint)); | 839 | d->buffered = newRange_TextBuf(d->font, uiAnnotation_ColorId, range_String(&d->hint)); |
840 | } | 840 | } |
841 | else { | 841 | else { |
842 | /* Draw all the potentially visible lines to a buffer. */ | 842 | /* Draw all the potentially visible lines to a buffer. */ |
@@ -1073,7 +1073,7 @@ static void insertRange_InputWidget_(iInputWidget *d, iRangecc range) { | |||
1073 | } | 1073 | } |
1074 | textOfLinesWasChanged_InputWidget_(d, (iRangei){ firstModified, d->cursor.y + 1 }); | 1074 | textOfLinesWasChanged_InputWidget_(d, (iRangei){ firstModified, d->cursor.y + 1 }); |
1075 | showCursor_InputWidget_(d); | 1075 | showCursor_InputWidget_(d); |
1076 | refresh_Widget(as_Widget(d)); | 1076 | refresh_Widget(as_Widget(d)); |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | static void insertChar_InputWidget_(iInputWidget *d, iChar chr) { | 1079 | static void insertChar_InputWidget_(iInputWidget *d, iChar chr) { |
@@ -1110,7 +1110,7 @@ void setCursor_InputWidget(iInputWidget *d, iInt2 pos) { | |||
1110 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir, int horiz) { | 1110 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir, int horiz) { |
1111 | const iInputLine *line = cursorLine_InputWidget_(d); | 1111 | const iInputLine *line = cursorLine_InputWidget_(d); |
1112 | iInt2 relCoord = relativeCursorCoord_InputWidget_(d); | 1112 | iInt2 relCoord = relativeCursorCoord_InputWidget_(d); |
1113 | int relLine = relCoord.y / lineHeight_Text(d->font); | 1113 | int relLine = relCoord.y / lineHeight_Text(d->font); |
1114 | if ((dir < 0 && relLine > 0) || (dir > 0 && relLine < numWrapLines_InputLine_(line) - 1)) { | 1114 | if ((dir < 0 && relLine > 0) || (dir > 0 && relLine < numWrapLines_InputLine_(line) - 1)) { |
1115 | relCoord.y += dir * lineHeight_Text(d->font); | 1115 | relCoord.y += dir * lineHeight_Text(d->font); |
1116 | } | 1116 | } |
@@ -1542,7 +1542,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1542 | else if (lineDelta > 0) { | 1542 | else if (lineDelta > 0) { |
1543 | lineDelta = iMin(lineDelta, | 1543 | lineDelta = iMin(lineDelta, |
1544 | lastLine_InputWidget_(d)->wrapLines.end - d->visWrapLines.end); | 1544 | lastLine_InputWidget_(d)->wrapLines.end - d->visWrapLines.end); |
1545 | if (!lineDelta) d->wheelAccum = 0; | 1545 | if (!lineDelta) d->wheelAccum = 0; |
1546 | } | 1546 | } |
1547 | d->wheelAccum -= lineDelta * lineHeight; | 1547 | d->wheelAccum -= lineDelta * lineHeight; |
1548 | d->visWrapLines.start += lineDelta; | 1548 | d->visWrapLines.start += lineDelta; |
@@ -1925,7 +1925,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1925 | } | 1925 | } |
1926 | iPaint p; | 1926 | iPaint p; |
1927 | init_Paint(&p); | 1927 | init_Paint(&p); |
1928 | /* `lines` is already up to date and ready for drawing. */ | 1928 | /* `lines` is already up to date and ready for drawing. */ |
1929 | fillRect_Paint( | 1929 | fillRect_Paint( |
1930 | &p, bounds, isFocused ? uiInputBackgroundFocused_ColorId : uiInputBackground_ColorId); | 1930 | &p, bounds, isFocused ? uiInputBackgroundFocused_ColorId : uiInputBackground_ColorId); |
1931 | drawRectThickness_Paint(&p, | 1931 | drawRectThickness_Paint(&p, |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index ea76a835..b816b572 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -1523,7 +1523,9 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1523 | return iTrue; | 1523 | return iTrue; |
1524 | } | 1524 | } |
1525 | } | 1525 | } |
1526 | if (hoverItem_ListWidget(d->list) || isVisible_Widget(d->menu)) { | 1526 | if (ev->type == SDL_MOUSEBUTTONDOWN && |
1527 | contains_Widget(as_Widget(d->list), init_I2(ev->button.x, ev->button.y)) && | ||
1528 | (hoverItem_ListWidget(d->list) || isVisible_Widget(d->menu))) { | ||
1527 | /* Update the menu before opening. */ | 1529 | /* Update the menu before opening. */ |
1528 | if (d->mode == bookmarks_SidebarMode && !isVisible_Widget(d->menu)) { | 1530 | if (d->mode == bookmarks_SidebarMode && !isVisible_Widget(d->menu)) { |
1529 | /* Remote bookmarks have limitations. */ | 1531 | /* Remote bookmarks have limitations. */ |
diff --git a/src/ui/text.c b/src/ui/text.c index c4596d1c..231281eb 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -195,7 +195,7 @@ static void init_Font(iFont *d, const iBlock *data, int height, float scale, | |||
195 | d->vertOffset = height * (1.0f - scale) / 2; | 195 | d->vertOffset = height * (1.0f - scale) / 2; |
196 | /* Custom tweaks. */ | 196 | /* Custom tweaks. */ |
197 | if (data == &fontNotoSansSymbolsRegular_Embedded) { | 197 | if (data == &fontNotoSansSymbolsRegular_Embedded) { |
198 | d->vertOffset *= 1.2f; | 198 | d->vertOffset *= 1.2f; |
199 | } | 199 | } |
200 | else if (data == &fontNotoSansSymbols2Regular_Embedded) { | 200 | else if (data == &fontNotoSansSymbols2Regular_Embedded) { |
201 | d->vertOffset /= 2; | 201 | d->vertOffset /= 2; |
@@ -1434,7 +1434,6 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1434 | iBool isFirst = iTrue; | 1434 | iBool isFirst = iTrue; |
1435 | const iBool checkHitPoint = wrap && !isEqual_I2(wrap->hitPoint, zero_I2()); | 1435 | const iBool checkHitPoint = wrap && !isEqual_I2(wrap->hitPoint, zero_I2()); |
1436 | const iBool checkHitChar = wrap && wrap->hitChar; | 1436 | const iBool checkHitChar = wrap && wrap->hitChar; |
1437 | iBool wasCharHit = iFalse; | ||
1438 | while (!isEmpty_Range(&wrapRuns)) { | 1437 | while (!isEmpty_Range(&wrapRuns)) { |
1439 | if (isFirst) { | 1438 | if (isFirst) { |
1440 | isFirst = iFalse; | 1439 | isFirst = iFalse; |
@@ -1448,17 +1447,16 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1448 | if (wrap && (wrap->maxWidth > 0 || checkHitPoint)) { | 1447 | if (wrap && (wrap->maxWidth > 0 || checkHitPoint)) { |
1449 | const iBool isHitPointOnThisLine = (checkHitPoint && wrap->hitPoint.y >= orig.y + yCursor && | 1448 | const iBool isHitPointOnThisLine = (checkHitPoint && wrap->hitPoint.y >= orig.y + yCursor && |
1450 | wrap->hitPoint.y < orig.y + yCursor + d->height); | 1449 | wrap->hitPoint.y < orig.y + yCursor + d->height); |
1450 | iBool wasCharHit = iFalse; /* on this line */ | ||
1451 | float breakAdvance = -1.0f; | 1451 | float breakAdvance = -1.0f; |
1452 | iAssert(wrapPosRange.end == textLen); | 1452 | iAssert(wrapPosRange.end == textLen); |
1453 | /* Determine ends of wrapRuns and wrapVisRange. */ | 1453 | /* Determine ends of wrapRuns and wrapVisRange. */ |
1454 | for (size_t runIndex = wrapRuns.start; runIndex < wrapRuns.end; runIndex++) { | 1454 | for (size_t runIndex = wrapRuns.start; runIndex < wrapRuns.end; runIndex++) { |
1455 | const iAttributedRun *run = at_Array(&attrText.runs, runIndex); | 1455 | const iAttributedRun *run = at_Array(&attrText.runs, runIndex); |
1456 | if (run->flags.isLineBreak) { | 1456 | if (run->flags.isLineBreak) { |
1457 | if (checkHitChar && !wasCharHit) { | 1457 | if (checkHitChar && |
1458 | if (wrap->hitChar == sourcePtr_AttributedText_(&attrText, run->logical.start)) { | 1458 | wrap->hitChar == sourcePtr_AttributedText_(&attrText, run->logical.start)) { |
1459 | wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); | 1459 | wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); |
1460 | wasCharHit = iTrue; | ||
1461 | } | ||
1462 | } | 1460 | } |
1463 | wrapPosRange.end = run->logical.start; | 1461 | wrapPosRange.end = run->logical.start; |
1464 | wrapResumePos = run->logical.end; | 1462 | wrapResumePos = run->logical.end; |
@@ -1482,11 +1480,10 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1482 | if (logPos < wrapPosRange.start || logPos >= wrapPosRange.end) { | 1480 | if (logPos < wrapPosRange.start || logPos >= wrapPosRange.end) { |
1483 | continue; | 1481 | continue; |
1484 | } | 1482 | } |
1485 | if (checkHitChar && !wasCharHit) { | 1483 | if (checkHitChar && !wasCharHit && |
1486 | if (wrap->hitChar == sourcePtr_AttributedText_(&attrText, logPos)) { | 1484 | wrap->hitChar == sourcePtr_AttributedText_(&attrText, logPos)) { |
1487 | wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); | 1485 | wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); |
1488 | wasCharHit = iTrue; | 1486 | wasCharHit = iTrue; /* variation selectors etc. have matching cluster */ |
1489 | } | ||
1490 | } | 1487 | } |
1491 | /* Check if the hit point is on the left side of this line. */ | 1488 | /* Check if the hit point is on the left side of this line. */ |
1492 | if (isHitPointOnThisLine && !wrap->hitChar_out && wrap->hitPoint.x < orig.x) { | 1489 | if (isHitPointOnThisLine && !wrap->hitChar_out && wrap->hitPoint.x < orig.x) { |
@@ -1873,7 +1870,7 @@ static void drawBoundedN_Text_(int fontId, iInt2 pos, int xposBound, int color, | |||
1873 | (color & fillBackground_ColorId ? fillBackground_RunMode : 0) | | 1870 | (color & fillBackground_ColorId ? fillBackground_RunMode : 0) | |
1874 | runFlagsFromId_(fontId), | 1871 | runFlagsFromId_(fontId), |
1875 | .text = text, | 1872 | .text = text, |
1876 | .maxLen = maxLen, | 1873 | .maxLen = maxLen, |
1877 | .pos = pos, | 1874 | .pos = pos, |
1878 | // .xposLayoutBound = xposBound, | 1875 | // .xposLayoutBound = xposBound, |
1879 | .color = color & mask_ColorId, | 1876 | .color = color & mask_ColorId, |