Skip to content

Commit 35a7adc

Browse files
authored
docs: render previews for daemon/tui events handling (#54)
## What does this PR do? Minor docs changes; adds ./preview/daemon that works like a test but invokes vhs to render gifs for daemon preview of the event handling scenarios.
2 parents 1fcc7b7 + 196b811 commit 35a7adc

32 files changed

+551
-16
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ record/preview: build/docs
250250
@git checkout -- ./preview/tapes/configs/
251251
@git clean -fd ./preview/tapes/configs/
252252

253+
record/preview/daemon/selected: build/docs
254+
@$(GOTESTSUM) -- ./preview/daemon/ -v -count=1 -run $(TEST_SELECTOR)
255+
256+
record/preview/daemon: build/docs
257+
@$(GOTESTSUM) -- ./preview/daemon/ -v -count=1
258+
253259
demo: record/preview
254260

255261
record/previews: build/docs

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,21 @@ An event-driven service with an interactive TUI that automatically manages Hyprl
1818

1919
## Preview
2020

21-
![demo](./preview/output/demo.gif)
21+
### Full TUI demo
22+
23+
![TUI demo](./preview/output/demo.gif)
24+
25+
### Daemon Render on async power events
26+
27+
![power events demo](./preview/output/power_events.gif)
2228

2329
## Table Of Contents
2430

2531
<!--ts-->
2632
* [HyprDynamicMonitors](#hyprdynamicmonitors)
2733
* [Preview](#preview)
34+
* [Full TUI demo](#full-tui-demo)
35+
* [Daemon Render on async power events](#daemon-render-on-async-power-events)
2836
* [Table Of Contents](#table-of-contents)
2937
* [Features](#features)
3038
* [Quick Start](#quick-start)

cmd/tui.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ var tuiCmd = &cobra.Command{
3131
}
3232
logrus.SetOutput(f)
3333
defer f.Close()
34+
} else {
35+
// disable logging completely for tui unless run in the debug mode
36+
logrus.SetLevel(logrus.PanicLevel)
3437
}
3538

3639
if runningUnderTest {

docs/docs/configuration/lid-events.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sidebar_position: 7
66

77
Lid state monitoring uses D-Bus to listen for UPower lid events. This feature is optional and needs to be explicitly enabled.
88

9+
![Lid events](/previews/lid_events.gif)
10+
911
## Enabling Lid Events
1012

1113
To enable lid state monitoring:

docs/docs/configuration/power-events.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sidebar_position: 4
66

77
Power state monitoring uses D-Bus to listen for UPower events. This allows profiles and templates to react to AC/battery power changes.
88

9+
![Power events](/previews/power_events.gif)
10+
911
## Disabling Power Events
1012

1113
To disable power state monitoring entirely:

docs/docs/intro.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ slug: /
88
HyprDynamicMonitors is an event-driven service that automatically manages Hyprland monitor configurations based on connected displays and power state.
99
It also provides a standalone TUI that can be used for ad-hoc modifications and profile management.
1010

11-
# Preview
11+
## Preview
1212

13-
![Adjusting monitor scaling](/previews/demo.gif)
13+
### Full TUI Preview
14+
15+
![Demo](/previews/demo.gif)
16+
17+
### Async Events
18+
19+
![Events](/previews/lid_tui.gif)
1420

1521
## Features
1622

internal/testutils/hypr.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ func respondToHyprIPC(t *testing.T, listener net.Listener, exitOnError bool, com
8989
}
9090

9191
func SetupFakeHyprEventsServer(ctx context.Context, t *testing.T, listener net.Listener, events []string) chan struct{} {
92+
return SetupFakeHyprEventsServerWithSleep(ctx, t, listener, events, nil, 10*time.Millisecond)
93+
}
94+
95+
func SetupFakeHyprEventsServerWithSleep(ctx context.Context, t *testing.T, listener net.Listener,
96+
events []string, initialSleep *time.Duration, sleepBetweenEvents time.Duration,
97+
) chan struct{} {
9298
serverDone := make(chan struct{})
9399
go func() {
94100
defer func() {
@@ -112,6 +118,10 @@ func SetupFakeHyprEventsServer(ctx context.Context, t *testing.T, listener net.L
112118
Logf(t, "Fake Hypr events server: accepted connection, ready to send events")
113119

114120
for i, event := range events {
121+
if initialSleep != nil {
122+
time.Sleep(*initialSleep)
123+
}
124+
115125
select {
116126
case <-ctx.Done():
117127
Logf(t, "Fake Hypr events server: context cancelled while sending events")
@@ -124,7 +134,7 @@ func SetupFakeHyprEventsServer(ctx context.Context, t *testing.T, listener net.L
124134
return
125135
}
126136
Logf(t, "Wrote event %d on the event socket: %s", i, event)
127-
time.Sleep(10 * time.Millisecond)
137+
time.Sleep(sleepBetweenEvents)
128138
}
129139

130140
Logf(t, "Fake Hypr events server: finished sending %d events, waiting for context cancellation", len(events))

internal/tui/hdm_config_pane.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ func (h *HDMConfigPane) renderProfileDetails(profile *config.Profile) string {
263263
content.WriteString("\n")
264264
}
265265

266+
if profile.Conditions != nil && profile.Conditions.LidState != nil {
267+
content.WriteString(configDetailLabelStyle.Render("Lid State: "))
268+
content.WriteString(configDetailStyle.Render(profile.Conditions.LidState.Value()))
269+
content.WriteString("\n")
270+
}
271+
266272
if profile.Conditions != nil && profile.Conditions.RequiredMonitors != nil {
267273
content.WriteString(configDetailLabelStyle.Render("Required Monitors:"))
268274
content.WriteString("\n")

internal/tui/header_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestHeader_Update(t *testing.T) {
4242
setupMsg: tui.OperationStatusCmd(tui.OperationNameMatchingProfile, testErr),
4343
expectedMode: "",
4444
expectedView: tui.ViewMode(0),
45-
expectedErr: "Matching Profile: test error",
45+
expectedErr: "Reload Profile: test error",
4646
expectedSuccess: "",
4747
},
4848
{
@@ -55,7 +55,7 @@ func TestHeader_Update(t *testing.T) {
5555
},
5656
{
5757
name: "OperationStatus success without showSuccessToUser",
58-
setupMsg: tui.OperationStatusCmd(tui.OperationNameMatchingProfile, nil),
58+
setupMsg: tui.OperationStatusCmd(tui.OperationNameMove, nil),
5959
expectedMode: "",
6060
expectedView: tui.ViewMode(0),
6161
expectedErr: "",

internal/tui/messages.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (o OperationStatus) String() string {
140140
case OperationNameCreateProfile:
141141
operationName = "Create Profile"
142142
case OperationNameMatchingProfile:
143-
operationName = "Matching Profile"
143+
operationName = "Reload Profile"
144144
case OperationNameEditProfile:
145145
operationName = "Edit Profile"
146146
case OperationNameHDMConfigReloadRequested:
@@ -181,6 +181,7 @@ func OperationStatusCmd(name OperationName, err error) tea.Cmd {
181181
OperationNameToggleVRR,
182182
OperationNameNextBitdepth,
183183
OperationNameSetColorPreset,
184+
OperationNameMatchingProfile,
184185
}
185186
showSuccessToUser := slices.Contains(criticalOperations, name)
186187
return func() tea.Msg {

0 commit comments

Comments
 (0)