From 5293de3a437b10656e4e678cffecdc1cf416b9d9 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Tue, 15 Sep 2020 22:12:49 +0300 Subject: Added software rendering fallback and --sw option --- src/ui/window.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/ui/window.c') diff --git a/src/ui/window.c b/src/ui/window.c index 0a63a941..38df42e0 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -477,26 +477,35 @@ static void drawBlank_Window_(iWindow *d) { SDL_RenderPresent(d->render); } -// #define ENABLE_SWRENDER +iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { + flags |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + if (SDL_CreateWindowAndRenderer( + width_Rect(rect), height_Rect(rect), flags, &d->win, &d->render)) { + return iFalse; + } + return iTrue; +} void init_Window(iWindow *d, iRect rect) { theWindow_ = d; iZap(d->cursors); d->pendingCursor = NULL; d->isDrawFrozen = iTrue; - uint32_t flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; -#if defined (ENABLE_SWRENDER) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); -#elif defined (iPlatformApple) + uint32_t flags = 0; +#if defined (iPlatformApple) SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); #else flags |= SDL_WINDOW_OPENGL; #endif SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); - if (SDL_CreateWindowAndRenderer( - width_Rect(rect), height_Rect(rect), flags, &d->win, &d->render)) { - fprintf(stderr, "Error when creating window: %s\n", SDL_GetError()); - exit(-2); + /* First try SDL's default renderer that should be the best option. */ + if (forceSoftwareRender_App() || !create_Window_(d, rect, flags)) { + /* No luck, maybe software only? This should always work as long as there is a display. */ + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + if (!create_Window_(d, rect, 0)) { + fprintf(stderr, "Error when creating window: %s\n", SDL_GetError()); + exit(-2); + } } if (left_Rect(rect) >= 0) { SDL_SetWindowPosition(d->win, left_Rect(rect), top_Rect(rect)); -- cgit v1.2.3 From 64a20813de671035c4a3a6d4b1568cf14f73f448 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 17 Sep 2020 08:20:39 +0300 Subject: Added a "Save Page" menu item --- src/app.c | 13 +++++++++++-- src/app.h | 1 + src/ui/window.c | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src/ui/window.c') diff --git a/src/app.c b/src/app.c index c6b9a548..c33664f9 100644 --- a/src/app.c +++ b/src/app.c @@ -73,8 +73,9 @@ static const char *dataDir_App_ = "~/AppData/Roaming/fi.skyjake.Lagrange"; static const char *dataDir_App_ = "~/.config/lagrange"; #endif #define EMB_BIN2 "../resources.binary" /* fallback from build/executable dir */ -static const char *prefsFileName_App_ = "prefs.cfg"; -static const char *stateFileName_App_ = "state.binary"; +static const char *prefsFileName_App_ = "prefs.cfg"; +static const char *stateFileName_App_ = "state.binary"; +static const char *downloadDir_App_ = "~/Downloads"; struct Impl_App { iCommandLine args; @@ -103,6 +104,7 @@ struct Impl_App { iBool useSystemTheme; iString gopherProxy; iString httpProxy; + iString downloadDir; }; static iApp app_; @@ -161,6 +163,7 @@ static iString *serializePrefs_App_(const iApp *d) { appendFormat_String(str, "ostheme arg:%d\n", d->useSystemTheme); appendFormat_String(str, "proxy.gopher address:%s\n", cstr_String(&d->gopherProxy)); appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->httpProxy)); + appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->downloadDir)); return str; } @@ -312,6 +315,7 @@ static void init_App_(iApp *d, int argc, char **argv) { d->tabEnum = 0; /* generates unique IDs for tab pages */ init_String(&d->gopherProxy); init_String(&d->httpProxy); + initCStr_String(&d->downloadDir, downloadDir_App_); setThemePalette_Color(d->theme); #if defined (iPlatformApple) setupApplication_MacOS(); @@ -386,6 +390,7 @@ static void init_App_(iApp *d, int argc, char **argv) { static void deinit_App(iApp *d) { saveState_App_(d); savePrefs_App_(d); + deinit_String(&d->downloadDir); deinit_String(&d->httpProxy); deinit_String(&d->gopherProxy); save_Bookmarks(d->bookmarks, dataDir_App_); @@ -783,6 +788,10 @@ iBool handleCommand_App(const char *cmd) { d->retainWindowSize = arg_Command(cmd); return iTrue; } + else if (equal_Command(cmd, "downloads")) { + setCStr_String(&d->downloadDir, suffixPtr_Command(cmd, "path")); + return iTrue; + } else if (equal_Command(cmd, "open")) { const iString *url = collectNewCStr_String(suffixPtr_Command(cmd, "url")); iUrl parts; diff --git a/src/app.h b/src/app.h index a5b1266d..acc3e952 100644 --- a/src/app.h +++ b/src/app.h @@ -48,6 +48,7 @@ enum iUserEventCode { const iString *execPath_App (void); const iString *dataDir_App (void); +const iString *downloadDir_App (void); const iString *debugInfo_App (void); int run_App (int argc, char **argv); diff --git a/src/ui/window.c b/src/ui/window.c index 38df42e0..fbcf42fe 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -91,10 +91,13 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) { #endif #if !defined (iHaveNativeMenus) +/* TODO: Submenus wouldn't hurt here. */ static const iMenuItem navMenuItems[] = { { "New Tab", 't', KMOD_PRIMARY, "tabs.new" }, { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, { "---", 0, 0, NULL }, + { "Save Page", SDLK_s, KMOD_PRIMARY, "document.save" }, + { "---", 0, 0, NULL }, { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" }, { "Bookmark This Page", SDLK_d, KMOD_PRIMARY, "bookmark.add" }, { "---", 0, 0, NULL }, @@ -104,7 +107,7 @@ static const iMenuItem navMenuItems[] = { { "Reset Zoom", SDLK_0, KMOD_PRIMARY, "zoom.set arg:100" }, { "---", 0, 0, NULL }, { "Preferences...", SDLK_COMMA, KMOD_PRIMARY, "preferences" }, - { "Help", 0, 0, "!open url:about:help" }, + { "Help", SDLK_F1, 0, "!open url:about:help" }, { "Release Notes", 0, 0, "!open url:about:version" }, { "---", 0, 0, NULL }, { "Quit Lagrange", 'q', KMOD_PRIMARY, "quit" } @@ -116,6 +119,8 @@ static const iMenuItem navMenuItems[] = { static const iMenuItem fileMenuItems[] = { { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, + { "---", 0, 0, NULL }, + { "Save Page", SDLK_s, KMOD_PRIMARY, "document.save" }, }; static const iMenuItem editMenuItems[] = { -- cgit v1.2.3 From cd88a87cbef2200e3d22f7d891124559e17e662a Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 17 Sep 2020 20:54:05 +0300 Subject: Download progress indicator for large downloads --- src/gmrequest.c | 1 - src/ui/documentwidget.c | 24 ++++++++++++++++++++++-- src/ui/inputwidget.c | 1 + src/ui/window.c | 24 ++++++++++++++++++------ 4 files changed, 41 insertions(+), 9 deletions(-) (limited to 'src/ui/window.c') diff --git a/src/gmrequest.c b/src/gmrequest.c index 96276636..43cc874a 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c @@ -228,7 +228,6 @@ static void readIncoming_GmRequest_(iAnyObject *obj) { lock_Mutex(&d->mutex); iAssert(d->state != finished_GmRequestState); /* notifications out of order? */ iBlock *data = readAll_TlsRequest(d->req); - fflush(stdout); if (d->state == receivingHeader_GmRequestState) { appendCStrN_String(&d->resp.meta, constData_Block(data), size_Block(data)); /* Check if the header line is complete. */ diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 23f34577..76ceebcd 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -554,6 +554,20 @@ static void updateTheme_DocumentWidget_(iDocumentWidget *d) { } } +static void updateFetchProgress_DocumentWidget_(iDocumentWidget *d) { + iLabelWidget *prog = findWidget_App("document.progress"); + const size_t dlSize = d->request ? size_Block(body_GmRequest(d->request)) : 0; + setFlags_Widget(as_Widget(prog), hidden_WidgetFlag, dlSize < 250000); + if (isVisible_Widget(prog)) { + updateText_LabelWidget(prog, + collectNewFormat_String("%s%.3f MB", + isFinished_GmRequest(d->request) + ? uiHeading_ColorEscape + : uiTextCaution_ColorEscape, + dlSize / 1.0e6f)); + } +} + static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse *response) { if (d->state == ready_RequestState) { return; @@ -566,7 +580,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse invalidate_DocumentWidget_(d); updateTheme_DocumentWidget_(d); clear_String(&d->sourceMime); - set_Block(&d->sourceContent, &response->body); +// set_Block(&d->sourceContent, &response->body); initBlock_String(&str, &response->body); if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { /* Check the MIME type. */ @@ -867,7 +881,6 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) { case categorySuccess_GmStatusCode: d->scrollY = 0; resetSmoothScroll_DocumentWidget_(d); - clear_Block(&d->sourceContent); reset_GmDocument(d->doc); /* new content incoming */ updateDocument_DocumentWidget_(d, response_GmRequest(d->request)); break; @@ -1062,6 +1075,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) } else if (equal_Command(cmd, "tabs.changed")) { d->showLinkNumbers = iFalse; + updateFetchProgress_DocumentWidget_(d); if (cmp_String(id_Widget(w), suffixPtr_Command(cmd, "id")) == 0) { /* Set palette for our document. */ updateTheme_DocumentWidget_(d); @@ -1148,11 +1162,16 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) } else if (equalWidget_Command(cmd, w, "document.request.updated") && pointerLabel_Command(cmd, "request") == d->request) { + set_Block(&d->sourceContent, body_GmRequest(d->request)); + updateFetchProgress_DocumentWidget_(d); checkResponse_DocumentWidget_(d); + set_Atomic(&d->isRequestUpdated, iFalse); /* ready to be notified again */ return iFalse; } else if (equalWidget_Command(cmd, w, "document.request.finished") && pointerLabel_Command(cmd, "request") == d->request) { + set_Block(&d->sourceContent, body_GmRequest(d->request)); + updateFetchProgress_DocumentWidget_(d); checkResponse_DocumentWidget_(d); resetSmoothScroll_DocumentWidget_(d); d->scrollY = d->initNormScrollY * size_GmDocument(d->doc).y; @@ -1185,6 +1204,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) postCommandf_App("document.request.cancelled doc:%p url:%s", d, cstr_String(d->mod.url)); iReleasePtr(&d->request); d->state = ready_RequestState; + updateFetchProgress_DocumentWidget_(d); return iTrue; } } diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 11098c80..320f21ce 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c @@ -733,6 +733,7 @@ static void draw_InputWidget_(const iInputWidget *d) { deinit_String(&cur); } delete_String(text); + drawChildren_Widget(w); } iBeginDefineSubclass(InputWidget, Widget) diff --git a/src/ui/window.c b/src/ui/window.c index fbcf42fe..5e64cf9e 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -367,12 +367,24 @@ static void setupUserInterface_Window(iWindow *d) { setId_Widget(as_Widget(lock), "navbar.lock"); setFont_LabelWidget(lock, defaultSymbols_FontId); updateTextCStr_LabelWidget(lock, "\U0001f512"); - iInputWidget *url = new_InputWidget(0); - setSelectAllOnFocus_InputWidget(url, iTrue); - setId_Widget(as_Widget(url), "url"); - setNotifyEdits_InputWidget(url, iTrue); - setTextCStr_InputWidget(url, "gemini://"); - addChildFlags_Widget(navBar, iClob(url), expand_WidgetFlag); + /* URL input field. */ { + iInputWidget *url = new_InputWidget(0); + setSelectAllOnFocus_InputWidget(url, iTrue); + setId_Widget(as_Widget(url), "url"); + setNotifyEdits_InputWidget(url, iTrue); + setTextCStr_InputWidget(url, "gemini://"); + addChildFlags_Widget(navBar, iClob(url), expand_WidgetFlag); + /* Download progress indicator is inside the input field, but hidden normally. */ + setPadding_Widget(as_Widget(url),0, 0, gap_UI * 1, 0); + iLabelWidget *progress = new_LabelWidget(uiTextCaution_ColorEscape "00.000 MB", 0, 0, NULL); + setId_Widget(as_Widget(progress), "document.progress"); + setAlignVisually_LabelWidget(progress, iTrue); + shrink_Rect(&as_Widget(progress)->rect, init_I2(0, gap_UI)); + addChildFlags_Widget(as_Widget(url), + iClob(progress), + moveToParentRightEdge_WidgetFlag); + setBackgroundColor_Widget(as_Widget(progress), uiBackground_ColorId); + } setId_Widget(addChild_Widget( navBar, iClob(newIcon_LabelWidget(reloadCStr_, 0, 0, "navigate.reload"))), "reload"); -- cgit v1.2.3 From 210d06a75c300593fb8353d48e9a3cb84fdcb4d1 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 18 Sep 2020 10:26:49 +0300 Subject: Cleanup --- res/about/version.gmi | 10 +++++----- src/ui/window.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/ui/window.c') diff --git a/res/about/version.gmi b/res/about/version.gmi index 6c731a89..f9311cb4 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -1,14 +1,14 @@ ``` - __ __ __ ___ -| /\ / _` |__) /\ |\ | / _` |__ -|___ /~~\ \__> | \ /~~\ | \| \__> |___ + __ __ __ ___ +| /\ / _` |__) /\ |\ | / _` |__ +|___ /~~\ \__> | \ /~~\ | \| \__> |___ -``` +``` # Release notes ## 0.2 * Added Downloads folder to Preferences. -* Added "Save Page" menu item (${CTRL+}S) for saving page contents. +* Added "Save to Downloads" menu item (${CTRL+}S) for saving page contents. * Added a download progress indicator in the URL input field. * Added a progress indicator for inline image fetching. * Added `--sw` option to force software rendering. diff --git a/src/ui/window.c b/src/ui/window.c index 5e64cf9e..b43e8421 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -96,7 +96,7 @@ static const iMenuItem navMenuItems[] = { { "New Tab", 't', KMOD_PRIMARY, "tabs.new" }, { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, { "---", 0, 0, NULL }, - { "Save Page", SDLK_s, KMOD_PRIMARY, "document.save" }, + { "Save to Downloads", SDLK_s, KMOD_PRIMARY, "document.save" }, { "---", 0, 0, NULL }, { "Copy Source Text", SDLK_c, KMOD_PRIMARY, "copy" }, { "Bookmark This Page", SDLK_d, KMOD_PRIMARY, "bookmark.add" }, @@ -120,7 +120,7 @@ static const iMenuItem fileMenuItems[] = { { "New Tab", SDLK_t, KMOD_PRIMARY, "tabs.new" }, { "Open Location...", SDLK_l, KMOD_PRIMARY, "focus.set id:url" }, { "---", 0, 0, NULL }, - { "Save Page", SDLK_s, KMOD_PRIMARY, "document.save" }, + { "Save to Downloads", SDLK_s, KMOD_PRIMARY, "document.save" }, }; static const iMenuItem editMenuItems[] = { -- cgit v1.2.3 From b7da52ec5711e999963df218d4fad69a8025daeb Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 18 Sep 2020 16:05:14 +0300 Subject: Added build options for X11 Build option to use software rendering if running under X11, and another option to set the position of a window only after the window has been shown. The latter is a workaround for an SDL bug regarding window borders affecting the initial position. --- CMakeLists.txt | 8 ++++++++ src/app.c | 10 +++++++++- src/ui/window.c | 11 +++++++++++ src/ui/window.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) (limited to 'src/ui/window.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f6c6064..d23ff2ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,10 @@ project (Lagrange set (COPYRIGHT_YEAR 2020) # Build configuration. +option (ENABLE_X11_SWRENDER "Use software rendering under X11" OFF) option (ENABLE_KERNING "Enable kerning in font renderer (slower)" ON) option (ENABLE_RESOURCE_EMBED "Embed resources inside the executable" OFF) +option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF) include (BuildType.cmake) include (Embed.cmake) @@ -170,9 +172,15 @@ target_compile_options (app PUBLIC ${SDL2_CFLAGS} ) target_compile_definitions (app PUBLIC LAGRANGE_APP_VERSION="${PROJECT_VERSION}") +if (ENABLE_X11_SWRENDER) + target_compile_definitions (app PUBLIC LAGRANGE_ENABLE_X11_SWRENDER=1) +endif () if (ENABLE_KERNING) target_compile_definitions (app PUBLIC LAGRANGE_ENABLE_KERNING=1) endif () +if (ENABLE_WINDOWPOS_FIX) + target_compile_definitions (app PUBLIC LAGRANGE_ENABLE_WINDOWPOS_FIX=1) +endif () target_link_libraries (app PUBLIC the_Foundation::the_Foundation) target_link_libraries (app PUBLIC ${SDL2_LDFLAGS}) if (APPLE) diff --git a/src/app.c b/src/app.c index 285036cb..84e57ce2 100644 --- a/src/app.c +++ b/src/app.c @@ -547,7 +547,15 @@ iBool forceLineWrap_App(void) { } iBool forceSoftwareRender_App(void) { - return app_.forceSoftwareRender; + if (app_.forceSoftwareRender) { + return iTrue; + } +#if defined (LAGRANGE_ENABLE_X11_SWRENDER) + if (getenv("DISPLAY")) { + return iTrue; + } +#endif + return iFalse; } enum iColorTheme colorTheme_App(void) { diff --git a/src/ui/window.c b/src/ui/window.c index b43e8421..8ebb67a8 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -506,6 +506,7 @@ iBool create_Window_(iWindow *d, iRect rect, uint32_t flags) { void init_Window(iWindow *d, iRect rect) { theWindow_ = d; iZap(d->cursors); + d->initialPos = rect.pos; d->pendingCursor = NULL; d->isDrawFrozen = iTrue; uint32_t flags = 0; @@ -597,6 +598,16 @@ SDL_Renderer *renderer_Window(const iWindow *d) { static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { switch (ev->event) { +#if defined (LAGRANGE_ENABLE_WINDOWPOS_FIX) + case SDL_WINDOWEVENT_EXPOSED: + if (d->initialPos.x >= 0) { + int bx, by; + SDL_GetWindowBordersSize(d->win, &by, &bx, NULL, NULL); + SDL_SetWindowPosition(d->win, d->initialPos.x + bx, d->initialPos.y + by); + d->initialPos = init1_I2(-1); + } + return iFalse; +#endif case SDL_WINDOWEVENT_MOVED: /* No need to do anything. */ return iTrue; diff --git a/src/ui/window.h b/src/ui/window.h index 4aec2fa7..b067d30e 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -34,6 +34,7 @@ iDeclareTypeConstructionArgs(Window, iRect rect) struct Impl_Window { SDL_Window * win; + iInt2 initialPos; iBool isDrawFrozen; /* avoids premature draws while restoring window state */ SDL_Renderer *render; iWidget * root; -- cgit v1.2.3