Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/windows-msi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,16 @@ jobs:
shell: pwsh
run: cargo install cargo-wix --locked

- name: Init WiX project if missing
- name: Build MSI
shell: pwsh
run: |
if (-not (Test-Path "wix\main.wxs")) {
cargo wix init --force
throw "Missing wix\main.wxs (desktop shortcuts + product icon must be committed)"
}

- name: Build MSI
shell: pwsh
run: cargo wix --nocapture
if (-not (Test-Path "wix\Product.ico")) {
throw "Missing wix\Product.ico"
}
cargo wix --nocapture

- name: Upload MSI artifact
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ product-name = "WSLc Desktop"
manufacturer = "WSLc Desktop"
license = false
eula = false
product-icon = "wix/Product.ico"
upgrade-guid = "31263ED9-28F7-4608-AF04-A8CAE4591EB0"

[dependencies]
anyhow = "1"
Expand Down
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- **Volumes**:列出 / 创建 / 删除命名卷
- **Run**:按镜像引用启动 detached 容器(可选名称)
- **引擎状态**:LIVE(真实 CLI)或 DEMO(内存样例数据)
- **设置**:界面语言(中文 / English,默认跟随系统:中文系统用中文,否则英文)与主题(深色 / 浅色)
- **设置**:TitleBar 齿轮按钮打开;界面语言(中文 / English,默认跟随系统)与主题(深色 / 浅色)

## 环境要求

Expand Down Expand Up @@ -68,15 +68,11 @@ rustc -vV # 确认 host 含 windows-msvc
cargo install cargo-wix
```

### 2. 生成安装工程并打 MSI
### 2. 打 MSI(含桌面图标)

在仓库根目录:
仓库已提交 `wix/main.wxs` 与 `wix/Product.ico`:安装后会创建 **开始菜单** 与 **桌面快捷方式**,**不会** 写入 PATH(无需命令行启动)。

```powershell
# 首次:根据 Cargo.toml 生成 wix\main.wxs(可按需改图标、快捷方式、安装目录)
cargo wix init

# 构建 release 并打包 MSI
cargo wix
```

Expand Down Expand Up @@ -134,15 +130,16 @@ git push origin v0.1.0

成功后可在对应 workflow run 的 **Artifacts** 下载 `wslc-desktop-msi`;打 tag 时还会出现在 **Releases**。

工作流在 `windows-latest` 上安装 Rust MSVC、WiX Toolset、`cargo-wix`,必要时执行 `cargo wix init`,再 `cargo wix` 产出 `target\wix\*.msi`。
工作流在 `windows-latest` 上安装 Rust MSVC、WiX Toolset、`cargo-wix`,再 `cargo wix` 产出带桌面快捷方式的 MSI。

## 项目结构

```text
.github/workflows/ # GitHub Actions(Windows MSI)
wix/ # MSI:桌面/开始菜单快捷方式 + 产品图标
src/
main.rs # 窗口启动与快捷键
app.rs # 侧栏 + 分区界面(含设置)
app.rs # 侧栏导航 + TitleBar 设置按钮
i18n.rs # 中英文字符串与系统语言检测
wslc.rs # wslc CLI 封装与 Demo 回退
```
Expand Down
62 changes: 22 additions & 40 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use std::sync::mpsc::{Receiver, TryRecvError};
use std::time::Duration;

use gpui_kit::component::{
ActiveTheme, Disableable as _, Icon, IconName, Sizable as _, StyledExt as _, Theme, ThemeMode,
TitleBar,
ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, StyledExt as _,
Theme, ThemeMode, TitleBar,
button::{Button, ButtonVariants as _},
h_flex,
input::{Input, InputState},
label::Label,
progress::Progress,
sidebar::{Sidebar, SidebarGroup, SidebarHeader, SidebarMenu, SidebarMenuItem},
tab::{Tab, TabBar},
v_flex,
};
use gpui_kit::prelude::FluentBuilder as _;
Expand All @@ -35,17 +34,6 @@ pub enum Section {
}

impl Section {
fn from_index(index: usize) -> Self {
match index {
0 => Self::Containers,
1 => Self::Images,
2 => Self::Volumes,
3 => Self::Run,
4 => Self::Settings,
_ => Self::Containers,
}
}

fn label(self, t: &Strings) -> &'static str {
match self {
Self::Containers => t.containers,
Expand Down Expand Up @@ -552,17 +540,30 @@ impl AppView {
]),
),
)
.child(
SidebarGroup::new(t.preferences).child(
SidebarMenu::new().children([SidebarMenuItem::new(t.settings)
}

fn render_title_bar(&self, cx: &mut Context<Self>) -> impl IntoElement {
let t = self.t();
TitleBar::new().child(
h_flex()
.id("title-bar-content")
.w_full()
.h_full()
.items_center()
.justify_end()
.pr_2()
.child(
Button::new("titlebar-settings")
.ghost()
.icon(IconName::Settings)
.active(self.section == Section::Settings)
.tooltip(t.settings)
.selected(self.section == Section::Settings)
.on_click(cx.listener(|this, _, _, cx| {
this.section = Section::Settings;
cx.notify();
}))]),
})),
),
)
)
}

fn render_toolbar(&self, cx: &mut Context<Self>) -> impl IntoElement {
Expand Down Expand Up @@ -1496,9 +1497,6 @@ impl AppView {

impl Render for AppView {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let section_index = self.section as usize;
let t = self.t();

h_flex()
.size_full()
.bg(cx.theme().background)
Expand All @@ -1507,23 +1505,7 @@ impl Render for AppView {
v_flex()
.size_full()
.min_w_0()
.child(
TitleBar::new().child(
TabBar::new("section-tabs")
.mt(px(1.))
.segmented()
.selected_index(section_index)
.on_click(cx.listener(|this, ix: &usize, _, cx| {
this.section = Section::from_index(*ix);
cx.notify();
}))
.child(Tab::new().label(t.containers))
.child(Tab::new().label(t.images))
.child(Tab::new().label(t.volumes))
.child(Tab::new().label(t.run))
.child(Tab::new().label(t.settings)),
),
)
.child(self.render_title_bar(cx))
.child(
v_flex()
.flex_1()
Expand Down
3 changes: 0 additions & 3 deletions src/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ impl Locale {
pub struct Strings {
pub app_subtitle: &'static str,
pub browse: &'static str,
pub preferences: &'static str,
pub containers: &'static str,
pub images: &'static str,
pub volumes: &'static str,
Expand Down Expand Up @@ -129,7 +128,6 @@ pub struct Strings {
pub static EN: Strings = Strings {
app_subtitle: "WSL Containers",
browse: "Browse",
preferences: "Preferences",
containers: "Containers",
images: "Images",
volumes: "Volumes",
Expand Down Expand Up @@ -217,7 +215,6 @@ pub static EN: Strings = Strings {
pub static ZH: Strings = Strings {
app_subtitle: "WSL 容器",
browse: "浏览",
preferences: "偏好",
containers: "容器",
images: "镜像",
volumes: "卷",
Expand Down
Binary file added wix/Product.ico
Binary file not shown.
122 changes: 122 additions & 0 deletions wix/main.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?xml version='1.0' encoding='windows-1252'?>
<!--
WSLc Desktop installer.
- Installs the GUI app under Program Files
- Creates Start Menu + Desktop shortcuts (with product icon)
- Does NOT add PATH (no command-line launch requirement)
-->
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>

<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

<Product
Id='*'
Name='WSLc Desktop'
UpgradeCode='31263ED9-28F7-4608-AF04-A8CAE4591EB0'
Manufacturer='WSLc Desktop'
Language='1033'
Codepage='1252'
Version='$(var.Version)'>

<Package Id='*'
Keywords='Installer'
Description='Lightweight desktop manager for Windows WSL Containers (WSLc)'
Manufacturer='WSLc Desktop'
InstallerVersion='450'
Languages='1033'
Compressed='yes'
InstallScope='perMachine'
SummaryCodepage='1252'
/>

<MajorUpgrade
Schedule='afterInstallInitialize'
DowngradeErrorMessage='A newer version of [ProductName] is already installed. Setup will now exit.'/>

<Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'/>
<Property Id='DiskPrompt' Value='WSLc Desktop Installation'/>

<Icon Id='ProductICO' SourceFile='wix\Product.ico'/>
<Property Id='ARPPRODUCTICON' Value='ProductICO'/>

<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
<Directory Id='APPLICATIONFOLDER' Name='WSLc Desktop'>
<Directory Id='Bin' Name='bin'>
<Component Id='binary0' Guid='*'>
<File
Id='exe0'
Name='wslc-desktop.exe'
DiskId='1'
Source='$(var.CargoTargetBinDir)\wslc-desktop.exe'
KeyPath='yes'/>
</Component>
</Directory>
</Directory>
</Directory>

<Directory Id='ProgramMenuFolder'>
<Directory Id='ApplicationProgramsFolder' Name='WSLc Desktop'/>
</Directory>

<Directory Id='DesktopFolder' Name='Desktop'/>
</Directory>

<DirectoryRef Id='ApplicationProgramsFolder'>
<Component Id='ApplicationShortcut' Guid='9E4E3369-A360-4C09-AA54-E3808FBB6FD4'>
<Shortcut
Id='ApplicationStartMenuShortcut'
Name='WSLc Desktop'
Description='WSL Containers desktop manager'
Target='[#exe0]'
WorkingDirectory='Bin'
Icon='ProductICO'/>
<Shortcut
Id='ApplicationDesktopShortcut'
Directory='DesktopFolder'
Name='WSLc Desktop'
Description='WSL Containers desktop manager'
Target='[#exe0]'
WorkingDirectory='Bin'
Icon='ProductICO'/>
<RemoveFolder Id='ApplicationProgramsFolder' On='uninstall'/>
<RegistryValue
Root='HKCU'
Key='Software\WSLc Desktop'
Name='installed'
Type='integer'
Value='1'
KeyPath='yes'/>
</Component>
</DirectoryRef>

<Feature
Id='Binaries'
Title='Application'
Description='Installs WSLc Desktop and desktop/start-menu shortcuts.'
Level='1'
ConfigurableDirectory='APPLICATIONFOLDER'
AllowAdvertise='no'
Display='expand'
Absent='disallow'>
<ComponentRef Id='binary0'/>
<ComponentRef Id='ApplicationShortcut'/>
</Feature>

<SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize'/>

<Property Id='ARPHELPLINK' Value='https://github.com/timeroute/wslc-desktop'/>

<UI>
<UIRef Id='WixUI_FeatureTree'/>
<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>
<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>
</UI>

</Product>

</Wix>
Loading