diff options
-rw-r--r-- | src/app.c | 14 | ||||
-rw-r--r-- | src/app.h | 8 | ||||
-rw-r--r-- | src/ui/command.c | 2 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 117 | ||||
-rw-r--r-- | src/ui/widget.c | 15 | ||||
-rw-r--r-- | src/ui/widget.h | 2 | ||||
-rw-r--r-- | src/ui/window.c | 52 |
7 files changed, 132 insertions, 78 deletions
@@ -389,6 +389,20 @@ iBool handleCommand_App(const char *cmd) { | |||
389 | #endif | 389 | #endif |
390 | return iFalse; | 390 | return iFalse; |
391 | } | 391 | } |
392 | else if (equal_Command(cmd, "tabs.new")) { | ||
393 | iWidget *tabs = findWidget_App("doctabs"); | ||
394 | iWidget *newTabButton = findChild_Widget(tabs, "newtab"); | ||
395 | removeChild_Widget(newTabButton->parent, newTabButton); | ||
396 | iDocumentWidget *newDoc = new_DocumentWidget(); | ||
397 | setId_Widget(as_Widget(newDoc), format_CStr("document%03d", tabCount_Widget(tabs))); | ||
398 | appendTabPage_Widget(tabs, iClob(newDoc), "", 0, 0); | ||
399 | addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton)); | ||
400 | postCommandf_App("tabs.switch page:%p", newDoc); | ||
401 | postCommand_App("navigate.home"); | ||
402 | arrange_Widget(tabs); | ||
403 | refresh_Widget(tabs); | ||
404 | return iTrue; | ||
405 | } | ||
392 | else if (equal_Command(cmd, "quit")) { | 406 | else if (equal_Command(cmd, "quit")) { |
393 | SDL_Event ev; | 407 | SDL_Event ev; |
394 | ev.type = SDL_QUIT; | 408 | ev.type = SDL_QUIT; |
@@ -5,6 +5,7 @@ | |||
5 | #include <the_Foundation/string.h> | 5 | #include <the_Foundation/string.h> |
6 | #include <the_Foundation/time.h> | 6 | #include <the_Foundation/time.h> |
7 | 7 | ||
8 | iDeclareType(DocumentWidget) | ||
8 | iDeclareType(GmCerts) | 9 | iDeclareType(GmCerts) |
9 | iDeclareType(Visited) | 10 | iDeclareType(Visited) |
10 | iDeclareType(Window) | 11 | iDeclareType(Window) |
@@ -26,8 +27,11 @@ void processEvents_App (enum iAppEventMode mode); | |||
26 | iBool handleCommand_App (const char *cmd); | 27 | iBool handleCommand_App (const char *cmd); |
27 | void refresh_App (void); | 28 | void refresh_App (void); |
28 | 29 | ||
29 | iGmCerts * certs_App (void); | 30 | iGmCerts * certs_App (void); |
30 | iVisited * visited_App (void); | 31 | iVisited * visited_App (void); |
32 | iDocumentWidget * document_App (void); | ||
33 | iDocumentWidget * document_Command (const char *cmd); | ||
34 | |||
31 | 35 | ||
32 | iAny * findWidget_App (const char *id); | 36 | iAny * findWidget_App (const char *id); |
33 | void addTicker_App (void (*ticker)(iAny *), iAny *context); | 37 | void addTicker_App (void (*ticker)(iAny *), iAny *context); |
diff --git a/src/ui/command.c b/src/ui/command.c index b79c8bcf..c0828343 100644 --- a/src/ui/command.c +++ b/src/ui/command.c | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | iBool equal_Command(const char *cmdWithArgs, const char *cmd) { | 7 | iBool equal_Command(const char *cmdWithArgs, const char *cmd) { |
8 | if (strchr(cmdWithArgs, ':')) { | 8 | if (strchr(cmdWithArgs, ':')) { |
9 | return beginsWith_CStr(cmdWithArgs, cmd) && cmdWithArgs[strlen(cmd)] == ' '; | 9 | return startsWith_CStr(cmdWithArgs, cmd) && cmdWithArgs[strlen(cmd)] == ' '; |
10 | } | 10 | } |
11 | return equal_CStr(cmdWithArgs, cmd); | 11 | return equal_CStr(cmdWithArgs, cmd); |
12 | } | 12 | } |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index a1299727..7ae43458 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -109,7 +109,7 @@ iDefineObjectConstruction(DocumentWidget) | |||
109 | void init_DocumentWidget(iDocumentWidget *d) { | 109 | void init_DocumentWidget(iDocumentWidget *d) { |
110 | iWidget *w = as_Widget(d); | 110 | iWidget *w = as_Widget(d); |
111 | init_Widget(w); | 111 | init_Widget(w); |
112 | setId_Widget(w, "document"); | 112 | setId_Widget(w, "document000"); |
113 | iZap(d->certExpiry); | 113 | iZap(d->certExpiry); |
114 | d->history = new_History(); | 114 | d->history = new_History(); |
115 | d->state = blank_DocumentState; | 115 | d->state = blank_DocumentState; |
@@ -195,13 +195,13 @@ static void requestUpdated_DocumentWidget_(iAnyObject *obj) { | |||
195 | iDocumentWidget *d = obj; | 195 | iDocumentWidget *d = obj; |
196 | const int wasUpdated = exchange_Atomic(&d->isRequestUpdated, iTrue); | 196 | const int wasUpdated = exchange_Atomic(&d->isRequestUpdated, iTrue); |
197 | if (!wasUpdated) { | 197 | if (!wasUpdated) { |
198 | postCommand_Widget(obj, "document.request.updated request:%p", d->request); | 198 | postCommand_Widget(obj, "document.request.updated doc:%p request:%p", d, d->request); |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | static void requestFinished_DocumentWidget_(iAnyObject *obj) { | 202 | static void requestFinished_DocumentWidget_(iAnyObject *obj) { |
203 | iDocumentWidget *d = obj; | 203 | iDocumentWidget *d = obj; |
204 | postCommand_Widget(obj, "document.request.finished request:%p", d->request); | 204 | postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request); |
205 | } | 205 | } |
206 | 206 | ||
207 | static iRangei visibleRange_DocumentWidget_(const iDocumentWidget *d) { | 207 | static iRangei visibleRange_DocumentWidget_(const iDocumentWidget *d) { |
@@ -330,6 +330,16 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
330 | d->state = ready_DocumentState; | 330 | d->state = ready_DocumentState; |
331 | } | 331 | } |
332 | 332 | ||
333 | static void updateTheme_DocumentWidget_(iDocumentWidget *d) { | ||
334 | if (isEmpty_String(d->titleUser)) { | ||
335 | setThemeSeed_GmDocument(d->doc, | ||
336 | collect_Block(newRange_Block(urlHost_String(d->url)))); | ||
337 | } | ||
338 | else { | ||
339 | setThemeSeed_GmDocument(d->doc, &d->titleUser->chars); | ||
340 | } | ||
341 | } | ||
342 | |||
333 | static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response) { | 343 | static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response) { |
334 | if (d->state == ready_DocumentState) { | 344 | if (d->state == ready_DocumentState) { |
335 | return; | 345 | return; |
@@ -339,15 +349,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
339 | const enum iGmStatusCode statusCode = response->statusCode; | 349 | const enum iGmStatusCode statusCode = response->statusCode; |
340 | if (category_GmStatusCode(statusCode) != categoryInput_GmStatusCode) { | 350 | if (category_GmStatusCode(statusCode) != categoryInput_GmStatusCode) { |
341 | iString str; | 351 | iString str; |
342 | /* Update theme. */ { | 352 | updateTheme_DocumentWidget_(d); |
343 | if (isEmpty_String(d->titleUser)) { | ||
344 | setThemeSeed_GmDocument(d->doc, | ||
345 | collect_Block(newRange_Block(urlHost_String(d->url)))); | ||
346 | } | ||
347 | else { | ||
348 | setThemeSeed_GmDocument(d->doc, &d->titleUser->chars); | ||
349 | } | ||
350 | } | ||
351 | initBlock_String(&str, &response->body); | 353 | initBlock_String(&str, &response->body); |
352 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { | 354 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { |
353 | /* Check the MIME type. */ | 355 | /* Check the MIME type. */ |
@@ -392,7 +394,7 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) { | |||
392 | iRelease(d->request); | 394 | iRelease(d->request); |
393 | d->request = NULL; | 395 | d->request = NULL; |
394 | } | 396 | } |
395 | postCommandf_App("document.request.started url:%s", cstr_String(d->url)); | 397 | postCommandf_App("document.request.started doc:%p url:%s", d, cstr_String(d->url)); |
396 | clear_ObjectList(d->media); | 398 | clear_ObjectList(d->media); |
397 | d->certFlags = 0; | 399 | d->certFlags = 0; |
398 | d->state = fetching_DocumentState; | 400 | d->state = fetching_DocumentState; |
@@ -632,7 +634,7 @@ static iBool requestMedia_DocumentWidget_(iDocumentWidget *d, iGmLinkId linkId) | |||
632 | return iFalse; | 634 | return iFalse; |
633 | } | 635 | } |
634 | 636 | ||
635 | static iBool handleMediaEvent_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 637 | static iBool handleMediaCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
636 | iMediaRequest *req = pointerLabel_Command(cmd, "request"); | 638 | iMediaRequest *req = pointerLabel_Command(cmd, "request"); |
637 | if (!req || req->doc != d) { | 639 | if (!req || req->doc != d) { |
638 | return iFalse; /* not our request */ | 640 | return iFalse; /* not our request */ |
@@ -680,9 +682,9 @@ static void changeTextSize_DocumentWidget_(iDocumentWidget *d, int delta) { | |||
680 | postCommandf_App("font.setfactor arg:%d", d->textSizePercent); | 682 | postCommandf_App("font.setfactor arg:%d", d->textSizePercent); |
681 | } | 683 | } |
682 | 684 | ||
683 | static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { | 685 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
684 | iWidget *w = as_Widget(d); | 686 | iWidget *w = as_Widget(d); |
685 | if (isResize_UserEvent(ev) || isCommand_UserEvent(ev, "font.changed")) { | 687 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { |
686 | const iGmRun *mid = middleRun_DocumentWidget_(d); | 688 | const iGmRun *mid = middleRun_DocumentWidget_(d); |
687 | const char *midLoc = (mid ? mid->text.start : NULL); | 689 | const char *midLoc = (mid ? mid->text.start : NULL); |
688 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | 690 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); |
@@ -696,9 +698,16 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
696 | } | 698 | } |
697 | refresh_Widget(w); | 699 | refresh_Widget(w); |
698 | } | 700 | } |
699 | else if (isCommand_UserEvent(ev, "server.showcert")) { | 701 | else if (equal_Command(cmd, "tabs.changed")) { |
702 | if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) { | ||
703 | /* Set palette for our document. */ | ||
704 | updateTheme_DocumentWidget_(d); | ||
705 | } | ||
706 | return iFalse; | ||
707 | } | ||
708 | else if (equal_Command(cmd, "server.showcert")) { | ||
700 | const char *unchecked = red_ColorEscape "\u2610"; | 709 | const char *unchecked = red_ColorEscape "\u2610"; |
701 | const char *checked = green_ColorEscape "\u2611"; | 710 | const char *checked = green_ColorEscape "\u2611"; |
702 | makeMessage_Widget( | 711 | makeMessage_Widget( |
703 | cyan_ColorEscape "CERTIFICATE STATUS", | 712 | cyan_ColorEscape "CERTIFICATE STATUS", |
704 | format_CStr("%s%s Domain name %s\n" | 713 | format_CStr("%s%s Domain name %s\n" |
@@ -721,7 +730,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
721 | d->certFlags & trusted_GmCertFlag ? "Trusted on first use" : "Not trusted")); | 730 | d->certFlags & trusted_GmCertFlag ? "Trusted on first use" : "Not trusted")); |
722 | return iTrue; | 731 | return iTrue; |
723 | } | 732 | } |
724 | else if (isCommand_UserEvent(ev, "copy")) { | 733 | else if (equal_Command(cmd, "copy")) { |
725 | if (d->selectMark.start) { | 734 | if (d->selectMark.start) { |
726 | iRangecc mark = d->selectMark; | 735 | iRangecc mark = d->selectMark; |
727 | if (mark.start > mark.end) { | 736 | if (mark.start > mark.end) { |
@@ -733,7 +742,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
733 | return iTrue; | 742 | return iTrue; |
734 | } | 743 | } |
735 | } | 744 | } |
736 | else if (isCommand_Widget(w, ev, "document.copylink")) { | 745 | else if (equalWidget_Command(cmd, w, "document.copylink")) { |
737 | if (d->hoverLink) { | 746 | if (d->hoverLink) { |
738 | SDL_SetClipboardText(cstr_String( | 747 | SDL_SetClipboardText(cstr_String( |
739 | absoluteUrl_String(d->url, linkUrl_GmDocument(d->doc, d->hoverLink->linkId)))); | 748 | absoluteUrl_String(d->url, linkUrl_GmDocument(d->doc, d->hoverLink->linkId)))); |
@@ -743,8 +752,8 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
743 | } | 752 | } |
744 | return iTrue; | 753 | return iTrue; |
745 | } | 754 | } |
746 | else if (isCommand_UserEvent(ev, "document.input.submit")) { | 755 | else if (equal_Command(cmd, "document.input.submit")) { |
747 | iString *value = collect_String(suffix_Command(command_UserEvent(ev), "value")); | 756 | iString *value = collect_String(suffix_Command(cmd, "value")); |
748 | urlEncode_String(value); | 757 | urlEncode_String(value); |
749 | iString *url = collect_String(copy_String(d->url)); | 758 | iString *url = collect_String(copy_String(d->url)); |
750 | const size_t qPos = indexOfCStr_String(url, "?"); | 759 | const size_t qPos = indexOfCStr_String(url, "?"); |
@@ -756,19 +765,18 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
756 | postCommandf_App("open url:%s", cstr_String(url)); | 765 | postCommandf_App("open url:%s", cstr_String(url)); |
757 | return iTrue; | 766 | return iTrue; |
758 | } | 767 | } |
759 | else if (isCommand_UserEvent(ev, "valueinput.cancelled") && | 768 | else if (equal_Command(cmd, "valueinput.cancelled") && |
760 | cmp_String(string_Command(command_UserEvent(ev), "id"), "document.input.submit") == | 769 | cmp_String(string_Command(cmd, "id"), "document.input.submit") == 0) { |
761 | 0) { | ||
762 | postCommand_App("navigate.back"); | 770 | postCommand_App("navigate.back"); |
763 | return iTrue; | 771 | return iTrue; |
764 | } | 772 | } |
765 | else if (isCommand_Widget(w, ev, "document.request.updated") && | 773 | else if (equalWidget_Command(cmd, w, "document.request.updated") && |
766 | pointerLabel_Command(command_UserEvent(ev), "request") == d->request) { | 774 | pointerLabel_Command(cmd, "request") == d->request) { |
767 | checkResponse_DocumentWidget_(d); | 775 | checkResponse_DocumentWidget_(d); |
768 | return iFalse; | 776 | return iFalse; |
769 | } | 777 | } |
770 | else if (isCommand_Widget(w, ev, "document.request.finished") && | 778 | else if (equalWidget_Command(cmd, w, "document.request.finished") && |
771 | pointerLabel_Command(command_UserEvent(ev), "request") == d->request) { | 779 | pointerLabel_Command(cmd, "request") == d->request) { |
772 | checkResponse_DocumentWidget_(d); | 780 | checkResponse_DocumentWidget_(d); |
773 | d->state = ready_DocumentState; | 781 | d->state = ready_DocumentState; |
774 | setCachedResponse_History(d->history, response_GmRequest(d->request)); | 782 | setCachedResponse_History(d->history, response_GmRequest(d->request)); |
@@ -776,45 +784,46 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
776 | postCommandf_App("document.changed url:%s", cstr_String(d->url)); | 784 | postCommandf_App("document.changed url:%s", cstr_String(d->url)); |
777 | return iFalse; | 785 | return iFalse; |
778 | } | 786 | } |
779 | else if (isCommand_UserEvent(ev, "document.request.cancelled")) { | 787 | else if (equal_Command(cmd, "document.request.cancelled") && document_Command(cmd) == d) { |
780 | postCommand_App("navigate.back"); | 788 | postCommand_App("navigate.back"); |
781 | return iFalse; | 789 | return iFalse; |
782 | } | 790 | } |
783 | else if (isCommand_UserEvent(ev, "document.stop")) { | 791 | else if (equal_Command(cmd, "document.stop")) { |
784 | if (d->request) { | 792 | if (d->request) { |
785 | postCommandf_App("document.request.cancelled url:%s", cstr_String(d->url)); | 793 | postCommandf_App("document.request.cancelled doc:%p url:%s", d, cstr_String(d->url)); |
786 | iReleasePtr(&d->request); | 794 | iReleasePtr(&d->request); |
787 | d->state = ready_DocumentState; | 795 | d->state = ready_DocumentState; |
796 | return iTrue; | ||
788 | } | 797 | } |
789 | return iTrue; | ||
790 | } | 798 | } |
791 | else if (isCommand_UserEvent(ev, "media.updated") || isCommand_UserEvent(ev, "media.finished")) { | 799 | else if (equal_Command(cmd, "media.updated") || equal_Command(cmd, "media.finished")) { |
792 | return handleMediaEvent_DocumentWidget_(d, command_UserEvent(ev)); | 800 | return handleMediaCommand_DocumentWidget_(d, cmd); |
793 | } | 801 | } |
794 | else if (isCommand_UserEvent(ev, "document.reload")) { | 802 | else if (equal_Command(cmd, "document.reload") && document_App() == d) { |
795 | fetch_DocumentWidget_(d); | 803 | fetch_DocumentWidget_(d); |
796 | return iTrue; | 804 | return iTrue; |
797 | } | 805 | } |
798 | else if (isCommand_UserEvent(ev, "navigate.back")) { | 806 | else if (equal_Command(cmd, "navigate.back") && document_App() == d) { |
799 | goBack_History(d->history); | 807 | goBack_History(d->history); |
800 | return iTrue; | 808 | return iTrue; |
801 | } | 809 | } |
802 | else if (isCommand_UserEvent(ev, "navigate.forward")) { | 810 | else if (equal_Command(cmd, "navigate.forward") && document_App() == d) { |
803 | goForward_History(d->history); | 811 | goForward_History(d->history); |
804 | return iTrue; | 812 | return iTrue; |
805 | } | 813 | } |
806 | else if (isCommand_Widget(w, ev, "scroll.moved")) { | 814 | else if (equalWidget_Command(cmd, w, "scroll.moved")) { |
807 | d->scrollY = arg_Command(command_UserEvent(ev)); | 815 | d->scrollY = arg_Command(cmd); |
808 | updateVisible_DocumentWidget_(d); | 816 | updateVisible_DocumentWidget_(d); |
809 | return iTrue; | 817 | return iTrue; |
810 | } | 818 | } |
811 | else if (isCommand_Widget(w, ev, "scroll.page")) { | 819 | else if (equalWidget_Command(cmd, w, "scroll.page")) { |
812 | scroll_DocumentWidget_( | 820 | scroll_DocumentWidget_(d, |
813 | d, arg_Command(command_UserEvent(ev)) * height_Rect(documentBounds_DocumentWidget_(d))); | 821 | arg_Command(cmd) * height_Rect(documentBounds_DocumentWidget_(d))); |
814 | return iTrue; | 822 | return iTrue; |
815 | } | 823 | } |
816 | else if (isCommand_UserEvent(ev, "find.next") || isCommand_UserEvent(ev, "find.prev")) { | 824 | else if ((equal_Command(cmd, "find.next") || equal_Command(cmd, "find.prev")) && |
817 | const int dir = isCommand_UserEvent(ev, "find.next") ? +1 : -1; | 825 | document_App() == d) { |
826 | const int dir = equal_Command(cmd, "find.next") ? +1 : -1; | ||
818 | iRangecc (*finder)(const iGmDocument *, const iString *, const char *) = | 827 | iRangecc (*finder)(const iGmDocument *, const iString *, const char *) = |
819 | dir > 0 ? findText_GmDocument : findTextBefore_GmDocument; | 828 | dir > 0 ? findText_GmDocument : findTextBefore_GmDocument; |
820 | iInputWidget *find = findWidget_App("find.input"); | 829 | iInputWidget *find = findWidget_App("find.input"); |
@@ -824,7 +833,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
824 | else { | 833 | else { |
825 | const iBool wrap = d->foundMark.start != NULL; | 834 | const iBool wrap = d->foundMark.start != NULL; |
826 | d->foundMark = finder(d->doc, text_InputWidget(find), dir > 0 ? d->foundMark.end | 835 | d->foundMark = finder(d->doc, text_InputWidget(find), dir > 0 ? d->foundMark.end |
827 | : d->foundMark.start); | 836 | : d->foundMark.start); |
828 | if (!d->foundMark.start && wrap) { | 837 | if (!d->foundMark.start && wrap) { |
829 | /* Wrap around. */ | 838 | /* Wrap around. */ |
830 | d->foundMark = finder(d->doc, text_InputWidget(find), NULL); | 839 | d->foundMark = finder(d->doc, text_InputWidget(find), NULL); |
@@ -838,14 +847,26 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
838 | } | 847 | } |
839 | refresh_Widget(w); | 848 | refresh_Widget(w); |
840 | return iTrue; | 849 | return iTrue; |
841 | } | 850 | } |
842 | else if (isCommand_UserEvent(ev, "find.clearmark")) { | 851 | else if (equal_Command(cmd, "find.clearmark")) { |
843 | if (d->foundMark.start) { | 852 | if (d->foundMark.start) { |
844 | d->foundMark = iNullRange; | 853 | d->foundMark = iNullRange; |
845 | refresh_Widget(w); | 854 | refresh_Widget(w); |
846 | } | 855 | } |
847 | return iTrue; | 856 | return iTrue; |
848 | } | 857 | } |
858 | return iFalse; | ||
859 | } | ||
860 | |||
861 | static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { | ||
862 | iWidget *w = as_Widget(d); | ||
863 | if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) { | ||
864 | if (!handleCommand_DocumentWidget_(d, command_UserEvent(ev))) { | ||
865 | /* Base class commands. */ | ||
866 | return processEvent_Widget(w, ev); | ||
867 | } | ||
868 | return iTrue; | ||
869 | } | ||
849 | if (ev->type == SDL_KEYDOWN) { | 870 | if (ev->type == SDL_KEYDOWN) { |
850 | const int mods = keyMods_Sym(ev->key.keysym.mod); | 871 | const int mods = keyMods_Sym(ev->key.keysym.mod); |
851 | const int key = ev->key.keysym.sym; | 872 | const int key = ev->key.keysym.sym; |
diff --git a/src/ui/widget.c b/src/ui/widget.c index b07b5709..0db8b8fd 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -551,11 +551,18 @@ iBool isSelected_Widget(const iWidget *d) { | |||
551 | return (d->flags & selected_WidgetFlag) != 0; | 551 | return (d->flags & selected_WidgetFlag) != 0; |
552 | } | 552 | } |
553 | 553 | ||
554 | iBool equalWidget_Command(const char *cmd, const iWidget *widget, const char *checkCommand) { | ||
555 | if (equal_Command(cmd, checkCommand)) { | ||
556 | const iWidget *src = pointer_Command(cmd); | ||
557 | iAssert(!src || strstr(cmd, " ptr:")); | ||
558 | return src == widget || hasParent_Widget(src, widget); | ||
559 | } | ||
560 | return iFalse; | ||
561 | } | ||
562 | |||
554 | iBool isCommand_Widget(const iWidget *d, const SDL_Event *ev, const char *cmd) { | 563 | iBool isCommand_Widget(const iWidget *d, const SDL_Event *ev, const char *cmd) { |
555 | if (isCommand_UserEvent(ev, cmd)) { | 564 | if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) { |
556 | const iWidget *src = pointer_Command(command_UserEvent(ev)); | 565 | return equalWidget_Command(command_UserEvent(ev), d, cmd); |
557 | iAssert(!src || strstr(ev->user.data1, " ptr:")); | ||
558 | return src == d || hasParent_Widget(src, d); | ||
559 | } | 566 | } |
560 | return iFalse; | 567 | return iFalse; |
561 | } | 568 | } |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 7208a755..0aff6505 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -140,3 +140,5 @@ iWidget *hover_Widget (void); | |||
140 | void unhover_Widget (void); | 140 | void unhover_Widget (void); |
141 | void setMouseGrab_Widget (iWidget *); | 141 | void setMouseGrab_Widget (iWidget *); |
142 | iWidget *mouseGrab_Widget (void); | 142 | iWidget *mouseGrab_Widget (void); |
143 | |||
144 | iBool equalWidget_Command (const char *cmd, const iWidget *widget, const char *checkCommand); | ||
diff --git a/src/ui/window.c b/src/ui/window.c index defe998f..1f05b80d 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -107,29 +107,34 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
107 | return iTrue; | 107 | return iTrue; |
108 | } | 108 | } |
109 | } | 109 | } |
110 | else if (equal_Command(cmd, "document.changed")) { | 110 | else if (startsWith_CStr(cmd, "document.")) { |
111 | iInputWidget *url = findWidget_App("url"); | 111 | /* React to the current document only. */ |
112 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); | 112 | if (document_Command(cmd) == document_App()) { |
113 | visitUrl_Visited(visited_App(), urlStr); | 113 | iLabelWidget *reloadButton = findChild_Widget(navBar, "reload"); |
114 | setText_InputWidget(url, urlStr); | 114 | if (equal_Command(cmd, "document.changed")) { |
115 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), reloadCStr_); | 115 | iInputWidget *url = findWidget_App("url"); |
116 | return iFalse; | 116 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); |
117 | } | 117 | setText_InputWidget(url, urlStr); |
118 | else if (equal_Command(cmd, "document.request.cancelled")) { | 118 | updateTextCStr_LabelWidget(reloadButton, reloadCStr_); |
119 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), reloadCStr_); | 119 | return iFalse; |
120 | return iFalse; | 120 | } |
121 | } | 121 | else if (equal_Command(cmd, "document.request.cancelled")) { |
122 | else if (equal_Command(cmd, "document.request.started")) { | 122 | updateTextCStr_LabelWidget(reloadButton, reloadCStr_); |
123 | iInputWidget *url = findChild_Widget(navBar, "url"); | 123 | return iFalse; |
124 | if (isFocused_Widget(as_Widget(url))) { | 124 | } |
125 | setFocus_Widget(NULL); | 125 | else if (equal_Command(cmd, "document.request.started")) { |
126 | iInputWidget *url = findChild_Widget(navBar, "url"); | ||
127 | if (isFocused_Widget(as_Widget(url))) { | ||
128 | setFocus_Widget(NULL); | ||
129 | } | ||
130 | setTextCStr_InputWidget(url, suffixPtr_Command(cmd, "url")); | ||
131 | updateTextCStr_LabelWidget(reloadButton, stopCStr_); | ||
132 | return iFalse; | ||
133 | } | ||
126 | } | 134 | } |
127 | setTextCStr_InputWidget(url, suffixPtr_Command(cmd, "url")); | ||
128 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), stopCStr_); | ||
129 | return iFalse; | ||
130 | } | 135 | } |
131 | else if (equal_Command(cmd, "navigate.reload")) { | 136 | else if (equal_Command(cmd, "navigate.reload")) { |
132 | iDocumentWidget *doc = findWidget_App("document"); | 137 | iDocumentWidget *doc = document_Command(cmd); |
133 | if (isRequestOngoing_DocumentWidget(doc)) { | 138 | if (isRequestOngoing_DocumentWidget(doc)) { |
134 | postCommand_App("document.stop"); | 139 | postCommand_App("document.stop"); |
135 | } | 140 | } |
@@ -224,15 +229,16 @@ static void setupUserInterface_Window(iWindow *d) { | |||
224 | setAlignVisually_LabelWidget(fileMenu, iTrue); | 229 | setAlignVisually_LabelWidget(fileMenu, iTrue); |
225 | addChild_Widget(navBar, iClob(fileMenu)); | 230 | addChild_Widget(navBar, iClob(fileMenu)); |
226 | } | 231 | } |
227 | |||
228 | /* Tab bar. */ { | 232 | /* Tab bar. */ { |
229 | iWidget *tabBar = makeTabs_Widget(div); | 233 | iWidget *tabBar = makeTabs_Widget(div); |
230 | setId_Widget(tabBar, "doctabs"); | 234 | setId_Widget(tabBar, "doctabs"); |
231 | setFlags_Widget(tabBar, expand_WidgetFlag, iTrue); | 235 | setFlags_Widget(tabBar, expand_WidgetFlag, iTrue); |
232 | setBackgroundColor_Widget(tabBar, gray25_ColorId); | 236 | setBackgroundColor_Widget(tabBar, gray25_ColorId); |
233 | appendTabPage_Widget(tabBar, iClob(new_DocumentWidget()), "Document", '1', KMOD_PRIMARY); | 237 | appendTabPage_Widget(tabBar, iClob(new_DocumentWidget()), "Document", '1', KMOD_PRIMARY); |
234 | addChild_Widget(findChild_Widget(tabBar, "tabs.buttons"), | 238 | setId_Widget( |
235 | iClob(newIcon_LabelWidget("\u2795", 't', KMOD_PRIMARY, "tabs.new"))); | 239 | addChild_Widget(findChild_Widget(tabBar, "tabs.buttons"), |
240 | iClob(newIcon_LabelWidget("\u2795", 't', KMOD_PRIMARY, "tabs.new"))), | ||
241 | "newtab"); | ||
236 | } | 242 | } |
237 | /* Search bar. */ { | 243 | /* Search bar. */ { |
238 | iWidget *searchBar = new_Widget(); | 244 | iWidget *searchBar = new_Widget(); |