Skip to content

Commit 71d1b34

Browse files
authored
fix(hints): ask for screen-capture consent before the contour strategy runs (#1596)
1 parent 0b29501 commit 71d1b34

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

internal/app/modes/hints.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,11 @@ func (h *handlerState) activateHintModeInternal(activation modecmd.Activation) {
310310
h.startIndicatorPolling(domain.ModeHints)
311311
}
312312

313-
// needsScreenCapturePermission reports whether the vision strategy is blocked
314-
// on the screen-recording permission.
313+
// needsScreenCapturePermission reports whether a screen-capture strategy is
314+
// blocked on the screen-recording permission. Vision and contour both read the
315+
// window's pixels, so both pay the gate. Axtree never touches the screen.
315316
func (h *handlerState) needsScreenCapturePermission(strategy string) bool {
316-
if strategy != domain.StrategyVision {
317+
if strategy != domain.StrategyVision && strategy != domain.StrategyContour {
317318
return false
318319
}
319320

internal/app/modes/hints_permission_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,25 @@ func newVisionHintsHandler(
6363
systemMock *portmocks.MockSystemPort,
6464
logger *zap.Logger,
6565
shutdown func(),
66+
) *Handler {
67+
return newCaptureHintsHandler(domain.StrategyVision, systemMock, logger, shutdown)
68+
}
69+
70+
// newCaptureHintsHandler builds a handler whose configured hint strategy is
71+
// strategy and whose screen-capture permission comes from systemMock.
72+
func newCaptureHintsHandler(
73+
strategy string,
74+
systemMock *portmocks.MockSystemPort,
75+
logger *zap.Logger,
76+
shutdown func(),
6677
) *Handler {
6778
handler := newHandlerWithState(handlerState{
6879
ctx: context.Background(),
6980
logger: logger,
7081
config: &configpkg.Config{
7182
Hints: configpkg.HintsConfig{
7283
Enabled: true,
73-
Strategy: domain.StrategyVision,
84+
Strategy: strategy,
7485
},
7586
},
7687
appState: state.NewAppState(),
@@ -121,6 +132,20 @@ func TestActivateMode_PermissionDialogDoesNotBlockOrHoldLock(t *testing.T) {
121132
}
122133
}
123134

135+
func TestActivateMode_ContourStrategyRequestsScreenCapturePermission(t *testing.T) {
136+
modal := newPermissionModal()
137+
handler := newCaptureHintsHandler(domain.StrategyContour, modal.system, zap.NewNop(), func() {})
138+
139+
// Contour reads the window's pixels just like vision does, so an
140+
// activation without consent must raise the dialog instead of letting the
141+
// capture fail under the mode handler's lock.
142+
handler.ActivateMode(modecmd.Activation{Mode: domain.ModeHints})
143+
144+
modal.awaitOpen(t)
145+
146+
modal.consent <- ports.ScreenCaptureCanceled
147+
}
148+
124149
func TestResumeHintActivationAfterPermission_DoesNotRepromptWhenCheckStillFails(t *testing.T) {
125150
requests := make(chan struct{}, 2)
126151
consent := make(chan ports.ScreenCaptureConsent)

0 commit comments

Comments
 (0)