summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-15 07:44:49 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-15 07:44:49 +0300
commita308db056515f8fb30be36d6ff028b788626465c (patch)
tree8ace58b91bebc7fcca27d0d2a09816cb198d05c8 /src
parenta0ebaca4600d38df843244bda5f54a75d7c59d83 (diff)
Init and scroll position improvements
Scroll positions are saved as normalized positions so they don’t get affected by zoom differences.
Diffstat (limited to 'src')
-rw-r--r--src/app.c3
-rw-r--r--src/history.c16
-rw-r--r--src/history.h2
-rw-r--r--src/ui/command.c9
-rw-r--r--src/ui/command.h1
-rw-r--r--src/ui/documentwidget.c36
-rw-r--r--src/ui/documentwidget.h2
7 files changed, 47 insertions, 22 deletions
diff --git a/src/app.c b/src/app.c
index bdd345f7..ee30d644 100644
--- a/src/app.c
+++ b/src/app.c
@@ -255,6 +255,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
255#endif 255#endif
256 d->window = new_Window(d->initialWindowRect); 256 d->window = new_Window(d->initialWindowRect);
257 /* Widget state init. */ 257 /* Widget state init. */
258 processEvents_App(postedEventsOnly_AppEventMode);
258 if (!loadState_App_(d)) { 259 if (!loadState_App_(d)) {
259 postCommand_App("navigate.home"); 260 postCommand_App("navigate.home");
260 } 261 }
@@ -512,7 +513,7 @@ iBool handleCommand_App(const char *cmd) {
512 } 513 }
513 } 514 }
514 visitUrl_Visited(d->visited, url); 515 visitUrl_Visited(d->visited, url);
515 setInitialScroll_DocumentWidget(doc, argLabel_Command(cmd, "scroll") * gap_UI); 516 setInitialScroll_DocumentWidget(doc, argfLabel_Command(cmd, "scroll"));
516 setUrlFromCache_DocumentWidget(doc, url, isHistory); 517 setUrlFromCache_DocumentWidget(doc, url, isHistory);
517 } 518 }
518 else if (equal_Command(cmd, "document.request.cancelled")) { 519 else if (equal_Command(cmd, "document.request.cancelled")) {
diff --git a/src/history.c b/src/history.c
index 9779795a..24912d81 100644
--- a/src/history.c
+++ b/src/history.c
@@ -8,7 +8,7 @@ static const size_t maxStack_History_ = 50; /* back/forward navigable items */
8 8
9void init_RecentUrl(iRecentUrl *d) { 9void init_RecentUrl(iRecentUrl *d) {
10 init_String(&d->url); 10 init_String(&d->url);
11 d->scrollY = 0; 11 d->normScrollY = 0;
12 d->cachedResponse = NULL; 12 d->cachedResponse = NULL;
13} 13}
14 14
@@ -22,7 +22,7 @@ iDefineTypeConstruction(RecentUrl)
22iRecentUrl *copy_RecentUrl(const iRecentUrl *d) { 22iRecentUrl *copy_RecentUrl(const iRecentUrl *d) {
23 iRecentUrl *copy = new_RecentUrl(); 23 iRecentUrl *copy = new_RecentUrl();
24 set_String(&copy->url, &d->url); 24 set_String(&copy->url, &d->url);
25 copy->scrollY = d->scrollY; 25 copy->normScrollY = d->normScrollY;
26 copy->cachedResponse = d->cachedResponse ? copy_GmResponse(d->cachedResponse) : NULL; 26 copy->cachedResponse = d->cachedResponse ? copy_GmResponse(d->cachedResponse) : NULL;
27 return copy; 27 return copy;
28} 28}
@@ -61,7 +61,7 @@ void serialize_History(const iHistory *d, iStream *outs) {
61 iConstForEach(Array, i, &d->recent) { 61 iConstForEach(Array, i, &d->recent) {
62 const iRecentUrl *item = i.value; 62 const iRecentUrl *item = i.value;
63 serialize_String(&item->url, outs); 63 serialize_String(&item->url, outs);
64 write32_Stream(outs, item->scrollY); 64 write32_Stream(outs, item->normScrollY * 1.0e6f);
65 if (item->cachedResponse) { 65 if (item->cachedResponse) {
66 write8_Stream(outs, 1); 66 write8_Stream(outs, 1);
67 serialize_GmResponse(item->cachedResponse, outs); 67 serialize_GmResponse(item->cachedResponse, outs);
@@ -80,7 +80,7 @@ void deserialize_History(iHistory *d, iStream *ins) {
80 iRecentUrl item; 80 iRecentUrl item;
81 init_RecentUrl(&item); 81 init_RecentUrl(&item);
82 deserialize_String(&item.url, ins); 82 deserialize_String(&item.url, ins);
83 item.scrollY = read32_Stream(ins); 83 item.normScrollY = (float) read32_Stream(ins) / 1.0e6f;
84 if (read8_Stream(ins)) { 84 if (read8_Stream(ins)) {
85 item.cachedResponse = new_GmResponse(); 85 item.cachedResponse = new_GmResponse();
86 deserialize_GmResponse(item.cachedResponse, ins); 86 deserialize_GmResponse(item.cachedResponse, ins);
@@ -166,8 +166,8 @@ void add_History(iHistory *d, const iString *url ){
166iBool goBack_History(iHistory *d) { 166iBool goBack_History(iHistory *d) {
167 if (d->recentPos < size_Array(&d->recent) - 1) { 167 if (d->recentPos < size_Array(&d->recent) - 1) {
168 d->recentPos++; 168 d->recentPos++;
169 postCommandf_App("open history:1 scroll:%d url:%s", 169 postCommandf_App("open history:1 scroll:%f url:%s",
170 mostRecentUrl_History(d)->scrollY, 170 mostRecentUrl_History(d)->normScrollY,
171 cstr_String(url_History(d, d->recentPos))); 171 cstr_String(url_History(d, d->recentPos)));
172 return iTrue; 172 return iTrue;
173 } 173 }
@@ -177,7 +177,9 @@ iBool goBack_History(iHistory *d) {
177iBool goForward_History(iHistory *d) { 177iBool goForward_History(iHistory *d) {
178 if (d->recentPos > 0) { 178 if (d->recentPos > 0) {
179 d->recentPos--; 179 d->recentPos--;
180 postCommandf_App("open history:1 url:%s", cstr_String(url_History(d, d->recentPos))); 180 postCommandf_App("open history:1 scroll:%f url:%s",
181 mostRecentUrl_History(d)->normScrollY,
182 cstr_String(url_History(d, d->recentPos)));
181 return iTrue; 183 return iTrue;
182 } 184 }
183 return iFalse; 185 return iFalse;
diff --git a/src/history.h b/src/history.h
index 6ccfd199..cf3a46be 100644
--- a/src/history.h
+++ b/src/history.h
@@ -11,7 +11,7 @@ iDeclareTypeConstruction(RecentUrl)
11 11
12struct Impl_RecentUrl { 12struct Impl_RecentUrl {
13 iString url; 13 iString url;
14 int scrollY; /* unit is gap_UI */ 14 float normScrollY; /* normalized to document height */
15 iGmResponse *cachedResponse; /* kept in memory for quicker back navigation */ 15 iGmResponse *cachedResponse; /* kept in memory for quicker back navigation */
16}; 16};
17 17
diff --git a/src/ui/command.c b/src/ui/command.c
index c0828343..19228e46 100644
--- a/src/ui/command.c
+++ b/src/ui/command.c
@@ -28,6 +28,15 @@ int arg_Command(const char *cmd) {
28 return argLabel_Command(cmd, "arg"); 28 return argLabel_Command(cmd, "arg");
29} 29}
30 30
31float argfLabel_Command(const char *cmd, const char *label) {
32 const iString *tok = tokenString_(label);
33 const char *ptr = strstr(cmd, cstr_String(tok));
34 if (ptr) {
35 return strtof(ptr + size_String(tok), NULL);
36 }
37 return 0.0f;
38}
39
31float argf_Command(const char *cmd) { 40float argf_Command(const char *cmd) {
32 const char *ptr = strstr(cmd, " arg:"); 41 const char *ptr = strstr(cmd, " arg:");
33 if (ptr) { 42 if (ptr) {
diff --git a/src/ui/command.h b/src/ui/command.h
index aed4a0f2..2124d527 100644
--- a/src/ui/command.h
+++ b/src/ui/command.h
@@ -7,6 +7,7 @@ iBool equal_Command (const char *commandWithArgs, const char *comman
7int arg_Command (const char *); /* arg: */ 7int arg_Command (const char *); /* arg: */
8float argf_Command (const char *); /* arg: */ 8float argf_Command (const char *); /* arg: */
9int argLabel_Command (const char *, const char *label); 9int argLabel_Command (const char *, const char *label);
10float argfLabel_Command (const char *, const char *label);
10void * pointer_Command (const char *); /* ptr: */ 11void * pointer_Command (const char *); /* ptr: */
11void * pointerLabel_Command (const char *, const char *label); 12void * pointerLabel_Command (const char *, const char *label);
12iInt2 coord_Command (const char *); 13iInt2 coord_Command (const char *);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index a04e1216..d425b8a9 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -131,7 +131,7 @@ struct Impl_DocumentWidget {
131 const iGmRun *hoverLink; 131 const iGmRun *hoverLink;
132 iBool noHoverWhileScrolling; 132 iBool noHoverWhileScrolling;
133 iClick click; 133 iClick click;
134 int initialScrollY; 134 float initialNormScrollY;
135 int scrollY; 135 int scrollY;
136 iScrollWidget *scroll; 136 iScrollWidget *scroll;
137 iWidget *menu; 137 iWidget *menu;
@@ -157,7 +157,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
157 d->isRequestUpdated = iFalse; 157 d->isRequestUpdated = iFalse;
158 d->media = new_ObjectList(); 158 d->media = new_ObjectList();
159 d->doc = new_GmDocument(); 159 d->doc = new_GmDocument();
160 d->initialScrollY = 0; 160 d->initialNormScrollY = 0;
161 d->scrollY = 0; 161 d->scrollY = 0;
162 d->selecting = iFalse; 162 d->selecting = iFalse;
163 d->selectMark = iNullRange; 163 d->selectMark = iNullRange;
@@ -262,6 +262,14 @@ static void addVisibleLink_DocumentWidget_(void *context, const iGmRun *run) {
262 } 262 }
263} 263}
264 264
265static float normScrollPos_DocumentWidget_(const iDocumentWidget *d) {
266 const int docSize = size_GmDocument(d->doc).y;
267 if (docSize) {
268 return (float) d->scrollY / (float) docSize;
269 }
270 return 0;
271}
272
265static int scrollMax_DocumentWidget_(const iDocumentWidget *d) { 273static int scrollMax_DocumentWidget_(const iDocumentWidget *d) {
266 return size_GmDocument(d->doc).y - height_Rect(bounds_Widget(constAs_Widget(d))) + 274 return size_GmDocument(d->doc).y - height_Rect(bounds_Widget(constAs_Widget(d))) +
267 2 * d->pageMargin * gap_UI; 275 2 * d->pageMargin * gap_UI;
@@ -307,8 +315,8 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
307 updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window())); 315 updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window()));
308 /* Remember scroll positions of recently visited pages. */ { 316 /* Remember scroll positions of recently visited pages. */ {
309 iRecentUrl *recent = mostRecentUrl_History(d->mod.history); 317 iRecentUrl *recent = mostRecentUrl_History(d->mod.history);
310 if (recent) { 318 if (recent && docSize && d->state == ready_RequestState) {
311 recent->scrollY = d->scrollY / gap_UI; 319 recent->normScrollY = normScrollPos_DocumentWidget_(d);
312 } 320 }
313 } 321 }
314} 322}
@@ -505,7 +513,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse
505 return; 513 return;
506 } 514 }
507 /* Convert the source to UTF-8 if needed. */ 515 /* Convert the source to UTF-8 if needed. */
508 if (!equal_Rangecc(&charset, "utf-8")) { 516 if (!equalCase_Rangecc(&charset, "utf-8")) {
509 set_String(&str, 517 set_String(&str,
510 collect_String(decode_Block(&str.chars, cstr_Rangecc(charset)))); 518 collect_String(decode_Block(&str.chars, cstr_Rangecc(charset))));
511 } 519 }
@@ -577,11 +585,13 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
577 if (recent && recent->cachedResponse) { 585 if (recent && recent->cachedResponse) {
578 const iGmResponse *resp = recent->cachedResponse; 586 const iGmResponse *resp = recent->cachedResponse;
579 d->state = fetching_RequestState; 587 d->state = fetching_RequestState;
588 d->initialNormScrollY = recent->normScrollY;
580 /* Use the cached response data. */ 589 /* Use the cached response data. */
581 d->scrollY = d->initialScrollY = recent->scrollY * gap_UI;
582 updateTrust_DocumentWidget_(d, resp); 590 updateTrust_DocumentWidget_(d, resp);
583 updateDocument_DocumentWidget_(d, resp); 591 updateDocument_DocumentWidget_(d, resp);
592 d->scrollY = d->initialNormScrollY * size_GmDocument(d->doc).y;
584 d->state = ready_RequestState; 593 d->state = ready_RequestState;
594 updateVisible_DocumentWidget_(d);
585 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); 595 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url));
586 return iTrue; 596 return iTrue;
587 } 597 }
@@ -621,8 +631,8 @@ void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBoo
621iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) { 631iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) {
622 iDocumentWidget *d = new_DocumentWidget(); 632 iDocumentWidget *d = new_DocumentWidget();
623 delete_History(d->mod.history); 633 delete_History(d->mod.history);
624 d->initialScrollY = orig->scrollY; 634 d->initialNormScrollY = normScrollPos_DocumentWidget_(d);
625 d->mod.history = copy_History(orig->mod.history); 635 d->mod.history = copy_History(orig->mod.history);
626 setUrlFromCache_DocumentWidget(d, orig->mod.url, iTrue); 636 setUrlFromCache_DocumentWidget(d, orig->mod.url, iTrue);
627 return d; 637 return d;
628} 638}
@@ -631,8 +641,8 @@ void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) {
631 setUrlFromCache_DocumentWidget(d, url, iFalse); 641 setUrlFromCache_DocumentWidget(d, url, iFalse);
632} 642}
633 643
634void setInitialScroll_DocumentWidget (iDocumentWidget *d, int scrollY) { 644void setInitialScroll_DocumentWidget(iDocumentWidget *d, float normScrollY) {
635 d->initialScrollY = scrollY; 645 d->initialNormScrollY = normScrollY;
636} 646}
637 647
638iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { 648iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) {
@@ -691,7 +701,7 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
691 break; 701 break;
692 } 702 }
693 case categorySuccess_GmStatusCode: 703 case categorySuccess_GmStatusCode:
694 d->scrollY = d->initialScrollY; 704 d->scrollY = 0;
695 reset_GmDocument(d->doc); /* new content incoming */ 705 reset_GmDocument(d->doc); /* new content incoming */
696 updateDocument_DocumentWidget_(d, response_GmRequest(d->request)); 706 updateDocument_DocumentWidget_(d, response_GmRequest(d->request));
697 break; 707 break;
@@ -944,9 +954,11 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
944 else if (equalWidget_Command(cmd, w, "document.request.finished") && 954 else if (equalWidget_Command(cmd, w, "document.request.finished") &&
945 pointerLabel_Command(cmd, "request") == d->request) { 955 pointerLabel_Command(cmd, "request") == d->request) {
946 checkResponse_DocumentWidget_(d); 956 checkResponse_DocumentWidget_(d);
957 d->scrollY = d->initialNormScrollY * size_GmDocument(d->doc).y;
947 d->state = ready_RequestState; 958 d->state = ready_RequestState;
948 setCachedResponse_History(d->mod.history, response_GmRequest(d->request)); 959 setCachedResponse_History(d->mod.history, response_GmRequest(d->request));
949 iReleasePtr(&d->request); 960 iReleasePtr(&d->request);
961 updateVisible_DocumentWidget_(d);
950 postCommandf_App("document.changed url:%s", cstr_String(d->mod.url)); 962 postCommandf_App("document.changed url:%s", cstr_String(d->mod.url));
951 return iFalse; 963 return iFalse;
952 } 964 }
@@ -971,7 +983,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
971 return handleMediaCommand_DocumentWidget_(d, cmd); 983 return handleMediaCommand_DocumentWidget_(d, cmd);
972 } 984 }
973 else if (equal_Command(cmd, "document.reload") && document_App() == d) { 985 else if (equal_Command(cmd, "document.reload") && document_App() == d) {
974 d->initialScrollY = d->scrollY; 986 d->initialNormScrollY = normScrollPos_DocumentWidget_(d);
975 fetch_DocumentWidget_(d); 987 fetch_DocumentWidget_(d);
976 return iTrue; 988 return iTrue;
977 } 989 }
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h
index 98591901..074516c3 100644
--- a/src/ui/documentwidget.h
+++ b/src/ui/documentwidget.h
@@ -22,6 +22,6 @@ const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *);
22 22
23void setUrl_DocumentWidget (iDocumentWidget *, const iString *url); 23void setUrl_DocumentWidget (iDocumentWidget *, const iString *url);
24void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache); 24void setUrlFromCache_DocumentWidget (iDocumentWidget *, const iString *url, iBool isFromCache);
25void setInitialScroll_DocumentWidget (iDocumentWidget *, int scrollY); /* set after content received */ 25void setInitialScroll_DocumentWidget (iDocumentWidget *, float normScrollY); /* set after content received */
26 26
27void updateSize_DocumentWidget (iDocumentWidget *); 27void updateSize_DocumentWidget (iDocumentWidget *);