mirror of
https://github.com/Cateners/tiny_computer.git
synced 2026-05-20 16:35:47 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23968eb1fc | ||
|
|
2aac0e57d7 | ||
|
|
ed1c4aa9b1 | ||
|
|
f2eb3e0491 | ||
|
|
d17e515981 | ||
|
|
10f481f976 | ||
|
|
c10d2b733f | ||
|
|
417cf7feef | ||
|
|
7b219facfe | ||
|
|
ed3ec63212 | ||
|
|
8f26ed77e7 | ||
|
|
db4431d4c7 | ||
|
|
0793f589f2 |
24
README.md
24
README.md
@@ -4,34 +4,36 @@
|
|||||||
|
|
||||||
给所有安卓 9 以上 arm64 设备的“PC 应用引擎”平替。你可以在小小电脑上安装 PC 级 WPS、CAJ Viewer、亿图图示等软件。
|
给所有安卓 9 以上 arm64 设备的“PC 应用引擎”平替。你可以在小小电脑上安装 PC 级 WPS、CAJ Viewer、亿图图示等软件。
|
||||||
|
|
||||||
Run Debian Bookworm with XFCE/LXQt/... on Android with just one click - optimized for Chinese users. This package comes preinstalled with the Fcitx Pinyin input method and doesn't require Termux.
|
|
||||||
|
|
||||||
To change the language in the container, simply run the "tmoe" command (this root filesystem was created using [tmoe](https://github.com/2moe/tmoe)). You'll need to remove the LANG=zh_CN.UTF-8 environment variable from the startup command (Control -> Advanced Settings -> Startup Command) when switching languages.
|
Run Debian Bookworm with XFCE, LXQt, or other desktop environments on Android—just with one click. Originally developed for Chinese users to run applications like WPS Office, it comes preinstalled with tools such as the Fcitx Pinyin input method. Please note that this app does not require Termux.
|
||||||
|
|
||||||
Note: Since version 1.0.23, English UI is supported, though some hint texts remain in Chinese.
|
To change the language inside the container, simply run the `tmoe` command, select “Manager” and navigate to the locale settings. The root filesystem was built using [tmoe](https://github.com/2moe/tmoe), so locale configuration is handled through it. You will also need to update the `LANG=zh_CN.UTF-8` environment variable in the startup command (go to Control → Advanced Settings → Startup Command) when switching to another language.
|
||||||
|
|
||||||
|
Note: English UI is supported since version 1.0.23, though some hint texts may still appear in Chinese.
|
||||||
|
As of version 1.0.100, the container will automatically switch to English if it detects that your device is not using Chinese.
|
||||||
|
|
||||||
## 特点
|
## 特点
|
||||||
|
|
||||||
- 一键安装,即开即用
|
- 一键安装,即开即用
|
||||||
- 来自 kali-undercover 的 win10 主题(仅 xfce 版本),友好的界面
|
- 来自 kali-undercover 的 win10 主题(仅 xfce 版本),友好的界面
|
||||||
|
|
||||||
[](https://github.com/Cateners/tiny_computer/blob/master/readme/img1.png)
|

|
||||||
|
|
||||||
- 提供常用软件的一键安装指令
|
- 提供常用软件的一键安装指令(点击图片可查看更多说明)
|
||||||
|
|
||||||
[](https://github.com/Cateners/tiny_computer/blob/master/readme/img2.png)
|
[](https://gitee.com/caten/tc-hints/blob/master/pool/solution.md)
|
||||||
|
|
||||||
- 可方便地改变屏幕缩放,不用担心屏幕过大或过小(仅 novnc)
|
- 可方便地改变屏幕缩放,不用担心屏幕过大或过小 (点击图片可查看更多说明)
|
||||||
|
|
||||||
[](https://github.com/Cateners/tiny_computer/blob/master/readme/img3.gif)
|
[](https://gitee.com/caten/tc-hints/blob/master/pool/scale.md)
|
||||||
|
|
||||||
- 便捷访问设备文件,或通过设备 SAF 访问软件文件
|
- 便捷访问设备文件,或通过设备 SAF 访问软件文件(点击图片可查看更多说明)
|
||||||
|
|
||||||
[](https://github.com/Cateners/tiny_computer/blob/master/readme/img4.png)
|
[](https://gitee.com/caten/tc-hints/blob/master/pool/fileaccess.md)
|
||||||
|
|
||||||
- 提供终端和众多可调节参数供高级用户使用
|
- 提供终端和众多可调节参数供高级用户使用
|
||||||
|
|
||||||
[](https://github.com/Cateners/tiny_computer/blob/master/readme/img5.png)
|

|
||||||
|
|
||||||
## 下载
|
## 下载
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="tc_app_name">Tiny Computer</string>
|
<string name="tc_app_name">Tiny Computer</string>
|
||||||
|
|
||||||
<string name="tc_s9a_error_message">Terminal terminated abnormally with error code 9. This error is caused by Android 12+ system limiting the number of child processes and requires manual removal of the restriction.</string>
|
<string name="tc_s9a_error_message">Terminal terminated abnormally with signal 9. This error is caused by Android 12+ system limiting the number of child processes and requires manual removal of the restriction.</string>
|
||||||
<string name="tc_s9a_kaomoji">:(</string>
|
<string name="tc_s9a_kaomoji">:(</string>
|
||||||
<string name="tc_s9a_solution_intro">You can use the following tool to fix:</string>
|
<string name="tc_s9a_solution_intro">You can use the following tool to fix:</string>
|
||||||
<string name="tc_s9a_solution_alternative">If the above tool cannot fix the issue, or if the device is a HarmonyOS device, please follow the tutorial below (requires a computer and data cable):</string>
|
<string name="tc_s9a_solution_alternative">If the above tool cannot fix the issue, or if the device is a HarmonyOS device, please follow the tutorial below (requires a computer and data cable):</string>
|
||||||
|
|||||||
147
build.ps1
Normal file
147
build.ps1
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true, ValueFromRemainingArguments=$true)]
|
||||||
|
[ValidateSet("xfce", "lxqt", "gxde")]
|
||||||
|
[string[]]$DesktopEnvs,
|
||||||
|
|
||||||
|
[string]$NameSuffix
|
||||||
|
)
|
||||||
|
|
||||||
|
# 设置路径
|
||||||
|
$SourceDir = "C:\Users\29513\Downloads"
|
||||||
|
$AssetsDir = "assets"
|
||||||
|
|
||||||
|
# 分割文件函数 - 使用xaa, xab, xac...命名
|
||||||
|
function Split-File {
|
||||||
|
param(
|
||||||
|
[string]$Path,
|
||||||
|
[long]$PartSizeBytes,
|
||||||
|
[string]$DestinationPath
|
||||||
|
)
|
||||||
|
|
||||||
|
$stream = [System.IO.File]::OpenRead($Path)
|
||||||
|
$buffer = New-Object byte[] $PartSizeBytes
|
||||||
|
$partNumber = 0
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (($bytesRead = $stream.Read($buffer, 0, $buffer.Length)) -gt 0) {
|
||||||
|
# 生成类似xaa, xab, xac...的文件名
|
||||||
|
$partName = Get-SplitFileName $partNumber
|
||||||
|
$partPath = Join-Path $DestinationPath $partName
|
||||||
|
|
||||||
|
$partStream = [System.IO.File]::OpenWrite($partPath)
|
||||||
|
try {
|
||||||
|
$partStream.Write($buffer, 0, $bytesRead)
|
||||||
|
} finally {
|
||||||
|
$partStream.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "创建分片: $partName"
|
||||||
|
$partNumber++
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
$stream.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return $partNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
# 生成split风格的文件名 (xaa, xab, xac, ..., xaz)
|
||||||
|
function Get-SplitFileName {
|
||||||
|
param([int]$index)
|
||||||
|
|
||||||
|
# 计算字母偏移量(0-25对应a-z)
|
||||||
|
$charOffset = $index % 26
|
||||||
|
# 将数字转换为对应的字母字符
|
||||||
|
$char = [char]([byte][char]'a' + $charOffset)
|
||||||
|
|
||||||
|
return "xa$char"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 处理每个桌面环境
|
||||||
|
foreach ($DesktopEnv in $DesktopEnvs) {
|
||||||
|
Write-Host "`n开始处理 $DesktopEnv 桌面环境..." -ForegroundColor Green
|
||||||
|
|
||||||
|
# 设置文件路径
|
||||||
|
$TarFile = "debian-$DesktopEnv.tar.xz"
|
||||||
|
$SourcePath = Join-Path $SourceDir $TarFile
|
||||||
|
|
||||||
|
# 检查源文件是否存在
|
||||||
|
if (-not (Test-Path $SourcePath)) {
|
||||||
|
Write-Error "错误:找不到文件 $SourcePath"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# 删除assets文件夹中已有的xa*文件
|
||||||
|
if (Test-Path $AssetsDir) {
|
||||||
|
Write-Host "正在清理assets文件夹中的旧文件..."
|
||||||
|
Get-ChildItem -Path $AssetsDir -Filter "xa*" | Remove-Item -Force
|
||||||
|
} else {
|
||||||
|
Write-Host "创建assets文件夹..."
|
||||||
|
New-Item -ItemType Directory -Path $AssetsDir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 分割文件 (98MB = 98 * 1024 * 1024 = 102760448 bytes)
|
||||||
|
Write-Host "正在分割 $TarFile 文件..."
|
||||||
|
$partCount = Split-File -Path $SourcePath -PartSizeBytes 102760448 -DestinationPath $AssetsDir
|
||||||
|
|
||||||
|
Write-Host "文件分割完成,共创建 $partCount 个分片文件"
|
||||||
|
|
||||||
|
# 运行Flutter构建
|
||||||
|
Write-Host "正在运行Flutter构建..."
|
||||||
|
flutter build apk --target-platform android-arm64 --split-per-abi --obfuscate --split-debug-info=tiny_computer/sdi
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "错误:Flutter构建失败"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# 构建APK文件名
|
||||||
|
$ApkBaseName = "tiny-computer-$DesktopEnv"
|
||||||
|
if (-not [string]::IsNullOrEmpty($NameSuffix)) {
|
||||||
|
$ApkBaseName += "-$NameSuffix"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 重命名APK和SHA1文件
|
||||||
|
$ApkSource = "build\app\outputs\flutter-apk\app-arm64-v8a-release.apk"
|
||||||
|
$Sha1Source = "build\app\outputs\flutter-apk\app-arm64-v8a-release.apk.sha1"
|
||||||
|
|
||||||
|
if (Test-Path $ApkSource) {
|
||||||
|
Rename-Item -Path $ApkSource -NewName "$ApkBaseName.apk"
|
||||||
|
Write-Host "已重命名APK文件: $ApkBaseName.apk"
|
||||||
|
} else {
|
||||||
|
Write-Error "错误:找不到APK文件 $ApkSource"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $Sha1Source) {
|
||||||
|
Rename-Item -Path $Sha1Source -NewName "$ApkBaseName.apk.sha1"
|
||||||
|
Write-Host "已重命名SHA1文件: $ApkBaseName.apk.sha1"
|
||||||
|
} else {
|
||||||
|
Write-Warning "警告:找不到SHA1文件 $Sha1Source"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "$DesktopEnv 处理完成!" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`n所有桌面环境处理完成!" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# 既然是开源,我认为应该把prompt开源出来才算,毕竟这个脚本更像编译后的产物,而不是源代码本身。
|
||||||
|
|
||||||
|
# 帮我写一个自动化脚本,做以下几件事:
|
||||||
|
# 1. 脚本所在目录是项目的根目录,脚本应该运行在windows电脑上,接收一个参数,这个参数的值会是xfce, lxqt或gxde。
|
||||||
|
# 2. 在C:\Users\29513\Downloads文件夹有debian-xfce.tar.xz,debian-lxqt.tar.xz和debian-gxde.tar.xz,需要根据之前的参数对应选择,然后分成98MB的小份,命名为xa*(就像linux上的split -b 98M debian.tar.xz),放到项目的assets文件夹。注意这个文件夹可能有之前残留的xa*文件,需要先彻底删除这些xa*文件。
|
||||||
|
# 3. 然后在当前目录运行flutter build apk --target-platform android-arm64 --split-per-abi --obfuscate --split-debug-info=tiny_computer/sdi编译。
|
||||||
|
# 4. 在build\app\outputs\flutter-apk文件夹会有app-arm64-v8a-release.apk和app-arm64-v8a-release.apk.sha1两个文件,需要重命名为tiny-computer-xfce.apk和tiny-computer-xfce.apk.sha1(以xfce为例,具体名称根据参数来定)
|
||||||
|
|
||||||
|
# 直接写成一个ps1脚本行吗
|
||||||
|
|
||||||
|
# 请再添加一些功能:首先可以传入多个选项,比如传入xfce lxqt就可以自动进行这两个构建;其实需要一个新参数允许在生成的apk名字加入后缀,比如添加targetSdk35后缀,就会生成tiny-computer-xfce-targetSdk35.apk和tiny-computer-xfce-targetSdk35.apk.sha1
|
||||||
|
|
||||||
|
# xa*文件的命名不对。要按照split命令默认的那样,命名为xaa,xab,xac... 另外我确定分割后的文件数量不多,不会超过xaz。
|
||||||
|
|
||||||
|
# Cannot convert value "97" to type "System.Char". Error: "Invalid cast from 'Decimal' to 'Char'."
|
||||||
|
# At C:\Users\29513\FlutterProjects\tiny_computer\build.ps1:52 char:5
|
||||||
|
# + $firstChar = [char](97 + [math]::Floor($index / 26)) # a-z
|
||||||
|
# + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# + CategoryInfo : InvalidArgument: (:) [], RuntimeException
|
||||||
|
# + FullyQualifiedErrorId : InvalidCastIConvertible
|
||||||
@@ -22,6 +22,7 @@ echo "最新版本: $latest_version"
|
|||||||
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-${latest_version}/hangover_${latest_version}_debian12_bookworm_arm64.tar"
|
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-${latest_version}/hangover_${latest_version}_debian12_bookworm_arm64.tar"
|
||||||
|
|
||||||
mirror_sites=(
|
mirror_sites=(
|
||||||
|
"https://github.akams.cn/"
|
||||||
"https://gh.llkk.cc/"
|
"https://gh.llkk.cc/"
|
||||||
"https://github.moeyy.xyz/"
|
"https://github.moeyy.xyz/"
|
||||||
"https://mirror.ghproxy.com/"
|
"https://mirror.ghproxy.com/"
|
||||||
@@ -65,13 +66,6 @@ tar xvf dxvk-v*.tar.gz
|
|||||||
mv dxvk-v*/x32/* /home/tiny/.wine/drive_c/windows/syswow64
|
mv dxvk-v*/x32/* /home/tiny/.wine/drive_c/windows/syswow64
|
||||||
mv dxvk-v*/arm64ec/* /home/tiny/.wine/drive_c/windows/system32
|
mv dxvk-v*/arm64ec/* /home/tiny/.wine/drive_c/windows/system32
|
||||||
|
|
||||||
echo "自动配置 DLL 覆盖..."
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1
|
|
||||||
|
|
||||||
echo "正在修复字体..."
|
echo "正在修复字体..."
|
||||||
regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f
|
regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ echo "正在更新软件包..."
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt upgrade -y
|
sudo apt upgrade -y
|
||||||
|
|
||||||
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-10.11/hangover_10.11_debian12_bookworm_arm64.tar"
|
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-10.14/hangover_10.14_debian12_bookworm_arm64.tar"
|
||||||
latest_version="10.11"
|
latest_version="10.14"
|
||||||
|
|
||||||
mirror_sites=(
|
mirror_sites=(
|
||||||
|
"https://github.akams.cn/"
|
||||||
"https://gh.llkk.cc/"
|
"https://gh.llkk.cc/"
|
||||||
"https://github.moeyy.xyz/"
|
"https://github.moeyy.xyz/"
|
||||||
"https://mirror.ghproxy.com/"
|
"https://mirror.ghproxy.com/"
|
||||||
@@ -51,13 +52,6 @@ tar xvf dxvk-v*.tar.gz
|
|||||||
mv dxvk-v*/x32/* /home/tiny/.wine/drive_c/windows/syswow64
|
mv dxvk-v*/x32/* /home/tiny/.wine/drive_c/windows/syswow64
|
||||||
mv dxvk-v*/arm64ec/* /home/tiny/.wine/drive_c/windows/system32
|
mv dxvk-v*/arm64ec/* /home/tiny/.wine/drive_c/windows/system32
|
||||||
|
|
||||||
echo "自动配置 DLL 覆盖..."
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1
|
|
||||||
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1
|
|
||||||
|
|
||||||
echo "正在修复字体..."
|
echo "正在修复字体..."
|
||||||
regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f
|
regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
synthetic-package: false
|
|
||||||
arb-dir: lib/l10n
|
arb-dir: lib/l10n
|
||||||
template-arb-file: intl_en.arb
|
template-arb-file: intl_en.arb
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"fixGetifaddrsPermission": "Fix getifaddrs permission on Android 13",
|
"fixGetifaddrsPermission": "Fix getifaddrs permission on Android 13",
|
||||||
"fakeUOSSystem": "Pretend System as UOS",
|
"fakeUOSSystem": "Pretend System as UOS",
|
||||||
"displaySettings": "Display Settings",
|
"displaySettings": "Display Settings",
|
||||||
"avncAdvantages": "AVNC provides better control experience than noVNC:\nTouchpad controls, two-finger tap for keyboard, auto clipboard, picture-in-picture mode, etc. This is an experimental feature.",
|
"avncAdvantages": "AVNC provides better control experience than noVNC:\nTouchpad controls, two-finger tap for keyboard, auto clipboard, picture-in-picture mode, etc.",
|
||||||
"avncSettings": "AVNC Settings",
|
"avncSettings": "AVNC Settings",
|
||||||
"aboutAVNC": "About AVNC",
|
"aboutAVNC": "About AVNC",
|
||||||
"avncResolution": "AVNC Startup Resolution",
|
"avncResolution": "AVNC Startup Resolution",
|
||||||
@@ -44,11 +44,11 @@
|
|||||||
"save": "Save",
|
"save": "Save",
|
||||||
"applyOnNextLaunch": "Apply on next launch",
|
"applyOnNextLaunch": "Apply on next launch",
|
||||||
"useAVNCByDefault": "Use AVNC by default",
|
"useAVNCByDefault": "Use AVNC by default",
|
||||||
"termuxX11Advantages": "Termux:X11 provides faster performance than VNC with better compatibility in some cases.\nSupports DRI3 (enable in Graphics Acceleration) for significant performance boost.\nNow supports features like bidirectional clipboard.\nExperimental feature! If black screen occurs, try fully closing and restarting the app.",
|
"termuxX11Advantages": "Termux:X11 may provide faster speeds than VNC in certain scenarios.\n\nNote that Termux:X11 operates slightly differently from AVNC:\n- A two-finger tap acts as a right mouse click\n- Pressing the back button reveals the additional keyboard\n\nIf you encounter a black screen, try completely closing and restarting the application.",
|
||||||
"termuxX11Preferences": "Termux:X11 Preferences",
|
"termuxX11Preferences": "Termux:X11 Preferences",
|
||||||
"useTermuxX11ByDefault": "Use Termux:X11 by default",
|
"useTermuxX11ByDefault": "Use Termux:X11 by default",
|
||||||
"disableVNC": "Disable VNC. Requires restart",
|
"disableVNC": "Disable VNC. Requires restart",
|
||||||
"hidpiAdvantages": "HiDPI support provides sharper display for high-resolution screens!\n\nNote:\nDisplay may appear too large - set appropriate resolution.\nSome apps may have display issues or slower rendering.",
|
"hidpiAdvantages": "One-click to enable HiDPI mode for clearer display... at the cost of reduced speed.",
|
||||||
"hidpiEnvVar": "HiDPI Environment Variables",
|
"hidpiEnvVar": "HiDPI Environment Variables",
|
||||||
"hidpiSupport": "HiDPI Support",
|
"hidpiSupport": "HiDPI Support",
|
||||||
"fileAccess": "File Access",
|
"fileAccess": "File Access",
|
||||||
@@ -74,13 +74,13 @@
|
|||||||
"installHangoverLatest": "Install Hangover Latest (may fail)",
|
"installHangoverLatest": "Install Hangover Latest (may fail)",
|
||||||
"uninstallHangover": "Uninstall Hangover",
|
"uninstallHangover": "Uninstall Hangover",
|
||||||
"clearWineData": "Clear Wine Data",
|
"clearWineData": "Clear Wine Data",
|
||||||
"wineCommandsHint": "Common Wine commands. Click to launch GUI and wait patiently.\n\nNote: DXVK is enabled by default. If the program crashes, try disabling it.\n\nTypical launch times:\nTiger T7510 6GB: over 1 minute\nSnapdragon 870 12GB: ~10 seconds",
|
"wineCommandsHint": "Common Wine commands. Click to launch GUI and wait patiently.\n\nTypical launch times:\nTiger T7510 6GB: over 1 minute\nSnapdragon 870 12GB: ~10 seconds",
|
||||||
"switchToJapanese": "Switch System to Japanese",
|
"switchToJapanese": "Switch System to Japanese",
|
||||||
"userManual": "User Manual",
|
"userManual": "User Manual",
|
||||||
"openSourceLicenses": "Open Source Licenses",
|
"openSourceLicenses": "Open Source Licenses",
|
||||||
"permissionUsage": "Permission Usage",
|
"permissionUsage": "Permission Usage",
|
||||||
"privacyStatement": "\nThis app does not collect your private information.\n\nHowever, I cannot control behaviors of apps you install/use inside the container system (including via shortcut commands).\n\nRequested permissions are used for:\nFile permissions: accessing phone directories\nNotifications & accessibility: Required by Termux:X11",
|
"privacyStatement": "\nThis app does not collect your private information.\n\nHowever, I cannot control behaviors of apps you install/use inside the container system (including via shortcut commands).\n\nRequested permissions are used for:\nFile permissions: accessing phone directories\nNotifications & accessibility: Required by Termux:X11",
|
||||||
"supportAuthor": "Support Author",
|
"supportAuthor": "Support Developers",
|
||||||
"recommendApp": "If you find it useful, please recommend to others!",
|
"recommendApp": "If you find it useful, please recommend to others!",
|
||||||
"projectUrl": "Project URL",
|
"projectUrl": "Project URL",
|
||||||
"commandEdit": "Command Edit",
|
"commandEdit": "Command Edit",
|
||||||
@@ -98,14 +98,17 @@
|
|||||||
"enterNumber": "Please enter a number",
|
"enterNumber": "Please enter a number",
|
||||||
"enterValidNumber": "Please enter a valid number",
|
"enterValidNumber": "Please enter a valid number",
|
||||||
"installingBootPackage": "Installing Boot Package",
|
"installingBootPackage": "Installing Boot Package",
|
||||||
"copyingContainerSystem": "Copying Container System",
|
"copyingContainerSystem": "Copying System Files",
|
||||||
"installingContainerSystem": "Installing Container System",
|
"installingContainerSystem": "Installing System Files",
|
||||||
"installationComplete": "Installation Complete",
|
"installationComplete": "Installation Complete",
|
||||||
"reinstallingBootPackage": "Reinstalling Boot Package",
|
"reinstallingBootPackage": "Reinstalling Boot Package",
|
||||||
"issueUrl": "Issue Report",
|
"issueUrl": "Issue Report",
|
||||||
"faqUrl": "FAQ",
|
"faqUrl": "FAQ",
|
||||||
"solutionUrl": "Usage Guide",
|
"solutionUrl": "Usage Guide",
|
||||||
"discussionUrl": "Discussion",
|
"discussionUrl": "Discussion",
|
||||||
"firstLoadInstructions": "The first load may take about 5 to 10 minutes...\n\nNormally, the software will automatically redirect to the graphical interface after loading.\n\nIn the graphical interface:\n- Tap for left-click\n- Long press for right-click\n- Two-finger tap to open the keyboard\n- Two-finger swipe for mouse wheel\n\nPlease do not exit the software during installation.\n\nWhile waiting, you can click the button below to request permissions.\n\nMany folders in Tiny Computer (e.g., Downloads, Documents, Pictures) are bound to the corresponding device folders. Without these permissions, access to these folders will be denied.\n\nIf you don't need to access these folders, you can skip granting file permissions (but this may cause Firefox to fail when downloading files due to denied access to the Downloads folder).",
|
"firstLoadInstructions": "The first load takes about 5 to 10 minutes... and does not require an internet connection.\n\nNormally, the software will automatically redirect to the graphical interface after loading.\n\nIn the graphical interface:\n- Tap for left-click\n- Long press for right-click\n- Two-finger tap to open the keyboard\n- Two-finger swipe for mouse wheel\n\nPlease do not exit the software during installation.\n\nWhile waiting, you can click the button below to request permissions.\n\nMany folders in Tiny Computer (e.g., Downloads, Documents, Pictures) are bound to the corresponding device folders. Without these permissions, access to these folders will be denied.\n\nIf you don't need to access these folders, you can skip granting file permissions (but this may cause Firefox to fail when downloading files due to denied access to the Downloads folder).",
|
||||||
"updateRequest": "Please try to use the latest version. Visit the project address to check for the latest version."
|
"updateRequest": "Please try to use the latest version. Visit the project address to check for the latest version.",
|
||||||
|
"avncScreenResize": "Adaptive Screen Size",
|
||||||
|
"avncResizeFactor": "Screen Scaling Ratio",
|
||||||
|
"avncResizeFactorValue": "Current scaling is"
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"fixGetifaddrsPermission": "修复安卓13设备getifaddrs无权限",
|
"fixGetifaddrsPermission": "修复安卓13设备getifaddrs无权限",
|
||||||
"fakeUOSSystem": "伪装系统为UOS",
|
"fakeUOSSystem": "伪装系统为UOS",
|
||||||
"displaySettings": "显示设置",
|
"displaySettings": "显示设置",
|
||||||
"avncAdvantages": "AVNC可以带来相比noVNC更好的操控体验;\n如触摸板触控,双指单击弹出键盘,自动剪切板,画中画模式等等。这是一个实验性功能。",
|
"avncAdvantages": "AVNC可以带来相比noVNC更好的操控体验;\n如触摸板触控,双指单击弹出键盘,自动剪切板,画中画模式等等。",
|
||||||
"avncSettings": "AVNC设置",
|
"avncSettings": "AVNC设置",
|
||||||
"aboutAVNC": "关于AVNC",
|
"aboutAVNC": "关于AVNC",
|
||||||
"avncResolution": "AVNC启动时分辨率设置",
|
"avncResolution": "AVNC启动时分辨率设置",
|
||||||
@@ -44,11 +44,11 @@
|
|||||||
"applyOnNextLaunch": "下次启动时生效",
|
"applyOnNextLaunch": "下次启动时生效",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"useAVNCByDefault": "默认使用AVNC",
|
"useAVNCByDefault": "默认使用AVNC",
|
||||||
"termuxX11Advantages": "Termux:X11可以带来比VNC更快的速度,某些情况下兼容性也会更好。\n支持使用DRI3(需在图形加速中开启),可以带来相当大的性能提升。\n随着版本的迭代,Termux:X11如今也支持了双向剪切板等功能。\n这是一个实验性功能!如果黑屏,请尝试彻底关闭本应用再重新启动。",
|
"termuxX11Advantages": "Termux:X11某些情况下可以带来比VNC更快的速度。\n\n注意Termux:X11的操作与AVNC略有不同。\n- 双指点击为鼠标右键\n- 返回弹出小键盘\n\n如果黑屏,请尝试彻底关闭本应用再重新启动。",
|
||||||
"termuxX11Preferences": "Termux:X11偏好设置",
|
"termuxX11Preferences": "Termux:X11偏好设置",
|
||||||
"useTermuxX11ByDefault": "默认使用Termux:X11",
|
"useTermuxX11ByDefault": "默认使用Termux:X11",
|
||||||
"disableVNC": "不使用VNC。重启生效",
|
"disableVNC": "不使用VNC。重启生效",
|
||||||
"hidpiAdvantages": "高分辨率支持可以为拥有高分辨率屏幕的设备带来更高清的体验!\n\n注意:\n选项开启后显示会变得很大,请设置一个合适的分辨率。\n\n一些软件可能会存在显示问题,或者显示速度变慢。",
|
"hidpiAdvantages": "一键开启高清模式,显示更清晰的同时...速度会变慢。",
|
||||||
"hidpiEnvVar": "HiDPI环境变量",
|
"hidpiEnvVar": "HiDPI环境变量",
|
||||||
"hidpiSupport": "高分辨率支持",
|
"hidpiSupport": "高分辨率支持",
|
||||||
"fileAccess": "文件访问",
|
"fileAccess": "文件访问",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"installHangoverLatest": "安装Hangover最新版(可能出错)",
|
"installHangoverLatest": "安装Hangover最新版(可能出错)",
|
||||||
"uninstallHangover": "卸载Hangover",
|
"uninstallHangover": "卸载Hangover",
|
||||||
"clearWineData": "清空Wine数据",
|
"clearWineData": "清空Wine数据",
|
||||||
"wineCommandsHint": "Wine的常用指令。点击后前往图形界面耐心等待。\n\n注:DXVK默认为开启状态,如程序崩溃可尝试关闭\n\n任意程序启动参考时间:\n虎贲T7510 6GB 超过一分钟\n骁龙870 12GB 约10秒\n",
|
"wineCommandsHint": "Wine的常用指令。点击后前往图形界面耐心等待。\n\n任意程序启动参考时间:\n虎贲T7510 6GB 超过一分钟\n骁龙870 12GB 约10秒\n",
|
||||||
"switchToJapanese": "切换系统到日语",
|
"switchToJapanese": "切换系统到日语",
|
||||||
"userManual": "使用说明",
|
"userManual": "使用说明",
|
||||||
"openSourceLicenses": "开源许可",
|
"openSourceLicenses": "开源许可",
|
||||||
@@ -106,6 +106,9 @@
|
|||||||
"faqUrl": "常见问题",
|
"faqUrl": "常见问题",
|
||||||
"solutionUrl": "典型场景使用指南",
|
"solutionUrl": "典型场景使用指南",
|
||||||
"discussionUrl": "论坛与讨论",
|
"discussionUrl": "论坛与讨论",
|
||||||
"firstLoadInstructions": "第一次加载大概需要5到10分钟...\n\n正常情况下,加载完成后软件会自动跳转到图形界面。\n\n在图形界面时:\n- 点击为鼠标左键\n- 长按为鼠标右键\n- 双指点击可弹出键盘\n- 双指划动为鼠标滚轮\n\n请不要在安装时退出软件。\n\n在等待时,可以点击下面的按钮申请一下权限。\n\n小小电脑的许多文件夹,比如下载、文档、图片等等都和设备的对应文件夹绑定,如果不授予这些权限会导致这些文件夹无权访问。\n\n但如果你不需要访问这些文件夹,也可以不授予文件权限(可能导致火狐浏览器下载文件失败,因为无权访问下载文件夹)。",
|
"firstLoadInstructions": "第一次加载大概需要5到10分钟...并且不需要网络。\n\n正常情况下,加载完成后软件会自动跳转到图形界面。\n\n在图形界面时:\n- 点击为鼠标左键\n- 长按为鼠标右键\n- 双指点击可弹出键盘\n- 双指划动为鼠标滚轮\n\n请不要在安装时退出软件。\n\n在等待时,可以点击下面的按钮申请一下权限。\n\n小小电脑的许多文件夹,比如下载、文档、图片等等都和设备的对应文件夹绑定,如果不授予这些权限会导致这些文件夹无权访问。\n\n但如果你不需要访问这些文件夹,也可以不授予文件权限(可能导致火狐浏览器下载文件失败,因为无权访问下载文件夹)。",
|
||||||
"updateRequest": "请尽量使用最新版本。前往项目地址可查看最新版本。"
|
"updateRequest": "请尽量使用最新版本。前往项目地址可查看最新版本。",
|
||||||
|
"avncScreenResize": "自适应屏幕尺寸",
|
||||||
|
"avncResizeFactor": "屏幕缩放比",
|
||||||
|
"avncResizeFactorValue": "当前缩放为"
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"fixGetifaddrsPermission": "修復 Android 13 裝置 getifaddrs 無權限",
|
"fixGetifaddrsPermission": "修復 Android 13 裝置 getifaddrs 無權限",
|
||||||
"fakeUOSSystem": "偽裝系統為 UOS",
|
"fakeUOSSystem": "偽裝系統為 UOS",
|
||||||
"displaySettings": "顯示設定",
|
"displaySettings": "顯示設定",
|
||||||
"avncAdvantages": "AVNC 可帶來比 noVNC 更好的操作體驗;如觸控板觸控、雙指單擊喚出鍵盤、自動剪貼簿、畫中畫模式等。這是一個實驗性功能。",
|
"avncAdvantages": "AVNC 可帶來比 noVNC 更好的操作體驗;如觸控板觸控、雙指單擊喚出鍵盤、自動剪貼簿、畫中畫模式等。",
|
||||||
"avncSettings": "AVNC 設定",
|
"avncSettings": "AVNC 設定",
|
||||||
"aboutAVNC": "關於 AVNC",
|
"aboutAVNC": "關於 AVNC",
|
||||||
"avncResolution": "AVNC 啟動時解析度設定",
|
"avncResolution": "AVNC 啟動時解析度設定",
|
||||||
@@ -44,11 +44,11 @@
|
|||||||
"applyOnNextLaunch": "下次啟動時生效",
|
"applyOnNextLaunch": "下次啟動時生效",
|
||||||
"save": "儲存",
|
"save": "儲存",
|
||||||
"useAVNCByDefault": "預設使用 AVNC",
|
"useAVNCByDefault": "預設使用 AVNC",
|
||||||
"termuxX11Advantages": "Termux:X11 可帶來比 VNC 更快的速度,有時兼容性也更好。\n支援使用 DRI3(需在圖形加速中開啟),可大幅提升效能。",
|
"termuxX11Advantages": "Termux:X11 在某些情況下可能比 VNC 提供更快的速度。\n\n請注意 Termux:X11 的操作與 AVNC 略有不同:\n- 雙指點擊相當於滑鼠右鍵\n- 返回鍵可彈出小鍵盤\n若出現黑屏,請嘗試完全關閉本應用後重新啟動。",
|
||||||
"termuxX11Preferences": "Termux:X11 偏好設定",
|
"termuxX11Preferences": "Termux:X11 偏好設定",
|
||||||
"useTermuxX11ByDefault": "預設使用 Termux:X11",
|
"useTermuxX11ByDefault": "預設使用 Termux:X11",
|
||||||
"disableVNC": "停用 VNC。重啟生效",
|
"disableVNC": "停用 VNC。重啟生效",
|
||||||
"hidpiAdvantages": "高解析度支援可讓有高解析度螢幕的裝置獲得更清晰的體驗!\n\n注意:\n啟用後顯示會變很大,請設定合適的解析度。",
|
"hidpiAdvantages": "一鍵開啟高清模式,顯示更清晰的同時...速度會變慢。",
|
||||||
"hidpiEnvVar": "HiDPI 環境變數",
|
"hidpiEnvVar": "HiDPI 環境變數",
|
||||||
"hidpiSupport": "高解析度支援",
|
"hidpiSupport": "高解析度支援",
|
||||||
"fileAccess": "檔案存取",
|
"fileAccess": "檔案存取",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"installHangoverLatest": "安裝 Hangover 最新版(可能有錯誤)",
|
"installHangoverLatest": "安裝 Hangover 最新版(可能有錯誤)",
|
||||||
"uninstallHangover": "解除安裝 Hangover",
|
"uninstallHangover": "解除安裝 Hangover",
|
||||||
"clearWineData": "清除 Wine 資料",
|
"clearWineData": "清除 Wine 資料",
|
||||||
"wineCommandsHint": "Wine 常用指令。點擊後進入圖形介面,請耐心等候。\n\n註:DXVK預設為開啟狀態,如程式崩潰可嘗試關閉\n\n不同裝置啟動程式參考時間:\n虎賁 T7510 6GB 超過一分鐘\n驍龍 870 12GB 約 10 秒\n",
|
"wineCommandsHint": "Wine 常用指令。點擊後進入圖形介面,請耐心等候。\n\n不同裝置啟動程式參考時間:\n虎賁 T7510 6GB 超過一分鐘\n驍龍 870 12GB 約 10 秒\n",
|
||||||
"switchToJapanese": "切換系統為日語",
|
"switchToJapanese": "切換系統為日語",
|
||||||
"userManual": "使用說明",
|
"userManual": "使用說明",
|
||||||
"openSourceLicenses": "開源授權",
|
"openSourceLicenses": "開源授權",
|
||||||
@@ -106,6 +106,9 @@
|
|||||||
"faqUrl": "常見問題",
|
"faqUrl": "常見問題",
|
||||||
"solutionUrl": "操作指南",
|
"solutionUrl": "操作指南",
|
||||||
"discussionUrl": "討論",
|
"discussionUrl": "討論",
|
||||||
"firstLoadInstructions": "第一次載入大概需要5到10分鐘...\n\n正常情況下,載入完成後軟體會自動跳轉到圖形介面。\n\n在圖形介面時:\n- 點擊為滑鼠左鍵\n- 長按為滑鼠右鍵\n- 雙指點擊可彈出鍵盤\n- 雙指滑動為滑鼠滾輪\n\n請不要在安裝時退出軟體。\n\n在等待時,可以點擊下面的按鈕申請權限。\n\n小小電腦的許多資料夾,比如下載、文件、圖片等等都和裝置的這些資料夾綁定,如果不授予這些權限會導致這些資料夾無權存取。\n\n但如果你不需要存取這些資料夾,也可以不授予檔案權限(可能導致火狐瀏覽器下載檔案失敗,因為無權存取下載資料夾)。",
|
"firstLoadInstructions": "第一次加載大概需要5到10分鐘...並且不需要網絡。\n\n正常情況下,載入完成後軟體會自動跳轉到圖形介面。\n\n在圖形介面時:\n- 點擊為滑鼠左鍵\n- 長按為滑鼠右鍵\n- 雙指點擊可彈出鍵盤\n- 雙指滑動為滑鼠滾輪\n\n請不要在安裝時退出軟體。\n\n在等待時,可以點擊下面的按鈕申請權限。\n\n小小電腦的許多資料夾,比如下載、文件、圖片等等都和裝置的這些資料夾綁定,如果不授予這些權限會導致這些資料夾無權存取。\n\n但如果你不需要存取這些資料夾,也可以不授予檔案權限(可能導致火狐瀏覽器下載檔案失敗,因為無權存取下載資料夾)。",
|
||||||
"updateRequest": "請盡量使用最新版本。前往專案網址查看最新版本。"
|
"updateRequest": "請盡量使用最新版本。前往專案網址查看最新版本。",
|
||||||
|
"avncScreenResize": "自適應螢幕尺寸",
|
||||||
|
"avncResizeFactor": "螢幕縮放比",
|
||||||
|
"avncResizeFactorValue": "目前縮放為"
|
||||||
}
|
}
|
||||||
|
|||||||
103
lib/main.dart
103
lib/main.dart
@@ -172,6 +172,8 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
|
|
||||||
final List<bool> _expandState = [false, false, false, false, false, false];
|
final List<bool> _expandState = [false, false, false, false, false, false];
|
||||||
|
|
||||||
|
double _avncScaleFactor = Util.getGlobal("avncScaleFactor") as double;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ExpansionPanelList(
|
return ExpansionPanelList(
|
||||||
@@ -195,7 +197,7 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}, child: Text(AppLocalizations.of(context)!.cancel)),
|
}, child: Text(AppLocalizations.of(context)!.cancel)),
|
||||||
TextButton(onPressed:() async {
|
TextButton(onPressed:() async {
|
||||||
await Util.setCurrentProp("boot", D.boot);
|
await Util.setCurrentProp("boot", Localizations.localeOf(context).languageCode == 'zh' ? D.boot : D.boot.replaceFirst('LANG=zh_CN.UTF-8', 'LANG=en_US.UTF-8').replaceFirst('公共', 'Public').replaceFirst('图片', 'Pictures').replaceFirst('音乐', 'Music').replaceFirst('视频', 'Videos').replaceFirst('下载', 'Downloads').replaceFirst('文档', 'Documents').replaceFirst('照片', 'Photos'));
|
||||||
G.bootTextChange.value = !G.bootTextChange.value;
|
G.bootTextChange.value = !G.bootTextChange.value;
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@@ -337,6 +339,27 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
headerBuilder: ((context, isExpanded) {
|
headerBuilder: ((context, isExpanded) {
|
||||||
return ListTile(title: Text(AppLocalizations.of(context)!.displaySettings));
|
return ListTile(title: Text(AppLocalizations.of(context)!.displaySettings));
|
||||||
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
||||||
|
const SizedBox.square(dimension: 16),
|
||||||
|
Text(AppLocalizations.of(context)!.hidpiAdvantages),
|
||||||
|
const SizedBox.square(dimension: 16),
|
||||||
|
TextFormField(maxLines: null, initialValue: Util.getGlobal("defaultHidpiOpt") as String, decoration: InputDecoration(border: OutlineInputBorder(), labelText: AppLocalizations.of(context)!.hidpiEnvVar),
|
||||||
|
onChanged: (value) async {
|
||||||
|
await G.prefs.setString("defaultHidpiOpt", value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox.square(dimension: 8),
|
||||||
|
SwitchListTile(title: Text(AppLocalizations.of(context)!.hidpiSupport), subtitle: Text(AppLocalizations.of(context)!.applyOnNextLaunch), value: Util.getGlobal("isHidpiEnabled") as bool, onChanged:(value) {
|
||||||
|
G.prefs.setBool("isHidpiEnabled", value);
|
||||||
|
// 开启高分辨率后把缩放比调为原来的两倍 +log4(2) = 0.5
|
||||||
|
_avncScaleFactor += value ? 0.5 : -0.5;
|
||||||
|
_avncScaleFactor = _avncScaleFactor.clamp(-1, 1);
|
||||||
|
G.prefs.setDouble("avncScaleFactor", _avncScaleFactor);
|
||||||
|
// Termux:X11 并不是设置缩放比例本身,而是倍率
|
||||||
|
X11Flutter.setX11ScaleFactor(value ? 0.5 : 2.0);
|
||||||
|
setState(() {});
|
||||||
|
},),
|
||||||
|
const SizedBox.square(dimension: 16),
|
||||||
|
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
Text(AppLocalizations.of(context)!.avncAdvantages),
|
Text(AppLocalizations.of(context)!.avncAdvantages),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
@@ -347,7 +370,7 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
OutlinedButton(style: D.commandButtonStyle, child: Text(AppLocalizations.of(context)!.aboutAVNC), onPressed: () async {
|
OutlinedButton(style: D.commandButtonStyle, child: Text(AppLocalizations.of(context)!.aboutAVNC), onPressed: () async {
|
||||||
await AvncFlutter.launchAboutPage();
|
await AvncFlutter.launchAboutPage();
|
||||||
}),
|
}),
|
||||||
OutlinedButton(style: D.commandButtonStyle, child: Text(AppLocalizations.of(context)!.avncResolution), onPressed: () async {
|
OutlinedButton(style: D.commandButtonStyle, onPressed: Util.getGlobal("avncResizeDesktop") as bool ? null : () async {
|
||||||
final s = WidgetsBinding.instance.platformDispatcher.views.first.physicalSize;
|
final s = WidgetsBinding.instance.platformDispatcher.views.first.physicalSize;
|
||||||
final w0 = max(s.width, s.height);
|
final w0 = max(s.width, s.height);
|
||||||
final h0 = min(s.width, s.height);
|
final h0 = min(s.width, s.height);
|
||||||
@@ -388,13 +411,44 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
|
|||||||
}, child: Text(AppLocalizations.of(context)!.save)),
|
}, child: Text(AppLocalizations.of(context)!.save)),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}),
|
}, child: Text(AppLocalizations.of(context)!.avncResolution)),
|
||||||
]),
|
]),
|
||||||
const SizedBox.square(dimension: 8),
|
const SizedBox.square(dimension: 8),
|
||||||
SwitchListTile(title: Text(AppLocalizations.of(context)!.useAVNCByDefault), subtitle: Text(AppLocalizations.of(context)!.applyOnNextLaunch), value: Util.getGlobal("useAvnc") as bool, onChanged:(value) {
|
SwitchListTile(title: Text(AppLocalizations.of(context)!.useAVNCByDefault), subtitle: Text(AppLocalizations.of(context)!.applyOnNextLaunch), value: Util.getGlobal("useAvnc") as bool, onChanged:(value) {
|
||||||
G.prefs.setBool("useAvnc", value);
|
G.prefs.setBool("useAvnc", value);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},),
|
},),
|
||||||
|
const SizedBox.square(dimension: 8),
|
||||||
|
SwitchListTile(title: Text(AppLocalizations.of(context)!.avncScreenResize), value: Util.getGlobal("avncResizeDesktop") as bool, onChanged:(value) {
|
||||||
|
G.prefs.setBool("avncResizeDesktop", value);
|
||||||
|
setState(() {});
|
||||||
|
},),
|
||||||
|
const SizedBox.square(dimension: 8),
|
||||||
|
ListTile(
|
||||||
|
title: Text(AppLocalizations.of(context)!.avncResizeFactor),
|
||||||
|
onTap: () {},
|
||||||
|
subtitle: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text('${AppLocalizations.of(context)!.avncResizeFactorValue} ${pow(4, _avncScaleFactor).toStringAsFixed(2)}x'),
|
||||||
|
SizedBox(height: 12),
|
||||||
|
Slider(
|
||||||
|
value: _avncScaleFactor,
|
||||||
|
min: -1,
|
||||||
|
max: 1,
|
||||||
|
divisions: 96,
|
||||||
|
onChangeEnd: (double value) {
|
||||||
|
G.prefs.setDouble("avncScaleFactor", value);
|
||||||
|
},
|
||||||
|
onChanged: Util.getGlobal("avncResizeDesktop") as bool ? (double value) {
|
||||||
|
_avncScaleFactor = value;
|
||||||
|
setState(() {});
|
||||||
|
} : null,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
@@ -414,21 +468,6 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
},),
|
},),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
|
||||||
const SizedBox.square(dimension: 16),
|
|
||||||
Text(AppLocalizations.of(context)!.hidpiAdvantages),
|
|
||||||
const SizedBox.square(dimension: 16),
|
|
||||||
TextFormField(maxLines: null, initialValue: Util.getGlobal("defaultHidpiOpt") as String, decoration: InputDecoration(border: OutlineInputBorder(), labelText: AppLocalizations.of(context)!.hidpiEnvVar),
|
|
||||||
onChanged: (value) async {
|
|
||||||
await G.prefs.setString("defaultHidpiOpt", value);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox.square(dimension: 8),
|
|
||||||
SwitchListTile(title: Text(AppLocalizations.of(context)!.hidpiSupport), subtitle: Text(AppLocalizations.of(context)!.applyOnNextLaunch), value: Util.getGlobal("isHidpiEnabled") as bool, onChanged:(value) {
|
|
||||||
G.prefs.setBool("isHidpiEnabled", value);
|
|
||||||
setState(() {});
|
|
||||||
},),
|
|
||||||
const SizedBox.square(dimension: 16),
|
|
||||||
],))),
|
],))),
|
||||||
ExpansionPanel(
|
ExpansionPanel(
|
||||||
isExpanded: _expandState[3],
|
isExpanded: _expandState[3],
|
||||||
@@ -514,7 +553,7 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
|
|||||||
Text(AppLocalizations.of(context)!.hangoverDescription),
|
Text(AppLocalizations.of(context)!.hangoverDescription),
|
||||||
const SizedBox.square(dimension: 8),
|
const SizedBox.square(dimension: 8),
|
||||||
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
|
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
|
||||||
OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}(10.11)"), onPressed: () async {
|
OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}(10.14)"), onPressed: () async {
|
||||||
Util.termWrite("bash ~/.local/share/tiny/extra/install-hangover-stable");
|
Util.termWrite("bash ~/.local/share/tiny/extra/install-hangover-stable");
|
||||||
G.pageIndex.value = 0;
|
G.pageIndex.value = 0;
|
||||||
}),
|
}),
|
||||||
@@ -536,14 +575,24 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
|
|||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
Text(AppLocalizations.of(context)!.wineCommandsHint),
|
Text(AppLocalizations.of(context)!.wineCommandsHint),
|
||||||
const SizedBox.square(dimension: 8),
|
const SizedBox.square(dimension: 8),
|
||||||
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: D.wineCommands.asMap().entries.map<Widget>(
|
Wrap(
|
||||||
(e) {
|
alignment: WrapAlignment.center,
|
||||||
return OutlinedButton(style: D.commandButtonStyle, child: Text(e.value["name"]!), onPressed: () {
|
spacing: 4.0,
|
||||||
|
runSpacing: 4.0,
|
||||||
|
children: (Localizations.localeOf(context).languageCode == 'zh'
|
||||||
|
? D.wineCommands
|
||||||
|
: D.wineCommands4En
|
||||||
|
).asMap().entries.map<Widget>((e) {
|
||||||
|
return OutlinedButton(
|
||||||
|
style: D.commandButtonStyle,
|
||||||
|
child: Text(e.value["name"]!),
|
||||||
|
onPressed: () {
|
||||||
Util.termWrite("${e.value["command"]!} &");
|
Util.termWrite("${e.value["command"]!} &");
|
||||||
G.pageIndex.value = 0;
|
G.pageIndex.value = 0;
|
||||||
});
|
},
|
||||||
}
|
);
|
||||||
).toList()),
|
}).toList(),
|
||||||
|
),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||||
const SizedBox.square(dimension: 16),
|
const SizedBox.square(dimension: 16),
|
||||||
@@ -1220,7 +1269,7 @@ class _FastCommandsState extends State<FastCommands> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}, child: Text(AppLocalizations.of(context)!.cancel)),
|
}, child: Text(AppLocalizations.of(context)!.cancel)),
|
||||||
TextButton(onPressed:() async {
|
TextButton(onPressed:() async {
|
||||||
await Util.setCurrentProp("commands", D.commands);
|
await Util.setCurrentProp("commands", Localizations.localeOf(context).languageCode == 'zh' ? D.commands : D.commands4En);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@@ -1247,7 +1296,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
Future.delayed(Duration.zero,() {
|
||||||
_initializeWorkflow();
|
_initializeWorkflow();
|
||||||
|
});
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays: []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ class Util {
|
|||||||
//bool isHidpiEnabled = false 是否开启高分辨率
|
//bool isHidpiEnabled = false 是否开启高分辨率
|
||||||
//bool isJpEnabled = false 是否切换系统到日语
|
//bool isJpEnabled = false 是否切换系统到日语
|
||||||
//bool useAvnc = false 是否默认使用AVNC
|
//bool useAvnc = false 是否默认使用AVNC
|
||||||
|
//bool avncResizeDesktop = true 是否默认AVNC按当前屏幕大小调整分辨率
|
||||||
|
//double avncScaleFactor = -0.5 AVNC:在当前屏幕大小的基础上调整缩放的比例。范围-1~1,对应比例4^-1~4^1
|
||||||
//String defaultHidpiOpt 默认HiDPI环境变量
|
//String defaultHidpiOpt 默认HiDPI环境变量
|
||||||
//? int bootstrapVersion: 启动包版本
|
//? int bootstrapVersion: 启动包版本
|
||||||
//String[] containersInfo: 所有容器信息(json)
|
//String[] containersInfo: 所有容器信息(json)
|
||||||
@@ -120,6 +122,8 @@ class Util {
|
|||||||
case "isHidpiEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
case "isHidpiEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||||
case "isJpEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
case "isJpEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||||
case "useAvnc" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
|
case "useAvnc" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
|
||||||
|
case "avncResizeDesktop" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
|
||||||
|
case "avncScaleFactor" : return b ? G.prefs.getDouble(key)!.clamp(-1.0, 1.0) : (value){G.prefs.setDouble(key, value); return value;}(-0.5);
|
||||||
case "useX11" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
case "useX11" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||||
case "defaultFFmpegCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("-hide_banner -an -max_delay 1000000 -r 30 -f android_camera -camera_index 0 -i 0:0 -vf scale=iw/2:-1 -rtsp_transport udp -f rtsp rtsp://127.0.0.1:8554/stream");
|
case "defaultFFmpegCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("-hide_banner -an -max_delay 1000000 -r 30 -f android_camera -camera_index 0 -i 0:0 -vf scale=iw/2:-1 -rtsp_transport udp -f rtsp rtsp://127.0.0.1:8554/stream");
|
||||||
case "defaultVirglCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("--use-egl-surfaceless --use-gles --socket-path=\$CONTAINER_DIR/tmp/.virgl_test");
|
case "defaultVirglCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("--use-egl-surfaceless --use-gles --socket-path=\$CONTAINER_DIR/tmp/.virgl_test");
|
||||||
@@ -208,10 +212,10 @@ class Util {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool isReady = await isXServerReady(host, port);
|
bool isReady = await isXServerReady(host, port);
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
if (isReady) {
|
if (isReady) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Future.delayed(Duration(seconds: 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +356,7 @@ class D {
|
|||||||
];
|
];
|
||||||
|
|
||||||
//默认快捷指令
|
//默认快捷指令
|
||||||
static const commands = [{"name":"检查更新并升级", "command":"sudo dpkg --configure -a && sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y && sudo localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8"},
|
static const commands = [{"name":"检查更新并升级", "command":"sudo dpkg --configure -a && sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y"},
|
||||||
{"name":"查看系统信息", "command":"neofetch -L && neofetch --off"},
|
{"name":"查看系统信息", "command":"neofetch -L && neofetch --off"},
|
||||||
{"name":"清屏", "command":"clear"},
|
{"name":"清屏", "command":"clear"},
|
||||||
{"name":"中断任务", "command":"\x03"},
|
{"name":"中断任务", "command":"\x03"},
|
||||||
@@ -383,6 +387,30 @@ rm /tmp/wps.deb"""},
|
|||||||
{"name":"???", "command":"timeout 8 cmatrix"}
|
{"name":"???", "command":"timeout 8 cmatrix"}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
//默认快捷指令,英文版本
|
||||||
|
static const commands4En = [{"name":"Update Packages", "command":"sudo dpkg --configure -a && sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y"},
|
||||||
|
{"name":"System Info", "command":"neofetch -L && neofetch --off"},
|
||||||
|
{"name":"Clear", "command":"clear"},
|
||||||
|
{"name":"Interrupt", "command":"\x03"},
|
||||||
|
{"name":"Install Painting Program Krita", "command":"sudo apt update && sudo apt install -y krita krita-l10n"},
|
||||||
|
{"name":"Uninstall Krita", "command":"sudo apt autoremove --purge -y krita krita-l10n"},
|
||||||
|
{"name":"Install KDE Non-Linear Video Editor", "command":"sudo apt update && sudo apt install -y kdenlive"},
|
||||||
|
{"name":"Uninstall Kdenlive", "command":"sudo apt autoremove --purge -y kdenlive"},
|
||||||
|
{"name":"Install LibreOffice", "command":"sudo apt update && sudo apt install -y libreoffice"},
|
||||||
|
{"name":"Uninstall LibreOffice", "command":"sudo apt autoremove --purge -y libreoffice"},
|
||||||
|
{"name":"Install WPS", "command":r"""cat << 'EOF' | sh && sudo dpkg --configure -a && sudo apt update && sudo apt install -y /tmp/wps.deb
|
||||||
|
wget https://github.com/tiny-computer/third-party-archives/releases/download/archives/wps-office_11.1.0.11720_arm64.deb -O /tmp/wps.deb
|
||||||
|
EOF
|
||||||
|
rm /tmp/wps.deb"""},
|
||||||
|
{"name":"Uninstall WPS", "command":"sudo apt autoremove --purge -y wps-office"},
|
||||||
|
{"name":"Install EdrawMax", "command":"""wget https://cc-download.wondershare.cc/business/prd/edrawmax_13.1.0-1_arm64_binner.deb -O /tmp/edraw.deb && sudo apt update && sudo apt install -y /tmp/edraw.deb && bash /home/tiny/.local/share/tiny/edraw/postinst && sudo sed -i 's/<Language V="cn"\\/>/<Language V="en"\\/>/g' /opt/apps/edrawmax/config/settings.xml; rm /tmp/edraw.deb"""},
|
||||||
|
{"name":"Uninstall EdrawMax", "command":"sudo apt autoremove --purge -y edrawmax libldap-2.4-2"},
|
||||||
|
{"name":"Enable Recycle Bin", "command":"sudo apt update && sudo apt install -y gvfs && echo 'Restart the app to use Recycle Bin.'"},
|
||||||
|
{"name":"Clean Package Cache", "command":"sudo apt clean"},
|
||||||
|
{"name":"Power Off", "command":"stopvnc\nexit\nexit"},
|
||||||
|
{"name":"???", "command":"timeout 8 cmatrix"}
|
||||||
|
];
|
||||||
|
|
||||||
//默认wine快捷指令
|
//默认wine快捷指令
|
||||||
static const wineCommands = [{"name":"Wine配置", "command":"winecfg"},
|
static const wineCommands = [{"name":"Wine配置", "command":"winecfg"},
|
||||||
{"name":"修复方块字", "command":"regedit Z:\\\\home\\\\tiny\\\\.local\\\\share\\\\tiny\\\\extra\\\\chn_fonts.reg && wine reg delete \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\" /va /f"},
|
{"name":"修复方块字", "command":"regedit Z:\\\\home\\\\tiny\\\\.local\\\\share\\\\tiny\\\\extra\\\\chn_fonts.reg && wine reg delete \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\" /va /f"},
|
||||||
@@ -408,6 +436,31 @@ WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_C
|
|||||||
{"name":"强制关闭Wine", "command":"wineserver -k"}
|
{"name":"强制关闭Wine", "command":"wineserver -k"}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
//默认wine快捷指令,英文版本
|
||||||
|
static const wineCommands4En = [{"name":"Wine Configuration", "command":"winecfg"},
|
||||||
|
{"name":"Fix CJK Characters", "command":"regedit Z:\\\\home\\\\tiny\\\\.local\\\\share\\\\tiny\\\\extra\\\\chn_fonts.reg && wine reg delete \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\" /va /f"},
|
||||||
|
{"name":"Start Menu Dir", "command":"wine explorer \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\""},
|
||||||
|
{"name":"Enable DXVK", "command":"""WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1"""},
|
||||||
|
{"name":"Disable DXVK", "command":"""WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d8 /d builtin /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d9 /d builtin /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d10core /d builtin /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d11 /d builtin /f >/dev/null 2>&1
|
||||||
|
WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v dxgi /d builtin /f >/dev/null 2>&1"""},
|
||||||
|
{"name":"Explorer", "command":"wine explorer"},
|
||||||
|
{"name":"Notepad", "command":"notepad"},
|
||||||
|
{"name":"Minesweeper", "command":"winemine"},
|
||||||
|
{"name":"Regedit", "command":"regedit"},
|
||||||
|
{"name":"Control Panel", "command":"wine control"},
|
||||||
|
{"name":"File Manager", "command":"winefile"},
|
||||||
|
{"name":"Task Manager", "command":"wine taskmgr"},
|
||||||
|
{"name":"Internet Explorer", "command":"wine iexplore"},
|
||||||
|
{"name":"Kill Wine Process", "command":"wineserver -k"}
|
||||||
|
];
|
||||||
|
|
||||||
//默认小键盘
|
//默认小键盘
|
||||||
static const termCommands = [
|
static const termCommands = [
|
||||||
{"name": "Esc", "key": TerminalKey.escape},
|
{"name": "Esc", "key": TerminalKey.escape},
|
||||||
@@ -534,7 +587,7 @@ ln -sf ../applib/libexec_tar.so \$DATA_DIR/bin/tar
|
|||||||
ln -sf ../applib/libexec_virgl_test_server.so \$DATA_DIR/bin/virgl_test_server
|
ln -sf ../applib/libexec_virgl_test_server.so \$DATA_DIR/bin/virgl_test_server
|
||||||
ln -sf ../applib/libexec_getifaddrs_bridge_server.so \$DATA_DIR/bin/getifaddrs_bridge_server
|
ln -sf ../applib/libexec_getifaddrs_bridge_server.so \$DATA_DIR/bin/getifaddrs_bridge_server
|
||||||
ln -sf ../applib/libexec_pulseaudio.so \$DATA_DIR/bin/pulseaudio
|
ln -sf ../applib/libexec_pulseaudio.so \$DATA_DIR/bin/pulseaudio
|
||||||
ln -sf ../applib/libbusybox.so \$DATA_DIR/lib/libbusybox.so.1.36.1
|
ln -sf ../applib/libbusybox.so \$DATA_DIR/lib/libbusybox.so.1.37.0
|
||||||
ln -sf ../applib/libtalloc.so \$DATA_DIR/lib/libtalloc.so.2
|
ln -sf ../applib/libtalloc.so \$DATA_DIR/lib/libtalloc.so.2
|
||||||
ln -sf ../applib/libvirglrenderer.so \$DATA_DIR/lib/libvirglrenderer.so
|
ln -sf ../applib/libvirglrenderer.so \$DATA_DIR/lib/libvirglrenderer.so
|
||||||
ln -sf ../applib/libepoxy.so \$DATA_DIR/lib/libepoxy.so
|
ln -sf ../applib/libepoxy.so \$DATA_DIR/lib/libepoxy.so
|
||||||
@@ -553,10 +606,10 @@ chmod 1777 tmp
|
|||||||
//初次启动要做的事情
|
//初次启动要做的事情
|
||||||
static Future<void> initForFirstTime() async {
|
static Future<void> initForFirstTime() async {
|
||||||
//首先设置bootstrap
|
//首先设置bootstrap
|
||||||
G.updateText.value = "正在安装引导包";
|
G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installingBootPackage;
|
||||||
await setupBootstrap();
|
await setupBootstrap();
|
||||||
|
|
||||||
G.updateText.value = "正在复制容器系统";
|
G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.copyingContainerSystem;
|
||||||
//存放容器的文件夹0和存放硬链接的文件夹.l2s
|
//存放容器的文件夹0和存放硬链接的文件夹.l2s
|
||||||
Util.createDirFromString("${G.dataPath}/containers/0/.l2s");
|
Util.createDirFromString("${G.dataPath}/containers/0/.l2s");
|
||||||
//这个是容器rootfs,被split命令分成了xa*,放在assets里
|
//这个是容器rootfs,被split命令分成了xa*,放在assets里
|
||||||
@@ -565,7 +618,7 @@ chmod 1777 tmp
|
|||||||
await Util.copyAsset("assets/$name", "${G.dataPath}/$name");
|
await Util.copyAsset("assets/$name", "${G.dataPath}/$name");
|
||||||
}
|
}
|
||||||
//-J
|
//-J
|
||||||
G.updateText.value = "正在安装容器系统";
|
G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installingContainerSystem;
|
||||||
await Util.execute(
|
await Util.execute(
|
||||||
"""
|
"""
|
||||||
export DATA_DIR=${G.dataPath}
|
export DATA_DIR=${G.dataPath}
|
||||||
@@ -595,18 +648,19 @@ cat tmp3 | while read -r group_name group_id; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
\$DATA_DIR/bin/busybox rm -rf xa* tmp1 tmp2 tmp3
|
\$DATA_DIR/bin/busybox rm -rf xa* tmp1 tmp2 tmp3
|
||||||
|
${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? "" : "echo 'LANG=en_US.UTF-8' > \$CONTAINER_DIR/usr/local/etc/tmoe-linux/locale.txt"}
|
||||||
""");
|
""");
|
||||||
//一些数据初始化
|
//一些数据初始化
|
||||||
//$DATA_DIR是数据文件夹, $CONTAINER_DIR是容器根目录
|
//$DATA_DIR是数据文件夹, $CONTAINER_DIR是容器根目录
|
||||||
//Termux:X11的启动命令并不在这里面,而是写死了。这下成💩山代码了:P
|
//Termux:X11的启动命令并不在这里面,而是写死了。这下成💩山代码了:P
|
||||||
await G.prefs.setStringList("containersInfo", ["""{
|
await G.prefs.setStringList("containersInfo", ["""{
|
||||||
"name":"Debian Bookworm",
|
"name":"Debian Bookworm",
|
||||||
"boot":"${D.boot}",
|
"boot":"${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? D.boot : D.boot.replaceFirst('LANG=zh_CN.UTF-8', 'LANG=en_US.UTF-8').replaceFirst('公共', 'Public').replaceFirst('图片', 'Pictures').replaceFirst('音乐', 'Music').replaceFirst('视频', 'Videos').replaceFirst('下载', 'Downloads').replaceFirst('文档', 'Documents').replaceFirst('照片', 'Photos')}",
|
||||||
"vnc":"startnovnc &",
|
"vnc":"startnovnc &",
|
||||||
"vncUrl":"http://localhost:36082/vnc.html?host=localhost&port=36082&autoconnect=true&resize=remote&password=12345678",
|
"vncUrl":"http://localhost:36082/vnc.html?host=localhost&port=36082&autoconnect=true&resize=remote&password=12345678",
|
||||||
"commands":${jsonEncode(D.commands)}
|
"commands":${jsonEncode(Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? D.commands : D.commands4En)}
|
||||||
}"""]);
|
}"""]);
|
||||||
G.updateText.value = "安装完成";
|
G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installationComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> initData() async {
|
static Future<void> initData() async {
|
||||||
@@ -630,13 +684,21 @@ done
|
|||||||
final String h = (min(s.width, s.height) * 0.75).round().toString();
|
final String h = (min(s.width, s.height) * 0.75).round().toString();
|
||||||
G.postCommand = """sed -i -E "s@(geometry)=.*@\\1=${w}x${h}@" /etc/tigervnc/vncserver-config-tmoe
|
G.postCommand = """sed -i -E "s@(geometry)=.*@\\1=${w}x${h}@" /etc/tigervnc/vncserver-config-tmoe
|
||||||
sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""";
|
sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""";
|
||||||
|
if (Localizations.localeOf(G.homePageStateContext).languageCode != 'zh') {
|
||||||
|
G.postCommand += "\nlocaledef -c -i en_US -f UTF-8 en_US.UTF-8";
|
||||||
|
// For English users, assume they need to enable terminal write
|
||||||
|
await G.prefs.setBool("isTerminalWriteEnabled", true);
|
||||||
|
await G.prefs.setBool("isTerminalCommandsEnabled", true);
|
||||||
|
await G.prefs.setBool("isStickyKey", false);
|
||||||
|
await G.prefs.setBool("wakelock", true);
|
||||||
|
}
|
||||||
await G.prefs.setBool("getifaddrsBridge", (await DeviceInfoPlugin().androidInfo).version.sdkInt >= 31);
|
await G.prefs.setBool("getifaddrsBridge", (await DeviceInfoPlugin().androidInfo).version.sdkInt >= 31);
|
||||||
}
|
}
|
||||||
G.currentContainer = Util.getGlobal("defaultContainer") as int;
|
G.currentContainer = Util.getGlobal("defaultContainer") as int;
|
||||||
|
|
||||||
//是否需要重新安装引导包?
|
//是否需要重新安装引导包?
|
||||||
if (Util.getGlobal("reinstallBootstrap")) {
|
if (Util.getGlobal("reinstallBootstrap")) {
|
||||||
G.updateText.value = "正在重新安装引导包";
|
G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.reinstallingBootPackage;
|
||||||
await setupBootstrap();
|
await setupBootstrap();
|
||||||
G.prefs.setBool("reinstallBootstrap", false);
|
G.prefs.setBool("reinstallBootstrap", false);
|
||||||
}
|
}
|
||||||
@@ -729,10 +791,14 @@ export PROOT_LOADER=\$DATA_DIR/applib/libproot-loader.so
|
|||||||
export PROOT_LOADER_32=\$DATA_DIR/applib/libproot-loader32.so
|
export PROOT_LOADER_32=\$DATA_DIR/applib/libproot-loader32.so
|
||||||
${Util.getCurrentProp("boot")}
|
${Util.getCurrentProp("boot")}
|
||||||
${G.postCommand}
|
${G.postCommand}
|
||||||
${(Util.getGlobal("autoLaunchVnc") as bool)?((Util.getGlobal("useX11") as bool)?"""mkdir -p "\$HOME/.vnc" && bash /etc/X11/xinit/Xsession &> "\$HOME/.vnc/x.log" &""":Util.getCurrentProp("vnc")):""}
|
|
||||||
clear""");
|
clear""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<void> launchGUIBackend() async {
|
||||||
|
Util.termWrite((Util.getGlobal("autoLaunchVnc") as bool)?((Util.getGlobal("useX11") as bool)?"""mkdir -p "\$HOME/.vnc" && bash /etc/X11/xinit/Xsession &> "\$HOME/.vnc/x.log" &""":Util.getCurrentProp("vnc")):"");
|
||||||
|
Util.termWrite("clear");
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> waitForConnection() async {
|
static Future<void> waitForConnection() async {
|
||||||
await retry(
|
await retry(
|
||||||
// Make a GET request
|
// Make a GET request
|
||||||
@@ -771,7 +837,7 @@ clear""");
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> launchAvnc() async {
|
static Future<void> launchAvnc() async {
|
||||||
await AvncFlutter.launchUsingUri(Util.getCurrentProp("vncUri") as String);
|
await AvncFlutter.launchUsingUri(Util.getCurrentProp("vncUri") as String, resizeRemoteDesktop: Util.getGlobal("avncResizeDesktop") as bool, resizeRemoteDesktopScaleFactor: pow(4, Util.getGlobal("avncScaleFactor") as double).toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> launchXServer() async {
|
static Future<void> launchXServer() async {
|
||||||
@@ -791,9 +857,11 @@ clear""");
|
|||||||
if (Util.getGlobal("autoLaunchVnc") as bool) {
|
if (Util.getGlobal("autoLaunchVnc") as bool) {
|
||||||
if (G.wasX11Enabled) {
|
if (G.wasX11Enabled) {
|
||||||
await Util.waitForXServer();
|
await Util.waitForXServer();
|
||||||
|
launchGUIBackend();
|
||||||
launchX11();
|
launchX11();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
launchGUIBackend();
|
||||||
waitForConnection().then((value) => G.wasAvncEnabled?launchAvnc():launchBrowser());
|
waitForConnection().then((value) => G.wasAvncEnabled?launchAvnc():launchBrowser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
pubspec.lock
28
pubspec.lock
@@ -21,8 +21,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "73f6672f955ae89606336e0a018d4958af3570e6"
|
ref: "4008565259f88fe4613b885979f79e439bc5a420"
|
||||||
resolved-ref: "73f6672f955ae89606336e0a018d4958af3570e6"
|
resolved-ref: "4008565259f88fe4613b885979f79e439bc5a420"
|
||||||
url: "https://github.com/tiny-computer/avnc_flutter.git"
|
url: "https://github.com/tiny-computer/avnc_flutter.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
@@ -202,26 +202,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.9"
|
version: "11.0.1"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.9"
|
version: "3.0.10"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.2"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -543,10 +543,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.4"
|
version: "0.7.6"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -623,10 +623,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -711,8 +711,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "778ae0873d9bf953d1fdbbd6bc4937ccf1020bb5"
|
ref: "3b92b515b1ebc32c93e18e8b3a2983656713e4dd"
|
||||||
resolved-ref: "778ae0873d9bf953d1fdbbd6bc4937ccf1020bb5"
|
resolved-ref: "3b92b515b1ebc32c93e18e8b3a2983656713e4dd"
|
||||||
url: "https://github.com/tiny-computer/x11_flutter.git"
|
url: "https://github.com/tiny-computer/x11_flutter.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.0.99+20250831
|
version: 1.0.100+20250912
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.1.0 <4.0.0'
|
sdk: '>=3.1.0 <4.0.0'
|
||||||
@@ -50,11 +50,11 @@ dependencies:
|
|||||||
x11_flutter:
|
x11_flutter:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/tiny-computer/x11_flutter.git
|
url: https://github.com/tiny-computer/x11_flutter.git
|
||||||
ref: 778ae0873d9bf953d1fdbbd6bc4937ccf1020bb5
|
ref: 3b92b515b1ebc32c93e18e8b3a2983656713e4dd
|
||||||
avnc_flutter:
|
avnc_flutter:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/tiny-computer/avnc_flutter.git
|
url: https://github.com/tiny-computer/avnc_flutter.git
|
||||||
ref: 73f6672f955ae89606336e0a018d4958af3570e6
|
ref: 4008565259f88fe4613b885979f79e439bc5a420
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|||||||
Reference in New Issue
Block a user