merge: upstream/libcosmic a l'etat pinne par epoch-1.9.0 (08a09e3df)

# Conflicts:
#	Cargo.toml
#	i18n/th/libcosmic.ftl
#	iced
#	src/surface/action.rs
#	src/surface/mod.rs
This commit is contained in:
Lionel DARNIS 2026-09-24 20:45:53 +02:00
commit 97f42e565a
51 changed files with 1212 additions and 611 deletions

View file

@ -1048,6 +1048,8 @@ where
.selection(&state.tracked_value)
.map(|(start, end)| state.tracked_value.select(start, end).to_string());
let has_selection = selected_text.is_some();
let has_text = !state.tracked_value.is_empty();
let clipboard_has_text = state.clipboard_has_text;
let click_position = state.context_menu_position.unwrap();
let menu_bar_state = state.menu_bar_state.clone();
let pending_action = state.pending_action.clone();
@ -1057,6 +1059,8 @@ where
selected_text,
true,
has_selection,
has_text,
clipboard_has_text,
&menu_bar_state,
&pending_action,
renderer,
@ -1611,6 +1615,7 @@ pub fn update<'a, Message: Clone + 'static>(
state.focus();
}
state.context_menu_position = Some(pos);
state.clipboard_has_text = iced_core::widget::text::clipboard_has_text(clipboard);
shell.capture_event();
return;
}
@ -2876,14 +2881,17 @@ pub fn draw<'a, Message>(
effective_alignment(state.value.raw()),
);
if cursors.is_empty() {
renderer.with_translation(Vector::ZERO, |_| {});
} else {
renderer.with_translation(Vector::new(alignment_offset - offset, 0.0), |renderer| {
let shift = Vector::new(alignment_offset - offset, 0.0);
let fill_cursors = |renderer: &mut crate::Renderer| {
renderer.with_translation(shift, |renderer| {
for (quad, color) in &cursors {
renderer.fill_quad(*quad, *color);
}
});
};
if !is_selecting {
fill_cursors(renderer);
}
let bounds = Rectangle {
@ -2898,27 +2906,39 @@ pub fn draw<'a, Message>(
text_color
};
renderer.fill_text(
Text {
content: if text.is_empty() {
placeholder.to_string()
} else {
text.clone()
},
font,
bounds: bounds.size(),
size: iced::Pixels(size),
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
line_height: text::LineHeight::default(),
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::None,
ellipsize: text::Ellipsize::None,
let text = Text {
content: if text.is_empty() {
placeholder.to_string()
} else {
text.clone()
},
bounds.position(),
color,
text_bounds,
);
font,
bounds: bounds.size(),
size: iced::Pixels(size),
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
line_height: text::LineHeight::default(),
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::None,
ellipsize: text::Ellipsize::None,
};
renderer.fill_text(text.clone(), bounds.position(), color, text_bounds);
// Redraw the same text in the selected color, clipped to the selection quads,
// so glyph shaping and positioning stay identical to the unselected pass.
if is_selecting {
fill_cursors(renderer);
for (quad, _) in &cursors {
renderer.with_layer(quad.bounds + shift, |renderer| {
renderer.fill_text(
text.clone(),
bounds.position(),
appearance.selected_text_color,
text_bounds,
);
});
}
}
};
// FIXME: we always must clip with a layer because of what appears to be a tiny-skia text clipping issue.
@ -3062,6 +3082,7 @@ pub struct State {
keyboard_modifiers: keyboard::Modifiers,
scroll_offset: f32,
context_menu_position: Option<iced_core::Point>,
clipboard_has_text: bool,
pub(crate) menu_bar_state: crate::widget::menu::MenuBarState,
pub(crate) pending_action: crate::widget::text_context_menu::PendingAction,
}
@ -3157,6 +3178,7 @@ impl State {
scroll_offset: 0.0,
dirty: false,
context_menu_position: None,
clipboard_has_text: false,
menu_bar_state: crate::widget::menu::MenuBarState::default(),
pending_action: crate::widget::text_context_menu::pending_action(),
}
@ -3520,6 +3542,14 @@ impl<Message: Clone + 'static> iced_core::widget::text::HasSelectableText
true
}
fn has_text(&self, tree: &WidgetTree) -> bool {
!tree.state.downcast_ref::<State>().tracked_value.is_empty()
}
fn clipboard_has_text(&self, tree: &WidgetTree) -> bool {
tree.state.downcast_ref::<State>().clipboard_has_text
}
fn is_focused(&self, tree: &WidgetTree) -> bool {
tree.state.downcast_ref::<State>().is_focused()
}