Skip to content

Instantly share code, notes, and snippets.

@HBehrens
Created January 30, 2014 09:43
Show Gist options
  • Save HBehrens/8705411 to your computer and use it in GitHub Desktop.
Save HBehrens/8705411 to your computer and use it in GitHub Desktop.
minimal example to demo PebbleCam's crash on Pebble Firmware 2.0.RC
#include <pebble.h>
/*
This is a minimal example to demo PebbleCam's crash on Pebble Firmware 2.0.RC
Even though the logs state an issue with cancel_timer, it's really an issue
with window_raw_click_subscribe on BUTTON_ID_UP and menu_layer_set_click_config_onto_window
on the sub window. Change any of those and the crash is gone.
This problem first occured on 2.0.RC, it was no problem with .beta7 or any
release before.
To reproduce the error, run this watch app, press the UP button to push a sub
window. After pushing BACK it should crash.
Have a look at the comments starting with NOTE and you will learn that it works
fine with single_click instead of raw_click and also won't crash if you press
the SELECT button.
Also, when pressing UP button a second time (after the sub menu already appeared)
you can go back without a crash.
DISCLAIMER: This code aims for simplicity. It leaks memory and doesn't use
best-practices such as window handlers.
*/
// subwindow
// ------------------------------------------------------------------------
static Window* subWindow;
static MenuLayer* menuLayer;
static uint16_t get_num_sections(struct MenuLayer *menu_layer, void *callback_context) {
return 1;
}
static uint16_t get_num_rows(struct MenuLayer *menu_layer, uint16_t section_index, void *callback_context) {
return 1;
}
static void draw_row(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *callback_context) {
menu_cell_basic_draw(ctx, cell_layer, "Just go back", NULL, NULL);
}
static void init_subWindow() {
subWindow = window_create();
Layer *rootLayer = window_get_root_layer(subWindow);
menuLayer = menu_layer_create(layer_get_bounds(rootLayer));
menu_layer_set_callbacks(menuLayer, NULL, (MenuLayerCallbacks){
.get_num_sections = get_num_sections,
.get_num_rows = get_num_rows,
.draw_row = draw_row,
});
layer_add_child(rootLayer, menu_layer_get_layer(menuLayer));
// NOTE: if you don't attach this click handler, everything is fine
menu_layer_set_click_config_onto_window(menuLayer, subWindow);
}
// main window
// ------------------------------------------------------------------------
static Window *window;
static TextLayer *text_layer;
static void clickHandler(ClickRecognizerRef recognizer, void *context) {
text_layer_set_text(text_layer, "app should have crashed before coming back to this window when you pushed UP to show the submenu");
init_subWindow();
window_stack_push(subWindow, true);
}
static void clickConfigProvider(void *context) {
// NOTE: there's no problem with ID_SELECT
window_raw_click_subscribe(BUTTON_ID_SELECT, clickHandler, NULL, NULL);
window_raw_click_subscribe(BUTTON_ID_UP, clickHandler, NULL, NULL);
// NOTE: if you replace the raw_click with a single_click it seems to work
// window_single_click_subscribe(BUTTON_ID_UP, clickHandler);
}
static void init(void) {
window = window_create();
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
text_layer = text_layer_create((GRect) { .origin = { 0, 40 }, .size = { bounds.size.w, 80 } });
text_layer_set_text(text_layer, "Press UP button to open sub window (SELECT to do so without crash).");
text_layer_set_text_alignment(text_layer, GTextAlignmentCenter);
layer_add_child(window_layer, text_layer_get_layer(text_layer));
window_set_click_config_provider(window, clickConfigProvider);
window_stack_push(window, true);
}
int main(void) {
init();
app_event_loop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment