From 984b005bd01a57e53212bc1176b57b617414e75d Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 19 Nov 2021 14:32:55 +0200 Subject: Fixed clicking on tabs when banner is underneath Banner was too eager to eat all mouse events. --- res/about/version.gmi | 3 +++ 1 file changed, 3 insertions(+) (limited to 'res/about') diff --git a/res/about/version.gmi b/res/about/version.gmi index ffd91f7f..020373e4 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -6,6 +6,9 @@ ``` # Release notes +## 1.8.3 +* Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. + ## 1.8.2 * Fixed encoding of `+` characters in URLs as per RFC 3986. * Fixed crash when fontpack.ini specifies a file that cannot be found. -- cgit v1.2.3 From c58985ed3105ff7fc29fc0d53ba81ba55882e05e Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sun, 21 Nov 2021 14:35:32 +0200 Subject: Site-specific Titan upload identity The identity to be used for uploads is now in sitespec.ini, so it applies to an entire site root. This should match actual use cases better than having URL-specific identities. Also fixed an issue with native menus. Replacing the items with new ones was not implemented. IssueID #379 --- res/about/version.gmi | 2 ++ src/gmcerts.c | 6 ++++++ src/sitespec.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/sitespec.h | 9 +++++++-- src/ui/uploadwidget.c | 45 +++++++++++++++++++++++++++++++++------------ src/ui/util.c | 50 +++++++++++++++++++++++++++++++------------------- src/ui/util.h | 1 + 7 files changed, 129 insertions(+), 35 deletions(-) (limited to 'res/about') diff --git a/res/about/version.gmi b/res/about/version.gmi index 020373e4..b5750c8c 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -8,6 +8,8 @@ ## 1.8.3 * Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. +* Titan upload identity is remembered as a site-specific setting. It is no longer affected by selections in the Identities sidebar. +* macOS: Fixed updating items in native menus, e.g., upload identity selection. ## 1.8.2 * Fixed encoding of `+` characters in URLs as per RFC 3986. diff --git a/src/gmcerts.c b/src/gmcerts.c index 36fd7d55..f95fea7d 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c @@ -295,6 +295,9 @@ static void loadIdentities_GmCerts_(iGmCerts *d) { } iGmIdentity *findIdentity_GmCerts(iGmCerts *d, const iBlock *fingerprint) { + if (isEmpty_Block(fingerprint)) { + return NULL; + } iForEach(PtrArray, i, &d->idents) { iGmIdentity *ident = i.ptr; if (cmp_Block(fingerprint, &ident->fingerprint) == 0) { /* TODO: could use a hash */ @@ -549,6 +552,9 @@ const iGmIdentity *constIdentity_GmCerts(const iGmCerts *d, unsigned int id) { } const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { + if (isEmpty_String(url)) { + return NULL; + } lock_Mutex(d->mtx); const iGmIdentity *found = NULL; iConstForEach(PtrArray, i, &d->idents) { diff --git a/src/sitespec.c b/src/sitespec.c index 0332af2d..6f4546f0 100644 --- a/src/sitespec.c +++ b/src/sitespec.c @@ -33,17 +33,19 @@ iDeclareObjectConstruction(SiteParams) struct Impl_SiteParams { iObject object; uint16_t titanPort; + iString titanIdentity; /* fingerprint */ int dismissWarnings; /* TODO: theme seed, style settings */ }; void init_SiteParams(iSiteParams *d) { - d->titanPort = 0; /* undefined */ + d->titanPort = 0; /* undefined */ + init_String(&d->titanIdentity); d->dismissWarnings = 0; } void deinit_SiteParams(iSiteParams *d) { - iUnused(d); + deinit_String(&d->titanIdentity); } iDefineClass(SiteParams) @@ -122,6 +124,9 @@ static void handleIniKeyValue_SiteSpec_(void *context, const iString *table, con if (!cmp_String(key, "titanPort")) { d->loadParams->titanPort = number_TomlValue(value); } + else if (!cmp_String(key, "titanIdentity") && value->type == string_TomlType) { + set_String(&d->loadParams->titanIdentity, value->value.string); + } else if (!cmp_String(key, "dismissWarnings") && value->type == int64_TomlType) { d->loadParams->dismissWarnings = value->value.int64; } @@ -152,6 +157,10 @@ static void save_SiteSpec_(iSiteSpec *d) { if (params->titanPort) { appendFormat_String(buf, "titanPort = %u\n", params->titanPort); } + if (!isEmpty_String(¶ms->titanIdentity)) { + appendFormat_String( + buf, "titanIdentity = \"%s\"\n", cstr_String(¶ms->titanIdentity)); + } if (params->dismissWarnings) { appendFormat_String(buf, "dismissWarnings = 0x%x\n", params->dismissWarnings); } @@ -205,6 +214,30 @@ void setValue_SiteSpec(const iString *site, enum iSiteSpecKey key, int value) { } } +void setValueString_SiteSpec(const iString *site, enum iSiteSpecKey key, const iString *value) { + iSiteSpec *d = &siteSpec_; + const iString *hashKey = collect_String(lower_String(site)); + iSiteParams *params = value_StringHash(&d->sites, hashKey); + if (!params) { + params = new_SiteParams(); + insert_StringHash(&d->sites, hashKey, params); + } + iBool needSave = iFalse; + switch (key) { + case titanIdentity_SiteSpecKey: + if (!equal_String(¶ms->titanIdentity, value)) { + needSave = iTrue; + set_String(¶ms->titanIdentity, value); + } + break; + default: + break; + } + if (needSave) { + save_SiteSpec_(d); + } +} + int value_SiteSpec(const iString *site, enum iSiteSpecKey key) { iSiteSpec *d = &siteSpec_; const iSiteParams *params = constValue_StringHash(&d->sites, collect_String(lower_String(site))); @@ -220,3 +253,17 @@ int value_SiteSpec(const iString *site, enum iSiteSpecKey key) { return 0; } } + +const iString *valueString_SiteSpec(const iString *site, enum iSiteSpecKey key) { + iSiteSpec *d = &siteSpec_; + const iSiteParams *params = constValue_StringHash(&d->sites, collect_String(lower_String(site))); + if (!params) { + return 0; + } + switch (key) { + case titanIdentity_SiteSpecKey: + return ¶ms->titanIdentity; + default: + return collectNew_String(); + } +} diff --git a/src/sitespec.h b/src/sitespec.h index 6b64f073..5adaeb8c 100644 --- a/src/sitespec.h +++ b/src/sitespec.h @@ -28,11 +28,16 @@ iDeclareType(SiteSpec) enum iSiteSpecKey { titanPort_SiteSpecKey, + titanIdentity_SiteSpecKey, dismissWarnings_SiteSpecKey, }; void init_SiteSpec (const char *saveDir); void deinit_SiteSpec (void); -void setValue_SiteSpec (const iString *site, enum iSiteSpecKey key, int value); /* changes saved immediately */ -int value_SiteSpec (const iString *site, enum iSiteSpecKey key); +/* changes saved immediately */ +void setValue_SiteSpec (const iString *site, enum iSiteSpecKey key, int value); +void setValueString_SiteSpec (const iString *site, enum iSiteSpecKey key, const iString *value); + +int value_SiteSpec (const iString *site, enum iSiteSpecKey key); +const iString * valueString_SiteSpec (const iString *site, enum iSiteSpecKey key); diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index 90df1958..bad00071 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c @@ -45,7 +45,7 @@ iDefineObjectConstruction(UploadWidget) enum iUploadIdentity { none_UploadIdentity, - defaultForUrl_UploadIdentity, + defaultForSite_UploadIdentity, dropdown_UploadIdentity, }; @@ -104,9 +104,16 @@ static void updateInputMaxHeight_UploadWidget_(iUploadWidget *d) { (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); } +static const iGmIdentity *titanIdentityForUrl_(const iString *url) { + return findIdentity_GmCerts( + certs_App(), + collect_Block(hexDecode_Rangecc(range_String(valueString_SiteSpec( + collectNewRange_String(urlRoot_String(url)), titanIdentity_SiteSpecKey))))); +} + static const iArray *makeIdentityItems_UploadWidget_(const iUploadWidget *d) { iArray *items = collectNew_Array(sizeof(iMenuItem)); - const iGmIdentity *urlId = identityForUrl_GmCerts(certs_App(), &d->url); + const iGmIdentity *urlId = titanIdentityForUrl_(&d->url); pushBack_Array(items, &(iMenuItem){ format_CStr("${dlg.upload.id.default} (%s)", urlId ? cstr_String(name_GmIdentity(urlId)) @@ -147,7 +154,7 @@ void init_UploadWidget(iUploadWidget *d) { d->request = NULL; init_String(&d->filePath); d->fileSize = 0; - d->idMode = defaultForUrl_UploadIdentity; + d->idMode = defaultForSite_UploadIdentity; init_Block(&d->idFingerprint, 0); const iMenuItem actions[] = { { "${upload.port}", 0, 0, "upload.setport" }, @@ -289,16 +296,22 @@ void deinit_UploadWidget(iUploadWidget *d) { static void remakeIdentityItems_UploadWidget_(iUploadWidget *d) { iWidget *dropMenu = findChild_Widget(findChild_Widget(as_Widget(d), "upload.id"), "menu"); - releaseChildren_Widget(dropMenu); const iArray *items = makeIdentityItems_UploadWidget_(d); - makeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); + /* TODO: Make the following a utility method. */ + if (flags_Widget(dropMenu) & nativeMenu_WidgetFlag) { + setNativeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); + } + else { + releaseChildren_Widget(dropMenu); + makeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); + } } static void updateIdentityDropdown_UploadWidget_(iUploadWidget *d) { updateDropdownSelection_LabelWidget( findChild_Widget(as_Widget(d), "upload.id"), d->idMode == none_UploadIdentity ? " arg:0" - : d->idMode == defaultForUrl_UploadIdentity + : d->idMode == defaultForSite_UploadIdentity ? " arg:1" : format_CStr(" fp:%s", cstrCollect_String(hexEncode_Block(&d->idFingerprint)))); } @@ -422,7 +435,7 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { } else if (arg_Command(cmd)) { clear_Block(&d->idFingerprint); - d->idMode = defaultForUrl_UploadIdentity; + d->idMode = defaultForSite_UploadIdentity; } else { clear_Block(&d->idFingerprint); @@ -452,19 +465,27 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); setUserData_Object(d->request, d); setUrl_GmRequest(d->request, &d->url); + const iString *site = collectNewRange_String(urlRoot_String(&d->url)); switch (d->idMode) { - case defaultForUrl_UploadIdentity: - break; /* GmRequest handles it */ case none_UploadIdentity: - setIdentity_GmRequest(d->request, NULL); + /* Ensure no identity will be used for this specific URL. */ signOut_GmCerts(certs_App(), url_GmRequest(d->request)); + setValueString_SiteSpec(site, titanIdentity_SiteSpecKey, collectNew_String()); break; case dropdown_UploadIdentity: { iGmIdentity *ident = findIdentity_GmCerts(certs_App(), &d->idFingerprint); - setIdentity_GmRequest(d->request, ident); - signIn_GmCerts(certs_App(), ident, url_GmRequest(d->request)); + if (ident) { + setValueString_SiteSpec(site, + titanIdentity_SiteSpecKey, + collect_String(hexEncode_Block(&ident->fingerprint))); + } break; } + default: + break; + } + if (d->idMode != none_UploadIdentity) { + setIdentity_GmRequest(d->request, titanIdentityForUrl_(&d->url)); } if (isText) { /* Uploading text. */ diff --git a/src/ui/util.c b/src/ui/util.c index 2624bf2b..0a9dde0c 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -809,14 +809,27 @@ static void deleteMenuItems_(iArray *items) { delete_Array(items); } -iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { - iWidget *menu = new_Widget(); +void releaseNativeMenu_Widget(iWidget *d) { #if defined (iHaveNativeContextMenus) - setFlags_Widget(menu, hidden_WidgetFlag | nativeMenu_WidgetFlag, iTrue); + iArray *items = userData_Object(d); + if (items) { + iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); + iAssert(items); + deleteMenuItems_(items); + setUserData_Object(d, NULL); + } +#else + iUnused(d); +#endif +} + +void setNativeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) { +#if defined (iHaveNativeContextMenus) + iAssert(flags_Widget(menu) & nativeMenu_WidgetFlag); + releaseNativeMenu_Widget(menu); setUserData_Object(menu, deepCopyMenuItems_(menu, items, n)); - addChild_Widget(parent, menu); - iRelease(menu); /* owned by parent now */ /* Keyboard shortcuts still need to triggerable via the menu, although the items don't exist. */ { + releaseChildren_Widget(menu); for (size_t i = 0; i < n; i++) { const iMenuItem *item = &items[i]; if (item->key) { @@ -824,6 +837,17 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { } } } +#endif +} + +iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { + iWidget *menu = new_Widget(); +#if defined (iHaveNativeContextMenus) + setFlags_Widget(menu, hidden_WidgetFlag | nativeMenu_WidgetFlag, iTrue); + addChild_Widget(parent, menu); + iRelease(menu); /* owned by parent now */ + setUserData_Object(menu, NULL); + setNativeMenuItems_Widget(menu, items, n); #else /* Non-native custom popup menu. This may still be displayed inside a separate window. */ setDrawBufferEnabled_Widget(menu, iTrue); @@ -990,18 +1014,6 @@ iLocalDef iBool isUsingMenuPopupWindows_(void) { #endif } -void releaseNativeMenu_Widget(iWidget *d) { -#if defined (iHaveNativeContextMenus) - iArray *items = userData_Object(d); - iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); - iAssert(items); - deleteMenuItems_(items); - setUserData_Object(d, NULL); -#else - iUnused(d); -#endif -} - void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, int menuOpenFlags) { const iBool postCommands = (menuOpenFlags & postCommands_MenuOpenFlags) != 0; #if defined (iHaveNativeContextMenus) @@ -1263,8 +1275,8 @@ void updateDropdownSelection_LabelWidget(iLabelWidget *dropButton, const char *s iMenuItem *item = findNativeMenuItem_Widget(menu, selectedCommand); if (item) { setSelected_NativeMenuItem(item, iTrue); - updateText_LabelWidget(dropButton, - removeMenuItemLabelPrefixes_String(collectNewCStr_String(item->label))); + updateText_LabelWidget( + dropButton, removeMenuItemLabelPrefixes_String(collectNewCStr_String(item->label))); } return; } diff --git a/src/ui/util.h b/src/ui/util.h index cf96dfe4..52b3a692 100644 --- a/src/ui/util.h +++ b/src/ui/util.h @@ -249,6 +249,7 @@ void setMenuItemDisabled_Widget (iWidget *menu, const char *comm void setMenuItemDisabledByIndex_Widget(iWidget *menu, size_t index, iBool disable); void setMenuItemLabel_Widget (iWidget *menu, const char *command, const char *newLabel); void setMenuItemLabelByIndex_Widget (iWidget *menu, size_t index, const char *newLabel); +void setNativeMenuItems_Widget (iWidget *, const iMenuItem *items, size_t n); int checkContextMenu_Widget (iWidget *, const SDL_Event *ev); /* see macro below */ -- cgit v1.2.3 From d55d3ce2089193aae1a33ea59626202ecfada56f Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sun, 21 Nov 2021 15:24:36 +0200 Subject: Help: `zip` options for creating fontpacks IssueID #387 --- res/about/help.gmi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'res/about') diff --git a/res/about/help.gmi b/res/about/help.gmi index 4af1581e..3c332f81 100644 --- a/res/about/help.gmi +++ b/res/about/help.gmi @@ -825,7 +825,7 @@ semibold = "FiraSans-SemiBold.ttf" bold = "FiraSans-Bold.ttf" ``` -Fontpacks may use the Deflate compression method, but that can slow down launching the app because each font must then be decompressed before loading. +Fontpacks may use the Deflate compression method, but that can slow down launching the app because each font must then be decompressed before loading. Therefore, it is recommended to use the -0 (--compression-method store) option when creating the archive. You may also find the -j (--junk-paths) option helpful if the current working directory is not the one where fontpack.ini is located. Each fontpack has an ID that comes from the file name: the ID of "firasans.fontpack" would be "firasans". Space characters are not allowed in the ID. -- cgit v1.2.3