feat: add register flow, update to use correct config file
This commit is contained in:
@@ -15,3 +15,8 @@ winreg = "0.56.0"
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
slint-build = "1.16.1"
|
slint-build = "1.16.1"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
strip = true
|
||||||
|
|||||||
+34
-1
@@ -129,10 +129,43 @@ HTML-макеты → PNG: **headless Edge** (`--headless --screenshot`), он
|
|||||||
- [x] env `BP_VIEW=settings` — запуск сразу с окном настроек (без пикера);
|
- [x] env `BP_VIEW=settings` — запуск сразу с окном настроек (без пикера);
|
||||||
нюанс: `run()` авто-показывает своё окно, поэтому в этом режиме цикл
|
нюанс: `run()` авто-показывает своё окно, поэтому в этом режиме цикл
|
||||||
крутится на settings_window
|
крутится на settings_window
|
||||||
- [ ] Редактирование браузера (имя/путь/флаги через LineEdit) — следующий шаг
|
- [ ] Редактирование браузера (имя/путь/флаги через LineEdit) — ОТЛОЖЕНО (решено:
|
||||||
|
cog в пикере открывает `config.toml` в редакторе — `subl`, fallback `notepad`;
|
||||||
|
если файла нет — создаётся с автодетектом). Окно SettingsWindow осталось
|
||||||
|
в коде (недоступно из UI), dev-доступ: env `BP_VIEW=settings`
|
||||||
- [ ] Чтение флагов из .lnk ярлыков (крейс `lnk`) — по желанию
|
- [ ] Чтение флагов из .lnk ярлыков (крейс `lnk`) — по желанию
|
||||||
- [ ] Добавить логотипы Edge/Zen в logos/ (пересоздать набор из alrrr/browser-logos)
|
- [ ] Добавить логотипы Edge/Zen в logos/ (пересоздать набор из alrrr/browser-logos)
|
||||||
|
|
||||||
|
### E3 — доведение до ежедневного использования — ГОТОВО
|
||||||
|
|
||||||
|
- [x] cog → открыть конфиг в редакторе (subl → notepad)
|
||||||
|
- [x] Замер cold start: Instant в main → печать при старте event loop
|
||||||
|
- [x] `tools/register.ps1` (+ `-Uninstall`): **ставит пакет в
|
||||||
|
`%LOCALAPPDATA%\bropicker\` (exe + logos + icons)** и регистрирует
|
||||||
|
ProgId/Capabilities/RegisteredApplications в HKCU на путь из LOCALAPPDATA
|
||||||
|
(не target\ — переживает cargo clean и перенос репо), открывает
|
||||||
|
ms-settings:defaultapps
|
||||||
|
- [x] Иконки резолвятся от папки exe (иначе при запуске обработчиком ссылок
|
||||||
|
cwd = system32 и иконки бы отвалились); проверено запуском из
|
||||||
|
LOCALAPPDATA с cwd=System32
|
||||||
|
- [x] Release-профиль: lto + codegen-units=1 + strip
|
||||||
|
|
||||||
|
## Этап F — релиз
|
||||||
|
|
||||||
|
- [x] `[profile.release]`: lto, codegen-units=1, strip
|
||||||
|
- [x] Замер cold start (release, до старта event loop): **183 ms холодный /
|
||||||
|
120-122 ms тёплый**; из LOCALAPPDATA первый запуск 153 ms.
|
||||||
|
Цель <100 ms чуть не достигнута; варианты оптимизации, если захочется:
|
||||||
|
renderer-femtovg вместо skia (быстрее init GPU), отложенная загрузка
|
||||||
|
конфига. Пока считаем приемлемым
|
||||||
|
- [ ] Иконка exe (.ico через build.rs winres)
|
||||||
|
- [ ] Выбрать лицензию проекта: GPLv3 (опенсорс) или Royalty-free Slint (закрытый десктоп,
|
||||||
|
атрибуция AboutSlint) — зафиксировать в README и LICENSE
|
||||||
|
- [ ] Скриншоты в README из tools/out
|
||||||
|
- [ ] Ручной сценарий приёмки: register → клик ссылки в другом приложении →
|
||||||
|
пикер → выбор → вкладка открылась; повторный клик того же домена при
|
||||||
|
always_ask=off → сразу браузер
|
||||||
|
|
||||||
## Этап F — релиз
|
## Этап F — релиз
|
||||||
|
|
||||||
- [ ] `[profile.release]`: lto, codegen-units=1, strip
|
- [ ] `[profile.release]`: lto, codegen-units=1, strip
|
||||||
|
|||||||
+22
-8
@@ -12,6 +12,14 @@ use config::{BrowserEntry, Config};
|
|||||||
slint::include_modules!();
|
slint::include_modules!();
|
||||||
|
|
||||||
fn load_icon(rel: &str) -> slint::Image {
|
fn load_icon(rel: &str) -> slint::Image {
|
||||||
|
if let Ok(exe) = std::env::current_exe() {
|
||||||
|
if let Some(dir) = exe.parent() {
|
||||||
|
let p = dir.join(rel);
|
||||||
|
if p.exists() {
|
||||||
|
return slint::Image::load_from_path(&p).unwrap_or_default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
slint::Image::load_from_path(std::path::Path::new(rel)).unwrap_or_default()
|
slint::Image::load_from_path(std::path::Path::new(rel)).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,16 +210,19 @@ fn init(cfg: Config, url: Option<String>) -> State {
|
|||||||
});
|
});
|
||||||
|
|
||||||
main_window.on_settings_clicked({
|
main_window.on_settings_clicked({
|
||||||
let settings_window = settings_window.clone_strong();
|
|
||||||
move || {
|
move || {
|
||||||
settings_window.show().unwrap();
|
let path = config::config_path();
|
||||||
let weak = settings_window.as_weak();
|
if !path.exists() {
|
||||||
let _ = slint::invoke_from_event_loop(move || {
|
let mut c = config::load();
|
||||||
if let Some(sw) = weak.upgrade() {
|
config::ensure_browsers(&mut c);
|
||||||
winit::center_window(sw.window());
|
}
|
||||||
sw.invoke_restore_focus();
|
let editor = std::process::Command::new("subl")
|
||||||
|
.arg(&path)
|
||||||
|
.spawn()
|
||||||
|
.or_else(|_| std::process::Command::new("notepad").arg(&path).spawn());
|
||||||
|
if let Err(e) = editor {
|
||||||
|
eprintln!("[bp] cannot open editor: {e}");
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -307,6 +318,8 @@ pub struct State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
let mut cfg = config::load();
|
let mut cfg = config::load();
|
||||||
config::ensure_browsers(&mut cfg);
|
config::ensure_browsers(&mut cfg);
|
||||||
|
|
||||||
@@ -347,6 +360,7 @@ pub fn main() {
|
|||||||
winit::center_window(mw.window());
|
winit::center_window(mw.window());
|
||||||
mw.invoke_restore_focus();
|
mw.invoke_restore_focus();
|
||||||
}
|
}
|
||||||
|
eprintln!("[bp] cold start -> event loop: {:?}", start.elapsed());
|
||||||
});
|
});
|
||||||
|
|
||||||
state.main_window.run().unwrap();
|
state.main_window.run().unwrap();
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
param(
|
||||||
|
[switch]$Uninstall
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$installDir = Join-Path $env:LOCALAPPDATA "bropicker"
|
||||||
|
$classes = "HKCU:\Software\Classes\bropicker"
|
||||||
|
$caps = "HKCU:\Software\bropicker-Capabilities"
|
||||||
|
$regApps = "HKCU:\Software\RegisteredApplications"
|
||||||
|
|
||||||
|
if ($Uninstall) {
|
||||||
|
Remove-Item -Recurse -Force $classes -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Recurse -Force $caps -ErrorAction SilentlyContinue
|
||||||
|
Remove-ItemProperty -Path $regApps -Name "bropicker" -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Recurse -Force $installDir -ErrorAction SilentlyContinue
|
||||||
|
Write-Host "bropicker unregistered and removed from $installDir"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
$src = Join-Path $PSScriptRoot "..\target\release\bropicker.exe"
|
||||||
|
if (-not (Test-Path $src)) {
|
||||||
|
Write-Error "target\release\bropicker.exe not found. Build first: cargo build --release"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
|
||||||
|
Copy-Item $src (Join-Path $installDir "bropicker.exe") -Force
|
||||||
|
Copy-Item (Join-Path $PSScriptRoot "..\logos") (Join-Path $installDir "logos") -Recurse -Force
|
||||||
|
Copy-Item (Join-Path $PSScriptRoot "..\icons") (Join-Path $installDir "icons") -Recurse -Force
|
||||||
|
|
||||||
|
$exe = Join-Path $installDir "bropicker.exe"
|
||||||
|
Write-Host "Installed to: $exe"
|
||||||
|
|
||||||
|
New-Item -Path "$classes\shell\open\command" -Force | Out-Null
|
||||||
|
Set-ItemProperty -Path $classes -Name "(default)" -Value "bropicker"
|
||||||
|
Set-ItemProperty -Path $classes -Name "URL Protocol" -Value ""
|
||||||
|
Set-ItemProperty -Path "$classes\shell\open\command" -Name "(default)" -Value "`"$exe`" `"%1`""
|
||||||
|
|
||||||
|
New-Item -Path $caps -Force | Out-Null
|
||||||
|
Set-ItemProperty -Path $caps -Name "ApplicationName" -Value "bropicker"
|
||||||
|
Set-ItemProperty -Path $caps -Name "ApplicationDescription" -Value "Lightweight link picker: choose which browser opens the URL"
|
||||||
|
|
||||||
|
New-Item -Path "$caps\URLAssociations" -Force | Out-Null
|
||||||
|
Set-ItemProperty -Path "$caps\URLAssociations" -Name "https" -Value "bropicker"
|
||||||
|
Set-ItemProperty -Path "$caps\URLAssociations" -Name "http" -Value "bropicker"
|
||||||
|
|
||||||
|
New-Item -Path $regApps -Force | Out-Null
|
||||||
|
Set-ItemProperty -Path $regApps -Name "bropicker" -Value "Software\bropicker-Capabilities"
|
||||||
|
|
||||||
|
Write-Host "Registered. Now select bropicker for HTTP/HTTPS in the opened Settings window."
|
||||||
|
Start-Process "ms-settings:defaultapps"
|
||||||
Reference in New Issue
Block a user