mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-31 19:02:37 +08:00
[feat] add live FPS to CLI status bar
This commit is contained in:
@@ -59,6 +59,8 @@ Windows 的可见传统控制台优先读取当前字体尺寸;Windows Termina
|
||||
|
||||
快捷键行使用 `KEYS |`、`VIEW |` 等固定宽度标题,标题和按键组之间用竖线分隔;键名用 `<c>`、`<+/->` 等标签标识。宽窗口中的分组分隔线按列对齐,窄窗口保留标题和完整按键标签,按可用宽度合并或减少分组。
|
||||
|
||||
顶部状态栏以整数显示实时帧率(例如 `FPS 30`),约每秒按最近统计区间内完整输出到终端的帧数计算;没有新画面输出时更新为 `FPS 0`。该数值是实际提交速率,不是 `--fps` 目标值或终端 GPU 呈现频率;窄窗口优先省略画面参数和网络信息,保留帧率。
|
||||
|
||||
ANSI 在完整桌面缩略图中仍无法保留普通字号的文字。先增加终端列数(缩小终端字体或扩大窗口),阅读局部时用 `--zoom native`。只读全景中点击目标位置可直接进入该区域的细节模式;按 `d` 则以当前中心进入。细节模式依据视口和字符宽高比选择源区域,避免为了完整装入桌面而把文字缩小;ANSI 视野较小,借助方向键平移阅读。`--zoom 1..32` 是相对整桌面的倍率;在细节模式中 `+/-` 是相对原始细节尺寸的倍率。画面缩放完全在本地进行,控制鼠标坐标映射回原始桌面的正确区域。
|
||||
|
||||
auto 模式发送 Kitty 查询与设备属性查询,等待最多 250ms;没有有效 Kitty 回应就用 ANSI。显式 kitty 模式探测失败时报错。tmux/screen 中 auto 使用 ANSI,显式 kitty 报不支持;不修改用户终端配置。
|
||||
|
||||
@@ -411,6 +411,9 @@ int View(SessionOptions options, const std::string &device,
|
||||
uint64_t view_revision = input.view_revision;
|
||||
bool redraw = true;
|
||||
uint64_t submitted = 0;
|
||||
uint64_t fps_submitted = 0;
|
||||
auto fps_sample_at = started;
|
||||
long output_fps = 0;
|
||||
std::optional<Clock::time_point> connected_at, first_frame_at,
|
||||
first_output_at;
|
||||
bool waiting_visible = false;
|
||||
@@ -550,6 +553,14 @@ int View(SessionOptions options, const std::string &device,
|
||||
size_query_tick = now + std::chrono::seconds(2);
|
||||
}
|
||||
if (output.Idle() && !shared_upload && now >= status_tick) {
|
||||
const double fps_seconds =
|
||||
std::chrono::duration<double>(now - fps_sample_at).count();
|
||||
// Mode changes can redraw the status early; keep a full sampling window.
|
||||
if (fps_seconds >= 1) {
|
||||
output_fps = std::lround((submitted - fps_submitted) / fps_seconds);
|
||||
fps_submitted = submitted;
|
||||
fps_sample_at = now;
|
||||
}
|
||||
auto st = s.Status();
|
||||
const auto last_state = st["state"].get<std::string>();
|
||||
std::string progress =
|
||||
@@ -577,6 +588,7 @@ int View(SessionOptions options, const std::string &device,
|
||||
bar.error = input.error;
|
||||
bar.control = input.control;
|
||||
bar.command_mode = input.command_mode;
|
||||
bar.fps = "FPS " + std::to_string(output_fps);
|
||||
bar.view = std::string(kitty ? "KITTY"
|
||||
: detail == AnsiDetail::Quadrant ? "QUAD"
|
||||
: "HALF") +
|
||||
|
||||
@@ -86,7 +86,7 @@ inline constexpr char kKittyDelete[] =
|
||||
"\033_Ga=d,d=I,i=31,q=2\033\\\033_Ga=d,d=I,i=32,q=2\033\\";
|
||||
bool KittyReply(const std::string &response);
|
||||
struct StatusBar {
|
||||
std::string progress, compact_progress, error, view, network;
|
||||
std::string progress, compact_progress, error, view, network, fps;
|
||||
bool control = false, command_mode = false;
|
||||
};
|
||||
// Three padded ASCII rows. Shortcuts are compacted as whole groups to fit.
|
||||
|
||||
@@ -59,11 +59,16 @@ std::vector<std::string> StatusLines(const StatusBar &bar, int columns) {
|
||||
const auto progress =
|
||||
bar.error.empty() ? bar.progress : "Error: " + bar.error;
|
||||
auto left = mode + " | " + progress;
|
||||
auto right = bar.view + (bar.network.empty() ? "" : " | " + bar.network);
|
||||
auto metrics = bar.fps;
|
||||
if (!bar.network.empty())
|
||||
metrics += (metrics.empty() ? "" : " | ") + bar.network;
|
||||
auto right = bar.view + (metrics.empty() ? "" : " | " + metrics);
|
||||
if (left.size() + right.size() + 2 > inner)
|
||||
right = bar.network;
|
||||
right = metrics;
|
||||
if (left.size() + right.size() + 2 > inner && bar.error.empty())
|
||||
left = mode + " | " + bar.compact_progress;
|
||||
if (left.size() + right.size() + 2 > inner)
|
||||
right = bar.fps;
|
||||
if (left.size() + right.size() + 2 > inner)
|
||||
right.clear();
|
||||
std::string status = Clip(left, inner);
|
||||
|
||||
Reference in New Issue
Block a user