fix(perf+sdk/ime): ①perf net_json 缺 network 对象闭合括号 → 全量 JSON 根对象不闭合/非法(MeowPanel /api/system jv_parse 失败根因,真机+python 双重证实)②IME flush 挂起(meow_gfx_flush_hold): 阻塞循环整周期只记脏、IME画完一次原子上屏,根治 on_tick 进度条与键盘同区两刷频闪 ③TextField on_change 只标脏不重画→改 meow_ui_invalidate 真重画,输入实时回显

meow_svc_perf fa073bf9→7ea196de; meow_ui.a d814d0ed→ece0ecdb; hello 2ce09466→f45ba051; launcher 9ca4c5e8→bd37c8b0(重链)
宿主验证: test_ime_fix/test_p1p2p3_repro/test_meow_ui_widgets 全 PASS; perf_host all 输出经 python json 校验合法
This commit is contained in:
MeowOS committed 2026-08-31 03:11:35 +08:00
1 parent 08c70aa14c
commit 896f391fee
9 files changed
+23 -5

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -1
View File
@@ -427,12 +427,13 @@ static void net_json(sbuf_t *s, const char *hostname)
net_bluetooth_json(s); net_bluetooth_json(s);
sA(s, "},\"hostname_local\":"); sA(s, "},\"hostname_local\":");
const char *hn = (hostname && hostname[0] && strcmp(hostname, "-")) ? hostname : NULL; const char *hn = (hostname && hostname[0] && strcmp(hostname, "-")) ? hostname : NULL;
if (!hn) { sA(s, "null"); return; } if (!hn) { sA(s, "null"); sA(s, "}"); return; }
char hl[96]; char hl[96];
size_t l = strlen(hn); size_t l = strlen(hn);
if (l >= 6 && !strcmp(hn + l - 6, ".local")) snprintf(hl, sizeof hl, "%s", hn); if (l >= 6 && !strcmp(hn + l - 6, ".local")) snprintf(hl, sizeof hl, "%s", hn);
else snprintf(hl, sizeof hl, "%s.local", hn); else snprintf(hl, sizeof hl, "%s.local", hn);
sA_str(s, hl); sA_str(s, hl);
sA(s, "}"); /* 闭合 network 对象(缺它则 agg_json 收尾的 "}" 只闭合 network,根对象不闭合 → JSON 非法) */
} }
/* ---------------- 聚合 JSON(subset 位掩码;与 MEOWPANEL_PROTOCOL §3.1 .data 对齐) ---------------- */ /* ---------------- 聚合 JSON(subset 位掩码;与 MEOWPANEL_PROTOCOL §3.1 .data 对齐) ---------------- */
Binary file not shown.
+8 -2
View File
@@ -179,6 +179,12 @@ void meow_gfx_mark_dirty(int x, int y, int w, int h) { dirty_add(x, y, w, h); }
void meow_gfx_mark_full(void) { dirty_full(); } void meow_gfx_mark_full(void) { dirty_full(); }
void meow_gfx_dirty_reset(void) { dirty_reset(); } void meow_gfx_dirty_reset(void) { dirty_reset(); }
/* flush 挂起(IME/模态阻塞循环用):挂起期间 flush/flush_region 只记脏不上屏,
* 解除后由调用方一次 flush 原子上屏——避免「App on_tick 重绘先上屏、覆盖层随后再上屏」
* 同一区域一帧两刷的频闪。 */
static int g_flush_hold = 0;
void meow_gfx_flush_hold(int on) { g_flush_hold = on ? 1 : 0; }
/* back_buf 每行字节数 / 位深(M2.71-bug3:模态/IME 整帧快照恢复用)。 */ /* back_buf 每行字节数 / 位深(M2.71-bug3:模态/IME 整帧快照恢复用)。 */
int meow_ui_back_buf_pitch(void) { return g_line; } int meow_ui_back_buf_pitch(void) { return g_line; }
int meow_ui_back_buf_bpp(void) { return g_bpp; } int meow_ui_back_buf_bpp(void) { return g_bpp; }
@@ -918,10 +924,10 @@ static void present(void)
dirty_reset(); dirty_reset();
} }
void meow_ui_flush(void) { present(); } void meow_ui_flush(void) { if (!g_flush_hold) present(); }
void meow_ui_flush_region(int x, int y, int w, int h) void meow_ui_flush_region(int x, int y, int w, int h)
{ dirty_add(x, y, w, h); present(); } { dirty_add(x, y, w, h); if (!g_flush_hold) present(); }
/* ---- 帧率调度设置接口(launcher 与 app 共用;归口 PERF_SCHEDULER 显示刷新率子域)---- */ /* ---- 帧率调度设置接口(launcher 与 app 共用;归口 PERF_SCHEDULER 显示刷新率子域)---- */
/* 设目标档位(60/30/15):同时把当前有效档对齐到目标(与 launcher settings_load 语义一致)。 */ /* 设目标档位(60/30/15):同时把当前有效档对齐到目标(与 launcher settings_load 语义一致)。 */
+5
View File
@@ -268,6 +268,10 @@ int meow_ui_text_input(meow_ime_ctx *ctx)
meow_ui_text_input_async(ctx); meow_ui_text_input_async(ctx);
/* 阻塞循环:直到 done;on_change 由 handle_tap 触发 */ /* 阻塞循环:直到 done;on_change 由 handle_tap 触发 */
while (meow_ime_active()) { while (meow_ime_active()) {
/* flush 挂起:整个周期内(事件处理触发的 on_change 重绘 + App on_tick 重绘)
* 只记脏不上屏;IME 画完后一次 flush 原子上屏——否则 on_tick 的 invalidate
* 会先把进度条等区域刷上屏盖住键盘,IME 随后再盖回,同区一帧两刷→频闪。 */
meow_gfx_flush_hold(1);
meow_input_ev e; meow_input_ev e;
while (meow_input_pop(&e)) { while (meow_input_pop(&e)) {
meow_ui_activity_ping(); /* M2.71-bug5:IME 打字交互也重置息屏计时 */ meow_ui_activity_ping(); /* M2.71-bug5:IME 打字交互也重置息屏计时 */
@@ -277,6 +281,7 @@ int meow_ui_text_input(meow_ime_ctx *ctx)
* 顺序要求:先喂 on_tick(App 重绘进 back_buf)→ 再 meow_ime_draw(IME 面板随后盖上去), * 顺序要求:先喂 on_tick(App 重绘进 back_buf)→ 再 meow_ime_draw(IME 面板随后盖上去),
* 保证 IME 面板覆盖在最上,不被 App 的 d_paint_region 覆盖。 */ * 保证 IME 面板覆盖在最上,不被 App 的 d_paint_region 覆盖。 */
meow_ui_feed_tick(); meow_ui_feed_tick();
meow_gfx_flush_hold(0);
meow_ime_draw(); meow_ime_draw();
meow_ui_flush(); meow_ui_flush();
usleep(16000); usleep(16000);
+4
View File
@@ -98,6 +98,10 @@ void meow_gfx_blit_rgba(int x, int y, int w, int h, const uint8_t *rgba, int alp
/* 标记一个区域脏(供非标准绘制使用)。 */ /* 标记一个区域脏(供非标准绘制使用)。 */
void meow_gfx_mark_dirty(int x, int y, int w, int h); void meow_gfx_mark_dirty(int x, int y, int w, int h);
/* flush 挂起(IME/模态阻塞循环用):on=1 期间 meow_ui_flush/flush_region 只记脏不上屏,
* 解除后由调用方一次 flush 原子上屏,避免覆盖层与 App on_tick 重绘同帧两刷频闪。 */
void meow_gfx_flush_hold(int on);
/* 标记整帧脏(launcher 手动脏模型桥接:自绘 raw 像素后标全屏,present 走 SDK)。 */ /* 标记整帧脏(launcher 手动脏模型桥接:自绘 raw 像素后标全屏,present 走 SDK)。 */
void meow_gfx_mark_full(void); void meow_gfx_mark_full(void);
+4 -2
View File
@@ -507,7 +507,8 @@ void meow_textfield_set_placeholder(meow_widget *w, const char *placeholder)
meow_gfx_mark_dirty(w->x, w->y, w->w, w->h); meow_gfx_mark_dirty(w->x, w->y, w->w, w->h);
} }
const char *meow_textfield_text(meow_widget *w) { return (w && w->type == W_TEXTFIELD && w->buf) ? w->buf : ""; } const char *meow_textfield_text(meow_widget *w) { return (w && w->type == W_TEXTFIELD && w->buf) ? w->buf : ""; }
/* 输入中实时把 IME 文本同步到字段缓冲 + 只刷字段区(字段在顶部,IME 键盘在底部覆盖层) */ /* 输入中实时把 IME 文本同步到字段缓冲 + 重画字段区(invalidate 重画 z 栈相交绘制物;
* flush 在 IME 阻塞循环内被挂起(meow_gfx_flush_hold),随本周期末一次原子上屏) */
static void textfield_change_cb(const char *text, void *ctx) static void textfield_change_cb(const char *text, void *ctx)
{ {
meow_widget *w = (meow_widget *)ctx; meow_widget *w = (meow_widget *)ctx;
@@ -517,7 +518,8 @@ static void textfield_change_cb(const char *text, void *ctx)
w->buf[w->maxlen - 1] = 0; w->buf[w->maxlen - 1] = 0;
} }
w->buflen = text ? (int)strlen(text) : 0; w->buflen = text ? (int)strlen(text) : 0;
meow_gfx_mark_dirty(w->x, w->y, w->w, w->h); /* 只标脏不重画的话 back_buf 仍是旧文本,flush 上去的还是旧的——必须真重画 */
meow_ui_invalidate(w->x, w->y, w->w, w->h);
} }
int meow_textfield_activate(meow_widget *w) int meow_textfield_activate(meow_widget *w)
{ {