fix: taskbar pins, Edge NTP, black bg, step progress strip
All checks were successful
release / build-and-release (push) Successful in 22s
All checks were successful
release / build-and-release (push) Successful in 22s
- 04-default-profile: default profile now pins Explorer+Edge (was empty), preventing MS Store and other defaults from appearing in taskbar - 03-system-registry: disable Edge new tab page quick links, background, content feed (NewTabPageQuickLinksEnabled/BackgroundEnabled/AllowedBackgroundTypes) - 05-personalization: set Wallpaper="" in default hive so new user accounts get solid-color background instead of black fallback - runner: add onStepStart callback, fires before each script launch - gui: step progress strip in run phase — color-coded labels per step (pending gray · / running blue ► / ok green ✓ / error red ✗ / skipped gray –) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3991e7a6d0
commit
0462881980
5 changed files with 97 additions and 13 deletions
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -231,6 +232,13 @@ func formPhase(cfg config.Config, runCfg runner.RunConfig, cfgPath string) formR
|
||||||
// Phase 2 – Live run view
|
// Phase 2 – Live run view
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// stepIndicator tracks a step's label and blink state.
|
||||||
|
type stepIndicator struct {
|
||||||
|
label *walk.Label
|
||||||
|
stepID string
|
||||||
|
status string // "pending", "running", "ok", "error", "skipped", "cancelled"
|
||||||
|
}
|
||||||
|
|
||||||
func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
var (
|
var (
|
||||||
mw *walk.MainWindow
|
mw *walk.MainWindow
|
||||||
|
|
@ -239,6 +247,21 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
cancelFn context.CancelFunc
|
cancelFn context.CancelFunc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Build step indicator labels (one per step, in order)
|
||||||
|
indicators := make([]stepIndicator, len(steps))
|
||||||
|
stepIndex := make(map[string]int, len(steps)) // stepID → index
|
||||||
|
indWidgets := make([]Widget, len(steps))
|
||||||
|
for i, s := range steps {
|
||||||
|
indicators[i] = stepIndicator{stepID: s.ID, status: "pending"}
|
||||||
|
stepIndex[s.ID] = i
|
||||||
|
indWidgets[i] = Label{
|
||||||
|
AssignTo: &indicators[i].label,
|
||||||
|
Text: s.Num + " \u00b7",
|
||||||
|
Font: Font{Family: "Consolas", PointSize: 9},
|
||||||
|
MinSize: Size{Width: 38},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := (MainWindow{
|
if err := (MainWindow{
|
||||||
AssignTo: &mw,
|
AssignTo: &mw,
|
||||||
Title: "xetup \u2014 probiha instalace",
|
Title: "xetup \u2014 probiha instalace",
|
||||||
|
|
@ -246,13 +269,18 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
Layout: VBox{},
|
Layout: VBox{},
|
||||||
Children: []Widget{
|
Children: []Widget{
|
||||||
Label{AssignTo: &statusLbl, Text: "Spoustim..."},
|
Label{AssignTo: &statusLbl, Text: "Spoustim..."},
|
||||||
|
// Step progress strip
|
||||||
|
Composite{
|
||||||
|
Layout: HBox{MarginsZero: true},
|
||||||
|
Children: indWidgets,
|
||||||
|
},
|
||||||
HSeparator{},
|
HSeparator{},
|
||||||
TextEdit{
|
TextEdit{
|
||||||
AssignTo: &logTE,
|
AssignTo: &logTE,
|
||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
VScroll: true,
|
VScroll: true,
|
||||||
Font: Font{Family: "Consolas", PointSize: 9},
|
Font: Font{Family: "Consolas", PointSize: 9},
|
||||||
MinSize: Size{Height: 590},
|
MinSize: Size{Height: 530},
|
||||||
},
|
},
|
||||||
HSeparator{},
|
HSeparator{},
|
||||||
Composite{
|
Composite{
|
||||||
|
|
@ -274,6 +302,29 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateIndicator refreshes label text and color — call inside Synchronize.
|
||||||
|
updateIndicator := func(idx int) {
|
||||||
|
ind := &indicators[idx]
|
||||||
|
s := steps[idx]
|
||||||
|
switch ind.status {
|
||||||
|
case "running":
|
||||||
|
ind.label.SetText(s.Num + " \u25ba") // ►
|
||||||
|
ind.label.SetTextColor(walk.RGB(30, 144, 255)) // dodger blue
|
||||||
|
case "ok":
|
||||||
|
ind.label.SetText(s.Num + " \u2713") // ✓
|
||||||
|
ind.label.SetTextColor(walk.RGB(0, 180, 0))
|
||||||
|
case "error":
|
||||||
|
ind.label.SetText(s.Num + " \u2717") // ✗
|
||||||
|
ind.label.SetTextColor(walk.RGB(220, 50, 50))
|
||||||
|
case "skipped", "cancelled":
|
||||||
|
ind.label.SetText(s.Num + " \u2013") // –
|
||||||
|
ind.label.SetTextColor(walk.RGB(140, 140, 140))
|
||||||
|
default:
|
||||||
|
ind.label.SetText(s.Num + " \u00b7") // ·
|
||||||
|
ind.label.SetTextColor(walk.RGB(180, 180, 180))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
results []runner.Result
|
results []runner.Result
|
||||||
|
|
@ -283,7 +334,6 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
cancelFn = cancel
|
cancelFn = cancel
|
||||||
|
|
||||||
// Cancel running scripts when user closes the window.
|
|
||||||
mw.Closing().Attach(func(_ *bool, _ walk.CloseReason) {
|
mw.Closing().Attach(func(_ *bool, _ walk.CloseReason) {
|
||||||
cancelFn()
|
cancelFn()
|
||||||
})
|
})
|
||||||
|
|
@ -295,11 +345,26 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
logTE.AppendText(l.Text + "\r\n")
|
logTE.AppendText(l.Text + "\r\n")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
func(step runner.Step) {
|
||||||
|
mw.Synchronize(func() {
|
||||||
|
statusLbl.SetText(fmt.Sprintf(
|
||||||
|
"Krok %s \u2013 %s...", step.Num, step.Name,
|
||||||
|
))
|
||||||
|
if idx, ok := stepIndex[step.ID]; ok {
|
||||||
|
indicators[idx].status = "running"
|
||||||
|
updateIndicator(idx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
func(res runner.Result) {
|
func(res runner.Result) {
|
||||||
mw.Synchronize(func() {
|
mw.Synchronize(func() {
|
||||||
statusLbl.SetText(fmt.Sprintf(
|
statusLbl.SetText(fmt.Sprintf(
|
||||||
"Krok %s \u2013 %s: %s", res.Step.Num, res.Step.Name, res.Status,
|
"Krok %s \u2013 %s: %s", res.Step.Num, res.Step.Name, res.Status,
|
||||||
))
|
))
|
||||||
|
if idx, ok := stepIndex[res.Step.ID]; ok {
|
||||||
|
indicators[idx].status = strings.ToLower(res.Status)
|
||||||
|
updateIndicator(idx)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -316,8 +381,8 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
mw.Run()
|
mw.Run()
|
||||||
cancel() // stop scripts if window was closed by user
|
cancel()
|
||||||
<-done // wait for goroutine to exit cleanly
|
<-done
|
||||||
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -143,13 +143,15 @@ type LogLine struct {
|
||||||
type Runner struct {
|
type Runner struct {
|
||||||
cfg RunConfig
|
cfg RunConfig
|
||||||
onLog func(LogLine)
|
onLog func(LogLine)
|
||||||
|
onStepStart func(Step)
|
||||||
onResult func(Result)
|
onResult func(Result)
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a Runner. onLog is called for each output line, onResult after each step.
|
// New creates a Runner. onLog is called for each output line, onResult after each step.
|
||||||
func New(cfg RunConfig, onLog func(LogLine), onResult func(Result)) *Runner {
|
// onStepStart (optional) is called immediately before a step's script is launched.
|
||||||
return &Runner{cfg: cfg, onLog: onLog, onResult: onResult}
|
func New(cfg RunConfig, onLog func(LogLine), onStepStart func(Step), onResult func(Result)) *Runner {
|
||||||
|
return &Runner{cfg: cfg, onLog: onLog, onStepStart: onStepStart, onResult: onResult}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes enabled steps sequentially. Blocks until done or context cancelled.
|
// Run executes enabled steps sequentially. Blocks until done or context cancelled.
|
||||||
|
|
@ -170,6 +172,9 @@ func (r *Runner) Run(ctx context.Context, steps []Step) []Result {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.onStepStart != nil {
|
||||||
|
r.onStepStart(step)
|
||||||
|
}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err := r.runScript(ctx, step, cfgArg)
|
err := r.runScript(ctx, step, cfgArg)
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
|
|
|
||||||
|
|
@ -316,8 +316,11 @@ if (Get-Feature $Config "systemRegistry" "edgePolicies") {
|
||||||
Set-Reg -Path $edgePath -Name "HideFirstRunExperience" -Value 1
|
Set-Reg -Path $edgePath -Name "HideFirstRunExperience" -Value 1
|
||||||
Set-Reg -Path $edgePath -Name "DefaultBrowserSettingEnabled" -Value 0
|
Set-Reg -Path $edgePath -Name "DefaultBrowserSettingEnabled" -Value 0
|
||||||
|
|
||||||
# New tab page / recommendations
|
# New tab page - disable all visual clutter
|
||||||
Set-Reg -Path $edgePath -Name "NewTabPageContentEnabled" -Value 0
|
Set-Reg -Path $edgePath -Name "NewTabPageContentEnabled" -Value 0 # feed / obsah
|
||||||
|
Set-Reg -Path $edgePath -Name "NewTabPageQuickLinksEnabled" -Value 0 # rychle odkazy
|
||||||
|
Set-Reg -Path $edgePath -Name "NewTabPageBackgroundEnabled" -Value 0 # pozadi
|
||||||
|
Set-Reg -Path $edgePath -Name "NewTabPageAllowedBackgroundTypes" -Value 3 # 3 = only solid color
|
||||||
Set-Reg -Path $edgePath -Name "ShowRecommendationsEnabled" -Value 0
|
Set-Reg -Path $edgePath -Name "ShowRecommendationsEnabled" -Value 0
|
||||||
Set-Reg -Path $edgePath -Name "SpotlightExperiencesAndRecommendationsEnabled" -Value 0
|
Set-Reg -Path $edgePath -Name "SpotlightExperiencesAndRecommendationsEnabled" -Value 0
|
||||||
Set-Reg -Path $edgePath -Name "PersonalizationReportingEnabled" -Value 0
|
Set-Reg -Path $edgePath -Name "PersonalizationReportingEnabled" -Value 0
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,12 @@ try {
|
||||||
<taskbar:DesktopApp DesktopApplicationLinkPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"/>
|
<taskbar:DesktopApp DesktopApplicationLinkPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"/>
|
||||||
'@
|
'@
|
||||||
}
|
}
|
||||||
default { "" } # empty = clean slate
|
default {
|
||||||
|
@'
|
||||||
|
<taskbar:DesktopApp DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\File Explorer.lnk"/>
|
||||||
|
<taskbar:DesktopApp DesktopApplicationLinkPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"/>
|
||||||
|
'@
|
||||||
|
} # explicit pins with Replace = no Store, no other defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
$taskbarLayoutXml = @"
|
$taskbarLayoutXml = @"
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,12 @@ function Apply-ThemeSettings {
|
||||||
Set-Reg -Path "$HiveRoot\Control Panel\Colors" `
|
Set-Reg -Path "$HiveRoot\Control Panel\Colors" `
|
||||||
-Name "Background" -Value "34 59 71" -Type "String"
|
-Name "Background" -Value "34 59 71" -Type "String"
|
||||||
|
|
||||||
|
# Empty Wallpaper path = solid color from Background key above.
|
||||||
|
# Without this, new users created from Default hive inherit a broken/missing
|
||||||
|
# wallpaper path and Windows falls back to black desktop.
|
||||||
|
Set-Reg -Path "$HiveRoot\Control Panel\Desktop" `
|
||||||
|
-Name "Wallpaper" -Value "" -Type "String"
|
||||||
|
|
||||||
Set-Reg -Path "$HiveRoot\Control Panel\Desktop" `
|
Set-Reg -Path "$HiveRoot\Control Panel\Desktop" `
|
||||||
-Name "WallpaperStyle" -Value "0" -Type "String"
|
-Name "WallpaperStyle" -Value "0" -Type "String"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue