Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 17 additions & 23 deletions src/backend/wayland/clipboard/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,29 +213,25 @@ where
}

pub(in crate::backend::wayland) fn poll(&mut self) -> ClipboardPoll<C, T> {
let Some(active) = self.active.as_ref() else {
let Some(active) = self.active.take() else {
return ClipboardPoll::Idle;
};
let active_id = active.id;
match active.receiver.try_recv() {
Err(TryRecvError::Empty) => ClipboardPoll::Pending { id: active_id },
Err(TryRecvError::Disconnected) => {
let active = self.active.take().expect("active receiver checked above");
ClipboardPoll::Disconnected {
id: active.id,
context: active.context,
}
}
Ok(ProducerMessage::Ready { id, outcome }) if id == active_id => {
let active = self.active.take().expect("active receiver checked above");
ClipboardPoll::Ready {
id,
context: active.context,
outcome,
}
Err(TryRecvError::Empty) => {
self.active = Some(active);
ClipboardPoll::Pending { id: active_id }
}
Err(TryRecvError::Disconnected) => ClipboardPoll::Disconnected {
id: active.id,
context: active.context,
},
Ok(ProducerMessage::Ready { id, outcome }) if id == active_id => ClipboardPoll::Ready {
id,
context: active.context,
outcome,
},
Ok(ProducerMessage::Failed { id, reason }) if id == active_id => {
let active = self.active.take().expect("active receiver checked above");
ClipboardPoll::ProducerFailed {
id,
context: active.context,
Expand All @@ -244,7 +240,6 @@ where
}
Ok(ProducerMessage::Ready { id, .. } | ProducerMessage::Failed { id, .. }) => {
self.healthy = false;
let active = self.active.take().expect("active receiver checked above");
ClipboardPoll::ProducerFailed {
id: active.id,
context: active.context,
Expand Down Expand Up @@ -290,12 +285,11 @@ impl<T> ClipboardProducerExitGuard<T> {
}

fn publish(mut self, message: ProducerMessage<T>) {
let result = self
let sender = self
.sender
.as_ref()
.expect("producer sender retained until publication")
.try_send(message);
self.sender.take();
.take()
.expect("clipboard producer still holds its sender until publish");
let result = sender.try_send(message);
self.terminal_published = true;
match result {
Ok(()) | Err(TrySendError::Disconnected(_)) => {}
Expand Down
9 changes: 4 additions & 5 deletions src/backend/wayland/portal_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,11 @@ impl<T> PortalTaskExitGuard<T> {
}

fn publish(mut self, message: PortalMessage<T>) {
let result = self
let sender = self
.sender
.as_ref()
.expect("portal sender retained until terminal publication")
.try_send(message);
self.sender.take();
.take()
.expect("portal task still holds its sender until publish");
let result = sender.try_send(message);
self.terminal_published = true;
match result {
Ok(()) | Err(TrySendError::Disconnected(_)) => {}
Expand Down
5 changes: 4 additions & 1 deletion src/backend/wayland/session/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,10 @@ impl PersistenceController {
shutdown_error = Some(err);
}
self.request_tx.take();
let join = self.worker.take().expect("worker presence checked").join();
let Some(worker) = self.worker.take() else {
return shutdown_error.map_or(Ok(()), Err);
};
let join = worker.join();
self.active_id = None;
if join.is_err() {
self.healthy = false;
Expand Down
7 changes: 3 additions & 4 deletions src/backend/wayland/state/core/output/transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,9 @@ impl WaylandState {
return Ok(true);
}

let pending = self
.session
.take_pending_output_transition()
.expect("pending transition checked above");
let Some(pending) = self.session.take_pending_output_transition() else {
return Ok(false);
};
if let Err(err) = self.run_output_transition(
pending.staged_options.clone(),
pending.physical_output_identity.clone(),
Expand Down
15 changes: 10 additions & 5 deletions src/backend/wayland/state/onboarding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ impl WaylandState {

let mut changed = false;
let mut hint_kind: Option<&'static str> = None;
let mut status_bar_hint_entry: Option<&str> = None;
{
let state = self.onboarding.state_mut();
if !state.first_run_completed {
Expand Down Expand Up @@ -286,7 +287,7 @@ impl WaylandState {
// status bar is the most important of the three — the board picker's
// on-screen entry point is easy to miss — so it comes first and at
// the earliest threshold among the new surfaces.
} else if status_bar_entry.is_some()
} else if let Some(entry) = status_bar_entry
&& state.sessions_seen >= 3
&& !state.hint_status_bar_shown
&& state.hint_status_bar_count < DEFERRED_HINT_REPEAT_MAX
Expand All @@ -295,6 +296,7 @@ impl WaylandState {
state.hint_status_bar_count = state.hint_status_bar_count.saturating_add(1);
changed = true;
hint_kind = Some("status_bar");
status_bar_hint_entry = Some(entry);
} else if canvas_hint_relevant
&& state.sessions_seen >= 5
&& !state.hint_canvas_popover_shown
Expand Down Expand Up @@ -329,10 +331,13 @@ impl WaylandState {
"Press {} to search actions.",
self.shortcut_label(Action::ToggleCommandPalette, "Command Palette")
),
"status_bar" => format!(
"Click the {} segment in the status bar to switch boards and pages.",
status_bar_entry.expect("status-bar hint requires a visible picker entry")
),
"status_bar" => {
let entry = status_bar_hint_entry
.expect("status_bar hint is only queued when the picker is on screen");
format!(
"Click the {entry} segment in the status bar to switch boards and pages."
)
}
"canvas_popover" => {
"Open \u{201c}Canvas\u{2026}\u{201d} from the \u{2026} overflow for boards, \
pages, zoom, and advanced controls."
Expand Down
19 changes: 10 additions & 9 deletions src/backend/wayland/state/pdf_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,16 @@ fn frame_content_bounds(frame: &Frame) -> Option<CanvasExportRect> {
found = true;
}

found.then(|| {
CanvasExportRect::new(
min_x as f64,
min_y as f64,
(max_x - min_x).max(1) as f64,
(max_y - min_y).max(1) as f64,
)
.expect("positive bounds")
})
found
.then(|| {
CanvasExportRect::new(
min_x as f64,
min_y as f64,
(max_x - min_x).max(1) as f64,
(max_y - min_y).max(1) as f64,
)
})
.flatten()
}

#[cfg(test)]
Expand Down
7 changes: 4 additions & 3 deletions src/backend/wayland/state/toolbar/inline/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,17 @@ impl WaylandState {
hit.rect.2 *= ui_scale;
hit.rect.3 *= ui_scale;
}
self.data.inline_top_rect = Some((
let top_rect = (
top_offset.0,
top_offset.1,
top_size.0 as f64,
top_size.1 as f64,
));
);
self.data.inline_top_rect = Some(top_rect);
crate::backend::wayland::toolbar::hit::clip_hit_regions_to_bounds(
&mut self.data.inline_top_hits,
0,
self.data.inline_top_rect.expect("top rect was just set"),
top_rect,
);
}
}
65 changes: 35 additions & 30 deletions src/backend/wayland/toolbar/view/top/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ fn build_top_minimized_tab(
(0.0, 0.0, width, height),
WidgetKind::IconButton {
glyph: IconFn(toolbar_icons::top_toolbar_icon_painter(
control.icon(snapshot).expect("restore icon"),
model::TopToolbarIcon::Restore,
)),
icon_size: (height * 0.75).min(18.0),
style: ButtonStyle::plain(),
Expand Down Expand Up @@ -456,7 +456,7 @@ fn build_top_micro_chip(
(0.0, 0.0, width, height),
WidgetKind::MicroChip {
glyph: IconFn(toolbar_icons::top_toolbar_icon_painter(
control.icon(snapshot).expect("micro chip tool icon"),
model::TopToolbarIcon::Tool(model::semantic_icon_for_tool(snapshot.active_tool)),
)),
ring_color: (
snapshot.color.r,
Expand Down Expand Up @@ -633,9 +633,10 @@ fn push_style_pill(
),
selected: control.active(snapshot),
},
control
.event(snapshot)
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
Some(Interaction::click(
control.click_event(snapshot),
control.tooltip(snapshot),
)),
));
x += TOP_CHIP_SIZE + gap;
}
Expand All @@ -648,17 +649,19 @@ fn push_style_pill(
color: (entry.color.r, entry.color.g, entry.color.b, entry.color.a),
selected: control.active(snapshot),
},
control
.event(snapshot)
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
Some(Interaction::click(
control.click_event(snapshot),
control.tooltip(snapshot),
)),
));
let is_last = index + 1 == swatch_count;
x += TOP_SWATCH_SIZE + if is_last { gap } else { TOP_SWATCH_GAP };
}
model::StylePillControl::ThicknessSlider
| model::StylePillControl::OpacitySlider
| model::StylePillControl::FontSizeSlider => {
let (slider_spec, value) = control.slider(snapshot).expect("slider control");
let (slider_spec, value) = control.slider_value(snapshot);
let event = control.click_event(snapshot);
let kind = match control {
model::StylePillControl::ThicknessSlider => HitKind::DragSetThickness {
min: slider_spec.min,
Expand All @@ -683,7 +686,7 @@ fn push_style_pill(
t: slider_spec.t_from_value(value),
},
Some(Interaction {
event: control.event(snapshot).expect("slider event"),
event,
kind,
tooltip: None,
}),
Expand All @@ -701,7 +704,7 @@ fn push_style_pill(
row_h,
),
WidgetKind::Label(LabelSpec::new(
control.value_text(snapshot).expect("opacity readout"),
control.required_value_text(snapshot),
TOP_LABEL_FONT_SIZE,
true,
)),
Expand All @@ -722,15 +725,16 @@ fn push_style_pill(
),
WidgetKind::TextButton {
label: LabelSpec::new(
control.value_text(snapshot).expect("numeral text"),
control.required_value_text(snapshot),
TOP_LABEL_FONT_SIZE,
true,
),
style: ButtonStyle::plain(),
},
control
.event(snapshot)
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
Some(Interaction::click(
control.click_event(snapshot),
control.tooltip(snapshot),
)),
));
x += ToolbarLayoutSpec::TOP_STYLE_VALUE_W + gap;
}
Expand All @@ -748,9 +752,10 @@ fn push_style_pill(
checked: control.active(snapshot),
label: LabelSpec::new(control.label(snapshot), MINI_LABEL_FONT_SIZE, false),
},
control
.event(snapshot)
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
Some(Interaction::click(
control.click_event(snapshot),
control.tooltip(snapshot),
)),
));
x += w + gap;
}
Expand All @@ -767,9 +772,10 @@ fn push_style_pill(
label: LabelSpec::new(control.label(snapshot), TOP_LABEL_FONT_SIZE, true),
style: ButtonStyle::plain(),
},
control
.event(snapshot)
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
Some(Interaction::click(
control.click_event(snapshot),
control.tooltip(snapshot),
)),
));
x += ToolbarLayoutSpec::TOP_STYLE_RESET_W + gap;
}
Expand All @@ -785,7 +791,7 @@ fn push_style_pill(
),
WidgetKind::TextButton {
label: LabelSpec::new(
control.value_text(snapshot).unwrap_or_default(),
control.required_value_text(snapshot),
TOP_LABEL_FONT_SIZE,
true,
),
Expand All @@ -795,16 +801,15 @@ fn push_style_pill(
ButtonStyle::disabled()
},
},
(enabled)
.then(|| control.event(snapshot))
.flatten()
.map(|event| Interaction::click(event, control.tooltip(snapshot))),
(enabled).then(|| {
Interaction::click(control.click_event(snapshot), control.tooltip(snapshot))
}),
));
x += ToolbarLayoutSpec::TOP_STYLE_SEL_VALUE_W + gap;
}
model::StylePillControl::SelectionStepper(_) => {
let enabled = control.enabled(snapshot);
let steps = control.steps(snapshot).expect("stepper halves");
let steps = control.required_steps(snapshot);
let step_w = ToolbarLayoutSpec::TOP_STYLE_STEP_W;
let value_w = ToolbarLayoutSpec::TOP_STYLE_SEL_VALUE_W;
let step_style = if enabled {
Expand All @@ -827,7 +832,7 @@ fn push_style_pill(
format!("{id}.value"),
(x + step_w, center(row_h), value_w, row_h),
WidgetKind::Label(LabelSpec::new(
control.value_text(snapshot).unwrap_or_default(),
control.required_value_text(snapshot),
TOP_LABEL_FONT_SIZE,
true,
)),
Expand All @@ -847,7 +852,7 @@ fn push_style_pill(
}
model::StylePillControl::FontFamilySegment
| model::StylePillControl::EraserModeSegment => {
let segments = control.segments(snapshot).expect("segment halves");
let segments = control.required_segments(snapshot);
// A clear gap before the segment so Sans│Mono never crowd the
// preceding numeral ("72pt") to its left (M7-C3).
x += ToolbarLayoutSpec::TOP_STYLE_SEGMENT_LEAD;
Expand Down Expand Up @@ -1075,7 +1080,7 @@ fn control_button_node_with_tooltip(
};
WidgetKind::IconButton {
glyph: IconFn(toolbar_icons::top_toolbar_icon_painter(
control.icon(snapshot).expect("button icon"),
control.glyph(snapshot),
)),
icon_size,
style,
Expand Down
9 changes: 4 additions & 5 deletions src/capture/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,10 @@ impl CaptureWorkerExitGuard {
}

fn publish(&self, completion: CaptureCompletion) -> bool {
let result = self
.completion_tx
.as_ref()
.expect("capture completion sender retained by worker")
.try_send(completion);
let Some(tx) = self.completion_tx.as_ref() else {
return false;
};
let result = tx.try_send(completion);
match result {
Ok(()) => {
(self.notifier)();
Expand Down
Loading
Loading