[feat] add mobile codec status and scrolling codec names

This commit is contained in:
dijunkun
2026-10-27 04:16:41 +08:00
parent 1687816bde
commit e123d5f2cc
20 changed files with 241 additions and 48 deletions
@@ -48,6 +48,8 @@ int main() {
auto& adapter = *backend->adapter;
stream->window().dispatch_resize_event(slint::LogicalSize({1280, 720}));
stream->show();
stream->set_secure_attention_supported(false);
stream->set_privacy_visible(true);
auto rows = std::make_shared<slint::VectorModel<crossdesk::ui::NetworkStatsRow>>();
stream->set_stats_rows(rows);
std::vector<crossdesk::ui::NetworkStatsRow> stats(4);
@@ -75,6 +77,13 @@ int main() {
};
settle();
const float top = stream->get_video_area_top();
// The initial control is only the logo. Wait for the toolbar reveal before
// clicking network status, just as a user does in a new session.
const slint::LogicalPosition logo({19, top + 19});
stream->window().dispatch_pointer_move_event(logo);
stream->window().dispatch_pointer_press_event(logo, slint::PointerEventButton::Left);
stream->window().dispatch_pointer_release_event(logo, slint::PointerEventButton::Left);
settle(20);
for (bool dock_right : {false, true}) {
if (dock_right) {
stream->invoke_begin_control_drag(5, 20);
@@ -82,19 +91,26 @@ int main() {
stream->invoke_end_control_drag();
settle();
}
const int control_x = dock_right ? 916 : 0;
const slint::LogicalPosition button({float(control_x + (dock_right ? 278 : 245)), top + 19});
// With privacy visible and no Windows shortcuts, the toolbar is 344 px.
// Its logo moves to the trailing edge when docked on the right.
const int control_x = dock_right ? int(stream->get_video_area_width()) - 344 : 0;
const slint::LogicalPosition button({float(control_x + (dock_right ? 214 : 250)), top + 19});
stream->window().dispatch_pointer_move_event(button);
settle(35); // Include the tooltip that appears before the click.
for (bool expanded : {true, false, true, false}) {
stream->window().dispatch_pointer_press_event(button, slint::PointerEventButton::Left);
stream->window().dispatch_pointer_release_event(button, slint::PointerEventButton::Left);
settle(); // No pointer movement: animation must finish on its own.
if (stats_visible != expanded) {
std::cerr << "Network status button did not toggle the panel; dock_right="
<< dock_right << '\n';
return 1;
}
for (int y : {65, 195}) {
const auto pixel = adapter.pixels[(int(top) + y) * 1280 + control_x + 4];
const bool painted = pixel.r >= 240 && pixel.g >= 240 && pixel.b >= 240;
const bool cleared = pixel.r == 0 && pixel.g == 0 && pixel.b == 0;
if (stats_visible != expanded || (expanded ? !painted : !cleared)) {
if (expanded ? !painted : !cleared) {
std::cerr << "Stats must fully " << (expanded ? "expand" : "collapse")
<< " without pointer movement; dock_right=" << dock_right
<< ", y=" << y << ", pixel=" << int(pixel.r) << ','
+35 -13
View File
@@ -779,7 +779,8 @@ bool VerifyWorkbenchActions() {
if (window->get_settings_tab() != 0) return false;
window->set_gallery_settings_error("");
window->set_settings_open(false);
click(60, 20);
// DeskHub follows the ID/IP mode switch when direct IP connections are enabled.
click(window->get_ip_direct_enabled() ? 204 : 60, 20);
if (!gallery_opened) return false;
crossdesk::ui::RecentConnection device{};
device.remote_id = "987654321";
@@ -850,24 +851,45 @@ bool VerifyWorkbenchActions() {
bool VerifySystemShortcutMenu() {
auto stream = crossdesk::ui::StreamWindow::create();
stream->window().set_size(slint::LogicalSize(slint::Size<float>{1280, 720}));
stream->show();
std::vector<std::string> commands;
stream->on_send_shortcut([&](slint::SharedString command) { commands.emplace_back(command); });
const auto click = [&](float y) {
const slint::LogicalPosition point({55, stream->get_video_area_top() + y});
const auto settle = [] {
for (int i = 0; i < 20; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(16));
slint::platform::update_timers_and_animations();
}
};
const auto click = [&](float x, float y) {
const slint::LogicalPosition point({x, stream->get_video_area_top() + y});
stream->window().dispatch_pointer_move_event(point);
stream->window().dispatch_pointer_press_event(point, slint::PointerEventButton::Left);
stream->window().dispatch_pointer_release_event(point, slint::PointerEventButton::Left);
};
click(20);
if (!stream->invoke_is_local_control_area(55, 90)) return false;
click(58);
stream->set_secure_attention_supported(false);
click(20);
if (stream->invoke_is_local_control_area(55, 90)) return false;
click(58);
// The toolbar starts collapsed. Reveal it before targeting its buttons.
click(19, 19);
settle();
stream->set_secure_attention_supported(true);
click(20); click(88);
return commands == std::vector<std::string>{"Ctrl+Alt+Del", "Win+L", "Win+L"};
settle();
click(90, 19);
if (!stream->invoke_is_local_control_area(90, 90)) return false;
click(90, 68);
// Switching away from a Windows host hides the entire shortcut entry and
// closes an open menu; its former rows must no longer dispatch commands.
click(90, 19);
if (!stream->invoke_is_local_control_area(90, 90)) return false;
stream->set_secure_attention_supported(false);
settle();
if (stream->invoke_is_local_control_area(90, 90)) return false;
click(90, 98);
if (commands != std::vector<std::string>{"Ctrl+Alt+Del"}) return false;
stream->set_secure_attention_supported(true);
settle();
click(90, 19);
click(90, 98);
return commands == std::vector<std::string>{"Ctrl+Alt+Del", "Win+L"};
}
bool VerifyRemoteIdEditing() {
@@ -905,7 +927,7 @@ bool VerifyRemoteIdEditing() {
int main() {
if (!VerifySystemShortcutMenu()) {
std::cerr << "Shortcut menu must omit unsupported SAS and resize its input area\n";
std::cerr << "Shortcut menu must dispatch Windows shortcuts and hide for unsupported hosts\n";
return 13;
}
if (!VerifyRemoteIdEditing()) {