diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-14 14:09:59 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-14 14:09:59 +0300 |
commit | c2dd6107db2ff4b8001085068f4c1c5971cdd9c3 (patch) | |
tree | f4dc684dae9611abf1f672c853de44c8911db8fd | |
parent | bf390e96735a156cb221385cc057aeb957c088b9 (diff) |
Cleaner window initialization
Create the window using the correct size and position, and don’t show the window contents while app state is being restored.
-rw-r--r-- | src/app.c | 74 | ||||
-rw-r--r-- | src/gmdocument.c | 4 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 8 | ||||
-rw-r--r-- | src/ui/window.c | 30 | ||||
-rw-r--r-- | src/ui/window.h | 5 |
5 files changed, 77 insertions, 44 deletions
@@ -55,19 +55,20 @@ static const char *stateFileName_App_ = "state.bin"; | |||
55 | 55 | ||
56 | struct Impl_App { | 56 | struct Impl_App { |
57 | iCommandLine args; | 57 | iCommandLine args; |
58 | iBool commandEcho; /* --echo */ | ||
59 | iBool running; | ||
60 | iWindow * window; | ||
61 | iSortedArray tickers; | ||
62 | iBool pendingRefresh; | ||
63 | iGmCerts * certs; | 58 | iGmCerts * certs; |
64 | iVisited * visited; | 59 | iVisited * visited; |
65 | iBookmarks * bookmarks; | 60 | iBookmarks * bookmarks; |
66 | int zoomPercent; | 61 | iWindow * window; |
62 | iSortedArray tickers; | ||
63 | iBool running; | ||
64 | iBool pendingRefresh; | ||
67 | int tabEnum; | 65 | int tabEnum; |
68 | /* Preferences: */ | 66 | /* Preferences: */ |
67 | iBool commandEcho; /* --echo */ | ||
69 | iBool retainWindowSize; | 68 | iBool retainWindowSize; |
69 | iRect initialWindowRect; | ||
70 | float uiScale; | 70 | float uiScale; |
71 | int zoomPercent; | ||
71 | }; | 72 | }; |
72 | 73 | ||
73 | static iApp app_; | 74 | static iApp app_; |
@@ -101,9 +102,10 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
101 | int w, h, x, y; | 102 | int w, h, x, y; |
102 | SDL_GetWindowSize(d->window->win, &w, &h); | 103 | SDL_GetWindowSize(d->window->win, &w, &h); |
103 | SDL_GetWindowPosition(d->window->win, &x, &y); | 104 | SDL_GetWindowPosition(d->window->win, &x, &y); |
104 | appendFormat_String(str, "restorewindow width:%d height:%d coord:%d %d\n", w, h, x, y); | 105 | appendFormat_String(str, "window.setrect width:%d height:%d coord:%d %d\n", w, h, x, y); |
105 | appendFormat_String(str, "sidebar.width arg:%d\n", width_SidebarWidget(sidebar)); | 106 | appendFormat_String(str, "sidebar.width arg:%d\n", width_SidebarWidget(sidebar)); |
106 | } | 107 | } |
108 | appendFormat_String(str, "retainwindow arg:%d\n", d->retainWindowSize); | ||
107 | if (isVisible_Widget(constAs_Widget(sidebar))) { | 109 | if (isVisible_Widget(constAs_Widget(sidebar))) { |
108 | appendCStr_String(str, "sidebar.toggle\n"); | 110 | appendCStr_String(str, "sidebar.toggle\n"); |
109 | } | 111 | } |
@@ -127,16 +129,22 @@ static void loadPrefs_App_(iApp *d) { | |||
127 | const iRangecc src = range_String(str); | 129 | const iRangecc src = range_String(str); |
128 | iRangecc line = iNullRange; | 130 | iRangecc line = iNullRange; |
129 | while (nextSplit_Rangecc(&src, "\n", &line)) { | 131 | while (nextSplit_Rangecc(&src, "\n", &line)) { |
130 | iString cmd; | 132 | iString cmdStr; |
131 | initRange_String(&cmd, line); | 133 | initRange_String(&cmdStr, line); |
132 | if (equal_Command(cstr_String(&cmd), "uiscale")) { | 134 | const char *cmd = cstr_String(&cmdStr); |
133 | /* Must be handled before the window is created. */ | 135 | /* Window init commands must be handled before the window is created. */ |
134 | setUiScale_Window(get_Window(), argf_Command(cstr_String(&cmd))); | 136 | if (equal_Command(cmd, "uiscale")) { |
137 | setUiScale_Window(get_Window(), argf_Command(cmd)); | ||
138 | } | ||
139 | else if (equal_Command(cmd, "window.setrect")) { | ||
140 | const iInt2 pos = coord_Command(cmd); | ||
141 | d->initialWindowRect = init_Rect( | ||
142 | pos.x, pos.y, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); | ||
135 | } | 143 | } |
136 | else { | 144 | else { |
137 | postCommandString_App(&cmd); | 145 | postCommandString_App(&cmdStr); |
138 | } | 146 | } |
139 | deinit_String(&cmd); | 147 | deinit_String(&cmdStr); |
140 | } | 148 | } |
141 | delete_String(str); | 149 | delete_String(str); |
142 | } | 150 | } |
@@ -221,16 +229,17 @@ static void saveState_App_(const iApp *d) { | |||
221 | static void init_App_(iApp *d, int argc, char **argv) { | 229 | static void init_App_(iApp *d, int argc, char **argv) { |
222 | init_CommandLine(&d->args, argc, argv); | 230 | init_CommandLine(&d->args, argc, argv); |
223 | init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); | 231 | init_SortedArray(&d->tickers, sizeof(iTicker), cmp_Ticker_); |
224 | d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL; | 232 | d->commandEcho = checkArgument_CommandLine(&d->args, "echo") != NULL; |
225 | d->running = iFalse; | 233 | d->initialWindowRect = init_Rect(-1, -1, 800, 500); |
226 | d->window = NULL; | 234 | d->running = iFalse; |
227 | d->retainWindowSize = iTrue; | 235 | d->window = NULL; |
228 | d->pendingRefresh = iFalse; | 236 | d->retainWindowSize = iTrue; |
229 | d->zoomPercent = 100; | 237 | d->pendingRefresh = iFalse; |
230 | d->certs = new_GmCerts(dataDir_App_); | 238 | d->zoomPercent = 100; |
231 | d->visited = new_Visited(); | 239 | d->certs = new_GmCerts(dataDir_App_); |
232 | d->bookmarks = new_Bookmarks(); | 240 | d->visited = new_Visited(); |
233 | d->tabEnum = 0; | 241 | d->bookmarks = new_Bookmarks(); |
242 | d->tabEnum = 0; /* generates unique IDs for tab pages */ | ||
234 | loadPrefs_App_(d); | 243 | loadPrefs_App_(d); |
235 | load_Visited(d->visited, dataDir_App_); | 244 | load_Visited(d->visited, dataDir_App_); |
236 | load_Bookmarks(d->bookmarks, dataDir_App_); | 245 | load_Bookmarks(d->bookmarks, dataDir_App_); |
@@ -244,11 +253,12 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
244 | } | 253 | } |
245 | } | 254 | } |
246 | #endif | 255 | #endif |
247 | d->window = new_Window(); | 256 | d->window = new_Window(d->initialWindowRect); |
248 | /* Widget state init. */ | 257 | /* Widget state init. */ |
249 | if (!loadState_App_(d)) { | 258 | if (!loadState_App_(d)) { |
250 | postCommand_App("navigate.home"); | 259 | postCommand_App("navigate.home"); |
251 | } | 260 | } |
261 | postCommand_App("window.unblank"); | ||
252 | } | 262 | } |
253 | 263 | ||
254 | static void deinit_App(iApp *d) { | 264 | static void deinit_App(iApp *d) { |
@@ -423,6 +433,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { | |||
423 | if (equal_Command(cmd, "prefs.dismiss") || equal_Command(cmd, "preferences")) { | 433 | if (equal_Command(cmd, "prefs.dismiss") || equal_Command(cmd, "preferences")) { |
424 | setUiScale_Window(get_Window(), | 434 | setUiScale_Window(get_Window(), |
425 | toFloat_String(text_InputWidget(findChild_Widget(d, "prefs.uiscale")))); | 435 | toFloat_String(text_InputWidget(findChild_Widget(d, "prefs.uiscale")))); |
436 | postCommandf_App("retainwindow arg:%d", | ||
437 | isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); | ||
426 | destroy_Widget(d); | 438 | destroy_Widget(d); |
427 | return iTrue; | 439 | return iTrue; |
428 | } | 440 | } |
@@ -472,7 +484,11 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf) { | |||
472 | 484 | ||
473 | iBool handleCommand_App(const char *cmd) { | 485 | iBool handleCommand_App(const char *cmd) { |
474 | iApp *d = &app_; | 486 | iApp *d = &app_; |
475 | if (equal_Command(cmd, "open")) { | 487 | if (equal_Command(cmd, "retainwindow")) { |
488 | d->retainWindowSize = arg_Command(cmd); | ||
489 | return iTrue; | ||
490 | } | ||
491 | else if (equal_Command(cmd, "open")) { | ||
476 | const iString *url = collect_String(newCStr_String(suffixPtr_Command(cmd, "url"))); | 492 | const iString *url = collect_String(newCStr_String(suffixPtr_Command(cmd, "url"))); |
477 | iUrl parts; | 493 | iUrl parts; |
478 | init_Url(&parts, url); | 494 | init_Url(&parts, url); |
@@ -569,12 +585,6 @@ iBool handleCommand_App(const char *cmd) { | |||
569 | collectNewFormat_String("%g", uiScale_Window(d->window))); | 585 | collectNewFormat_String("%g", uiScale_Window(d->window))); |
570 | setCommandHandler_Widget(dlg, handlePrefsCommands_); | 586 | setCommandHandler_Widget(dlg, handlePrefsCommands_); |
571 | } | 587 | } |
572 | else if (equal_Command(cmd, "restorewindow")) { | ||
573 | d->retainWindowSize = iTrue; | ||
574 | resize_Window(d->window, argLabel_Command(cmd, "width"), argLabel_Command(cmd, "height")); | ||
575 | const iInt2 pos = coord_Command(cmd); | ||
576 | SDL_SetWindowPosition(d->window->win, pos.x, pos.y); | ||
577 | } | ||
578 | else if (equal_Command(cmd, "navigate.home")) { | 588 | else if (equal_Command(cmd, "navigate.home")) { |
579 | postCommand_App("open url:about:home"); | 589 | postCommand_App("open url:about:home"); |
580 | return iTrue; | 590 | return iTrue; |
diff --git a/src/gmdocument.c b/src/gmdocument.c index ed1d1cae..d140b065 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c | |||
@@ -648,8 +648,8 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) { | |||
648 | 0.8f * (d->themeSeed >> 24) / 255.0f, | 648 | 0.8f * (d->themeSeed >> 24) / 255.0f, |
649 | 0.06f + 0.09f * ((d->themeSeed >> 5) & 0x7) / 7.0f, | 649 | 0.06f + 0.09f * ((d->themeSeed >> 5) & 0x7) / 7.0f, |
650 | 1.0f }; | 650 | 1.0f }; |
651 | printf("background: %d %f %f\n", (int) base.hue, base.sat, base.lum); | 651 | // printf("background: %d %f %f\n", (int) base.hue, base.sat, base.lum); |
652 | printf("isDarkBgSat: %d\n", isDarkBgSat); | 652 | // printf("isDarkBgSat: %d\n", isDarkBgSat); |
653 | setHsl_Color(tmBackground_ColorId, base); | 653 | setHsl_Color(tmBackground_ColorId, base); |
654 | 654 | ||
655 | setHsl_Color(tmBannerBackground_ColorId, addSatLum_HSLColor(base, 0.1f, 0.04f * (isBannerLighter ? 1 : -1))); | 655 | setHsl_Color(tmBannerBackground_ColorId, addSatLum_HSLColor(base, 0.1f, 0.04f * (isBannerLighter ? 1 : -1))); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 7e4bdc73..2e53e6ef 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -808,10 +808,10 @@ static iBool handleMediaCommand_DocumentWidget_(iDocumentWidget *d, const char * | |||
808 | const enum iGmStatusCode code = status_GmRequest(req->req); | 808 | const enum iGmStatusCode code = status_GmRequest(req->req); |
809 | /* Give the media to the document for presentation. */ | 809 | /* Give the media to the document for presentation. */ |
810 | if (code == success_GmStatusCode) { | 810 | if (code == success_GmStatusCode) { |
811 | printf("media finished: %s\n size: %zu\n type: %s\n", | 811 | // printf("media finished: %s\n size: %zu\n type: %s\n", |
812 | cstr_String(url_GmRequest(req->req)), | 812 | // cstr_String(url_GmRequest(req->req)), |
813 | size_Block(body_GmRequest(req->req)), | 813 | // size_Block(body_GmRequest(req->req)), |
814 | cstr_String(meta_GmRequest(req->req))); | 814 | // cstr_String(meta_GmRequest(req->req))); |
815 | if (startsWith_String(meta_GmRequest(req->req), "image/")) { | 815 | if (startsWith_String(meta_GmRequest(req->req), "image/")) { |
816 | setImage_GmDocument(d->doc, req->linkId, meta_GmRequest(req->req), | 816 | setImage_GmDocument(d->doc, req->linkId, meta_GmRequest(req->req), |
817 | body_GmRequest(req->req)); | 817 | body_GmRequest(req->req)); |
diff --git a/src/ui/window.c b/src/ui/window.c index 4f59ef1a..315c4243 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -36,7 +36,7 @@ static float initialUiScale_ = 1.0f; | |||
36 | static float initialUiScale_ = 1.1f; | 36 | static float initialUiScale_ = 1.1f; |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | iDefineTypeConstruction(Window) | 39 | iDefineTypeConstructionArgs(Window, (iRect rect), rect) |
40 | 40 | ||
41 | static iBool handleRootCommands_(iWidget *root, const char *cmd) { | 41 | static iBool handleRootCommands_(iWidget *root, const char *cmd) { |
42 | iUnused(root); | 42 | iUnused(root); |
@@ -354,8 +354,16 @@ static float pixelRatio_Window_(const iWindow *d) { | |||
354 | return (float) dx / (float) x; | 354 | return (float) dx / (float) x; |
355 | } | 355 | } |
356 | 356 | ||
357 | void init_Window(iWindow *d) { | 357 | static void drawBlank_Window_(iWindow *d) { |
358 | const iColor bg = get_Color(gray25_ColorId); | ||
359 | SDL_SetRenderDrawColor(d->render, bg.r, bg.g, bg.b, 255); | ||
360 | SDL_RenderClear(d->render); | ||
361 | SDL_RenderPresent(d->render); | ||
362 | } | ||
363 | |||
364 | void init_Window(iWindow *d, iRect rect) { | ||
358 | theWindow_ = d; | 365 | theWindow_ = d; |
366 | d->isBlank = iTrue; | ||
359 | uint32_t flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; | 367 | uint32_t flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; |
360 | #if defined (iPlatformApple) | 368 | #if defined (iPlatformApple) |
361 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); | 369 | SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); |
@@ -363,17 +371,22 @@ void init_Window(iWindow *d) { | |||
363 | flags |= SDL_WINDOW_OPENGL; | 371 | flags |= SDL_WINDOW_OPENGL; |
364 | #endif | 372 | #endif |
365 | SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); | 373 | SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); |
366 | if (SDL_CreateWindowAndRenderer(800, 500, flags, &d->win, &d->render)) { | 374 | if (SDL_CreateWindowAndRenderer( |
375 | width_Rect(rect), height_Rect(rect), flags, &d->win, &d->render)) { | ||
367 | fprintf(stderr, "Error when creating window: %s\n", SDL_GetError()); | 376 | fprintf(stderr, "Error when creating window: %s\n", SDL_GetError()); |
368 | exit(-2); | 377 | exit(-2); |
369 | } | 378 | } |
379 | if (left_Rect(rect) >= 0) { | ||
380 | SDL_SetWindowPosition(d->win, left_Rect(rect), top_Rect(rect)); | ||
381 | } | ||
370 | SDL_SetWindowMinimumSize(d->win, 640, 400); | 382 | SDL_SetWindowMinimumSize(d->win, 640, 400); |
371 | SDL_SetWindowTitle(d->win, "Lagrange"); | 383 | SDL_SetWindowTitle(d->win, "Lagrange"); |
372 | /* Some info. */ { | 384 | /* Some info. */ { |
373 | SDL_RendererInfo info; | 385 | SDL_RendererInfo info; |
374 | SDL_GetRendererInfo(d->render, &info); | 386 | SDL_GetRendererInfo(d->render, &info); |
375 | printf("[window] renderer: %s\n", info.name); | 387 | printf("[window] renderer: %s\n", info.name); |
376 | } | 388 | } |
389 | drawBlank_Window_(d); | ||
377 | d->uiScale = initialUiScale_; | 390 | d->uiScale = initialUiScale_; |
378 | d->pixelRatio = pixelRatio_Window_(d); | 391 | d->pixelRatio = pixelRatio_Window_(d); |
379 | setPixelRatio_Metrics(d->pixelRatio * d->uiScale); | 392 | setPixelRatio_Metrics(d->pixelRatio * d->uiScale); |
@@ -447,6 +460,11 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
447 | } | 460 | } |
448 | default: { | 461 | default: { |
449 | SDL_Event event = *ev; | 462 | SDL_Event event = *ev; |
463 | if (event.type == SDL_USEREVENT && isCommand_UserEvent(ev, "window.unblank")) { | ||
464 | d->isBlank = iFalse; | ||
465 | postRefresh_App(); | ||
466 | return iTrue; | ||
467 | } | ||
450 | /* Map mouse pointer coordinate to our coordinate system. */ | 468 | /* Map mouse pointer coordinate to our coordinate system. */ |
451 | if (event.type == SDL_MOUSEMOTION) { | 469 | if (event.type == SDL_MOUSEMOTION) { |
452 | const iInt2 pos = coord_Window(d, event.motion.x, event.motion.y); | 470 | const iInt2 pos = coord_Window(d, event.motion.x, event.motion.y); |
@@ -479,6 +497,10 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) { | |||
479 | 497 | ||
480 | void draw_Window(iWindow *d) { | 498 | void draw_Window(iWindow *d) { |
481 | /* Clear the window. */ | 499 | /* Clear the window. */ |
500 | if (d->isBlank) { | ||
501 | drawBlank_Window_(d); | ||
502 | return; | ||
503 | } | ||
482 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); | 504 | SDL_SetRenderDrawColor(d->render, 0, 0, 0, 255); |
483 | SDL_RenderClear(d->render); | 505 | SDL_RenderClear(d->render); |
484 | /* Draw widgets. */ | 506 | /* Draw widgets. */ |
diff --git a/src/ui/window.h b/src/ui/window.h index 413c454c..6f4e01ce 100644 --- a/src/ui/window.h +++ b/src/ui/window.h | |||
@@ -2,16 +2,17 @@ | |||
2 | 2 | ||
3 | #include "widget.h" | 3 | #include "widget.h" |
4 | 4 | ||
5 | #include <the_Foundation/defs.h> | 5 | #include <the_Foundation/rect.h> |
6 | #include <SDL_events.h> | 6 | #include <SDL_events.h> |
7 | #include <SDL_render.h> | 7 | #include <SDL_render.h> |
8 | #include <SDL_video.h> | 8 | #include <SDL_video.h> |
9 | 9 | ||
10 | iDeclareType(Window) | 10 | iDeclareType(Window) |
11 | iDeclareTypeConstruction(Window) | 11 | iDeclareTypeConstructionArgs(Window, iRect rect) |
12 | 12 | ||
13 | struct Impl_Window { | 13 | struct Impl_Window { |
14 | SDL_Window * win; | 14 | SDL_Window * win; |
15 | iBool isBlank; /* avoids premature draws while restoring window state */ | ||
15 | SDL_Renderer *render; | 16 | SDL_Renderer *render; |
16 | iWidget * root; | 17 | iWidget * root; |
17 | float pixelRatio; | 18 | float pixelRatio; |