Merge pull request #3942 from bobrippling/workaround/promenu-2v27

promenu: workaround `setUI` touch handler bug (2v26/2v27)
master
Rob Pilling 2025-07-27 21:49:51 +01:00 committed by GitHub
commit 318656a5d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 69 additions and 23 deletions

View File

@ -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

View File

@ -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);
return l;
};
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;
});

View File

@ -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;

View File

@ -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",