This commit is contained in:
Jeremy Soller 2024-04-26 10:27:52 -06:00
commit 4cec08875f
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
8 changed files with 183 additions and 217 deletions

View file

@ -292,11 +292,11 @@ impl Config {
let color_schemes = self.color_schemes(color_scheme_kind); let color_schemes = self.color_schemes(color_scheme_kind);
let mut color_scheme_names = let mut color_scheme_names =
Vec::<(String, ColorSchemeId)>::with_capacity(color_schemes.len()); Vec::<(String, ColorSchemeId)>::with_capacity(color_schemes.len());
for (color_scheme_id, color_scheme) in color_schemes.iter() { for (color_scheme_id, color_scheme) in color_schemes {
let mut name = color_scheme.name.clone(); let mut name = color_scheme.name.clone();
let mut copies = 1; let mut copies = 1;
while color_scheme_names.iter().find(|x| x.0 == name).is_some() { while color_scheme_names.iter().any(|x| x.0 == name) {
copies += 1; copies += 1;
name = format!("{} ({})", color_scheme.name, copies); name = format!("{} ({})", color_scheme.name, copies);
} }
@ -322,17 +322,17 @@ impl Config {
} }
pub fn opacity_ratio(&self) -> f32 { pub fn opacity_ratio(&self) -> f32 {
(self.opacity as f32) / 100.0 f32::from(self.opacity) / 100.0
} }
// Get a sorted and adjusted for duplicates list of profile names and ids // Get a sorted and adjusted for duplicates list of profile names and ids
pub fn profile_names(&self) -> Vec<(String, ProfileId)> { pub fn profile_names(&self) -> Vec<(String, ProfileId)> {
let mut profile_names = Vec::<(String, ProfileId)>::with_capacity(self.profiles.len()); let mut profile_names = Vec::<(String, ProfileId)>::with_capacity(self.profiles.len());
for (profile_id, profile) in self.profiles.iter() { for (profile_id, profile) in &self.profiles {
let mut name = profile.name.clone(); let mut name = profile.name.clone();
let mut copies = 1; let mut copies = 1;
while profile_names.iter().find(|x| x.0 == name).is_some() { while profile_names.iter().any(|x| x.0 == name) {
copies += 1; copies += 1;
name = format!("{} ({})", profile.name, copies); name = format!("{} ({})", profile.name, copies);
} }

View file

@ -43,6 +43,6 @@ pub fn localize() {
let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages(); let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages();
if let Err(error) = localizer.select(&requested_languages) { if let Err(error) = localizer.select(&requested_languages) {
eprintln!("Error while loading language for App List {}", error); eprintln!("Error while loading language for App List {error}");
} }
} }

View file

@ -76,7 +76,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(fork::Fork::Child) => (), Ok(fork::Fork::Child) => (),
Ok(fork::Fork::Parent(_child_pid)) => process::exit(0), Ok(fork::Fork::Parent(_child_pid)) => process::exit(0),
Err(err) => { Err(err) => {
eprintln!("failed to daemonize: {:?}", err); eprintln!("failed to daemonize: {err:?}");
process::exit(1); process::exit(1);
} }
} }
@ -209,45 +209,45 @@ impl MenuAction for Action {
fn message(&self, entity_opt: Option<segmented_button::Entity>) -> Message { fn message(&self, entity_opt: Option<segmented_button::Entity>) -> Message {
match self { match self {
Action::About => Message::ToggleContextPage(ContextPage::About), Self::About => Message::ToggleContextPage(ContextPage::About),
Action::ColorSchemes(color_scheme_kind) => { Self::ColorSchemes(color_scheme_kind) => {
Message::ToggleContextPage(ContextPage::ColorSchemes(*color_scheme_kind)) Message::ToggleContextPage(ContextPage::ColorSchemes(*color_scheme_kind))
} }
Action::Copy => Message::Copy(entity_opt), Self::Copy => Message::Copy(entity_opt),
Action::CopyPrimary => Message::CopyPrimary(entity_opt), Self::CopyPrimary => Message::CopyPrimary(entity_opt),
Action::Find => Message::Find(true), Self::Find => Message::Find(true),
Action::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down), Self::PaneFocusDown => Message::PaneFocusAdjacent(pane_grid::Direction::Down),
Action::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left), Self::PaneFocusLeft => Message::PaneFocusAdjacent(pane_grid::Direction::Left),
Action::PaneFocusRight => Message::PaneFocusAdjacent(pane_grid::Direction::Right), Self::PaneFocusRight => Message::PaneFocusAdjacent(pane_grid::Direction::Right),
Action::PaneFocusUp => Message::PaneFocusAdjacent(pane_grid::Direction::Up), Self::PaneFocusUp => Message::PaneFocusAdjacent(pane_grid::Direction::Up),
Action::PaneSplitHorizontal => Message::PaneSplit(pane_grid::Axis::Horizontal), Self::PaneSplitHorizontal => Message::PaneSplit(pane_grid::Axis::Horizontal),
Action::PaneSplitVertical => Message::PaneSplit(pane_grid::Axis::Vertical), Self::PaneSplitVertical => Message::PaneSplit(pane_grid::Axis::Vertical),
Action::PaneToggleMaximized => Message::PaneToggleMaximized, Self::PaneToggleMaximized => Message::PaneToggleMaximized,
Action::Paste => Message::Paste(entity_opt), Self::Paste => Message::Paste(entity_opt),
Action::PastePrimary => Message::PastePrimary(entity_opt), Self::PastePrimary => Message::PastePrimary(entity_opt),
Action::ProfileOpen(profile_id) => Message::ProfileOpen(*profile_id), Self::ProfileOpen(profile_id) => Message::ProfileOpen(*profile_id),
Action::Profiles => Message::ToggleContextPage(ContextPage::Profiles), Self::Profiles => Message::ToggleContextPage(ContextPage::Profiles),
Action::SelectAll => Message::SelectAll(entity_opt), Self::SelectAll => Message::SelectAll(entity_opt),
Action::Settings => Message::ToggleContextPage(ContextPage::Settings), Self::Settings => Message::ToggleContextPage(ContextPage::Settings),
Action::ShowHeaderBar(show_headerbar) => Message::ShowHeaderBar(*show_headerbar), Self::ShowHeaderBar(show_headerbar) => Message::ShowHeaderBar(*show_headerbar),
Action::TabActivate0 => Message::TabActivateJump(0), Self::TabActivate0 => Message::TabActivateJump(0),
Action::TabActivate1 => Message::TabActivateJump(1), Self::TabActivate1 => Message::TabActivateJump(1),
Action::TabActivate2 => Message::TabActivateJump(2), Self::TabActivate2 => Message::TabActivateJump(2),
Action::TabActivate3 => Message::TabActivateJump(3), Self::TabActivate3 => Message::TabActivateJump(3),
Action::TabActivate4 => Message::TabActivateJump(4), Self::TabActivate4 => Message::TabActivateJump(4),
Action::TabActivate5 => Message::TabActivateJump(5), Self::TabActivate5 => Message::TabActivateJump(5),
Action::TabActivate6 => Message::TabActivateJump(6), Self::TabActivate6 => Message::TabActivateJump(6),
Action::TabActivate7 => Message::TabActivateJump(7), Self::TabActivate7 => Message::TabActivateJump(7),
Action::TabActivate8 => Message::TabActivateJump(8), Self::TabActivate8 => Message::TabActivateJump(8),
Action::TabClose => Message::TabClose(entity_opt), Self::TabClose => Message::TabClose(entity_opt),
Action::TabNew => Message::TabNew, Self::TabNew => Message::TabNew,
Action::TabNext => Message::TabNext, Self::TabNext => Message::TabNext,
Action::TabPrev => Message::TabPrev, Self::TabPrev => Message::TabPrev,
Action::WindowClose => Message::WindowClose, Self::WindowClose => Message::WindowClose,
Action::WindowNew => Message::WindowNew, Self::WindowNew => Message::WindowNew,
Action::ZoomIn => Message::ZoomIn, Self::ZoomIn => Message::ZoomIn,
Action::ZoomOut => Message::ZoomOut, Self::ZoomOut => Message::ZoomOut,
Action::ZoomReset => Message::ZoomReset, Self::ZoomReset => Message::ZoomReset,
} }
} }
} }
@ -460,9 +460,9 @@ impl App {
{ {
let color = Color::from(theme.cosmic().background.base); let color = Color::from(theme.cosmic().background.base);
let bytes = color.into_rgba8(); let bytes = color.into_rgba8();
let data = (bytes[2] as u32) let data = u32::from(bytes[2])
| ((bytes[1] as u32) << 8) | (u32::from(bytes[1]) << 8)
| ((bytes[0] as u32) << 16) | (u32::from(bytes[0]) << 16)
| 0xFF000000; | 0xFF000000;
terminal::WINDOW_BG_COLOR.store(data, Ordering::SeqCst); terminal::WINDOW_BG_COLOR.store(data, Ordering::SeqCst);
} }
@ -499,17 +499,14 @@ impl App {
fn save_color_schemes(&mut self, color_scheme_kind: ColorSchemeKind) -> Command<Message> { fn save_color_schemes(&mut self, color_scheme_kind: ColorSchemeKind) -> Command<Message> {
// Optimized for just saving color_schemes // Optimized for just saving color_schemes
if let Some(ref config_handler) = self.config_handler { if let Some(ref config_handler) = self.config_handler {
match config_handler.set( if let Err(err) = config_handler.set(
match color_scheme_kind { match color_scheme_kind {
ColorSchemeKind::Dark => "color_schemes_dark", ColorSchemeKind::Dark => "color_schemes_dark",
ColorSchemeKind::Light => "color_schemes_light", ColorSchemeKind::Light => "color_schemes_light",
}, },
&self.config.color_schemes(color_scheme_kind), self.config.color_schemes(color_scheme_kind),
) { ) {
Ok(()) => {} log::error!("failed to save config: {}", err);
Err(err) => {
log::error!("failed to save config: {}", err);
}
} }
} }
self.update_color_schemes(); self.update_color_schemes();
@ -664,7 +661,7 @@ impl App {
hash = short_hash.as_str(), hash = short_hash.as_str(),
date = date date = date
)) ))
.on_press(Message::LaunchUrl(format!("{}/commits/{}", repository, hash))) .on_press(Message::LaunchUrl(format!("{repository}/commits/{hash}")))
.padding(0) .padding(0)
.into(), .into(),
]) ])
@ -754,7 +751,7 @@ impl App {
.into(), .into(),
); );
for error in self.color_scheme_errors.iter() { for error in &self.color_scheme_errors {
sections.push( sections.push(
widget::row::with_children(vec![ widget::row::with_children(vec![
icon_cache_get("dialog-error-symbolic", 16) icon_cache_get("dialog-error-symbolic", 16)
@ -797,9 +794,8 @@ impl App {
if !self.config.profiles.is_empty() { if !self.config.profiles.is_empty() {
let mut profiles_section = widget::settings::view_section(""); let mut profiles_section = widget::settings::view_section("");
for (profile_name, profile_id) in self.config.profile_names() { for (profile_name, profile_id) in self.config.profile_names() {
let profile = match self.config.profiles.get(&profile_id) { let Some(profile) = self.config.profiles.get(&profile_id) else {
Some(some) => some, continue;
None => continue,
}; };
let expanded = self.profile_expanded == Some(profile_id); let expanded = self.profile_expanded == Some(profile_id);
@ -946,8 +942,8 @@ impl App {
let padding = Padding { let padding = Padding {
top: 0.0, top: 0.0,
bottom: 0.0, bottom: 0.0,
left: space_s as f32, left: space_s.into(),
right: space_s as f32, right: space_s.into(),
}; };
profiles_section = profiles_section =
profiles_section.add(widget::container(expanded_section).padding(padding)) profiles_section.add(widget::container(expanded_section).padding(padding))
@ -1193,7 +1189,6 @@ impl App {
.and_then(|profile_id| self.config.profiles.get(&profile_id)) .and_then(|profile_id| self.config.profiles.get(&profile_id))
{ {
Some(profile) => { Some(profile) => {
if !profile.tab_title.is_empty() {}
let mut shell = None; let mut shell = None;
if let Some(mut args) = shlex::split(&profile.command) { if let Some(mut args) = shlex::split(&profile.command) {
if !args.is_empty() { if !args.is_empty() {
@ -1210,10 +1205,10 @@ impl App {
hold: profile.hold, hold: profile.hold,
env: HashMap::new(), env: HashMap::new(),
}; };
let tab_title_override = if !profile.tab_title.is_empty() { let tab_title_override = if profile.tab_title.is_empty() {
Some(profile.tab_title.clone())
} else {
None None
} else {
Some(profile.tab_title.clone())
}; };
(options, tab_title_override) (options, tab_title_override)
} }
@ -1268,7 +1263,7 @@ impl App {
log::warn!("tried to create new tab before having event channel"); log::warn!("tried to create new tab before having event channel");
} }
} }
return self.update_title(Some(pane)); self.update_title(Some(pane))
} }
} }
@ -1349,7 +1344,7 @@ impl Application for App {
let mut font_size_names = Vec::new(); let mut font_size_names = Vec::new();
let mut font_sizes = Vec::new(); let mut font_sizes = Vec::new();
for font_size in 4..=32 { for font_size in 4..=32 {
font_size_names.push(format!("{}px", font_size)); font_size_names.push(format!("{font_size}px"));
font_sizes.push(font_size); font_sizes.push(font_size);
} }
@ -1400,7 +1395,7 @@ impl Application for App {
let mut terminal_ids = HashMap::new(); let mut terminal_ids = HashMap::new();
terminal_ids.insert(pane_model.focus, widget::Id::unique()); terminal_ids.insert(pane_model.focus, widget::Id::unique());
let mut app = App { let mut app = Self {
core, core,
pane_model, pane_model,
config_handler: flags.config_handler, config_handler: flags.config_handler,
@ -1464,10 +1459,10 @@ impl Application for App {
} }
fn on_context_drawer(&mut self) -> Command<Message> { fn on_context_drawer(&mut self) -> Command<Message> {
if !self.core.window.show_context { if self.core.window.show_context {
self.update_focus()
} else {
Command::none() Command::none()
} else {
self.update_focus()
} }
} }
@ -1478,15 +1473,10 @@ impl Application for App {
($name: ident, $value: expr) => { ($name: ident, $value: expr) => {
match &self.config_handler { match &self.config_handler {
Some(config_handler) => { Some(config_handler) => {
match paste::paste! { self.config.[<set_ $name>](config_handler, $value) } { if let Err(err) =
Ok(_) => {} paste::paste! { self.config.[<set_ $name>](config_handler, $value) }
Err(err) => { {
log::warn!( log::warn!("failed to save config {:?}: {}", stringify!($name), err);
"failed to save config {:?}: {}",
stringify!($name),
err
);
}
} }
} }
None => { None => {
@ -1532,7 +1522,7 @@ impl Application for App {
move |result| { move |result| {
Message::ColorSchemeExportResult( Message::ColorSchemeExportResult(
color_scheme_kind, color_scheme_kind,
color_scheme_id.clone(), color_scheme_id,
result, result,
) )
}, },
@ -1556,9 +1546,8 @@ impl Application for App {
&color_scheme, &color_scheme,
ron::ser::PrettyConfig::new(), ron::ser::PrettyConfig::new(),
) { ) {
Ok(ron) => match fs::write(path, &ron) { Ok(ron) => {
Ok(()) => {} if let Err(err) = fs::write(path, ron) {
Err(err) => {
log::error!( log::error!(
"failed to export {:?} to {:?}: {}", "failed to export {:?} to {:?}: {}",
color_scheme_id, color_scheme_id,
@ -1566,7 +1555,7 @@ impl Application for App {
err err
); );
} }
}, }
Err(err) => { Err(err) => {
log::error!( log::error!(
"failed to serialize color scheme {:?}: {}", "failed to serialize color scheme {:?}: {}",
@ -1600,12 +1589,12 @@ impl Application for App {
self.dialog_opt = None; self.dialog_opt = None;
if let DialogResult::Open(paths) = result { if let DialogResult::Open(paths) = result {
self.color_scheme_errors.clear(); self.color_scheme_errors.clear();
for path in paths.iter() { for path in &paths {
let mut file = match fs::File::open(path) { let mut file = match fs::File::open(path) {
Ok(ok) => ok, Ok(ok) => ok,
Err(err) => { Err(err) => {
self.color_scheme_errors self.color_scheme_errors
.push(format!("Failed to open {:?}: {}", path, err)); .push(format!("Failed to open {path:?}: {err}"));
continue; continue;
} }
}; };
@ -1624,7 +1613,7 @@ impl Application for App {
} }
Err(err) => { Err(err) => {
self.color_scheme_errors self.color_scheme_errors
.push(format!("Failed to parse {:?}: {}", path, err)); .push(format!("Failed to parse {path:?}: {err}"));
} }
} }
} }
@ -1866,18 +1855,17 @@ impl Application for App {
config_set!(focus_follow_mouse, focus_follow_mouse); config_set!(focus_follow_mouse, focus_follow_mouse);
} }
Message::Key(modifiers, key) => { Message::Key(modifiers, key) => {
for (key_bind, action) in self.key_binds.iter() { for (key_bind, action) in &self.key_binds {
if key_bind.matches(modifiers, &key) { if key_bind.matches(modifiers, &key) {
return self.update(action.message(None)); return self.update(action.message(None));
} }
} }
} }
Message::LaunchUrl(url) => match open::that_detached(&url) { Message::LaunchUrl(url) => {
Ok(()) => {} if let Err(err) = open::that_detached(&url) {
Err(err) => {
log::warn!("failed to open {:?}: {}", url, err); log::warn!("failed to open {:?}: {}", url, err);
} }
}, }
Message::Modifiers(modifiers) => { Message::Modifiers(modifiers) => {
self.modifiers = modifiers; self.modifiers = modifiers;
} }
@ -2367,31 +2355,28 @@ impl Application for App {
} }
// Extra work to do to prepare context pages // Extra work to do to prepare context pages
match self.context_page { if let ContextPage::ColorSchemes(color_scheme_kind) = self.context_page {
ContextPage::ColorSchemes(color_scheme_kind) => { self.color_scheme_errors.clear();
self.color_scheme_errors.clear(); self.color_scheme_expanded = None;
self.color_scheme_expanded = None; self.color_scheme_renaming = None;
self.color_scheme_renaming = None; self.color_scheme_tab_model = widget::segmented_button::Model::default();
self.color_scheme_tab_model = widget::segmented_button::Model::default(); let dark_entity = self
let dark_entity = self .color_scheme_tab_model
.color_scheme_tab_model .insert()
.insert() .text(fl!("dark"))
.text(fl!("dark")) .data(ColorSchemeKind::Dark)
.data(ColorSchemeKind::Dark) .id();
.id(); let light_entity = self
let light_entity = self .color_scheme_tab_model
.color_scheme_tab_model .insert()
.insert() .text(fl!("light"))
.text(fl!("light")) .data(ColorSchemeKind::Light)
.data(ColorSchemeKind::Light) .id();
.id(); self.color_scheme_tab_model
self.color_scheme_tab_model .activate(match color_scheme_kind {
.activate(match color_scheme_kind { ColorSchemeKind::Dark => dark_entity,
ColorSchemeKind::Dark => dark_entity, ColorSchemeKind::Light => light_entity,
ColorSchemeKind::Light => light_entity, });
});
}
_ => {}
} }
self.set_context_title(context_page.title()); self.set_context_title(context_page.title());
@ -2491,41 +2476,33 @@ impl Application for App {
.get(&pane) .get(&pane)
.cloned() .cloned()
.unwrap_or_else(widget::Id::unique); .unwrap_or_else(widget::Id::unique);
match tab_model.data::<Mutex<Terminal>>(entity) { if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
Some(terminal) => { let mut terminal_box = terminal_box(terminal)
let mut terminal_box = terminal_box(terminal) .id(terminal_id)
.id(terminal_id) .on_context_menu(move |position_opt| {
.on_context_menu(move |position_opt| { Message::TabContextMenu(pane, position_opt)
Message::TabContextMenu(pane, position_opt) })
}) .on_middle_click(move || Message::MiddleClick(pane, Some(entity_middle_click)))
.on_middle_click(move || { .opacity(self.config.opacity_ratio())
Message::MiddleClick(pane, Some(entity_middle_click)) .padding(space_xxs);
})
.opacity(self.config.opacity_ratio())
.padding(space_xxs);
if self.config.focus_follow_mouse { if self.config.focus_follow_mouse {
terminal_box = terminal_box = terminal_box.on_mouse_enter(move || Message::MouseEnter(pane));
terminal_box.on_mouse_enter(move || Message::MouseEnter(pane));
}
let context_menu = {
let terminal = terminal.lock().unwrap();
terminal.context_menu
};
let tab_element: Element<'_, Message> = match context_menu {
Some(point) => widget::popover(terminal_box.context_menu(point))
.popup(menu::context_menu(&self.config, &self.key_binds, entity))
.position(widget::popover::Position::Point(point))
.into(),
None => terminal_box.into(),
};
tab_column = tab_column.push(tab_element);
}
None => {
//TODO
} }
let context_menu = {
let terminal = terminal.lock().unwrap();
terminal.context_menu
};
let tab_element: Element<'_, Message> = match context_menu {
Some(point) => widget::popover(terminal_box.context_menu(point))
.popup(menu::context_menu(&self.config, &self.key_binds, entity))
.position(widget::popover::Position::Point(point))
.into(),
None => terminal_box.into(),
};
tab_column = tab_column.push(tab_element);
} }
//Only draw find in the currently focused pane //Only draw find in the currently focused pane
@ -2583,6 +2560,8 @@ impl Application for App {
tab_column = tab_column tab_column = tab_column
.push(widget::layer_container(find_widget).layer(cosmic_theme::Layer::Primary)); .push(widget::layer_container(find_widget).layer(cosmic_theme::Layer::Primary));
} else {
// TODO
} }
pane_grid::Content::new(tab_column) pane_grid::Content::new(tab_column)

View file

@ -26,7 +26,7 @@ pub fn context_menu<'a>(
entity: segmented_button::Entity, entity: segmented_button::Entity,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
let find_key = |action: &Action| -> String { let find_key = |action: &Action| -> String {
for (key_bind, key_action) in key_binds.iter() { for (key_bind, key_action) in key_binds {
if action == key_action { if action == key_action {
return key_bind.to_string(); return key_bind.to_string();
} }

View file

@ -15,7 +15,7 @@ pub struct MouseReporter {
} }
impl MouseReporter { impl MouseReporter {
fn button_number(&self, button: Button) -> Option<u8> { fn button_number(button: Button) -> Option<u8> {
match button { match button {
Button::Left => Some(0), Button::Left => Some(0),
Button::Middle => Some(1), Button::Middle => Some(1),
@ -36,10 +36,10 @@ impl MouseReporter {
) -> Option<Vec<u8>> { ) -> Option<Vec<u8>> {
//Buttons are handle slightly different between normal and sgr //Buttons are handle slightly different between normal and sgr
//for normal/utf8 the button release is always reported as button 3 //for normal/utf8 the button release is always reported as button 3
let Some(mut button) = (match event { let mut button = (match event {
Event::Mouse(MouseEvent::ButtonPressed(b)) => { Event::Mouse(MouseEvent::ButtonPressed(b)) => {
self.button = Some(b); self.button = Some(b);
self.button_number(b) Self::button_number(b)
} }
Event::Mouse(MouseEvent::ButtonReleased(_b)) => { Event::Mouse(MouseEvent::ButtonReleased(_b)) => {
self.button = None; self.button = None;
@ -59,14 +59,10 @@ impl MouseReporter {
//character, Cb). //character, Cb).
//For example, motion into cell x,y with button 1 down is reported as //For example, motion into cell x,y with button 1 down is reported as
//CSI M @ CxCy ( @ = 32 + 0 (button 1) + 32 (motion indicator) ). //CSI M @ CxCy ( @ = 32 + 0 (button 1) + 32 (motion indicator) ).
self.button self.button.and_then(Self::button_number).map(|b| b + 32)
.and_then(|button| self.button_number(button))
.map(|b| b + 32)
} }
_ => None, _ => None,
}) else { })?;
return None;
};
if modifiers.shift() { if modifiers.shift() {
button += 4; button += 4;
@ -127,16 +123,16 @@ impl MouseReporter {
x: u32, x: u32,
y: u32, y: u32,
) -> Option<Vec<u8>> { ) -> Option<Vec<u8>> {
let Some((button_no, event_code)) = (match event { let (button_no, event_code) = (match event {
Event::Mouse(MouseEvent::ButtonPressed(button)) => { Event::Mouse(MouseEvent::ButtonPressed(button)) => {
//Button pressed is reported as button 0,1,2 and event code M //Button pressed is reported as button 0,1,2 and event code M
self.button = Some(button); self.button = Some(button);
Some((self.button_number(button), "M")) Some((Self::button_number(button), "M"))
} }
Event::Mouse(MouseEvent::ButtonReleased(button)) => { Event::Mouse(MouseEvent::ButtonReleased(button)) => {
//Button pressed is reported as button 0,1,2 and event code m //Button pressed is reported as button 0,1,2 and event code m
self.button = None; self.button = None;
Some((self.button_number(button), "m")) Some((Self::button_number(button), "m"))
} }
Event::Mouse(MouseEvent::CursorMoved { .. }) => { Event::Mouse(MouseEvent::CursorMoved { .. }) => {
//Button pressed is reported as button 32 + 0,1,2 and event code M //Button pressed is reported as button 32 + 0,1,2 and event code M
@ -148,12 +144,10 @@ impl MouseReporter {
self.last_movment_y = Some(y); self.last_movment_y = Some(y);
} }
self.button self.button
.map(|button| (self.button_number(button).map(|b| b + 32), "M")) .map(|button| (Self::button_number(button).map(|b| b + 32), "M"))
} }
_ => None, _ => None,
}) else { })?;
return None;
};
if let Some(mut button_no) = button_no { if let Some(mut button_no) = button_no {
if modifiers.shift() { if modifiers.shift() {
@ -174,7 +168,6 @@ impl MouseReporter {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn report_sgr_mouse_wheel_scroll( pub fn report_sgr_mouse_wheel_scroll(
&self,
terminal: &Terminal, terminal: &Terminal,
term_cell_width: f32, term_cell_width: f32,
term_cell_height: f32, term_cell_height: f32,
@ -217,7 +210,6 @@ impl MouseReporter {
//Emulate mouse wheel scroll with up/down arrows. Using mouse spec uses //Emulate mouse wheel scroll with up/down arrows. Using mouse spec uses
//scroll-back and scroll-forw actions, which moves whole windows like page up/page down. //scroll-back and scroll-forw actions, which moves whole windows like page up/page down.
pub fn report_mouse_wheel_as_arrows( pub fn report_mouse_wheel_as_arrows(
&self,
terminal: &Terminal, terminal: &Terminal,
term_cell_width: f32, term_cell_width: f32,
term_cell_height: f32, term_cell_height: f32,

View file

@ -110,25 +110,25 @@ fn convert_color(colors: &Colors, color: Color) -> cosmic_text::Color {
let rgb = match color { let rgb = match color {
Color::Named(named_color) => match colors[named_color] { Color::Named(named_color) => match colors[named_color] {
Some(rgb) => rgb, Some(rgb) => rgb,
None => match named_color { None => {
NamedColor::Background => { if named_color == NamedColor::Background {
// Allow using an unset background // Allow using an unset background
return cosmic_text::Color(WINDOW_BG_COLOR.load(Ordering::SeqCst)); return cosmic_text::Color(WINDOW_BG_COLOR.load(Ordering::SeqCst));
} } else {
_ => {
log::warn!("missing named color {:?}", named_color); log::warn!("missing named color {:?}", named_color);
Rgb::default() Rgb::default()
} }
}, }
}, },
Color::Spec(rgb) => rgb, Color::Spec(rgb) => rgb,
Color::Indexed(index) => match colors[index as usize] { Color::Indexed(index) => {
Some(rgb) => rgb, if let Some(rgb) = colors[index as usize] {
None => { rgb
} else {
log::warn!("missing indexed color {}", index); log::warn!("missing indexed color {}", index);
Rgb::default() Rgb::default()
} }
}, }
}; };
cosmic_text::Color::rgb(rgb.r, rgb.g, rgb.b) cosmic_text::Color::rgb(rgb.r, rgb.g, rgb.b)
} }
@ -437,9 +437,8 @@ impl Terminal {
} }
} }
let search_regex = match &mut self.search_regex_opt { let Some(search_regex) = &mut self.search_regex_opt else {
Some(some) => some, return;
None => return,
}; };
// Determine search origin // Determine search origin
@ -856,7 +855,7 @@ impl Terminal {
let term_lock = self.term.lock(); let term_lock = self.term.lock();
let mode = term_lock.mode(); let mode = term_lock.mode();
if mode.contains(TermMode::SGR_MOUSE) { if mode.contains(TermMode::SGR_MOUSE) {
self.mouse_reporter.report_sgr_mouse_wheel_scroll( MouseReporter::report_sgr_mouse_wheel_scroll(
self, self,
self.size().cell_width, self.size().cell_width,
self.size().cell_height, self.size().cell_height,
@ -866,7 +865,7 @@ impl Terminal {
y, y,
); );
} else { } else {
self.mouse_reporter.report_mouse_wheel_as_arrows( MouseReporter::report_mouse_wheel_as_arrows(
self, self,
self.size().cell_width, self.size().cell_width,
self.size().cell_height, self.size().cell_height,

View file

@ -172,10 +172,9 @@ where
// Calculate layout lines // Calculate layout lines
terminal.with_buffer(|buffer| { terminal.with_buffer(|buffer| {
let mut layout_lines = 0; let mut layout_lines = 0;
for line in buffer.lines.iter() { for line in &buffer.lines {
match line.layout_opt() { if let Some(layout) = line.layout_opt() {
Some(layout) => layout_lines += layout.len(), layout_lines += layout.len()
None => (),
} }
} }
@ -241,7 +240,7 @@ where
let state = tree.state.downcast_ref::<State>(); let state = tree.state.downcast_ref::<State>();
let cosmic_theme = theme.cosmic(); let cosmic_theme = theme.cosmic();
let scrollbar_w = cosmic_theme.spacing.space_xxs as f32; let scrollbar_w = f32::from(cosmic_theme.spacing.space_xxs);
let view_position = layout.position() + [self.padding.left, self.padding.top].into(); let view_position = layout.position() + [self.padding.left, self.padding.top].into();
let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32) let view_w = cmp::min(viewport.width as i32, layout.bounds().width as i32)
@ -278,12 +277,12 @@ where
..Default::default() ..Default::default()
}, },
Color::new( Color::new(
background_color.r() as f32 / 255.0, f32::from(background_color.r()) / 255.0,
background_color.g() as f32 / 255.0, f32::from(background_color.g()) / 255.0,
background_color.b() as f32 / 255.0, f32::from(background_color.b()) / 255.0,
match self.opacity { match self.opacity {
Some(opacity) => opacity, Some(opacity) => opacity,
None => background_color.a() as f32 / 255.0, None => f32::from(background_color.a()) / 255.0,
}, },
), ),
); );
@ -329,10 +328,10 @@ where
) { ) {
let cosmic_text_to_iced_color = |color: cosmic_text::Color| { let cosmic_text_to_iced_color = |color: cosmic_text::Color| {
Color::new( Color::new(
color.r() as f32 / 255.0, f32::from(color.r()) / 255.0,
color.g() as f32 / 255.0, f32::from(color.g()) / 255.0,
color.b() as f32 / 255.0, f32::from(color.b()) / 255.0,
color.a() as f32 / 255.0, f32::from(color.a()) / 255.0,
) )
}; };
@ -370,8 +369,7 @@ where
} }
if !metadata.flags.is_empty() { if !metadata.flags.is_empty() {
let style_line_height = let style_line_height = (self.glyph_font_size / 10.0).clamp(2.0, 16.0);
(self.glyph_font_size / 10.0).max(2.0).min(16.0);
let line_color = cosmic_text_to_iced_color(metadata.underline_color); let line_color = cosmic_text_to_iced_color(metadata.underline_color);
@ -488,7 +486,7 @@ where
view_position, view_position,
metadata_set, metadata_set,
}; };
for glyph in run.glyphs.iter() { for glyph in run.glyphs {
bg_rect.update(glyph, renderer, state.is_focused); bg_rect.update(glyph, renderer, state.is_focused);
} }
bg_rect.fill(renderer, state.is_focused); bg_rect.fill(renderer, state.is_focused);
@ -606,7 +604,7 @@ where
modifiers, modifiers,
.. ..
}) if state.is_focused => { }) if state.is_focused => {
for (key_bind, _) in self.key_binds.iter() { for key_bind in self.key_binds.keys() {
if key_bind.matches(modifiers, &Key::Named(named)) { if key_bind.matches(modifiers, &Key::Named(named)) {
return Status::Captured; return Status::Captured;
} }
@ -705,8 +703,7 @@ where
match named { match named {
Named::Backspace => { Named::Backspace => {
let code = if modifiers.control() { "\x08" } else { "\x7f" }; let code = if modifiers.control() { "\x08" } else { "\x7f" };
terminal terminal.input_scroll(format!("{alt_prefix}{code}").as_bytes().to_vec());
.input_scroll(format!("{}{}", alt_prefix, code).as_bytes().to_vec());
status = Status::Captured; status = Status::Captured;
} }
Named::Enter => { Named::Enter => {
@ -735,8 +732,7 @@ where
} }
Named::Tab => { Named::Tab => {
let code = if modifiers.shift() { "\x1b[Z" } else { "\x09" }; let code = if modifiers.shift() { "\x1b[Z" } else { "\x09" };
terminal terminal.input_scroll(format!("{alt_prefix}{code}").as_bytes().to_vec());
.input_scroll(format!("{}{}", alt_prefix, code).as_bytes().to_vec());
status = Status::Captured; status = Status::Captured;
} }
_ => {} _ => {}
@ -751,7 +747,7 @@ where
key, key,
.. ..
}) if state.is_focused => { }) if state.is_focused => {
for (key_bind, _) in self.key_binds.iter() { for key_bind in self.key_binds.keys() {
if key_bind.matches(modifiers, &key) { if key_bind.matches(modifiers, &key) {
return Status::Captured; return Status::Captured;
} }
@ -1064,9 +1060,9 @@ fn shade(color: cosmic_text::Color, is_focused: bool) -> cosmic_text::Color {
} else { } else {
let shade = 0.92; let shade = 0.92;
cosmic_text::Color::rgba( cosmic_text::Color::rgba(
(color.r() as f32 * shade) as u8, (f32::from(color.r()) * shade) as u8,
(color.g() as f32 * shade) as u8, (f32::from(color.g()) * shade) as u8,
(color.b() as f32 * shade) as u8, (f32::from(color.b()) * shade) as u8,
color.a(), color.a(),
) )
} }
@ -1106,8 +1102,8 @@ pub struct State {
impl State { impl State {
/// Creates a new [`State`]. /// Creates a new [`State`].
pub fn new() -> State { pub fn new() -> Self {
State { Self {
modifiers: Modifiers::empty(), modifiers: Modifiers::empty(),
click: None, click: None,
dragging: None, dragging: None,
@ -1142,7 +1138,7 @@ meta 0b100000 (32)
caps_lock 0b1000000 (64) caps_lock 0b1000000 (64)
num_lock 0b10000000 (128) num_lock 0b10000000 (128)
*/ */
fn calculate_modifier_number(state: &mut State) -> u8 { fn calculate_modifier_number(state: &State) -> u8 {
let mut mod_no = 0; let mut mod_no = 0;
if state.modifiers.shift() { if state.modifiers.shift() {
mod_no |= 1; mod_no |= 1;
@ -1162,10 +1158,10 @@ fn calculate_modifier_number(state: &mut State) -> u8 {
#[inline(always)] #[inline(always)]
fn csi(code: &str, suffix: &str, modifiers: u8) -> Option<Vec<u8>> { fn csi(code: &str, suffix: &str, modifiers: u8) -> Option<Vec<u8>> {
if modifiers == 1 { if modifiers == 1 {
Some(format!("\x1B[{}{}", code, suffix).as_bytes().to_vec()) Some(format!("\x1B[{code}{suffix}").as_bytes().to_vec())
} else { } else {
Some( Some(
format!("\x1B[{};{}{}", code, modifiers, suffix) format!("\x1B[{code};{modifiers}{suffix}")
.as_bytes() .as_bytes()
.to_vec(), .to_vec(),
) )
@ -1175,8 +1171,8 @@ fn csi(code: &str, suffix: &str, modifiers: u8) -> Option<Vec<u8>> {
#[inline(always)] #[inline(always)]
fn ss3(code: &str, modifiers: u8) -> Option<Vec<u8>> { fn ss3(code: &str, modifiers: u8) -> Option<Vec<u8>> {
if modifiers == 1 { if modifiers == 1 {
Some(format!("\x1B\x4F{}", code).as_bytes().to_vec()) Some(format!("\x1B\x4F{code}").as_bytes().to_vec())
} else { } else {
Some(format!("\x1B[1;{}{}", modifiers, code).as_bytes().to_vec()) Some(format!("\x1B[1;{modifiers}{code}").as_bytes().to_vec())
} }
} }

View file

@ -55,8 +55,8 @@ impl ColorDerive {
fn color_adj(rgb: Rgb, saturation_adj: f32, lightness_adj: f32) -> Rgb { fn color_adj(rgb: Rgb, saturation_adj: f32, lightness_adj: f32) -> Rgb {
let mut okhsl = Self::rgb_to_okhsl(rgb); let mut okhsl = Self::rgb_to_okhsl(rgb);
okhsl.saturation = (okhsl.saturation + saturation_adj).max(0.0).min(1.0); okhsl.saturation = (okhsl.saturation + saturation_adj).clamp(0.0, 1.0);
okhsl.lightness = (okhsl.lightness + lightness_adj).max(0.0).min(1.0); okhsl.lightness = (okhsl.lightness + lightness_adj).clamp(0.0, 1.0);
Self::okhsl_to_rgb(okhsl) Self::okhsl_to_rgb(okhsl)
} }