diff options
-rw-r--r-- | src/gmdocument.c | 2 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 61 | ||||
-rw-r--r-- | src/ui/inputwidget.h | 1 | ||||
-rw-r--r-- | src/ui/root.c | 13 | ||||
-rw-r--r-- | src/ui/util.c | 28 | ||||
-rw-r--r-- | src/ui/util.h | 2 | ||||
-rw-r--r-- | src/ui/widget.c | 5 |
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 | ||
164 | static iRect contentBounds_InputWidget_(const iInputWidget *d) { | 165 | static 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 | ||
259 | static int contentHeight_InputWidget_(const iInputWidget *d) { | 266 | static 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 | ||
263 | static void updateMetrics_InputWidget_(iInputWidget *d) { | 274 | static 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 | ||
421 | void setMaxLayoutLines_InputWidget(iInputWidget *d, size_t maxLayoutLines) { | ||
422 | d->maxLayoutLines = maxLayoutLines; | ||
423 | updateMetrics_InputWidget_(d); | ||
424 | } | ||
425 | |||
408 | void setHint_InputWidget(iInputWidget *d, const char *hintText) { | 426 | void 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 | ||
887 | static 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 | |||
897 | static iBool contains_InputWidget_(const iInputWidget *d, iInt2 coord) { | ||
898 | return contains_Rect(bounds_InputWidget_(d), coord); | ||
899 | } | ||
900 | |||
869 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | 901 | static 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 | ||
1194 | static void draw_InputWidget_(const iInputWidget *d) { | 1233 | static 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); | |||
47 | void setFont_InputWidget (iInputWidget *, int fontId); | 47 | void setFont_InputWidget (iInputWidget *, int fontId); |
48 | void setCursor_InputWidget (iInputWidget *, size_t pos); | 48 | void setCursor_InputWidget (iInputWidget *, size_t pos); |
49 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ | 49 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ |
50 | void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines); | ||
50 | void begin_InputWidget (iInputWidget *); | 51 | void begin_InputWidget (iInputWidget *); |
51 | void end_InputWidget (iInputWidget *, iBool accept); | 52 | void end_InputWidget (iInputWidget *, iBool accept); |
52 | void selectAll_InputWidget (iInputWidget *); | 53 | void 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 | ||
537 | static 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 | |||
537 | static void showSearchQueryIndicator_(iBool show) { | 544 | static 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 | ||
546 | static int navBarAvailableSpace_(iWidget *navBar) { | 550 | static 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 | ||
386 | iBool 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 | |||
385 | enum iClickResult processEvent_Click(iClick *d, const SDL_Event *event) { | 395 | enum 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 | ||
904 | static 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 | |||
894 | static iBool tabSwitcher_(iWidget *tabs, const char *cmd) { | 912 | static 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 *); | |||
166 | iInt2 pos_Click (const iClick *); | 167 | iInt2 pos_Click (const iClick *); |
167 | iRect rect_Click (const iClick *); | 168 | iRect rect_Click (const iClick *); |
168 | iInt2 delta_Click (const iClick *); | 169 | iInt2 delta_Click (const iClick *); |
170 | iBool 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 | } |