fix(statusbar): 全屏状态栏收合 — 上移出屏+停渲染+热区28保留+左缘指示条屏顶(agent-146)
- 根因: launcher/App 双进程各持SDK态, hello运行时全屏(set_fullscreen+set_collapsed)只改App进程, launcher仍expanded→画28px+时序闪 - SDK render_off(yoff): 顶条内容整体上移+裁顶, 收合 statusbar_collapsed_render 只画4px提示线(无时钟/图标/值) - 热区保留: meow_ui_statusbar_hotzone() 收合时返回28(渲染与热区事件分离)→收合仍可下滑 - 左缘指示条: meow_ui_swipe_hint y=statusbar_height()=4 平移屏顶 - 模式感知: /tmp/meowapp_sbar(App进程SDK写0展开/1收合/2隐藏, launcher读); launch_app循环新变立即叠(消半秒闪)+过渡期~20ms高频刷(动画平滑) - meow_ui.a=ed0267a9 launcher=7ea80408 hello=1a3ff13e 0warning; 宿主 test_sb_collapse/test_sb_statusbar ALL PASS - 遗留: 全屏上收观感/收合下App前台打开通知中心归④M3(meow_ui_sys_notif_pull桩)
This commit is contained in:
1 parent
03962fffac
commit
1481ae00c4
8 files changed
+183
-33
No files matched your search
+48
-13
@@ -25,6 +25,11 @@
|
||||
|
||||
#define MEOW_SETTINGS_FILE "/usr/data/meow/settings.conf"
|
||||
|
||||
/* App 前台顶条模式文件(App 进程 SDK 写,launcher 读)。与 /tmp/meowapp_state(immersive,launcher 写/
|
||||
* watchdog 读)语义不同,独立文件避免冲突。值:'0'=展开 28px 整条;'1'=收合(提示线);'2'=隐藏(沉浸 inset0)。
|
||||
* 仅 App 进程写(!g_sys_render);launcher(系统 UI)不写,只读。App 退出时由 launcher unlink。 */
|
||||
#define MEOW_SBAR_MODE_FILE "/tmp/meowapp_sbar"
|
||||
|
||||
/* 蓝牙 powered 缓存刷新间隔(hciconfig 较贵) */
|
||||
#define BT_REFRESH_MS 30000
|
||||
|
||||
@@ -190,6 +195,21 @@ void meow_ui_sys_set_system_mode(int on)
|
||||
g_statusbar_force = 1; /* 切换即强制下次 present 反映(画/不画顶条) */
|
||||
}
|
||||
|
||||
/* ---- App 前台顶条模式上报(agent-146 全屏收合接入)----
|
||||
* 仅在 App 进程(!g_sys_render)写;launcher(system_mode=1)不写,避免覆盖 App 的状态。
|
||||
* 由 meow_ui_set_fullscreen / meow_ui_statusbar_set_collapsed 调用,使 launcher(read 进程)
|
||||
* 能感知 App 运行时的全屏/收合态,从而把新顶条切到收合(提示线)而非仍画 28px 整条。 */
|
||||
void meow_ui_sbar_write_mode(void)
|
||||
{
|
||||
if (g_sys_render) return; /* 系统进程(launcher)不写 */
|
||||
char m = meow_ui_statusbar_collapsed() ? '1'
|
||||
: (g_fullscreen ? '2' : '0');
|
||||
int fd = open(MEOW_SBAR_MODE_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) return;
|
||||
if (write(fd, &m, 1) < 0) { /* ignore write error */ }
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int meow_ui_sys_render_enabled(void)
|
||||
{
|
||||
return g_sys_render;
|
||||
@@ -200,6 +220,7 @@ void meow_ui_set_statusbar(int visible)
|
||||
{
|
||||
g_statusbar_on = visible ? 1 : 0;
|
||||
g_statusbar_force = 1; /* 显隐切换也要重画顶条 */
|
||||
meow_ui_sbar_write_mode(); /* App 进程上报顶条模式(launcher 感知全屏/收合) */
|
||||
}
|
||||
|
||||
int meow_ui_statusbar_visible(void)
|
||||
@@ -211,6 +232,7 @@ void meow_ui_set_fullscreen(int on)
|
||||
{
|
||||
g_fullscreen = on ? 1 : 0;
|
||||
g_statusbar_force = 1; /* 进出全屏立即反映(显示/隐藏顶条) */
|
||||
meow_ui_sbar_write_mode(); /* App 进程上报顶条模式(launcher 感知全屏/收合) */
|
||||
}
|
||||
|
||||
int meow_ui_statusbar_height(void)
|
||||
@@ -259,14 +281,14 @@ int meow_ui_sys_statusbar_force(void)
|
||||
/* 画一个右对齐项:右边界=*xr,画完向左推进 *xr(含 MEOW_SB_XGAP 项间隙)。
|
||||
* icon>=0 画图标(可配右侧数值 txt;txt==NULL 仅图标)。文字/图标同用主题色 col。
|
||||
* ink_h 传给 meow_gfx_blit_icon(主图标用 MEOW_SB_ICON_INK 等大;WiFi 强弱档传 0 保持自然 ink)。
|
||||
* 返回该项左边缘(供亮度可选判宽)。 */
|
||||
static int sb_r_place(int *xr, int icon, const char *txt, uint32_t col, int ink_h, int ty)
|
||||
* ycy = 图标 ink 垂直中心线(收合上移时随 -off 上移);ty = 文字 y。返回该项左边缘(供亮度可选判宽)。 */
|
||||
static int sb_r_place(int *xr, int icon, const char *txt, uint32_t col, int ink_h, int ty, int ycy)
|
||||
{
|
||||
int iconw = (icon >= 0) ? MEOW_SB_ICON_SIZE : 0;
|
||||
int gap = (icon >= 0 && txt) ? MEOW_SB_TGAP : 0;
|
||||
int tw = txt ? meow_ui_text_width(txt, MUI_SBAR_FONT) : 0;
|
||||
int x = *xr - (iconw + gap + tw);
|
||||
if (icon >= 0) { meow_gfx_blit_icon(icon, x, 0, ink_h, col, MEOW_SB_ICON_CY); x += iconw + gap; }
|
||||
if (icon >= 0) { meow_gfx_blit_icon(icon, x, 0, ink_h, col, ycy); x += iconw + gap; }
|
||||
if (txt) meow_ui_text_right(*xr, ty, txt, MUI_SBAR_FONT, col);
|
||||
*xr -= (iconw + gap + tw) + MEOW_SB_XGAP;
|
||||
return *xr + MEOW_SB_XGAP;
|
||||
@@ -285,19 +307,31 @@ static int sb_wifi_icon(void)
|
||||
}
|
||||
|
||||
void meow_ui_sys_statusbar_render(void)
|
||||
{
|
||||
meow_ui_sys_statusbar_render_off(0);
|
||||
}
|
||||
|
||||
void meow_ui_sys_statusbar_render_off(int yoff)
|
||||
{
|
||||
if (!g_sys_render) return; /* 仅系统进程(launcher)渲染;App 不画顶条 */
|
||||
if (!meow_ui_sys_statusbar_active()) return;
|
||||
if (yoff < 0) yoff = 0;
|
||||
if (yoff > MUI_SBAR_H) yoff = MUI_SBAR_H;
|
||||
const meow_theme *th = meow_theme_get();
|
||||
int w = meow_ui_width();
|
||||
int h = MUI_SBAR_H;
|
||||
int vis = h - yoff; /* 收合上移:可见条高 = 28-yoff(其余行=App 内容,由 launcher 保留) */
|
||||
if (vis <= 0) return; /* 完全收合由 statusbar_collapsed_render(提示线)处理 */
|
||||
|
||||
/* 整条清底:覆盖 app 可能画进顶行的内容(z 最顶)。仅系统进程(launcher)渲染本函数。 */
|
||||
meow_ui_fill_rect(0, 0, w, h, th->bg);
|
||||
/* 整条清底(仅可见条高 [0,vis) 行):覆盖 app 可能画进顶行的内容(z 最顶)。仅系统进程渲染本函数。 */
|
||||
meow_ui_fill_rect(0, 0, w, vis, th->bg);
|
||||
|
||||
/* 文字垂直锚 y:(栏高-行高)/2 居中;下限 1 防极端行高 > 栏高时负 y 溢出顶端(不越界优先)。 */
|
||||
/* 文字垂直锚 y:(栏高-行高)/2 居中;下限 1 防极端行高 > 栏高时负 y 溢出顶端(不越界优先)。
|
||||
* 收合上移:内容整体上移 yoff 像素并裁顶(meow_font/图标 blit 已带 y<0 边界钳制,安全)。 */
|
||||
int ty = (h - meow_ui_text_height(MUI_SBAR_FONT)) / 2;
|
||||
if (ty < 1) ty = 1;
|
||||
ty -= yoff;
|
||||
int ycy = MEOW_SB_ICON_CY - yoff; /* 图标 ink 垂直中心随上移 */
|
||||
|
||||
/* 时钟(左):每秒现取 localtime */
|
||||
char timebuf[16];
|
||||
@@ -314,28 +348,29 @@ void meow_ui_sys_statusbar_render(void)
|
||||
char val[16];
|
||||
if (g_sys.batt >= 0) { /* 电量:图标+%(未知不画)——最右项 */
|
||||
snprintf(val, sizeof val, "%d%%", g_sys.batt);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BATT, val, col, MEOW_SB_ICON_INK, ty);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BATT, val, col, MEOW_SB_ICON_INK, ty, ycy);
|
||||
}
|
||||
snprintf(val, sizeof val, "%d%%", g_sys.vol);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_VOL, val, col, MEOW_SB_ICON_INK, ty); /* 音量:图标+% */
|
||||
sb_r_place(&xr, MEOW_SB_ICON_VOL, val, col, MEOW_SB_ICON_INK, ty, ycy); /* 音量:图标+% */
|
||||
if (g_sys.bt_seen && g_sys.bt_on) { /* 蓝牙:仅图标(上电即显示,连接态占位;多态留后续) */
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BT_CONN, NULL, col2, MEOW_SB_ICON_INK, ty);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BT_CONN, NULL, col2, MEOW_SB_ICON_INK, ty, ycy);
|
||||
}
|
||||
if (g_sys.wifi_on) { /* WiFi:仅图标(关不画;开未连/分档) */
|
||||
int wco = sb_wifi_icon();
|
||||
int is_weak = (wco == MEOW_SB_ICON_WIFI_MEDIUM || wco == MEOW_SB_ICON_WIFI_WEAK);
|
||||
sb_r_place(&xr, wco, NULL, col, is_weak ? 0 : MEOW_SB_ICON_INK, ty);
|
||||
sb_r_place(&xr, wco, NULL, col, is_weak ? 0 : MEOW_SB_ICON_INK, ty, ycy);
|
||||
}
|
||||
if (g_sys.brightness > 0) { /* 亮度:图标+%(>0 才显示;与时钟不重叠才画) */
|
||||
int bl = (g_sys.brightness > 100) ? 100 : g_sys.brightness;
|
||||
snprintf(val, sizeof val, "%d%%", bl);
|
||||
int bw = MEOW_SB_ICON_SIZE + MEOW_SB_TGAP + meow_ui_text_width(val, MUI_SBAR_FONT) + MEOW_SB_XGAP;
|
||||
if (xr - bw > 8 + meow_ui_text_width(timebuf, MUI_SBAR_FONT) + MEOW_SB_CLK_MARGIN)
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BRIGHT, val, col, MEOW_SB_ICON_INK, ty);
|
||||
sb_r_place(&xr, MEOW_SB_ICON_BRIGHT, val, col, MEOW_SB_ICON_INK, ty, ycy);
|
||||
}
|
||||
|
||||
/* 分隔线(栏内最底 1px,主题次要色);内容 inset=statusbar_height()=28 从 y=28 起即干净 */
|
||||
meow_ui_fill_rect(0, h - 1, w, 1, th->dim);
|
||||
/* 分隔线(栏内最底 1px,主题次要色);上移后仍在可见条高内;内容 inset=statusbar_height() 从该线之下即干净 */
|
||||
int dy = h - 1 - yoff;
|
||||
if (dy >= 0 && dy < vis) meow_ui_fill_rect(0, dy, w, 1, th->dim);
|
||||
|
||||
g_statusbar_force = 0;
|
||||
}
|
||||
Reference in new issue
Block a user