diff --git a/apps/promenu/ChangeLog b/apps/promenu/ChangeLog index 6cf4b09b8..174ff7e22 100644 --- a/apps/promenu/ChangeLog +++ b/apps/promenu/ChangeLog @@ -16,3 +16,4 @@ 0.12: Fix bug where settings would behave as if all were set to false 0.13: Update to new touch-event handling 0.14: Fix bug in handling changes to `Bangle.appRect` +0.15: Workaround bug in 2v26/2v27 firmware diff --git a/apps/promenu/bootb2.js b/apps/promenu/bootb2.js index 368bc623b..f458e426f 100644 --- a/apps/promenu/bootb2.js +++ b/apps/promenu/bootb2.js @@ -2,7 +2,11 @@ var _a, _b; var prosettings = (require("Storage").readJSON("promenu.settings.json", true) || {}); (_a = prosettings.naturalScroll) !== null && _a !== void 0 ? _a : (prosettings.naturalScroll = false); (_b = prosettings.wrapAround) !== null && _b !== void 0 ? _b : (prosettings.wrapAround = true); -E.showMenu = function (items) { +E.showMenu = (function (items) { + if (items == null) { + g.clearRect(Bangle.appRect); + return Bangle.setUI(); + } var RectRnd = function (x1, y1, x2, y2, r) { var pp = []; pp.push.apply(pp, g.quadraticBezier([x2 - r, y1, x2, y1, x2, y1 + r])); @@ -122,7 +126,6 @@ E.showMenu = function (items) { nameScroll_1 = 0; }, 300, name, v, item, idx, x, iy); } - g.setColor(g.theme.fg); iy += fontHeight; idx++; }; @@ -204,7 +207,10 @@ E.showMenu = function (items) { else l.select(evt); }; - Bangle.setUI({ + var touchcb = (function (_button, xy) { + cb(void 0, xy); + }); + var uiopts = { mode: "updown", back: back, remove: function () { @@ -212,11 +218,20 @@ E.showMenu = function (items) { if (nameScroller) clearInterval(nameScroller); Bangle.removeListener("swipe", onSwipe); + if (setUITouch) + Bangle.removeListener("touch", touchcb); (_a = options.remove) === null || _a === void 0 ? void 0 : _a.call(options); }, - touch: (function (_button, xy) { - cb(void 0, xy); - }), - }, cb); + }; + var setUITouch = process.env.VERSION >= "2v26"; + if (!setUITouch) { + uiopts.touch = touchcb; + } + Bangle.setUI(uiopts, cb); + if (setUITouch) { + Bangle.removeListener("touch", Bangle.touchHandler); + delete Bangle.touchHandler; + Bangle.on("touch", touchcb); + } return l; -}; +}); diff --git a/apps/promenu/bootb2.ts b/apps/promenu/bootb2.ts index ab5444113..0306128f1 100644 --- a/apps/promenu/bootb2.ts +++ b/apps/promenu/bootb2.ts @@ -13,7 +13,12 @@ const prosettings = (require("Storage").readJSON("promenu.settings.json", true) prosettings.naturalScroll ??= false; prosettings.wrapAround ??= true; -E.showMenu = (items?: Menu): MenuInstance => { +E.showMenu = ((items?: Menu): MenuInstance | void => { + if(items == null){ + g.clearRect(Bangle.appRect); + return Bangle.setUI(); + } + const RectRnd = (x1: number, y1: number, x2: number, y2: number, r: number) => { const pp = []; pp.push(...g.quadraticBezier([x2 - r, y1, x2, y1, x2, y1 + r])); @@ -167,7 +172,6 @@ E.showMenu = (items?: Menu): MenuInstance => { }, 300, name, v, item, idx, x, iy); } - g.setColor(g.theme.fg); iy += fontHeight; idx++; } @@ -252,21 +256,47 @@ E.showMenu = (items?: Menu): MenuInstance => { else l.select(evt); }; - Bangle.setUI({ - mode: "updown", - back, - remove: () => { - if (nameScroller) clearInterval(nameScroller); - Bangle.removeListener("swipe", onSwipe); - options.remove?.(); - }, - touch: ((_button, xy) => { + const touchcb = ((_button, xy) => { // since we've specified options.touch, // we need to pass through all taps since the default // touchHandler isn't installed in setUI cb(void 0, xy); - }) satisfies TouchCallback, - } as SetUIArg<"updown">, cb); + }) satisfies TouchCallback; + + const uiopts = { + mode: "updown", + back: back as () => void, + remove: () => { + if (nameScroller) clearInterval(nameScroller); + Bangle.removeListener("swipe", onSwipe); + if(setUITouch) + Bangle.removeListener("touch", touchcb); + options.remove?.(); + }, + } satisfies SetUIArg<"updown">; + + // does setUI install its own touch handler? + const setUITouch = process.env.VERSION >= "2v26"; + if (!setUITouch) { + // old firmware, we can use its touch handler - no need for workaround + (uiopts as any).touch = touchcb; + } + + Bangle.setUI(uiopts, cb); + + if(setUITouch){ + // new firmware, remove setUI's touch handler and use just our own to + // avoid `cb` drawing the menu (as part of setUI's touch handler) + // followed by us drawing the menu (as part of our touch handler) + // + // work around details: + // - https://github.com/espruino/Espruino/issues/2648 + // - https://github.com/orgs/espruino/discussions/7697#discussioncomment-13782299 + Bangle.removeListener("touch", (Bangle as any).touchHandler); + delete (Bangle as any).touchHandler; + + Bangle.on("touch", touchcb); + } return l; -}; +}) as typeof E.showMenu; diff --git a/apps/promenu/metadata.json b/apps/promenu/metadata.json index cd7e66e99..cfbd1ebd8 100644 --- a/apps/promenu/metadata.json +++ b/apps/promenu/metadata.json @@ -1,7 +1,7 @@ { "id": "promenu", "name": "Pro Menu", - "version": "0.14", + "version": "0.15", "description": "Replace the built in menu function. Supports Bangle.js 1 and Bangle.js 2.", "icon": "icon.png", "type": "bootloader",