mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-22 12:33:05 +08:00
[docs] refresh README screenshots and platform guides
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <charconv>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -44,6 +45,7 @@ struct CaptureOptions {
|
||||
std::string page;
|
||||
int language = 0;
|
||||
std::string snapshot_path;
|
||||
std::string demo_assets_path;
|
||||
};
|
||||
|
||||
// Compatibility entry point for the former application-level debug capture
|
||||
@@ -98,9 +100,55 @@ CaptureOptions LoadCaptureOptions() {
|
||||
std::getenv("CROSSDESK_UI_CAPTURE_SNAPSHOT")) {
|
||||
options.snapshot_path = snapshot;
|
||||
}
|
||||
if (const char *assets = std::getenv("CROSSDESK_UI_CAPTURE_DEMO_ASSETS")) {
|
||||
options.demo_assets_path = assets;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
// Opt-in documentation data, separate from the smoke test's baseline state.
|
||||
// The images are public page captures, never a user's cached remote desktops.
|
||||
bool ConfigureDocumentationDemo(
|
||||
const slint::ComponentHandle<crossdesk::ui::MainWindow> &window,
|
||||
const CaptureOptions &options) {
|
||||
if (options.demo_assets_path.empty()) {
|
||||
return true;
|
||||
}
|
||||
struct DemoDevice {
|
||||
const char *id;
|
||||
const char *name;
|
||||
const char *thumbnail;
|
||||
};
|
||||
const DemoDevice devices[] = {
|
||||
{"987654321", "Dev Workstation", "fixtures/source.png"},
|
||||
{"246813579", "Office PC", "fixtures/website.png"},
|
||||
{"135792468", "Home Laptop", "web-client.png"},
|
||||
};
|
||||
std::vector<crossdesk::ui::RecentConnection> connections;
|
||||
for (const auto &device : devices) {
|
||||
const std::string path = options.demo_assets_path + "/" + device.thumbnail;
|
||||
const auto thumbnail =
|
||||
slint::Image::load_from_path(slint::SharedString(path.c_str()));
|
||||
if (thumbnail.size().width == 0 || thumbnail.size().height == 0) {
|
||||
std::cerr << "Missing documentation thumbnail: " << path << '\n';
|
||||
return false;
|
||||
}
|
||||
crossdesk::ui::RecentConnection connection;
|
||||
connection.remote_id = device.id;
|
||||
connection.display_name = device.name;
|
||||
connection.host_name = device.name;
|
||||
connection.online = true;
|
||||
connection.thumbnail = thumbnail;
|
||||
connections.emplace_back(std::move(connection));
|
||||
}
|
||||
window->set_recent_connections(
|
||||
std::make_shared<slint::VectorModel<crossdesk::ui::RecentConnection>>(
|
||||
std::move(connections)));
|
||||
window->set_signal_connected(true);
|
||||
window->set_hardware_codec_available(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasNonEmptyEnvironmentVariable(const char *name) {
|
||||
const char *value = std::getenv(name);
|
||||
return value != nullptr && value[0] != '\0';
|
||||
@@ -306,6 +354,9 @@ int RunCaptureMode(
|
||||
slint::ComponentHandle<crossdesk::ui::StreamWindow> &stream,
|
||||
slint::ComponentHandle<crossdesk::ui::ServerWindow> &server) {
|
||||
ConfigureMainCapturePage(window, options);
|
||||
if (!ConfigureDocumentationDemo(window, options)) {
|
||||
return 8;
|
||||
}
|
||||
stream->hide();
|
||||
server->hide();
|
||||
|
||||
|
||||
+51
-23
@@ -12,12 +12,34 @@ There is no `WKWebView` or browser runtime.
|
||||
|
||||
## Build
|
||||
|
||||
Open `CrossDeskMobile.xcodeproj`, select the `CrossDeskMobile` scheme and a
|
||||
physical device, then build. The first build phase compiles MiniRTC and the
|
||||
CrossDesk wire library, then merges their iPhoneOS static dependencies into
|
||||
a local archive under `Vendor/`.
|
||||
Clone the repository with its submodules. Run these commands from the parent
|
||||
directory where you want to place the checkout:
|
||||
|
||||
You can also verify the target without code signing:
|
||||
```sh
|
||||
git clone --recurse-submodules https://github.com/kunkundi/crossdesk.git
|
||||
cd crossdesk
|
||||
```
|
||||
|
||||
For an existing checkout, run `git submodule update --init --recursive` from
|
||||
the repository root. All remaining commands below use that root directory.
|
||||
|
||||
1. Open `apps/ios/CrossDeskMobile.xcodeproj` and select the `CrossDeskMobile`
|
||||
target and scheme.
|
||||
2. Under **Signing & Capabilities**, select your own development team and set
|
||||
a bundle identifier available to that team. The checked-in signing team
|
||||
and `cn.crossdesk.mobile` identifier belong to the project maintainer.
|
||||
3. Connect and select a physical iPhone or iPad, configure device trust and
|
||||
Developer Mode as prompted by Xcode, then build and run. See Apple's
|
||||
[device setup guide](https://developer.apple.com/documentation/xcode/running-your-app-on-simulated-or-physical-devices).
|
||||
|
||||
The first build phase builds MiniRTC and the CrossDesk wire library, downloads
|
||||
and builds their dependencies, then merges the iPhoneOS archives into a local library under
|
||||
`Vendor/`. This build path targets physical devices; simulator builds are
|
||||
not supported. The exact tool versions used by CI are recorded in the
|
||||
[workflow](../../.github/workflows/build.yml).
|
||||
|
||||
You can also build the target without code signing. The resulting app, like
|
||||
the unsigned CI artifact, requires signing before device installation:
|
||||
|
||||
```sh
|
||||
xcodebuild -project apps/ios/CrossDeskMobile.xcodeproj \
|
||||
@@ -35,8 +57,9 @@ the desktop-compatible `DisplayN`, `control_audio`, `mouse`, `keyboard`,
|
||||
## Video codecs
|
||||
|
||||
Every iOS build includes VideoToolbox, OpenH264, dav1d, libaom, and SVT-AV1. H.264 uses
|
||||
VideoToolbox by default; the in-app **Settings > Video Codec** selector switches
|
||||
H.264 software processing to OpenH264. AV1 encoding uses SVT-AV1 and AV1 decoding
|
||||
VideoToolbox by default; choose software processing under **设置 → 视频编解码 →
|
||||
处理方式** (Settings → Video codec → Processing mode) to use OpenH264 for H.264.
|
||||
The change takes effect on the next connection. AV1 encoding uses SVT-AV1 and AV1 decoding
|
||||
uses dav1d; VideoToolbox AV1 hardware decoding is currently unsupported.
|
||||
|
||||
## Physical-device test checklist
|
||||
@@ -45,26 +68,31 @@ Run the app from Xcode on a physical device and connect to a current desktop
|
||||
build. Test the features in this order so a media problem is not confused with
|
||||
a data-channel problem:
|
||||
|
||||
1. **Video:** after the connection turns green, the waiting panel should be
|
||||
replaced by the remote desktop. The status bar reports the decoded size and
|
||||
frame count.
|
||||
1. **Video:** after the session connects, the waiting panel should be replaced
|
||||
by the remote desktop. Tap the floating icon to see the connection state,
|
||||
P2P/TURN mode, decoded resolution, and bitrate. The current menu does not
|
||||
display a frame counter.
|
||||
2. **Audio:** play continuous sound on the remote computer, then toggle the
|
||||
speaker button. Audio is Opus-decoded by MiniRTC and played as 48 kHz mono
|
||||
16-bit PCM through `AVAudioEngine`.
|
||||
3. **Clipboard:** copy a short text value on the phone and choose **Send local
|
||||
clipboard**. Copy a different value on the desktop and confirm that it is
|
||||
written to the iOS pasteboard. Text is limited to 128 KiB.
|
||||
3. **Clipboard:** copy a short text value on the remote desktop, then paste it
|
||||
into a text field on the phone to verify reception. Text is limited to
|
||||
128 KiB. The bridge supports sending local text, but the current UI has no
|
||||
**Send local clipboard** action.
|
||||
4. **Displays:** open the display menu, switch every listed monitor, and check
|
||||
that the frame counter restarts and the selected monitor appears after a
|
||||
new key frame.
|
||||
5. **Files:** use the folder button to pick a small file, then send a file back
|
||||
that the selected monitor appears and the displayed resolution updates
|
||||
after a new key frame.
|
||||
5. **Files:** choose **发送文件** (Send file) from the floating menu to pick a
|
||||
small file, then send a file back
|
||||
from the desktop. Progress is ACK-driven. Received files are stored in the
|
||||
app's `Documents/Received` directory and can be exported with the share
|
||||
button or Finder's Files tab.
|
||||
button beside the transfer status or Finder's Files tab.
|
||||
|
||||
For black-screen diagnosis, keep Xcode's device console open and filter for
|
||||
`CrossDesk`. A working pipeline prints both `VideoToolbox decoded frame` from
|
||||
MiniRTC and `CrossDesk received decoded frame` from the iOS bridge. If only the
|
||||
first message appears, verify that the selected stream is named `Display1`,
|
||||
`Display2`, and so on. If neither appears, update and rebuild the desktop side
|
||||
and request a key frame.
|
||||
For black-screen diagnosis, keep Xcode's debug console open and look for
|
||||
`CrossDesk` and `VideoToolbox` messages. With VideoToolbox H.264 decoding selected, look for
|
||||
`VideoToolbox decoded frame` from MiniRTC and `CrossDesk delivered latest frame`
|
||||
from the iOS bridge. Other codec paths do not produce the VideoToolbox message.
|
||||
If decoded frames do not reach the bridge, check that the selected stream is
|
||||
named `Display1`, `Display2`, and so on. If no frames decode, check the selected
|
||||
codec and the desktop capture/encoding logs, then reconnect or switch displays
|
||||
to request a new key frame.
|
||||
|
||||
Reference in New Issue
Block a user