summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gmdocument.c2
-rw-r--r--src/ui/inputwidget.c61
-rw-r--r--src/ui/inputwidget.h1
-rw-r--r--src/ui/root.c13
-rw-r--r--src/ui/util.c28
-rw-r--r--src/ui/util.h2
-rw-r--r--src/ui/widget.c5
7 files changed, 91 insertions, 21 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 466169fc..b2f2e236 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -722,7 +722,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
722 const int wrapAvail = d->size.x - run.bounds.pos.x - rightMargin * gap_Text; 722 const int wrapAvail = d->size.x - run.bounds.pos.x - rightMargin * gap_Text;
723 const int avail = isWordWrapped ? wrapAvail : 0; 723 const int avail = isWordWrapped ? wrapAvail : 0;
724 const char *contPos; 724 const char *contPos;
725 const iInt2 dims = tryAdvance_Text(run.font, runLine, avail, &contPos); 725 const iInt2 dims = tryAdvance_Text(run.font, runLine, avail, &contPos);
726 iChangeFlags(run.flags, wide_GmRunFlag, (isPreformat && dims.x > d->size.x)); 726 iChangeFlags(run.flags, wide_GmRunFlag, (isPreformat && dims.x > d->size.x));
727 run.bounds.size.x = iMax(wrapAvail, dims.x); /* Extends to the right edge for selection. */ 727 run.bounds.size.x = iMax(wrapAvail, dims.x); /* Extends to the right edge for selection. */
728 run.bounds.size.y = dims.y; 728 run.bounds.size.y = dims.y;
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 22dd4c92..0fd80ca5 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -104,6 +104,7 @@ struct Impl_InputWidget {
104 enum iInputMode mode; 104 enum iInputMode mode;
105 int inFlags; 105 int inFlags;
106 size_t maxLen; 106 size_t maxLen;
107 size_t maxLayoutLines;
107 iArray text; /* iChar[] */ 108 iArray text; /* iChar[] */
108 iArray oldText; /* iChar[] */ 109 iArray oldText; /* iChar[] */
109 iArray lines; 110 iArray lines;
@@ -162,7 +163,8 @@ iLocalDef iInt2 padding_(void) {
162} 163}
163 164
164static iRect contentBounds_InputWidget_(const iInputWidget *d) { 165static iRect contentBounds_InputWidget_(const iInputWidget *d) {
165 const iWidget *w = constAs_Widget(d); 166 const iWidget *w = constAs_Widget(d);
167 const iRect widgetBounds = bounds_Widget(w);
166 iRect bounds = adjusted_Rect(bounds_Widget(w), 168 iRect bounds = adjusted_Rect(bounds_Widget(w),
167 addX_I2(padding_(), d->leftPadding), 169 addX_I2(padding_(), d->leftPadding),
168 neg_I2(addX_I2(padding_(), d->rightPadding))); 170 neg_I2(addX_I2(padding_(), d->rightPadding)));
@@ -233,7 +235,12 @@ static void updateLines_InputWidget_(iInputWidget *d) {
233 const int wrapWidth = contentBounds_InputWidget_(d).size.x; 235 const int wrapWidth = contentBounds_InputWidget_(d).size.x;
234 while (wrapWidth > 0 && content.end != content.start) { 236 while (wrapWidth > 0 && content.end != content.start) {
235 const char *endPos; 237 const char *endPos;
236 tryAdvance_Text(d->font, content, wrapWidth, &endPos); 238 if (d->inFlags & isUrl_InputWidgetFlag) {
239 tryAdvanceNoWrap_Text(d->font, content, wrapWidth, &endPos);
240 }
241 else {
242 tryAdvance_Text(d->font, content, wrapWidth, &endPos);
243 }
237 const iRangecc part = (iRangecc){ content.start, endPos }; 244 const iRangecc part = (iRangecc){ content.start, endPos };
238 iInputLine line; 245 iInputLine line;
239 init_InputLine(&line); 246 init_InputLine(&line);
@@ -256,15 +263,19 @@ static void updateLines_InputWidget_(iInputWidget *d) {
256 updateCursorLine_InputWidget_(d); 263 updateCursorLine_InputWidget_(d);
257} 264}
258 265
259static int contentHeight_InputWidget_(const iInputWidget *d) { 266static int contentHeight_InputWidget_(const iInputWidget *d, iBool forLayout) {
260 return iMax(1, size_Array(&d->lines)) * lineHeight_Text(d->font); 267 size_t numLines = iMax(1, size_Array(&d->lines));
268 if (forLayout) {
269 numLines = iMin(numLines, d->maxLayoutLines);
270 }
271 return numLines * lineHeight_Text(d->font);
261} 272}
262 273
263static void updateMetrics_InputWidget_(iInputWidget *d) { 274static void updateMetrics_InputWidget_(iInputWidget *d) {
264 iWidget *w = as_Widget(d); 275 iWidget *w = as_Widget(d);
265 updateSizeForFixedLength_InputWidget_(d); 276 updateSizeForFixedLength_InputWidget_(d);
266 /* Caller must arrange the width, but the height is fixed. */ 277 /* Caller must arrange the width, but the height is fixed. */
267 w->rect.size.y = contentHeight_InputWidget_(d) + 3 * padding_().y; /* TODO: Why 3x? */ 278 w->rect.size.y = contentHeight_InputWidget_(d, iTrue) + 3 * padding_().y; /* TODO: Why 3x? */
268 if (flags_Widget(w) & extraPadding_WidgetFlag) { 279 if (flags_Widget(w) & extraPadding_WidgetFlag) {
269 w->rect.size.y += 2 * gap_UI; 280 w->rect.size.y += 2 * gap_UI;
270 } 281 }
@@ -276,6 +287,7 @@ static void updateLinesAndResize_InputWidget_(iInputWidget *d) {
276 const size_t oldCount = size_Array(&d->lines); 287 const size_t oldCount = size_Array(&d->lines);
277 updateLines_InputWidget_(d); 288 updateLines_InputWidget_(d);
278 if (oldCount != size_Array(&d->lines)) { 289 if (oldCount != size_Array(&d->lines)) {
290 d->click.minHeight = contentHeight_InputWidget_(d, iFalse);
279 updateMetrics_InputWidget_(d); 291 updateMetrics_InputWidget_(d);
280 } 292 }
281} 293}
@@ -303,6 +315,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
303 d->inFlags = eatEscape_InputWidgetFlag; 315 d->inFlags = eatEscape_InputWidgetFlag;
304 iZap(d->mark); 316 iZap(d->mark);
305 setMaxLen_InputWidget(d, maxLen); 317 setMaxLen_InputWidget(d, maxLen);
318 d->maxLayoutLines = iInvalidSize;
306 setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); 319 setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue);
307 init_Click(&d->click, d, SDL_BUTTON_LEFT); 320 init_Click(&d->click, d, SDL_BUTTON_LEFT);
308 d->timer = 0; 321 d->timer = 0;
@@ -405,6 +418,11 @@ void setMaxLen_InputWidget(iInputWidget *d, size_t maxLen) {
405 updateSizeForFixedLength_InputWidget_(d); 418 updateSizeForFixedLength_InputWidget_(d);
406} 419}
407 420
421void setMaxLayoutLines_InputWidget(iInputWidget *d, size_t maxLayoutLines) {
422 d->maxLayoutLines = maxLayoutLines;
423 updateMetrics_InputWidget_(d);
424}
425
408void setHint_InputWidget(iInputWidget *d, const char *hintText) { 426void setHint_InputWidget(iInputWidget *d, const char *hintText) {
409 /* Keep original for retranslations. */ 427 /* Keep original for retranslations. */
410 setCStr_String(&d->srcHint, hintText); 428 setCStr_String(&d->srcHint, hintText);
@@ -532,7 +550,7 @@ void begin_InputWidget(iInputWidget *d) {
532 } 550 }
533 updateCursorLine_InputWidget_(d); 551 updateCursorLine_InputWidget_(d);
534 SDL_StartTextInput(); 552 SDL_StartTextInput();
535 setFlags_Widget(w, selected_WidgetFlag, iTrue); 553 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iTrue);
536 showCursor_InputWidget_(d); 554 showCursor_InputWidget_(d);
537 refresh_Widget(w); 555 refresh_Widget(w);
538 d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); 556 d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d);
@@ -560,7 +578,7 @@ void end_InputWidget(iInputWidget *d, iBool accept) {
560 SDL_RemoveTimer(d->timer); 578 SDL_RemoveTimer(d->timer);
561 d->timer = 0; 579 d->timer = 0;
562 SDL_StopTextInput(); 580 SDL_StopTextInput();
563 setFlags_Widget(w, selected_WidgetFlag, iFalse); 581 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iFalse);
564 const char *id = cstr_String(id_Widget(as_Widget(d))); 582 const char *id = cstr_String(id_Widget(as_Widget(d)));
565 if (!*id) id = "_"; 583 if (!*id) id = "_";
566 updateLinesAndResize_InputWidget_(d); 584 updateLinesAndResize_InputWidget_(d);
@@ -866,6 +884,20 @@ static void extendRange_InputWidget_(iInputWidget *d, size_t *pos, int dir) {
866 } 884 }
867} 885}
868 886
887static iRect bounds_InputWidget_(const iInputWidget *d) {
888 const iWidget *w = constAs_Widget(d);
889 iRect bounds = bounds_Widget(w);
890 if (!isFocused_Widget(d)) {
891 return bounds;
892 }
893 bounds.size.y = contentHeight_InputWidget_(d, iFalse) + 3 * padding_().y;
894 return bounds;
895}
896
897static iBool contains_InputWidget_(const iInputWidget *d, iInt2 coord) {
898 return contains_Rect(bounds_InputWidget_(d), coord);
899}
900
869static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { 901static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
870 iWidget *w = as_Widget(d); 902 iWidget *w = as_Widget(d);
871 if (isCommand_Widget(w, ev, "focus.gained")) { 903 if (isCommand_Widget(w, ev, "focus.gained")) {
@@ -925,8 +957,9 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
925 copy_InputWidget_(d, iFalse); 957 copy_InputWidget_(d, iFalse);
926 return iTrue; 958 return iTrue;
927 } 959 }
928 if (ev->type == SDL_MOUSEMOTION && isHover_Widget(d)) { 960 if (ev->type == SDL_MOUSEMOTION && (isHover_Widget(d) || flags_Widget(w) & keepOnTop_WidgetFlag)) {
929 const iInt2 inner = windowToInner_Widget(w, init_I2(ev->motion.x, ev->motion.y)); 961 const iInt2 coord = init_I2(ev->motion.x, ev->motion.y);
962 const iInt2 inner = windowToInner_Widget(w, coord);
930 setCursor_Window(get_Window(), 963 setCursor_Window(get_Window(),
931 inner.x >= 2 * gap_UI + d->leftPadding && 964 inner.x >= 2 * gap_UI + d->leftPadding &&
932 inner.x < width_Widget(w) - d->rightPadding 965 inner.x < width_Widget(w) - d->rightPadding
@@ -976,6 +1009,12 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
976 d->inFlags &= ~isMarking_InputWidgetFlag; 1009 d->inFlags &= ~isMarking_InputWidgetFlag;
977 return iTrue; 1010 return iTrue;
978 } 1011 }
1012 if (ev->type == SDL_MOUSEMOTION && flags_Widget(w) & keepOnTop_WidgetFlag) {
1013 const iInt2 coord = init_I2(ev->motion.x, ev->motion.y);
1014 if (contains_Click(&d->click, coord)) {
1015 return iTrue;
1016 }
1017 }
979 if (ev->type == SDL_MOUSEBUTTONDOWN && ev->button.button == SDL_BUTTON_RIGHT && 1018 if (ev->type == SDL_MOUSEBUTTONDOWN && ev->button.button == SDL_BUTTON_RIGHT &&
980 contains_Widget(w, init_I2(ev->button.x, ev->button.y))) { 1019 contains_Widget(w, init_I2(ev->button.x, ev->button.y))) {
981 iWidget *clipMenu = findWidget_App("clipmenu"); 1020 iWidget *clipMenu = findWidget_App("clipmenu");
@@ -1193,11 +1232,11 @@ static iBool isWhite_(const iString *str) {
1193 1232
1194static void draw_InputWidget_(const iInputWidget *d) { 1233static void draw_InputWidget_(const iInputWidget *d) {
1195 const iWidget *w = constAs_Widget(d); 1234 const iWidget *w = constAs_Widget(d);
1196 iRect bounds = adjusted_Rect(bounds_Widget(w), padding_(), neg_I2(padding_())); 1235 iRect bounds = adjusted_Rect(bounds_InputWidget_(d), padding_(), neg_I2(padding_()));
1197 iBool isHint = iFalse; 1236 iBool isHint = iFalse;
1198 const iBool isFocused = isFocused_Widget(w); 1237 const iBool isFocused = isFocused_Widget(w);
1199 const iBool isHover = isHover_Widget(w) && 1238 const iBool isHover = isHover_Widget(w) &&
1200 contains_Widget(w, mouseCoord_Window(get_Window())); 1239 contains_InputWidget_(d, mouseCoord_Window(get_Window()));
1201 if (d->inFlags & needUpdateBuffer_InputWidgetFlag) { 1240 if (d->inFlags & needUpdateBuffer_InputWidgetFlag) {
1202 updateBuffered_InputWidget_(iConstCast(iInputWidget *, d)); 1241 updateBuffered_InputWidget_(iConstCast(iInputWidget *, d));
1203 } 1242 }
diff --git a/src/ui/inputwidget.h b/src/ui/inputwidget.h
index 86484dcc..a632e230 100644
--- a/src/ui/inputwidget.h
+++ b/src/ui/inputwidget.h
@@ -47,6 +47,7 @@ void setTextCStr_InputWidget (iInputWidget *, const char *cstr);
47void setFont_InputWidget (iInputWidget *, int fontId); 47void setFont_InputWidget (iInputWidget *, int fontId);
48void setCursor_InputWidget (iInputWidget *, size_t pos); 48void setCursor_InputWidget (iInputWidget *, size_t pos);
49void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ 49void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */
50void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines);
50void begin_InputWidget (iInputWidget *); 51void begin_InputWidget (iInputWidget *);
51void end_InputWidget (iInputWidget *, iBool accept); 52void end_InputWidget (iInputWidget *, iBool accept);
52void selectAll_InputWidget (iInputWidget *); 53void selectAll_InputWidget (iInputWidget *);
diff --git a/src/ui/root.c b/src/ui/root.c
index 8db8f7af..6f91b370 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -534,13 +534,17 @@ static iBool willPerformSearchQuery_(const iString *userInput) {
534 return !isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(userInput); 534 return !isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(userInput);
535} 535}
536 536
537static void updateUrlInputContentPadding_(iWidget *navBar) {
538 iInputWidget *url = findChild_Widget(navBar, "url");
539 const iWidget *indicators = findChild_Widget(navBar, "url.rightembed");
540 setContentPadding_InputWidget(url, -1,
541 width_Widget(indicators));
542}
543
537static void showSearchQueryIndicator_(iBool show) { 544static void showSearchQueryIndicator_(iBool show) {
538 iWidget *indicator = findWidget_App("input.indicator.search"); 545 iWidget *indicator = findWidget_App("input.indicator.search");
539 showCollapsed_Widget(indicator, show); 546 showCollapsed_Widget(indicator, show);
540 iAssert(isInstance_Object(parent_Widget(parent_Widget(indicator)), &Class_InputWidget)); 547 updateUrlInputContentPadding_(findWidget_Root("navbar"));
541 iInputWidget *url = (iInputWidget *) parent_Widget(parent_Widget(indicator));
542 setContentPadding_InputWidget(url, -1, contentPadding_InputWidget(url).left +
543 (show ? width_Widget(indicator) : 0));
544} 548}
545 549
546static int navBarAvailableSpace_(iWidget *navBar) { 550static int navBarAvailableSpace_(iWidget *navBar) {
@@ -1008,6 +1012,7 @@ void createUserInterface_Root(iRoot *d) {
1008 setFlags_Widget(as_Widget(url), resizeHeightOfChildren_WidgetFlag, iTrue); 1012 setFlags_Widget(as_Widget(url), resizeHeightOfChildren_WidgetFlag, iTrue);
1009 setSelectAllOnFocus_InputWidget(url, iTrue); 1013 setSelectAllOnFocus_InputWidget(url, iTrue);
1010 setId_Widget(as_Widget(url), "url"); 1014 setId_Widget(as_Widget(url), "url");
1015 setMaxLayoutLines_InputWidget(url, 1);
1011 setUrlContent_InputWidget(url, iTrue); 1016 setUrlContent_InputWidget(url, iTrue);
1012 setNotifyEdits_InputWidget(url, iTrue); 1017 setNotifyEdits_InputWidget(url, iTrue);
1013 setTextCStr_InputWidget(url, "gemini://"); 1018 setTextCStr_InputWidget(url, "gemini://");
diff --git a/src/ui/util.c b/src/ui/util.c
index 92cf85b7..f20338b5 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -378,10 +378,20 @@ void init_Click(iClick *d, iAnyObject *widget, int button) {
378 d->isActive = iFalse; 378 d->isActive = iFalse;
379 d->button = button; 379 d->button = button;
380 d->bounds = as_Widget(widget); 380 d->bounds = as_Widget(widget);
381 d->minHeight = 0;
381 d->startPos = zero_I2(); 382 d->startPos = zero_I2();
382 d->pos = zero_I2(); 383 d->pos = zero_I2();
383} 384}
384 385
386iBool contains_Click(const iClick *d, iInt2 coord) {
387 if (d->minHeight) {
388 iRect rect = bounds_Widget(d->bounds);
389 rect.size.y = iMax(d->minHeight, rect.size.y);
390 return contains_Rect(rect, coord);
391 }
392 return contains_Widget(d->bounds, coord);
393}
394
385enum iClickResult processEvent_Click(iClick *d, const SDL_Event *event) { 395enum iClickResult processEvent_Click(iClick *d, const SDL_Event *event) {
386 if (event->type == SDL_MOUSEMOTION) { 396 if (event->type == SDL_MOUSEMOTION) {
387 const iInt2 pos = init_I2(event->motion.x, event->motion.y); 397 const iInt2 pos = init_I2(event->motion.x, event->motion.y);
@@ -403,7 +413,7 @@ enum iClickResult processEvent_Click(iClick *d, const SDL_Event *event) {
403 } 413 }
404 if (!d->isActive) { 414 if (!d->isActive) {
405 if (mb->state == SDL_PRESSED) { 415 if (mb->state == SDL_PRESSED) {
406 if (contains_Widget(d->bounds, pos)) { 416 if (contains_Click(d, pos)) {
407 d->isActive = iTrue; 417 d->isActive = iTrue;
408 d->startPos = d->pos = pos; 418 d->startPos = d->pos = pos;
409 setMouseGrab_Widget(d->bounds); 419 setMouseGrab_Widget(d->bounds);
@@ -413,7 +423,7 @@ enum iClickResult processEvent_Click(iClick *d, const SDL_Event *event) {
413 } 423 }
414 else { /* Active. */ 424 else { /* Active. */
415 if (mb->state == SDL_RELEASED) { 425 if (mb->state == SDL_RELEASED) {
416 enum iClickResult result = contains_Widget(d->bounds, pos) 426 enum iClickResult result = contains_Click(d, pos)
417 ? finished_ClickResult 427 ? finished_ClickResult
418 : aborted_ClickResult; 428 : aborted_ClickResult;
419 d->isActive = iFalse; 429 d->isActive = iFalse;
@@ -891,6 +901,14 @@ static iBool isTabPage_Widget_(const iWidget *tabs, const iWidget *page) {
891 return page && page->parent == findChild_Widget(tabs, "tabs.pages"); 901 return page && page->parent == findChild_Widget(tabs, "tabs.pages");
892} 902}
893 903
904static void unfocusFocusInsideTabPage_(const iWidget *page) {
905 iWidget *focus = focus_Widget();
906 if (page && focus && hasParent_Widget(focus, page)) {
907 printf("unfocus inside page: %p\n", focus);
908 setFocus_Widget(NULL);
909 }
910}
911
894static iBool tabSwitcher_(iWidget *tabs, const char *cmd) { 912static iBool tabSwitcher_(iWidget *tabs, const char *cmd) {
895 if (equal_Command(cmd, "tabs.switch")) { 913 if (equal_Command(cmd, "tabs.switch")) {
896 iWidget *target = pointerLabel_Command(cmd, "page"); 914 iWidget *target = pointerLabel_Command(cmd, "page");
@@ -898,6 +916,7 @@ static iBool tabSwitcher_(iWidget *tabs, const char *cmd) {
898 target = findChild_Widget(tabs, cstr_Rangecc(range_Command(cmd, "id"))); 916 target = findChild_Widget(tabs, cstr_Rangecc(range_Command(cmd, "id")));
899 } 917 }
900 if (!target) return iFalse; 918 if (!target) return iFalse;
919 unfocusFocusInsideTabPage_(currentTabPage_Widget(tabs));
901 if (flags_Widget(target) & focusable_WidgetFlag) { 920 if (flags_Widget(target) & focusable_WidgetFlag) {
902 setFocus_Widget(target); 921 setFocus_Widget(target);
903 } 922 }
@@ -915,6 +934,7 @@ static iBool tabSwitcher_(iWidget *tabs, const char *cmd) {
915 } 934 }
916 } 935 }
917 else if (equal_Command(cmd, "tabs.next") || equal_Command(cmd, "tabs.prev")) { 936 else if (equal_Command(cmd, "tabs.next") || equal_Command(cmd, "tabs.prev")) {
937 unfocusFocusInsideTabPage_(currentTabPage_Widget(tabs));
918 iWidget *pages = findChild_Widget(tabs, "tabs.pages"); 938 iWidget *pages = findChild_Widget(tabs, "tabs.pages");
919 int tabIndex = 0; 939 int tabIndex = 0;
920 iConstForEach(ObjectList, i, pages->children) { 940 iConstForEach(ObjectList, i, pages->children) {
@@ -2205,7 +2225,9 @@ iWidget *makePreferences_Widget(void) {
2205 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.downloads}"))); 2225 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.downloads}")));
2206 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.downloads"); 2226 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.downloads");
2207#endif 2227#endif
2208 addPrefsInputWithHeading_(headings, values, "prefs.searchurl", iClob(new_InputWidget(0))); 2228 iInputWidget *searchUrl;
2229 addPrefsInputWithHeading_(headings, values, "prefs.searchurl", iClob(searchUrl = new_InputWidget(0)));
2230 setUrlContent_InputWidget(searchUrl, iTrue);
2209 addChild_Widget(headings, iClob(makePadding_Widget(bigGap))); 2231 addChild_Widget(headings, iClob(makePadding_Widget(bigGap)));
2210 addChild_Widget(values, iClob(makePadding_Widget(bigGap))); 2232 addChild_Widget(values, iClob(makePadding_Widget(bigGap)));
2211 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.collapsepreonload}"))); 2233 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.collapsepreonload}")));
diff --git a/src/ui/util.h b/src/ui/util.h
index cbedefaa..50845280 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -154,6 +154,7 @@ struct Impl_Click {
154 int button; 154 int button;
155 int count; 155 int count;
156 iWidget *bounds; 156 iWidget *bounds;
157 int minHeight;
157 iInt2 startPos; 158 iInt2 startPos;
158 iInt2 pos; 159 iInt2 pos;
159}; 160};
@@ -166,6 +167,7 @@ iBool isMoved_Click (const iClick *);
166iInt2 pos_Click (const iClick *); 167iInt2 pos_Click (const iClick *);
167iRect rect_Click (const iClick *); 168iRect rect_Click (const iClick *);
168iInt2 delta_Click (const iClick *); 169iInt2 delta_Click (const iClick *);
170iBool contains_Click (const iClick *, iInt2 coord);
169 171
170/*-----------------------------------------------------------------------------------------------*/ 172/*-----------------------------------------------------------------------------------------------*/
171 173
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 67ce1345..6412481b 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -1035,6 +1035,7 @@ void drawBackground_Widget(const iWidget *d) {
1035 init_Paint(&p); 1035 init_Paint(&p);
1036 drawSoftShadow_Paint(&p, bounds_Widget(d), 12 * gap_UI, black_ColorId, 30); 1036 drawSoftShadow_Paint(&p, bounds_Widget(d), 12 * gap_UI, black_ColorId, 30);
1037 } 1037 }
1038
1038 if (fadeBackground && ~d->flags & noFadeBackground_WidgetFlag) { 1039 if (fadeBackground && ~d->flags & noFadeBackground_WidgetFlag) {
1039 iPaint p; 1040 iPaint p;
1040 init_Paint(&p); 1041 init_Paint(&p);
@@ -1131,10 +1132,10 @@ void drawChildren_Widget(const iWidget *d) {
1131 } 1132 }
1132 } 1133 }
1133 /* Root draws the on-top widgets on top of everything else. */ 1134 /* Root draws the on-top widgets on top of everything else. */
1134 if (!d->parent) { 1135 if (d == d->root->widget) {
1135 iConstForEach(PtrArray, i, onTop_Root(d->root)) { 1136 iConstForEach(PtrArray, i, onTop_Root(d->root)) {
1136 const iWidget *top = *i.value; 1137 const iWidget *top = *i.value;
1137 draw_Widget(top); 1138 class_Widget(top)->draw(top);
1138 } 1139 }
1139 } 1140 }
1140} 1141}