diff --git a/components/micropython/usermodule/mp_sys_display.c b/components/micropython/usermodule/mp_sys_display.c
index 806ed1ae1a9c2c277e7f76dace7bc84caa96a108..22e9de626debed3589535d1f7083a9358a21dc66 100644
--- a/components/micropython/usermodule/mp_sys_display.c
+++ b/components/micropython/usermodule/mp_sys_display.c
@@ -77,9 +77,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_ctx_obj, mp_ctx);
 
 STATIC mp_obj_t mp_fb(mp_obj_t mode_in) {
     int mode = mp_obj_get_int(mode_in);
-    int size = 240 * 240 * st3m_gfx_bpp(mode) / 8;
-    if (mode == st3m_gfx_palette) size = 256 * 3;
-    return mp_obj_new_bytearray_by_ref(size, st3m_gfx_fb(mode));
+    int stride, width, height;
+    void *fb = st3m_gfx_fb(mode, &stride, &width, &height);
+    int size = height * stride;
+    return mp_obj_new_bytearray_by_ref(size, fb);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_fb_obj, mp_fb);
 
diff --git a/components/st3m/st3m_gfx.c b/components/st3m/st3m_gfx.c
index 89c42f52630d09a8ac46ffb1b046458073ba01db..be428cc0a5f6c6c68f2f8d316c5f3c965f13f186 100644
--- a/components/st3m/st3m_gfx.c
+++ b/components/st3m/st3m_gfx.c
@@ -218,6 +218,9 @@ void st3m_gfx_set_default_mode(st3m_gfx_mode mode) {
             default_mode &= ~st3m_gfx_low_latency;
         else if (mode & st3m_gfx_direct_ctx)
             default_mode &= ~st3m_gfx_direct_ctx;
+    } else if ((mode & (1|2|4|8|16|32)) == mode) {
+        default_mode &= ~(1|2|4|8|16|32);
+        default_mode |= mode;
     } else if (mode == st3m_gfx_2x) {
         default_mode &= ~st3m_gfx_4x;
         default_mode |= st3m_gfx_2x;
@@ -335,19 +338,32 @@ st3m_gfx_mode st3m_gfx_set_mode(st3m_gfx_mode mode) {
 
 st3m_gfx_mode st3m_gfx_get_mode(void) { return _st3m_gfx_mode; }
 
-uint8_t *st3m_gfx_fb(st3m_gfx_mode mode) {
+uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *stride, int *width, int *height) {
     st3m_gfx_mode set_mode = _st3m_gfx_mode ? _st3m_gfx_mode : default_mode;
+    int bpp = st3m_gfx_bpp(set_mode);
     if (mode == st3m_gfx_palette) {
+        if (stride) *stride = 3;
+        if (width) *width = 1;
+        if (height) *height = 256;
         return st3m_pal;
     } else if (mode == st3m_gfx_default) {
-        if (st3m_gfx_bpp(set_mode) <= 16) return (uint8_t *)st3m_fb;
+        if (stride) *stride = 240 * bpp / 8;
+        if (width) *width = 240;
+        if (height) *height = 240;
+        if (bpp <= 16) return (uint8_t *)st3m_fb;
         return st3m_osd_fb;
     } else if (mode == st3m_gfx_osd) {
+        if (stride) *stride = 240 * bpp / 8;
+        if (width) *width = 240;
+        if (height) *height = 240;
         if (st3m_gfx_bpp(set_mode) <= 16) return st3m_osd_fb;
         return (uint8_t *)st3m_fb;
     }
 
-    if (st3m_gfx_bpp(set_mode) <= 16) return (uint8_t *)st3m_fb;
+    if (stride) *stride = 240 * bpp / 8;
+    if (width) *width = 240;
+    if (height) *height = 240;
+    if (bpp <= 16) return (uint8_t *)st3m_fb;
     return st3m_osd_fb;
 }
 
diff --git a/components/st3m/st3m_gfx.h b/components/st3m/st3m_gfx.h
index cd9dcc1aa0672913e7cb9d0db1d6604c8a317168..58c96232def9236e413ee0bbb7edb96617d57e82 100644
--- a/components/st3m/st3m_gfx.h
+++ b/components/st3m/st3m_gfx.h
@@ -76,7 +76,7 @@ Ctx *st3m_gfx_ctx(st3m_gfx_mode mode);
 // get the framebuffer associated with graphics mode
 // if you ask for st3m_gfx_default you get the current modes fb
 // and if you ask for st3m_gfx_osd you get the current modes overlay fb
-uint8_t *st3m_gfx_fb(st3m_gfx_mode mode);
+uint8_t *st3m_gfx_fb(st3m_gfx_mode mode, int *stride, int *width, int *height);
 
 // get the bits per pixel for a given mode
 int st3m_gfx_bpp(st3m_gfx_mode mode);
diff --git a/python_payload/st3m/run.py b/python_payload/st3m/run.py
index 24ff5eab2ffc2ca2ede3ed6a98f44c91d4cab107..2d0c24e79cb02fc67cb95cb9a571d5eeb6fdcfe0 100644
--- a/python_payload/st3m/run.py
+++ b/python_payload/st3m/run.py
@@ -169,10 +169,10 @@ def run_main() -> None:
         [
             MenuItemBack(),
             MenuItemAction(
-                "RGB565_BS", lambda: sys_display.set_default_mode(16 + sys_display.osd)
+                "RGB565_BS", lambda: sys_display.set_default_mode(16)
             ),
             MenuItemAction(
-                "RGB888", lambda: sys_display.set_default_mode(24 + sys_display.osd)
+                "RGB888", lambda: sys_display.set_default_mode(24)
             ),
             MenuItemAction(
                 "RGB332",
@@ -181,7 +181,7 @@ def run_main() -> None:
                 ),
             ),
             MenuItemAction(
-                "gray", lambda: sys_display.set_default_mode(8 + sys_display.osd)
+                "gray", lambda: sys_display.set_default_mode(8)
             ),
             MenuItemAction(
                 "sepia",
@@ -237,7 +237,7 @@ def run_main() -> None:
                 "force mode", lambda: sys_display.set_default_mode(sys_display.force)
             ),
             MenuItemAction(
-                "force mode off",
+                "force mode off (apps can change graphics mode)",
                 lambda: sys_display.set_default_mode(
                     sys_display.unset + sys_display.force
                 ),