update method
Updates overlay state and reports whether the message was consumed.
Implementation
({DebugOverlayModel model, Cmd? cmd, bool consumed}) update(Msg msg) {
switch (msg) {
case RenderMetricsMsg(:final metrics):
return (model: copyWith(metrics: metrics), cmd: null, consumed: false);
case WindowSizeMsg(:final width, :final height):
final next = copyWith(terminalWidth: width, terminalHeight: height);
// Clamp stored position if set.
if (next.panelX != null || next.panelY != null) {
final (:x, :y, :w, :h) = next._panelRect();
final clampedX = x.clamp(0, (width - w).clamp(0, width));
final clampedY = y.clamp(0, (height - h).clamp(0, height));
return (
model: next.copyWith(panelX: clampedX, panelY: clampedY),
cmd: null,
consumed: false,
);
}
return (model: next, cmd: null, consumed: false);
case MouseMsg(:final x, :final y, :final button, :final action):
if (!enabled) return (model: this, cmd: null, consumed: false);
// When dragging, consume ALL mouse events to prevent selection bleed.
if (dragging) {
if (action == MouseAction.release) {
return (
model: copyWith(dragging: false, pointerCaptured: false),
cmd: null,
consumed: true,
);
}
if (action == MouseAction.motion) {
final bounds = panelBounds;
final maxX = (terminalWidth - bounds.w).clamp(0, terminalWidth);
final maxY = (terminalHeight - bounds.h).clamp(0, terminalHeight);
final nx = (x - dragOffsetX).clamp(0, maxX);
final ny = (y - dragOffsetY).clamp(0, maxY);
return (
model: copyWith(panelX: nx, panelY: ny),
cmd: null,
consumed: true,
);
}
return (model: this, cmd: null, consumed: true);
}
if (pointerCaptured) {
return (
model: action == MouseAction.release
? copyWith(pointerCaptured: false)
: this,
cmd: null,
consumed: true,
);
}
// Tabs and the title bar have distinct pointer actions. Neither takes
// keyboard focus from the application.
if (action == MouseAction.press && button == MouseButton.left) {
final tab = _tabAt(x, y);
if (tab != null) {
return (
model: selectMode(tab).copyWith(pointerCaptured: true),
cmd: null,
consumed: true,
);
}
final bounds = panelBounds;
if (containsPoint(x, y) && y == bounds.y) {
return (
model: copyWith(
panelX: bounds.x,
panelY: bounds.y,
dragging: true,
pointerCaptured: true,
dragOffsetX: x - bounds.x,
dragOffsetY: y - bounds.y,
),
cmd: null,
consumed: true,
);
}
}
// Do not activate application buttons hidden behind the opaque panel.
if (action == MouseAction.press &&
button == MouseButton.left &&
containsPoint(x, y)) {
return (
model: copyWith(pointerCaptured: true),
cmd: null,
consumed: true,
);
}
return (model: this, cmd: null, consumed: false);
default:
return (model: this, cmd: null, consumed: false);
}
}