@@ -13,7 +13,12 @@ const prosettings = (require("Storage").readJSON("promenu.settings.json", true)
1313prosettings . naturalScroll ??= false ;
1414prosettings . wrapAround ??= true ;
1515
16- E . showMenu = ( items ?: Menu ) : MenuInstance => {
16+ E . showMenu = ( ( items ?: Menu ) : MenuInstance | void => {
17+ if ( items == null ) {
18+ g . clearRect ( Bangle . appRect ) ;
19+ return Bangle . setUI ( ) ;
20+ }
21+
1722 const RectRnd = ( x1 : number , y1 : number , x2 : number , y2 : number , r : number ) => {
1823 const pp = [ ] ;
1924 pp . push ( ...g . quadraticBezier ( [ x2 - r , y1 , x2 , y1 , x2 , y1 + r ] ) ) ;
@@ -167,7 +172,6 @@ E.showMenu = (items?: Menu): MenuInstance => {
167172 } , 300 , name , v , item , idx , x , iy ) ;
168173 }
169174
170- g . setColor ( g . theme . fg ) ;
171175 iy += fontHeight ;
172176 idx ++ ;
173177 }
@@ -252,21 +256,47 @@ E.showMenu = (items?: Menu): MenuInstance => {
252256 else l . select ( evt ) ;
253257 } ;
254258
255- Bangle . setUI ( {
259+ const touchcb = ( ( _button , xy ) => {
260+ // since we've specified options.touch,
261+ // we need to pass through all taps since the default
262+ // touchHandler isn't installed in setUI
263+ cb ( void 0 , xy ) ;
264+ } ) satisfies TouchCallback ;
265+
266+ const uiopts = {
256267 mode : "updown" ,
257- back,
268+ back : back as ( ) => void ,
258269 remove : ( ) => {
259270 if ( nameScroller ) clearInterval ( nameScroller ) ;
260271 Bangle . removeListener ( "swipe" , onSwipe ) ;
272+ if ( setUITouch )
273+ Bangle . removeListener ( "touch" , touchcb ) ;
261274 options . remove ?.( ) ;
262275 } ,
263- touch : ( ( _button , xy ) => {
264- // since we've specified options.touch,
265- // we need to pass through all taps since the default
266- // touchHandler isn't installed in setUI
267- cb ( void 0 , xy ) ;
268- } ) satisfies TouchCallback ,
269- } as SetUIArg < "updown" > , cb ) ;
276+ } satisfies SetUIArg < "updown" > ;
277+
278+ // does setUI install its own touch handler?
279+ const setUITouch = process . env . VERSION >= "2v26" ;
280+ if ( ! setUITouch ) {
281+ // old firmware, we can use its touch handler - no need for workaround
282+ ( uiopts as any ) . touch = touchcb ;
283+ }
284+
285+ Bangle . setUI ( uiopts , cb ) ;
286+
287+ if ( setUITouch ) {
288+ // new firmware, remove setUI's touch handler and use just our own to
289+ // avoid `cb` drawing the menu (as part of setUI's touch handler)
290+ // followed by us drawing the menu (as part of our touch handler)
291+ //
292+ // work around details:
293+ // - https://github.com/espruino/Espruino/issues/2648
294+ // - https://github.com/orgs/espruino/discussions/7697#discussioncomment-13782299
295+ Bangle . removeListener ( "touch" , ( Bangle as any ) . touchHandler ) ;
296+ delete ( Bangle as any ) . touchHandler ;
297+
298+ Bangle . on ( "touch" , touchcb ) ;
299+ }
270300
271301 return l ;
272- } ;
302+ } ) as typeof E . showMenu ;
0 commit comments