pub struct BrowserView { /* private fields */ }Expand description
One browser, plus everyone watching it.
Implementations§
Source§impl BrowserView
impl BrowserView
Sourcepub async fn note_disconnect(
self: &Arc<Self>,
client_id: &str,
was_watching: bool,
) -> bool
pub async fn note_disconnect( self: &Arc<Self>, client_id: &str, was_watching: bool, ) -> bool
The connection holding control dropped. Starts the stated grace period, after which control reverts to the agent — an agent is never parked forever behind a controller who is not coming back.
Returns whether this connection actually held control, i.e. whether
this call took ownership of the disconnect clock. The caller uses that
to keep Self::note_watcher_disconnect off a view whose holder just
left: both arm a grace timer, with DIFFERENT require_unwatched
semantics (see Self::spawn_grace_timer_inner), and each bumps
control.generation, retiring the other’s timer. Exactly one of the
two owns any given disconnect.
was_watching is why collapsing the two calls does not silently pick
the holder semantics for everybody. The ordinary drawer is the holder
AND the only subscriber, and for it the WATCHER semantics are the
load-bearing ones: a drawer that comes back inside the window is
precisely what says the person’s sign-in window is still theirs. So the
single surviving timer takes require_unwatched from whether this
connection was the last drawer watching — see the arming site below.
Sourcepub async fn note_run_ended(self: &Arc<Self>)
pub async fn note_run_ended(self: &Arc<Self>)
The run that owned this browser ended: no ceremony, the user’s browser again.
Deliberately a method on the VIEW, not a registry lookup by key. The
run-end signal is asynchronous (see mcp_assistant::BrowserViewGuard),
so re-resolving the key at fire time can land on whatever view holds it
by then — clearing the strip and re-opening input to everyone on a
SUCCESSOR run’s browser while its agent is actively driving. Holding
the Arc makes the signal act on the identity it was created for, and
a late arrival for a replaced view is then simply inert.
Sourcepub async fn note_watcher_disconnect(self: &Arc<Self>)
pub async fn note_watcher_disconnect(self: &Arc<Self>)
A connection that was WATCHING this view went away.
Distinct from Self::note_disconnect, which is about the control
HOLDER — and the distinction is the whole point. The ordinary sign-in
flow never involves Take control (the strip IS the affordance, and
require_control admits input while a sign-in is pending so the person
can type without pressing anything), so their window has no holder for
note_disconnect to match. Since round 8 that window OUTLIVES the run:
an agent-side ending may not clear a strip somebody is standing at. So
this is the only signal left that says they are not coming back, and
without it a person who closed the laptop mid-sign-in would leave the
blackout latched for the daemon’s life — wedging every later run’s
browse call behind it.
Armed only when nobody is watching any more: another connection still subscribed means the drawer is still there. Re-checked at expiry too.
Never called for a connection that held control: the registry keys this
off note_disconnect’s return value, because the ordinary drawer is
BOTH holder and watcher and the two arm grace timers with different
semantics. The holder.is_some() guard below covers the other shape —
someone ELSE is driving — and cannot see this connection’s own holder
record, which note_disconnect clears before returning.
Auto Trait Implementations§
impl !Freeze for BrowserView
impl !RefUnwindSafe for BrowserView
impl !UnwindSafe for BrowserView
impl Send for BrowserView
impl Sync for BrowserView
impl Unpin for BrowserView
impl UnsafeUnpin for BrowserView
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more