diff options
-rw-r--r-- | res/about/version.gmi | 2 | ||||
-rw-r--r-- | src/gmcerts.c | 6 | ||||
-rw-r--r-- | src/sitespec.c | 51 | ||||
-rw-r--r-- | src/sitespec.h | 9 | ||||
-rw-r--r-- | src/ui/uploadwidget.c | 45 | ||||
-rw-r--r-- | src/ui/util.c | 50 | ||||
-rw-r--r-- | src/ui/util.h | 1 |
7 files changed, 129 insertions, 35 deletions
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 @@ | |||
8 | 8 | ||
9 | ## 1.8.3 | 9 | ## 1.8.3 |
10 | * Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. | 10 | * Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. |
11 | * Titan upload identity is remembered as a site-specific setting. It is no longer affected by selections in the Identities sidebar. | ||
12 | * macOS: Fixed updating items in native menus, e.g., upload identity selection. | ||
11 | 13 | ||
12 | ## 1.8.2 | 14 | ## 1.8.2 |
13 | * Fixed encoding of `+` characters in URLs as per RFC 3986. | 15 | * 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) { | |||
295 | } | 295 | } |
296 | 296 | ||
297 | iGmIdentity *findIdentity_GmCerts(iGmCerts *d, const iBlock *fingerprint) { | 297 | iGmIdentity *findIdentity_GmCerts(iGmCerts *d, const iBlock *fingerprint) { |
298 | if (isEmpty_Block(fingerprint)) { | ||
299 | return NULL; | ||
300 | } | ||
298 | iForEach(PtrArray, i, &d->idents) { | 301 | iForEach(PtrArray, i, &d->idents) { |
299 | iGmIdentity *ident = i.ptr; | 302 | iGmIdentity *ident = i.ptr; |
300 | if (cmp_Block(fingerprint, &ident->fingerprint) == 0) { /* TODO: could use a hash */ | 303 | 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) { | |||
549 | } | 552 | } |
550 | 553 | ||
551 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { | 554 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { |
555 | if (isEmpty_String(url)) { | ||
556 | return NULL; | ||
557 | } | ||
552 | lock_Mutex(d->mtx); | 558 | lock_Mutex(d->mtx); |
553 | const iGmIdentity *found = NULL; | 559 | const iGmIdentity *found = NULL; |
554 | iConstForEach(PtrArray, i, &d->idents) { | 560 | 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) | |||
33 | struct Impl_SiteParams { | 33 | struct Impl_SiteParams { |
34 | iObject object; | 34 | iObject object; |
35 | uint16_t titanPort; | 35 | uint16_t titanPort; |
36 | iString titanIdentity; /* fingerprint */ | ||
36 | int dismissWarnings; | 37 | int dismissWarnings; |
37 | /* TODO: theme seed, style settings */ | 38 | /* TODO: theme seed, style settings */ |
38 | }; | 39 | }; |
39 | 40 | ||
40 | void init_SiteParams(iSiteParams *d) { | 41 | void init_SiteParams(iSiteParams *d) { |
41 | d->titanPort = 0; /* undefined */ | 42 | d->titanPort = 0; /* undefined */ |
43 | init_String(&d->titanIdentity); | ||
42 | d->dismissWarnings = 0; | 44 | d->dismissWarnings = 0; |
43 | } | 45 | } |
44 | 46 | ||
45 | void deinit_SiteParams(iSiteParams *d) { | 47 | void deinit_SiteParams(iSiteParams *d) { |
46 | iUnused(d); | 48 | deinit_String(&d->titanIdentity); |
47 | } | 49 | } |
48 | 50 | ||
49 | iDefineClass(SiteParams) | 51 | iDefineClass(SiteParams) |
@@ -122,6 +124,9 @@ static void handleIniKeyValue_SiteSpec_(void *context, const iString *table, con | |||
122 | if (!cmp_String(key, "titanPort")) { | 124 | if (!cmp_String(key, "titanPort")) { |
123 | d->loadParams->titanPort = number_TomlValue(value); | 125 | d->loadParams->titanPort = number_TomlValue(value); |
124 | } | 126 | } |
127 | else if (!cmp_String(key, "titanIdentity") && value->type == string_TomlType) { | ||
128 | set_String(&d->loadParams->titanIdentity, value->value.string); | ||
129 | } | ||
125 | else if (!cmp_String(key, "dismissWarnings") && value->type == int64_TomlType) { | 130 | else if (!cmp_String(key, "dismissWarnings") && value->type == int64_TomlType) { |
126 | d->loadParams->dismissWarnings = value->value.int64; | 131 | d->loadParams->dismissWarnings = value->value.int64; |
127 | } | 132 | } |
@@ -152,6 +157,10 @@ static void save_SiteSpec_(iSiteSpec *d) { | |||
152 | if (params->titanPort) { | 157 | if (params->titanPort) { |
153 | appendFormat_String(buf, "titanPort = %u\n", params->titanPort); | 158 | appendFormat_String(buf, "titanPort = %u\n", params->titanPort); |
154 | } | 159 | } |
160 | if (!isEmpty_String(¶ms->titanIdentity)) { | ||
161 | appendFormat_String( | ||
162 | buf, "titanIdentity = \"%s\"\n", cstr_String(¶ms->titanIdentity)); | ||
163 | } | ||
155 | if (params->dismissWarnings) { | 164 | if (params->dismissWarnings) { |
156 | appendFormat_String(buf, "dismissWarnings = 0x%x\n", params->dismissWarnings); | 165 | appendFormat_String(buf, "dismissWarnings = 0x%x\n", params->dismissWarnings); |
157 | } | 166 | } |
@@ -205,6 +214,30 @@ void setValue_SiteSpec(const iString *site, enum iSiteSpecKey key, int value) { | |||
205 | } | 214 | } |
206 | } | 215 | } |
207 | 216 | ||
217 | void setValueString_SiteSpec(const iString *site, enum iSiteSpecKey key, const iString *value) { | ||
218 | iSiteSpec *d = &siteSpec_; | ||
219 | const iString *hashKey = collect_String(lower_String(site)); | ||
220 | iSiteParams *params = value_StringHash(&d->sites, hashKey); | ||
221 | if (!params) { | ||
222 | params = new_SiteParams(); | ||
223 | insert_StringHash(&d->sites, hashKey, params); | ||
224 | } | ||
225 | iBool needSave = iFalse; | ||
226 | switch (key) { | ||
227 | case titanIdentity_SiteSpecKey: | ||
228 | if (!equal_String(¶ms->titanIdentity, value)) { | ||
229 | needSave = iTrue; | ||
230 | set_String(¶ms->titanIdentity, value); | ||
231 | } | ||
232 | break; | ||
233 | default: | ||
234 | break; | ||
235 | } | ||
236 | if (needSave) { | ||
237 | save_SiteSpec_(d); | ||
238 | } | ||
239 | } | ||
240 | |||
208 | int value_SiteSpec(const iString *site, enum iSiteSpecKey key) { | 241 | int value_SiteSpec(const iString *site, enum iSiteSpecKey key) { |
209 | iSiteSpec *d = &siteSpec_; | 242 | iSiteSpec *d = &siteSpec_; |
210 | const iSiteParams *params = constValue_StringHash(&d->sites, collect_String(lower_String(site))); | 243 | 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) { | |||
220 | return 0; | 253 | return 0; |
221 | } | 254 | } |
222 | } | 255 | } |
256 | |||
257 | const iString *valueString_SiteSpec(const iString *site, enum iSiteSpecKey key) { | ||
258 | iSiteSpec *d = &siteSpec_; | ||
259 | const iSiteParams *params = constValue_StringHash(&d->sites, collect_String(lower_String(site))); | ||
260 | if (!params) { | ||
261 | return 0; | ||
262 | } | ||
263 | switch (key) { | ||
264 | case titanIdentity_SiteSpecKey: | ||
265 | return ¶ms->titanIdentity; | ||
266 | default: | ||
267 | return collectNew_String(); | ||
268 | } | ||
269 | } | ||
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) | |||
28 | 28 | ||
29 | enum iSiteSpecKey { | 29 | enum iSiteSpecKey { |
30 | titanPort_SiteSpecKey, | 30 | titanPort_SiteSpecKey, |
31 | titanIdentity_SiteSpecKey, | ||
31 | dismissWarnings_SiteSpecKey, | 32 | dismissWarnings_SiteSpecKey, |
32 | }; | 33 | }; |
33 | 34 | ||
34 | void init_SiteSpec (const char *saveDir); | 35 | void init_SiteSpec (const char *saveDir); |
35 | void deinit_SiteSpec (void); | 36 | void deinit_SiteSpec (void); |
36 | 37 | ||
37 | void setValue_SiteSpec (const iString *site, enum iSiteSpecKey key, int value); /* changes saved immediately */ | 38 | /* changes saved immediately */ |
38 | int value_SiteSpec (const iString *site, enum iSiteSpecKey key); | 39 | void setValue_SiteSpec (const iString *site, enum iSiteSpecKey key, int value); |
40 | void setValueString_SiteSpec (const iString *site, enum iSiteSpecKey key, const iString *value); | ||
41 | |||
42 | int value_SiteSpec (const iString *site, enum iSiteSpecKey key); | ||
43 | 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) | |||
45 | 45 | ||
46 | enum iUploadIdentity { | 46 | enum iUploadIdentity { |
47 | none_UploadIdentity, | 47 | none_UploadIdentity, |
48 | defaultForUrl_UploadIdentity, | 48 | defaultForSite_UploadIdentity, |
49 | dropdown_UploadIdentity, | 49 | dropdown_UploadIdentity, |
50 | }; | 50 | }; |
51 | 51 | ||
@@ -104,9 +104,16 @@ static void updateInputMaxHeight_UploadWidget_(iUploadWidget *d) { | |||
104 | (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); | 104 | (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); |
105 | } | 105 | } |
106 | 106 | ||
107 | static const iGmIdentity *titanIdentityForUrl_(const iString *url) { | ||
108 | return findIdentity_GmCerts( | ||
109 | certs_App(), | ||
110 | collect_Block(hexDecode_Rangecc(range_String(valueString_SiteSpec( | ||
111 | collectNewRange_String(urlRoot_String(url)), titanIdentity_SiteSpecKey))))); | ||
112 | } | ||
113 | |||
107 | static const iArray *makeIdentityItems_UploadWidget_(const iUploadWidget *d) { | 114 | static const iArray *makeIdentityItems_UploadWidget_(const iUploadWidget *d) { |
108 | iArray *items = collectNew_Array(sizeof(iMenuItem)); | 115 | iArray *items = collectNew_Array(sizeof(iMenuItem)); |
109 | const iGmIdentity *urlId = identityForUrl_GmCerts(certs_App(), &d->url); | 116 | const iGmIdentity *urlId = titanIdentityForUrl_(&d->url); |
110 | pushBack_Array(items, | 117 | pushBack_Array(items, |
111 | &(iMenuItem){ format_CStr("${dlg.upload.id.default} (%s)", | 118 | &(iMenuItem){ format_CStr("${dlg.upload.id.default} (%s)", |
112 | urlId ? cstr_String(name_GmIdentity(urlId)) | 119 | urlId ? cstr_String(name_GmIdentity(urlId)) |
@@ -147,7 +154,7 @@ void init_UploadWidget(iUploadWidget *d) { | |||
147 | d->request = NULL; | 154 | d->request = NULL; |
148 | init_String(&d->filePath); | 155 | init_String(&d->filePath); |
149 | d->fileSize = 0; | 156 | d->fileSize = 0; |
150 | d->idMode = defaultForUrl_UploadIdentity; | 157 | d->idMode = defaultForSite_UploadIdentity; |
151 | init_Block(&d->idFingerprint, 0); | 158 | init_Block(&d->idFingerprint, 0); |
152 | const iMenuItem actions[] = { | 159 | const iMenuItem actions[] = { |
153 | { "${upload.port}", 0, 0, "upload.setport" }, | 160 | { "${upload.port}", 0, 0, "upload.setport" }, |
@@ -289,16 +296,22 @@ void deinit_UploadWidget(iUploadWidget *d) { | |||
289 | 296 | ||
290 | static void remakeIdentityItems_UploadWidget_(iUploadWidget *d) { | 297 | static void remakeIdentityItems_UploadWidget_(iUploadWidget *d) { |
291 | iWidget *dropMenu = findChild_Widget(findChild_Widget(as_Widget(d), "upload.id"), "menu"); | 298 | iWidget *dropMenu = findChild_Widget(findChild_Widget(as_Widget(d), "upload.id"), "menu"); |
292 | releaseChildren_Widget(dropMenu); | ||
293 | const iArray *items = makeIdentityItems_UploadWidget_(d); | 299 | const iArray *items = makeIdentityItems_UploadWidget_(d); |
294 | makeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); | 300 | /* TODO: Make the following a utility method. */ |
301 | if (flags_Widget(dropMenu) & nativeMenu_WidgetFlag) { | ||
302 | setNativeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); | ||
303 | } | ||
304 | else { | ||
305 | releaseChildren_Widget(dropMenu); | ||
306 | makeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); | ||
307 | } | ||
295 | } | 308 | } |
296 | 309 | ||
297 | static void updateIdentityDropdown_UploadWidget_(iUploadWidget *d) { | 310 | static void updateIdentityDropdown_UploadWidget_(iUploadWidget *d) { |
298 | updateDropdownSelection_LabelWidget( | 311 | updateDropdownSelection_LabelWidget( |
299 | findChild_Widget(as_Widget(d), "upload.id"), | 312 | findChild_Widget(as_Widget(d), "upload.id"), |
300 | d->idMode == none_UploadIdentity ? " arg:0" | 313 | d->idMode == none_UploadIdentity ? " arg:0" |
301 | : d->idMode == defaultForUrl_UploadIdentity | 314 | : d->idMode == defaultForSite_UploadIdentity |
302 | ? " arg:1" | 315 | ? " arg:1" |
303 | : format_CStr(" fp:%s", cstrCollect_String(hexEncode_Block(&d->idFingerprint)))); | 316 | : format_CStr(" fp:%s", cstrCollect_String(hexEncode_Block(&d->idFingerprint)))); |
304 | } | 317 | } |
@@ -422,7 +435,7 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
422 | } | 435 | } |
423 | else if (arg_Command(cmd)) { | 436 | else if (arg_Command(cmd)) { |
424 | clear_Block(&d->idFingerprint); | 437 | clear_Block(&d->idFingerprint); |
425 | d->idMode = defaultForUrl_UploadIdentity; | 438 | d->idMode = defaultForSite_UploadIdentity; |
426 | } | 439 | } |
427 | else { | 440 | else { |
428 | clear_Block(&d->idFingerprint); | 441 | clear_Block(&d->idFingerprint); |
@@ -452,19 +465,27 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
452 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); | 465 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); |
453 | setUserData_Object(d->request, d); | 466 | setUserData_Object(d->request, d); |
454 | setUrl_GmRequest(d->request, &d->url); | 467 | setUrl_GmRequest(d->request, &d->url); |
468 | const iString *site = collectNewRange_String(urlRoot_String(&d->url)); | ||
455 | switch (d->idMode) { | 469 | switch (d->idMode) { |
456 | case defaultForUrl_UploadIdentity: | ||
457 | break; /* GmRequest handles it */ | ||
458 | case none_UploadIdentity: | 470 | case none_UploadIdentity: |
459 | setIdentity_GmRequest(d->request, NULL); | 471 | /* Ensure no identity will be used for this specific URL. */ |
460 | signOut_GmCerts(certs_App(), url_GmRequest(d->request)); | 472 | signOut_GmCerts(certs_App(), url_GmRequest(d->request)); |
473 | setValueString_SiteSpec(site, titanIdentity_SiteSpecKey, collectNew_String()); | ||
461 | break; | 474 | break; |
462 | case dropdown_UploadIdentity: { | 475 | case dropdown_UploadIdentity: { |
463 | iGmIdentity *ident = findIdentity_GmCerts(certs_App(), &d->idFingerprint); | 476 | iGmIdentity *ident = findIdentity_GmCerts(certs_App(), &d->idFingerprint); |
464 | setIdentity_GmRequest(d->request, ident); | 477 | if (ident) { |
465 | signIn_GmCerts(certs_App(), ident, url_GmRequest(d->request)); | 478 | setValueString_SiteSpec(site, |
479 | titanIdentity_SiteSpecKey, | ||
480 | collect_String(hexEncode_Block(&ident->fingerprint))); | ||
481 | } | ||
466 | break; | 482 | break; |
467 | } | 483 | } |
484 | default: | ||
485 | break; | ||
486 | } | ||
487 | if (d->idMode != none_UploadIdentity) { | ||
488 | setIdentity_GmRequest(d->request, titanIdentityForUrl_(&d->url)); | ||
468 | } | 489 | } |
469 | if (isText) { | 490 | if (isText) { |
470 | /* Uploading text. */ | 491 | /* 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) { | |||
809 | delete_Array(items); | 809 | delete_Array(items); |
810 | } | 810 | } |
811 | 811 | ||
812 | iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | 812 | void releaseNativeMenu_Widget(iWidget *d) { |
813 | iWidget *menu = new_Widget(); | ||
814 | #if defined (iHaveNativeContextMenus) | 813 | #if defined (iHaveNativeContextMenus) |
815 | setFlags_Widget(menu, hidden_WidgetFlag | nativeMenu_WidgetFlag, iTrue); | 814 | iArray *items = userData_Object(d); |
815 | if (items) { | ||
816 | iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); | ||
817 | iAssert(items); | ||
818 | deleteMenuItems_(items); | ||
819 | setUserData_Object(d, NULL); | ||
820 | } | ||
821 | #else | ||
822 | iUnused(d); | ||
823 | #endif | ||
824 | } | ||
825 | |||
826 | void setNativeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) { | ||
827 | #if defined (iHaveNativeContextMenus) | ||
828 | iAssert(flags_Widget(menu) & nativeMenu_WidgetFlag); | ||
829 | releaseNativeMenu_Widget(menu); | ||
816 | setUserData_Object(menu, deepCopyMenuItems_(menu, items, n)); | 830 | setUserData_Object(menu, deepCopyMenuItems_(menu, items, n)); |
817 | addChild_Widget(parent, menu); | ||
818 | iRelease(menu); /* owned by parent now */ | ||
819 | /* Keyboard shortcuts still need to triggerable via the menu, although the items don't exist. */ { | 831 | /* Keyboard shortcuts still need to triggerable via the menu, although the items don't exist. */ { |
832 | releaseChildren_Widget(menu); | ||
820 | for (size_t i = 0; i < n; i++) { | 833 | for (size_t i = 0; i < n; i++) { |
821 | const iMenuItem *item = &items[i]; | 834 | const iMenuItem *item = &items[i]; |
822 | if (item->key) { | 835 | if (item->key) { |
@@ -824,6 +837,17 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | |||
824 | } | 837 | } |
825 | } | 838 | } |
826 | } | 839 | } |
840 | #endif | ||
841 | } | ||
842 | |||
843 | iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { | ||
844 | iWidget *menu = new_Widget(); | ||
845 | #if defined (iHaveNativeContextMenus) | ||
846 | setFlags_Widget(menu, hidden_WidgetFlag | nativeMenu_WidgetFlag, iTrue); | ||
847 | addChild_Widget(parent, menu); | ||
848 | iRelease(menu); /* owned by parent now */ | ||
849 | setUserData_Object(menu, NULL); | ||
850 | setNativeMenuItems_Widget(menu, items, n); | ||
827 | #else | 851 | #else |
828 | /* Non-native custom popup menu. This may still be displayed inside a separate window. */ | 852 | /* Non-native custom popup menu. This may still be displayed inside a separate window. */ |
829 | setDrawBufferEnabled_Widget(menu, iTrue); | 853 | setDrawBufferEnabled_Widget(menu, iTrue); |
@@ -990,18 +1014,6 @@ iLocalDef iBool isUsingMenuPopupWindows_(void) { | |||
990 | #endif | 1014 | #endif |
991 | } | 1015 | } |
992 | 1016 | ||
993 | void releaseNativeMenu_Widget(iWidget *d) { | ||
994 | #if defined (iHaveNativeContextMenus) | ||
995 | iArray *items = userData_Object(d); | ||
996 | iAssert(flags_Widget(d) & nativeMenu_WidgetFlag); | ||
997 | iAssert(items); | ||
998 | deleteMenuItems_(items); | ||
999 | setUserData_Object(d, NULL); | ||
1000 | #else | ||
1001 | iUnused(d); | ||
1002 | #endif | ||
1003 | } | ||
1004 | |||
1005 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, int menuOpenFlags) { | 1017 | void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, int menuOpenFlags) { |
1006 | const iBool postCommands = (menuOpenFlags & postCommands_MenuOpenFlags) != 0; | 1018 | const iBool postCommands = (menuOpenFlags & postCommands_MenuOpenFlags) != 0; |
1007 | #if defined (iHaveNativeContextMenus) | 1019 | #if defined (iHaveNativeContextMenus) |
@@ -1263,8 +1275,8 @@ void updateDropdownSelection_LabelWidget(iLabelWidget *dropButton, const char *s | |||
1263 | iMenuItem *item = findNativeMenuItem_Widget(menu, selectedCommand); | 1275 | iMenuItem *item = findNativeMenuItem_Widget(menu, selectedCommand); |
1264 | if (item) { | 1276 | if (item) { |
1265 | setSelected_NativeMenuItem(item, iTrue); | 1277 | setSelected_NativeMenuItem(item, iTrue); |
1266 | updateText_LabelWidget(dropButton, | 1278 | updateText_LabelWidget( |
1267 | removeMenuItemLabelPrefixes_String(collectNewCStr_String(item->label))); | 1279 | dropButton, removeMenuItemLabelPrefixes_String(collectNewCStr_String(item->label))); |
1268 | } | 1280 | } |
1269 | return; | 1281 | return; |
1270 | } | 1282 | } |
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 | |||
249 | void setMenuItemDisabledByIndex_Widget(iWidget *menu, size_t index, iBool disable); | 249 | void setMenuItemDisabledByIndex_Widget(iWidget *menu, size_t index, iBool disable); |
250 | void setMenuItemLabel_Widget (iWidget *menu, const char *command, const char *newLabel); | 250 | void setMenuItemLabel_Widget (iWidget *menu, const char *command, const char *newLabel); |
251 | void setMenuItemLabelByIndex_Widget (iWidget *menu, size_t index, const char *newLabel); | 251 | void setMenuItemLabelByIndex_Widget (iWidget *menu, size_t index, const char *newLabel); |
252 | void setNativeMenuItems_Widget (iWidget *, const iMenuItem *items, size_t n); | ||
252 | 253 | ||
253 | int checkContextMenu_Widget (iWidget *, const SDL_Event *ev); /* see macro below */ | 254 | int checkContextMenu_Widget (iWidget *, const SDL_Event *ev); /* see macro below */ |
254 | 255 | ||