The issue is that if a ActivityRecording.Session is stopped and no user input is received (key presses in the case of this example, but taps and swipes are known to be affected) before pushing a new view (or menu, or whatever), the first user input after the Ui.pushView() has no effect. Note that I cannot reproduce this problem on the simulator. I have reproduced it on the 920XT w/ 3.20 firmware, and I've been told the problem exists for the VivoActive as well (not sure of firmware version).
The following test case walks you through several scenarios, like a wizard, interacting with the Session and Ui.pushView(). In the cases that the session is modified and the view is pushed, you'll notice that the first up/down key press has no effect on the key press count.
I'm fairly certain that this issue relates to this one I filed the other day. My gut tells me that the session object creates some sort of drawable that hooks into the rendering system (I'm betting that it is the lap screen that appears automatically when Session.addLap() is called). For some reason that drawable is always resetting the draw colors (which it should not do), and it is somehow causing input to be consumed.
using Toybox.Application as App;
using Toybox.ActivityRecording as Arc;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.WatchUi as Ui;
class Delegate2 extends Ui.InputDelegate
{
hidden var view;
hidden var count;
function initialize(view) {
self.view = view;
setCount(0);
}
function onKey(evt) {
var key = evt.getKey();
if (key == Ui.KEY_ESC) {
Ui.popView(Ui.SLIDE_IMMEDIATE);
}
else if (key == Ui.KEY_ENTER) {
Ui.popView(Ui.SLIDE_IMMEDIATE);
}
else {
setCount(count + 1);
}
return true;
}
hidden function setCount(n) {
count = n;
view.setText("Up/Down Presses " + n.toString());
}
}
class Delegate1 extends Ui.InputDelegate
{
hidden var view;
hidden var activity;
hidden var state;
function initialize(view) {
self.view = view;
activity = null;
state = 0;
}
function showMenu() {
var next = new TestView();
Ui.pushView(next, new Delegate2(next), Ui.SLIDE_IMMEDIATE);
view.setText("Press Enter\nto Start");
}
function onKey(evt) {
var key = evt.getKey();
if (key == Ui.KEY_ENTER) {
Sys.println("state="+state);
if (state == 0) {
// menu is normal
showMenu();
view.setText("Press Enter\nto create session");
}
else if (state == 1) {
activity = Arc.createSession({
:sport => Arc.SPORT_GENERIC,
:subSport => Arc.SUB_SPORT_GENERIC,
:name => "testing"
});
view.setText("Created.\nPress Enter\nto show menu");
}
else if (state == 2) {
// menu is black, but behaves normally
showMenu();
view.setText("Created.\nPress Enter\nto record");
}
else if (state == 3) {
activity.start();
view.setText("Recording.\nPress Enter\nto stop");
}
else if (state == 4) {
activity.stop();
view.setText("Paused.\nPress Enter\nto show menu");
}
else if (state == 5) {
// menu is black, but behaves normally
showMenu();
view.setText("Created.\nPress Enter\nto resume and\nshow menu");
}
else if (state == 6) {
activity.start();
// menu is black, but requires one key input before it behaves normally
showMenu();
view.setText("Recording.\nPress Enter\nto stop and\nshow menu");
}
else if (state == 7) {
activity.stop();
// menu is black, but requires one key input before it behaves normally
showMenu();
view.setText("Paused.\nPress Enter\nto discard");
}
else if (state == 8) {
activity.discard();
view.setText("Discarded.\nPress Enter\nto deallocate");
}
else if (state == 9) {
activity = null;
view.setText("Deallocated.\nPress Enter\nto exit");
}
else {
Ui.popView(Ui.SLIDE_IMMEDIATE);
}
++state;
}
return true;
}
}
class TestView extends Ui.View
{
var text;
function initialize() {
text = "Press Enter\nTo Start";
}
function setText(text) {
self.text = text;
Ui.requestUpdate();
}
function onUpdate(dc) {
dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_WHITE);
dc.clear();
var cx = dc.getWidth() / 2;
var cy = dc.getHeight() / 2;
dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT);
dc.drawText(cx, cy, Gfx.FONT_SMALL,
text,
Gfx.TEXT_JUSTIFY_CENTER | Gfx.TEXT_JUSTIFY_VCENTER);
}
}
class Test_ToGeoStringApp extends App.AppBase
{
function getInitialView() {
var view = new TestView();
var delegate = new Delegate1(view);
return [ view, delegate ];
}
}