feat: rebase libcosmic onto iced 0.14
This commit is contained in:
parent
adb938420e
commit
f62abcea4e
6 changed files with 1432 additions and 1418 deletions
2613
Cargo.lock
generated
2613
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
10
Cargo.toml
10
Cargo.toml
|
|
@ -4,7 +4,7 @@ version = "1.0.8"
|
||||||
authors = ["Jeremy Soller <jeremy@system76.com>"]
|
authors = ["Jeremy Soller <jeremy@system76.com>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
rust-version = "1.85"
|
rust-version = "1.90"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
alacritty_terminal = "0.25.1"
|
alacritty_terminal = "0.25.1"
|
||||||
|
|
@ -67,7 +67,7 @@ inherits = "release"
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
|
||||||
# [patch.'https://github.com/pop-os/libcosmic']
|
#[patch.'https://github.com/pop-os/libcosmic']
|
||||||
# libcosmic = { path = "../libcosmic" }
|
#libcosmic = { path = "../libcosmic" }
|
||||||
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
#cosmic-config = { path = "../libcosmic/cosmic-config" }
|
||||||
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }
|
#cosmic-theme = { path = "../libcosmic/cosmic-theme" }
|
||||||
|
|
|
||||||
40
src/main.rs
40
src/main.rs
|
|
@ -949,7 +949,7 @@ impl App {
|
||||||
|
|
||||||
sections.push(
|
sections.push(
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
widget::button::standard(fl!("import"))
|
widget::button::standard(fl!("import"))
|
||||||
.on_press(Message::ColorSchemeImport(color_scheme_kind))
|
.on_press(Message::ColorSchemeImport(color_scheme_kind))
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -1003,7 +1003,7 @@ impl App {
|
||||||
|
|
||||||
let mut groups = Vec::new();
|
let mut groups = Vec::new();
|
||||||
//TODO: fix text input focus going outside bounds
|
//TODO: fix text input focus going outside bounds
|
||||||
groups.push(widget::horizontal_space().into());
|
groups.push(widget::space::horizontal().into());
|
||||||
groups.push(
|
groups.push(
|
||||||
widget::text_input::search_input(fl!("type-to-search"), &self.shortcut_search_value)
|
widget::text_input::search_input(fl!("type-to-search"), &self.shortcut_search_value)
|
||||||
.id(self.shortcut_search_id.clone())
|
.id(self.shortcut_search_id.clone())
|
||||||
|
|
@ -1269,7 +1269,7 @@ impl App {
|
||||||
])
|
])
|
||||||
.spacing(space_xxxs)
|
.spacing(space_xxxs)
|
||||||
.into(),
|
.into(),
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
widget::toggler(profile.drain_on_exit)
|
widget::toggler(profile.drain_on_exit)
|
||||||
.on_toggle(move |t| Message::ProfileHold(profile_id, t))
|
.on_toggle(move |t| Message::ProfileHold(profile_id, t))
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -1292,7 +1292,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
let add_profile = widget::row::with_children(vec![
|
let add_profile = widget::row::with_children(vec![
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
widget::button::standard(fl!("add-profile"))
|
widget::button::standard(fl!("add-profile"))
|
||||||
.on_press(Message::ProfileNew)
|
.on_press(Message::ProfileNew)
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -3362,7 +3362,7 @@ impl Application for App {
|
||||||
widget::tooltip::Position::Top,
|
widget::tooltip::Position::Top,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
button::custom(icon_cache_get("window-close-symbolic", 16))
|
button::custom(icon_cache_get("window-close-symbolic", 16))
|
||||||
.on_press(Message::Find(false))
|
.on_press(Message::Find(false))
|
||||||
.padding(space_xxs)
|
.padding(space_xxs)
|
||||||
|
|
@ -3428,22 +3428,24 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}),
|
}),
|
||||||
Subscription::run_with_id(
|
Subscription::run_with(TypeId::of::<TerminalEventSubscription>(), |_| {
|
||||||
TypeId::of::<TerminalEventSubscription>(),
|
stream::channel(
|
||||||
stream::channel(100, |mut output| async move {
|
100,
|
||||||
let (event_tx, mut event_rx) = mpsc::unbounded_channel();
|
|mut output: iced::futures::channel::mpsc::Sender<Message>| async move {
|
||||||
output.send(Message::TermEventTx(event_tx)).await.unwrap();
|
let (event_tx, mut event_rx) = mpsc::unbounded_channel();
|
||||||
|
output.send(Message::TermEventTx(event_tx)).await.unwrap();
|
||||||
|
|
||||||
while let Some((pane, entity, event)) = event_rx.recv().await {
|
while let Some((pane, entity, event)) = event_rx.recv().await {
|
||||||
output
|
output
|
||||||
.send(Message::TermEvent(pane, entity, event))
|
.send(Message::TermEvent(pane, entity, event))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
panic!("terminal event channel closed");
|
panic!("terminal event channel closed");
|
||||||
}),
|
},
|
||||||
),
|
)
|
||||||
|
}),
|
||||||
cosmic_config::config_subscription(
|
cosmic_config::config_subscription(
|
||||||
TypeId::of::<ConfigSubscription>(),
|
TypeId::of::<ConfigSubscription>(),
|
||||||
Self::APP_ID.into(),
|
Self::APP_ID.into(),
|
||||||
|
|
|
||||||
10
src/menu.rs
10
src/menu.rs
|
|
@ -1,15 +1,13 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use cosmic::iced::Point;
|
use cosmic::iced::Point;
|
||||||
use cosmic::widget::Column;
|
|
||||||
use cosmic::widget::menu::key_bind::KeyBind;
|
use cosmic::widget::menu::key_bind::KeyBind;
|
||||||
use cosmic::widget::menu::{Item as MenuItem, menu_button};
|
use cosmic::widget::menu::{Item as MenuItem, menu_button};
|
||||||
|
use cosmic::widget::{Column, space};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
Element,
|
Element,
|
||||||
app::Core,
|
app::Core,
|
||||||
iced::{
|
iced::{Background, Length, advanced::widget::text::Style as TextStyle},
|
||||||
Background, Length, advanced::widget::text::Style as TextStyle, widget::horizontal_space,
|
|
||||||
},
|
|
||||||
iced_core::Border,
|
iced_core::Border,
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
|
|
@ -57,7 +55,7 @@ pub fn context_menu<'a>(
|
||||||
let key = find_key(&action);
|
let key = find_key(&action);
|
||||||
menu_button(vec![
|
menu_button(vec![
|
||||||
widget::text(label).into(),
|
widget::text(label).into(),
|
||||||
horizontal_space().into(),
|
space::horizontal().into(),
|
||||||
widget::text(key)
|
widget::text(key)
|
||||||
.class(theme::Text::Custom(key_style))
|
.class(theme::Text::Custom(key_style))
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -68,7 +66,7 @@ pub fn context_menu<'a>(
|
||||||
let menu_checkbox = |label, value, action| {
|
let menu_checkbox = |label, value, action| {
|
||||||
menu_button(vec![
|
menu_button(vec![
|
||||||
widget::text(label).into(),
|
widget::text(label).into(),
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
widget::toggler(value)
|
widget::toggler(value)
|
||||||
.on_toggle(move |_| Message::TabContextAction(entity, action))
|
.on_toggle(move |_| Message::TabContextAction(entity, action))
|
||||||
.size(16.0)
|
.size(16.0)
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,7 @@ impl PasswordManager {
|
||||||
sections.push(passwords_section.into());
|
sections.push(passwords_section.into());
|
||||||
|
|
||||||
let add_password = widget::row::with_children(vec![
|
let add_password = widget::row::with_children(vec![
|
||||||
widget::horizontal_space().into(),
|
widget::space::horizontal().into(),
|
||||||
widget::button::standard(fl!("add-password"))
|
widget::button::standard(fl!("add-password"))
|
||||||
.on_press(Message::PasswordManager(PasswordManagerMessage::New))
|
.on_press(Message::PasswordManager(PasswordManagerMessage::New))
|
||||||
.into(),
|
.into(),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use alacritty_terminal::{
|
||||||
term::{TermMode, cell::Flags},
|
term::{TermMode, cell::Flags},
|
||||||
vte::ansi::{CursorShape, NamedColor},
|
vte::ansi::{CursorShape, NamedColor},
|
||||||
};
|
};
|
||||||
use cosmic::widget::menu::key_bind::KeyBind;
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
Renderer,
|
Renderer,
|
||||||
cosmic_theme::palette::{WithAlpha, blend::Compose},
|
cosmic_theme::palette::{WithAlpha, blend::Compose},
|
||||||
|
|
@ -34,6 +33,7 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
theme::Theme,
|
theme::Theme,
|
||||||
};
|
};
|
||||||
|
use cosmic::{iced_core::SmolStr, widget::menu::key_bind::KeyBind};
|
||||||
use cosmic_text::LayoutGlyph;
|
use cosmic_text::LayoutGlyph;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -263,7 +263,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&mut self,
|
||||||
_tree: &mut widget::Tree,
|
_tree: &mut widget::Tree,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
|
|
@ -297,15 +297,15 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
&self,
|
&mut self,
|
||||||
tree: &mut widget::Tree,
|
tree: &mut widget::Tree,
|
||||||
_layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
operation: &mut dyn Operation,
|
operation: &mut dyn Operation,
|
||||||
) {
|
) {
|
||||||
let state = tree.state.downcast_mut::<State>();
|
let state = tree.state.downcast_mut::<State>();
|
||||||
|
|
||||||
operation.focusable(state, self.id.as_ref());
|
operation.focusable(self.id.as_ref(), layout.bounds(), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
|
|
@ -316,6 +316,9 @@ where
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
|
if self.disabled {
|
||||||
|
return mouse::Interaction::default();
|
||||||
|
}
|
||||||
let state = tree.state.downcast_ref::<State>();
|
let state = tree.state.downcast_ref::<State>();
|
||||||
|
|
||||||
if let Some(Dragging::Scrollbar { .. }) = &state.dragging {
|
if let Some(Dragging::Scrollbar { .. }) = &state.dragging {
|
||||||
|
|
@ -348,7 +351,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse::Interaction::Idle
|
mouse::Interaction::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
|
|
@ -377,10 +380,10 @@ where
|
||||||
|
|
||||||
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)
|
||||||
- self.padding.horizontal() as i32
|
- self.padding.x() as i32
|
||||||
- scrollbar_w as i32;
|
- scrollbar_w as i32;
|
||||||
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32)
|
let view_h = cmp::min(viewport.height as i32, layout.bounds().height as i32)
|
||||||
- self.padding.vertical() as i32;
|
- self.padding.y() as i32;
|
||||||
|
|
||||||
if view_w <= 0 || view_h <= 0 {
|
if view_w <= 0 || view_h <= 0 {
|
||||||
// Zero sized image
|
// Zero sized image
|
||||||
|
|
@ -417,7 +420,7 @@ where
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Color::new(
|
Color::from_rgba(
|
||||||
f32::from(background_color.r()) / 255.0,
|
f32::from(background_color.r()) / 255.0,
|
||||||
f32::from(background_color.g()) / 255.0,
|
f32::from(background_color.g()) / 255.0,
|
||||||
f32::from(background_color.b()) / 255.0,
|
f32::from(background_color.b()) / 255.0,
|
||||||
|
|
@ -468,7 +471,7 @@ where
|
||||||
is_focused: bool,
|
is_focused: bool,
|
||||||
) {
|
) {
|
||||||
let cosmic_text_to_iced_color = |color: cosmic_text::Color| {
|
let cosmic_text_to_iced_color = |color: cosmic_text::Color| {
|
||||||
Color::new(
|
Color::from_rgba(
|
||||||
f32::from(color.r()) / 255.0,
|
f32::from(color.r()) / 255.0,
|
||||||
f32::from(color.g()) / 255.0,
|
f32::from(color.g()) / 255.0,
|
||||||
f32::from(color.b()) / 255.0,
|
f32::from(color.b()) / 255.0,
|
||||||
|
|
@ -645,7 +648,7 @@ where
|
||||||
renderer.fill_raw(Raw {
|
renderer.fill_raw(Raw {
|
||||||
buffer: terminal.buffer_weak(),
|
buffer: terminal.buffer_weak(),
|
||||||
position: view_position,
|
position: view_position,
|
||||||
color: Color::new(1.0, 1.0, 1.0, 1.0), // TODO
|
color: Color::from_rgba(1.0, 1.0, 1.0, 1.0), // TODO
|
||||||
clip_bounds: Rectangle::new(view_position, Size::new(view_w as f32, view_h as f32)),
|
clip_bounds: Rectangle::new(view_position, Size::new(view_w as f32, view_h as f32)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -799,19 +802,19 @@ where
|
||||||
log::trace!("redraw {}, {}: {:?}", view_w, view_h, duration);
|
log::trace!("redraw {}, {}: {:?}", view_w, view_h, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut widget::Tree,
|
tree: &mut widget::Tree,
|
||||||
event: Event,
|
event: &Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: mouse::Cursor,
|
cursor_position: mouse::Cursor,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
_viewport: &Rectangle<f32>,
|
_viewport: &Rectangle<f32>,
|
||||||
) -> Status {
|
) {
|
||||||
if self.disabled {
|
if self.disabled {
|
||||||
return Status::Ignored;
|
return;
|
||||||
}
|
}
|
||||||
let state = tree.state.downcast_mut::<State>();
|
let state = tree.state.downcast_mut::<State>();
|
||||||
let scrollbar_rect = state.scrollbar_rect.get();
|
let scrollbar_rect = state.scrollbar_rect.get();
|
||||||
|
|
@ -820,7 +823,6 @@ where
|
||||||
|
|
||||||
let is_app_cursor = terminal.term.lock().mode().contains(TermMode::APP_CURSOR);
|
let is_app_cursor = terminal.term.lock().mode().contains(TermMode::APP_CURSOR);
|
||||||
let is_mouse_mode = terminal.term.lock().mode().intersects(TermMode::MOUSE_MODE);
|
let is_mouse_mode = terminal.term.lock().mode().intersects(TermMode::MOUSE_MODE);
|
||||||
let mut status = Status::Ignored;
|
|
||||||
match event {
|
match event {
|
||||||
Event::Window(event) => match event {
|
Event::Window(event) => match event {
|
||||||
cosmic::iced::window::Event::Focused => {
|
cosmic::iced::window::Event::Focused => {
|
||||||
|
|
@ -842,11 +844,11 @@ where
|
||||||
self.padding,
|
self.padding,
|
||||||
multiplier,
|
multiplier,
|
||||||
) {
|
) {
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if state.autoscroll.is_active() {
|
if state.autoscroll.is_active() {
|
||||||
shell.request_redraw(RedrawRequest::NextFrame);
|
shell.request_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -867,8 +869,9 @@ where
|
||||||
..
|
..
|
||||||
}) if state.is_focused && named == modified_named => {
|
}) if state.is_focused && named == modified_named => {
|
||||||
for key_bind in self.key_binds.keys() {
|
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;
|
shell.capture_event();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -956,7 +959,9 @@ where
|
||||||
};
|
};
|
||||||
if let Some(escape_code) = escape_code {
|
if let Some(escape_code) = escape_code {
|
||||||
terminal.input_scroll(escape_code);
|
terminal.input_scroll(escape_code);
|
||||||
return Status::Captured;
|
shell.capture_event();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Special handle Enter, Escape, Backspace and Tab as described in
|
//Special handle Enter, Escape, Backspace and Tab as described in
|
||||||
|
|
@ -967,11 +972,11 @@ where
|
||||||
Named::Backspace => {
|
Named::Backspace => {
|
||||||
let code = if modifiers.control() { "\x08" } else { "\x7f" };
|
let code = if modifiers.control() { "\x08" } else { "\x7f" };
|
||||||
terminal.input_scroll(format!("{alt_prefix}{code}").into_bytes());
|
terminal.input_scroll(format!("{alt_prefix}{code}").into_bytes());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
Named::Enter => {
|
Named::Enter => {
|
||||||
terminal.input_scroll(format!("{}{}", alt_prefix, "\x0D").into_bytes());
|
terminal.input_scroll(format!("{}{}", alt_prefix, "\x0D").into_bytes());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
Named::Escape => {
|
Named::Escape => {
|
||||||
//Escape with any modifier will cancel selection
|
//Escape with any modifier will cancel selection
|
||||||
|
|
@ -984,31 +989,19 @@ where
|
||||||
} else {
|
} else {
|
||||||
terminal.input_scroll(format!("{}{}", alt_prefix, "\x1B").into_bytes());
|
terminal.input_scroll(format!("{}{}", alt_prefix, "\x1B").into_bytes());
|
||||||
}
|
}
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
Named::Space => {
|
|
||||||
// Keep this instead of hardcoding the space to allow for dead keys
|
|
||||||
let character = text.and_then(|c| c.chars().next()).unwrap_or_default();
|
|
||||||
|
|
||||||
if modifiers.control() {
|
|
||||||
// Send NUL character (\x00) for Ctrl + Space
|
|
||||||
terminal.input_scroll(b"\x00".to_vec());
|
|
||||||
} else {
|
|
||||||
terminal
|
|
||||||
.input_scroll(format!("{}{}", alt_prefix, character).into_bytes());
|
|
||||||
}
|
|
||||||
status = Status::Captured;
|
|
||||||
}
|
|
||||||
Named::Tab => {
|
Named::Tab => {
|
||||||
let code = if modifiers.shift() { "\x1b[Z" } else { "\x09" };
|
let code = if modifiers.shift() { "\x1b[Z" } else { "\x09" };
|
||||||
terminal.input_scroll(format!("{alt_prefix}{code}").into_bytes());
|
terminal.input_scroll(format!("{alt_prefix}{code}").into_bytes());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
|
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
|
||||||
state.modifiers = modifiers;
|
state.modifiers = *modifiers;
|
||||||
|
|
||||||
if modifiers.contains(Modifiers::CTRL)
|
if modifiers.contains(Modifiers::CTRL)
|
||||||
|| terminal.active_regex_match.is_some()
|
|| terminal.active_regex_match.is_some()
|
||||||
|
|
@ -1032,6 +1025,31 @@ where
|
||||||
update_active_regex_match(&mut terminal, location, Some(&state.modifiers));
|
update_active_regex_match(&mut terminal, location, Some(&state.modifiers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
|
text,
|
||||||
|
modifiers,
|
||||||
|
key,
|
||||||
|
..
|
||||||
|
}) if *key == Key::Character(SmolStr::new(" ")) => {
|
||||||
|
//Special handle Enter, Escape, Backspace and Tab as described in
|
||||||
|
//https://sw.kovidgoyal.net/kitty/keyboard-protocol/#legacy-key-event-encoding
|
||||||
|
//Also special handle Ctrl-_ to behave like xterm
|
||||||
|
let alt_prefix = if modifiers.alt() { "\x1B" } else { "" };
|
||||||
|
|
||||||
|
// Keep this instead of hardcoding the space to allow for dead keys
|
||||||
|
let character = text
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.chars().next())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if modifiers.control() {
|
||||||
|
// Send NUL character (\x00) for Ctrl + Space
|
||||||
|
terminal.input_scroll(b"\x00".to_vec());
|
||||||
|
} else {
|
||||||
|
terminal.input_scroll(format!("{}{}", alt_prefix, character).into_bytes());
|
||||||
|
}
|
||||||
|
shell.capture_event();
|
||||||
|
}
|
||||||
Event::Keyboard(KeyEvent::KeyPressed {
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
text,
|
text,
|
||||||
modifiers,
|
modifiers,
|
||||||
|
|
@ -1039,11 +1057,16 @@ where
|
||||||
..
|
..
|
||||||
}) if state.is_focused => {
|
}) if state.is_focused => {
|
||||||
for key_bind in self.key_binds.keys() {
|
for key_bind in self.key_binds.keys() {
|
||||||
if key_bind.matches(modifiers, &key) {
|
if key_bind.matches(*modifiers, key) {
|
||||||
return Status::Captured;
|
shell.capture_event();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let character = text.and_then(|c| c.chars().next()).unwrap_or_default();
|
let character = text
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.chars().next())
|
||||||
|
.unwrap_or_default();
|
||||||
match (
|
match (
|
||||||
modifiers.logo(),
|
modifiers.logo(),
|
||||||
modifiers.control(),
|
modifiers.control(),
|
||||||
|
|
@ -1064,7 +1087,7 @@ where
|
||||||
str.len() + 1
|
str.len() + 1
|
||||||
};
|
};
|
||||||
terminal.input_scroll(buf[..len].to_vec());
|
terminal.input_scroll(buf[..len].to_vec());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, true, _, false) => {
|
(false, true, _, false) => {
|
||||||
|
|
@ -1073,7 +1096,7 @@ where
|
||||||
let mut buf = [0, 0, 0, 0];
|
let mut buf = [0, 0, 0, 0];
|
||||||
let str = character.encode_utf8(&mut buf);
|
let str = character.encode_utf8(&mut buf);
|
||||||
terminal.input_scroll(str.as_bytes().to_vec());
|
terminal.input_scroll(str.as_bytes().to_vec());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, true, _, true) => {
|
(false, true, _, true) => {
|
||||||
|
|
@ -1081,9 +1104,9 @@ where
|
||||||
//is taken by zoom, we send that code for
|
//is taken by zoom, we send that code for
|
||||||
//Ctrl+Underline instead, like xterm and
|
//Ctrl+Underline instead, like xterm and
|
||||||
//gnome-terminal
|
//gnome-terminal
|
||||||
if key == Key::Character("_".into()) {
|
if *key == Key::Character("_".into()) {
|
||||||
terminal.input_scroll(b"\x1F".as_slice());
|
terminal.input_scroll(b"\x1F".as_slice());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, false, true, _) => {
|
(false, false, true, _) => {
|
||||||
|
|
@ -1095,7 +1118,7 @@ where
|
||||||
str.len() + 1
|
str.len() + 1
|
||||||
};
|
};
|
||||||
terminal.input_scroll(buf[..len].to_vec());
|
terminal.input_scroll(buf[..len].to_vec());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, false, false, _) => {
|
(false, false, false, _) => {
|
||||||
|
|
@ -1104,7 +1127,7 @@ where
|
||||||
let mut buf = [0, 0, 0, 0];
|
let mut buf = [0, 0, 0, 0];
|
||||||
let str = character.encode_utf8(&mut buf);
|
let str = character.encode_utf8(&mut buf);
|
||||||
terminal.input_scroll(str.as_bytes().to_vec());
|
terminal.input_scroll(str.as_bytes().to_vec());
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1119,7 +1142,12 @@ where
|
||||||
|
|
||||||
if is_mouse_mode {
|
if is_mouse_mode {
|
||||||
state.autoscroll.stop();
|
state.autoscroll.stop();
|
||||||
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
terminal.report_mouse(
|
||||||
|
event.clone(),
|
||||||
|
&state.modifiers,
|
||||||
|
col as u32,
|
||||||
|
row as u32,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
state.is_focused = true;
|
state.is_focused = true;
|
||||||
|
|
||||||
|
|
@ -1214,7 +1242,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if button == Button::Middle {
|
} else if *button == Button::Middle {
|
||||||
if let Some(on_middle_click) = &self.on_middle_click {
|
if let Some(on_middle_click) = &self.on_middle_click {
|
||||||
shell.publish(on_middle_click());
|
shell.publish(on_middle_click());
|
||||||
}
|
}
|
||||||
|
|
@ -1226,7 +1254,7 @@ where
|
||||||
shell.publish(on_context_menu(None));
|
shell.publish(on_context_menu(None));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if button == Button::Right {
|
if *button == Button::Right {
|
||||||
let x = p.x - self.padding.left;
|
let x = p.x - self.padding.left;
|
||||||
let y = p.y - self.padding.top;
|
let y = p.y - self.padding.top;
|
||||||
//TODO: better calculation of position
|
//TODO: better calculation of position
|
||||||
|
|
@ -1251,7 +1279,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1286,18 +1314,23 @@ where
|
||||||
if let Some(on_open_hyperlink) = &self.on_open_hyperlink {
|
if let Some(on_open_hyperlink) = &self.on_open_hyperlink {
|
||||||
if let Some(hyperlink) = get_hyperlink(&terminal, location) {
|
if let Some(hyperlink) = get_hyperlink(&terminal, location) {
|
||||||
shell.publish(on_open_hyperlink(hyperlink));
|
shell.publish(on_open_hyperlink(hyperlink));
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_mouse_mode {
|
if is_mouse_mode {
|
||||||
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
terminal.report_mouse(
|
||||||
|
event.clone(),
|
||||||
|
&state.modifiers,
|
||||||
|
col as u32,
|
||||||
|
row as u32,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Mouse(MouseEvent::ButtonReleased(_button)) => {
|
Event::Mouse(MouseEvent::ButtonReleased(_button)) => {
|
||||||
|
|
@ -1309,7 +1342,12 @@ where
|
||||||
let col = x / terminal.size().cell_width;
|
let col = x / terminal.size().cell_width;
|
||||||
let row = y / terminal.size().cell_height;
|
let row = y / terminal.size().cell_height;
|
||||||
if is_mouse_mode {
|
if is_mouse_mode {
|
||||||
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
terminal.report_mouse(
|
||||||
|
event.clone(),
|
||||||
|
&state.modifiers,
|
||||||
|
col as u32,
|
||||||
|
row as u32,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1351,7 +1389,12 @@ where
|
||||||
|
|
||||||
if is_mouse_mode {
|
if is_mouse_mode {
|
||||||
if let Some((col, row)) = col_row_opt {
|
if let Some((col, row)) = col_row_opt {
|
||||||
terminal.report_mouse(event, &state.modifiers, col as u32, row as u32);
|
terminal.report_mouse(
|
||||||
|
event.clone(),
|
||||||
|
&state.modifiers,
|
||||||
|
col as u32,
|
||||||
|
row as u32,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let handled_buffer_drag = update_buffer_drag(
|
let handled_buffer_drag = update_buffer_drag(
|
||||||
|
|
@ -1364,7 +1407,7 @@ where
|
||||||
0.0,
|
0.0,
|
||||||
);
|
);
|
||||||
if handled_buffer_drag {
|
if handled_buffer_drag {
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
} else if let Some(Dragging::Scrollbar {
|
} else if let Some(Dragging::Scrollbar {
|
||||||
start_y,
|
start_y,
|
||||||
start_scroll,
|
start_scroll,
|
||||||
|
|
@ -1377,7 +1420,7 @@ where
|
||||||
(y - start_y) / buffer.size().1.unwrap_or(1.0)
|
(y - start_y) / buffer.size().1.unwrap_or(1.0)
|
||||||
});
|
});
|
||||||
terminal.scroll_to(start_scroll.0 + scroll_offset);
|
terminal.scroll_to(start_scroll.0 + scroll_offset);
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(state.dragging, Some(Dragging::Buffer { .. })) {
|
if matches!(state.dragging, Some(Dragging::Buffer { .. })) {
|
||||||
|
|
@ -1389,7 +1432,7 @@ where
|
||||||
} else {
|
} else {
|
||||||
state.autoscroll.start(p_global);
|
state.autoscroll.start(p_global);
|
||||||
}
|
}
|
||||||
shell.request_redraw(RedrawRequest::NextFrame);
|
shell.request_redraw();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.autoscroll.stop();
|
state.autoscroll.stop();
|
||||||
|
|
@ -1405,15 +1448,15 @@ where
|
||||||
//TODO: better calculation of position
|
//TODO: better calculation of position
|
||||||
let col = x / terminal.size().cell_width;
|
let col = x / terminal.size().cell_width;
|
||||||
let row = y / terminal.size().cell_height;
|
let row = y / terminal.size().cell_height;
|
||||||
terminal.scroll_mouse(delta, &state.modifiers, col as u32, row as u32);
|
terminal.scroll_mouse(*delta, &state.modifiers, col as u32, row as u32);
|
||||||
} else if terminal.term.lock().mode().contains(TermMode::ALT_SCREEN) {
|
} else if terminal.term.lock().mode().contains(TermMode::ALT_SCREEN) {
|
||||||
MouseReporter::report_mouse_wheel_as_arrows(
|
MouseReporter::report_mouse_wheel_as_arrows(
|
||||||
&terminal,
|
&terminal,
|
||||||
terminal.size().cell_width,
|
terminal.size().cell_width,
|
||||||
terminal.size().cell_height,
|
terminal.size().cell_height,
|
||||||
delta,
|
*delta,
|
||||||
);
|
);
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
} else {
|
} else {
|
||||||
match delta {
|
match delta {
|
||||||
ScrollDelta::Lines { x: _, y } => {
|
ScrollDelta::Lines { x: _, y } => {
|
||||||
|
|
@ -1423,7 +1466,7 @@ where
|
||||||
if lines != 0 {
|
if lines != 0 {
|
||||||
terminal.scroll(TerminalScroll::Delta(-lines));
|
terminal.scroll(TerminalScroll::Delta(-lines));
|
||||||
}
|
}
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
ScrollDelta::Pixels { x: _, y } => {
|
ScrollDelta::Pixels { x: _, y } => {
|
||||||
//TODO: this adjustment is just a guess!
|
//TODO: this adjustment is just a guess!
|
||||||
|
|
@ -1441,7 +1484,7 @@ where
|
||||||
if lines != 0 {
|
if lines != 0 {
|
||||||
terminal.scroll(TerminalScroll::Delta(-lines));
|
terminal.scroll(TerminalScroll::Delta(-lines));
|
||||||
}
|
}
|
||||||
status = Status::Captured;
|
shell.capture_event();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1466,8 +1509,6 @@ where
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
status
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue