mirror of
https://github.com/nyakang/nyaterm.git
synced 2026-10-04 08:00:50 +00:00
feat(security): use real masked password inputs
This commit is contained in:
@@ -581,7 +581,6 @@ impl NyaTermApp {
|
||||
multi_line_paste_focus: cx.focus_handle(),
|
||||
lock_focus: cx.focus_handle(),
|
||||
lock_password_draft: String::new(),
|
||||
lock_password_marked_text: String::new(),
|
||||
lock_status: String::new(),
|
||||
pending_terminal_frame_events: VecDeque::new(),
|
||||
pending_session_events: VecDeque::new(),
|
||||
|
||||
@@ -266,7 +266,6 @@ pub struct NyaTermApp {
|
||||
pub(in crate::features) multi_line_paste_focus: FocusHandle,
|
||||
pub(in crate::features) lock_focus: FocusHandle,
|
||||
pub(in crate::features) lock_password_draft: String,
|
||||
pub(in crate::features) lock_password_marked_text: String,
|
||||
pub(in crate::features) lock_status: String,
|
||||
pub(in crate::features) pending_terminal_frame_events: VecDeque<TerminalFrameEvent>,
|
||||
pub(in crate::features) pending_session_events: VecDeque<SessionEvent>,
|
||||
|
||||
@@ -88,14 +88,13 @@ impl NyaTermApp {
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let palette = self.theme_palette();
|
||||
let draft_length = self.security.unlock.draft.chars().count()
|
||||
+ self.security.unlock.marked_text.chars().count();
|
||||
let draft = if draft_length == 0 {
|
||||
" ".to_string()
|
||||
} else {
|
||||
"•".repeat(draft_length.min(32))
|
||||
};
|
||||
let input_entity = cx.entity();
|
||||
let password_input = self.text_input(
|
||||
"security.unlock.password",
|
||||
&self.security.unlock.draft.clone(),
|
||||
TextInputSetup::masked(),
|
||||
cx,
|
||||
);
|
||||
let password_focus = password_input.read(cx).focus_handle();
|
||||
div()
|
||||
.absolute()
|
||||
.inset_0()
|
||||
@@ -146,25 +145,16 @@ impl NyaTermApp {
|
||||
.font_family(crate::features::gpui_code_font_family())
|
||||
.text_xs()
|
||||
.text_color(rgb(palette.text))
|
||||
.child(draft)
|
||||
.cursor_text()
|
||||
.on_mouse_down(MouseButton::Left, move |_, window, _| {
|
||||
window.focus(&password_focus);
|
||||
})
|
||||
.child(
|
||||
gpui::canvas(
|
||||
|_bounds, _window, _cx| {},
|
||||
move |bounds, _state, window, cx| {
|
||||
let focus =
|
||||
input_entity.read(cx).security.unlock.focus.clone();
|
||||
window.handle_input(
|
||||
&focus,
|
||||
gpui::ElementInputHandler::new(
|
||||
bounds,
|
||||
input_entity.clone(),
|
||||
),
|
||||
cx,
|
||||
);
|
||||
},
|
||||
)
|
||||
.absolute()
|
||||
.inset_0(),
|
||||
div()
|
||||
.min_w_0()
|
||||
.flex_1()
|
||||
.overflow_hidden()
|
||||
.child(password_input),
|
||||
),
|
||||
)
|
||||
.when_some(self.security.unlock.error.clone(), |this, error| {
|
||||
|
||||
@@ -7,13 +7,17 @@ impl NyaTermApp {
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let palette = self.theme_palette();
|
||||
let input_entity = cx.entity();
|
||||
let password_length = self.lock_password_draft.chars().count()
|
||||
+ self.lock_password_marked_text.chars().count();
|
||||
let password_display = if password_length == 0 {
|
||||
" ".to_string()
|
||||
let password_input = self.text_input(
|
||||
"lock-screen.password",
|
||||
&self.lock_password_draft.clone(),
|
||||
TextInputSetup::masked(),
|
||||
cx,
|
||||
);
|
||||
let password_focus = password_input.read(cx).focus_handle();
|
||||
let overlay_focus = if self.settings.has_master_password {
|
||||
password_focus.clone()
|
||||
} else {
|
||||
"•".repeat(password_length.min(32))
|
||||
self.lock_focus.clone()
|
||||
};
|
||||
let lock_status = if self.lock_status.trim().is_empty() {
|
||||
if self.settings.has_master_password {
|
||||
@@ -39,10 +43,7 @@ impl NyaTermApp {
|
||||
.bg(rgba(0x000000d9))
|
||||
.text_color(rgb(0xffffff))
|
||||
.track_focus(&self.lock_focus)
|
||||
.on_click(cx.listener(|this, _, window, cx| {
|
||||
window.focus(&this.lock_focus);
|
||||
cx.notify();
|
||||
}))
|
||||
.on_click(move |_, window, _| window.focus(&overlay_focus))
|
||||
.on_key_down(cx.listener(|this, event: &KeyDownEvent, _, cx| {
|
||||
cx.stop_propagation();
|
||||
this.handle_lock_key_down(event, cx);
|
||||
@@ -98,10 +99,12 @@ impl NyaTermApp {
|
||||
.justify_center()
|
||||
.child(
|
||||
div()
|
||||
.id("lock-screen-content")
|
||||
.flex()
|
||||
.flex_col()
|
||||
.items_center()
|
||||
.gap_5()
|
||||
.on_click(|_, _, cx| cx.stop_propagation())
|
||||
.child(
|
||||
div()
|
||||
.relative()
|
||||
@@ -185,33 +188,19 @@ impl NyaTermApp {
|
||||
)
|
||||
.text_sm()
|
||||
.text_color(rgb(palette.text))
|
||||
.cursor_pointer()
|
||||
.track_focus(&self.lock_focus)
|
||||
.on_click(cx.listener(|this, _, window, cx| {
|
||||
window.focus(&this.lock_focus);
|
||||
cx.notify();
|
||||
}))
|
||||
.child(password_display)
|
||||
.cursor_text()
|
||||
.on_mouse_down(
|
||||
MouseButton::Left,
|
||||
move |_, window, _| {
|
||||
window.focus(&password_focus);
|
||||
},
|
||||
)
|
||||
.child(
|
||||
gpui::canvas(
|
||||
|_bounds, _window, _cx| {},
|
||||
move |bounds, _state, window, cx| {
|
||||
let focus = input_entity
|
||||
.read(cx)
|
||||
.lock_focus
|
||||
.clone();
|
||||
window.handle_input(
|
||||
&focus,
|
||||
gpui::ElementInputHandler::new(
|
||||
bounds,
|
||||
input_entity.clone(),
|
||||
),
|
||||
cx,
|
||||
);
|
||||
},
|
||||
)
|
||||
.absolute()
|
||||
.inset_0(),
|
||||
div()
|
||||
.min_w_0()
|
||||
.flex_1()
|
||||
.overflow_hidden()
|
||||
.child(password_input),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
||||
@@ -7,21 +7,26 @@ impl NyaTermApp {
|
||||
pub(in crate::features) fn lock_app(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.is_locked = true;
|
||||
self.lock_password_draft.clear();
|
||||
self.lock_password_marked_text.clear();
|
||||
self.forget_text_inputs("lock-screen.password");
|
||||
self.lock_status = if self.settings.has_master_password {
|
||||
self.tr("lockScreen.passwordPlaceholder").to_string()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
self.terminal.view.status = "screen locked".to_string();
|
||||
window.focus(&self.lock_focus);
|
||||
if self.settings.has_master_password {
|
||||
let field = self.text_input("lock-screen.password", "", TextInputSetup::masked(), cx);
|
||||
window.focus(&field.read(cx).focus_handle());
|
||||
} else {
|
||||
window.focus(&self.lock_focus);
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(in crate::features) fn unlock_app(&mut self, cx: &mut Context<Self>) {
|
||||
self.is_locked = false;
|
||||
self.lock_password_draft.clear();
|
||||
self.lock_password_marked_text.clear();
|
||||
self.forget_text_inputs("lock-screen.password");
|
||||
self.lock_status.clear();
|
||||
self.last_user_activity_at = Instant::now();
|
||||
self.terminal.view.status = "screen unlocked".to_string();
|
||||
@@ -43,14 +48,14 @@ impl NyaTermApp {
|
||||
Ok(true) => self.unlock_app(cx),
|
||||
Ok(false) => {
|
||||
self.lock_password_draft.clear();
|
||||
self.lock_password_marked_text.clear();
|
||||
self.reset_text_input("lock-screen.password", "", cx);
|
||||
self.lock_status = self.tr("lockScreen.wrongPassword").to_string();
|
||||
self.terminal.view.status = "screen unlock rejected".to_string();
|
||||
cx.notify();
|
||||
}
|
||||
Err(error) => {
|
||||
self.lock_password_draft.clear();
|
||||
self.lock_password_marked_text.clear();
|
||||
self.reset_text_input("lock-screen.password", "", cx);
|
||||
self.lock_status = format!("{}: {error}", self.tr("lockScreen.unlockFailed"));
|
||||
self.terminal.view.status = "screen unlock failed".to_string();
|
||||
cx.notify();
|
||||
@@ -73,30 +78,24 @@ impl NyaTermApp {
|
||||
"escape" if !self.settings.has_master_password => self.unlock_app(cx),
|
||||
"escape" => {
|
||||
self.lock_password_draft.clear();
|
||||
self.reset_text_input("lock-screen.password", "", cx);
|
||||
self.lock_status = self.tr("lockScreen.passwordPlaceholder").to_string();
|
||||
cx.notify();
|
||||
}
|
||||
"backspace" => {
|
||||
self.lock_password_draft.pop();
|
||||
self.lock_password_marked_text.clear();
|
||||
cx.notify();
|
||||
}
|
||||
_ if self.settings.has_master_password => {
|
||||
if let Some(value) = keystroke
|
||||
.key_char
|
||||
.as_deref()
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
self.lock_password_draft.push_str(value);
|
||||
self.lock_password_marked_text.clear();
|
||||
self.lock_status = self.tr("lockScreen.passwordPlaceholder").to_string();
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::features) fn apply_lock_password_input(
|
||||
&mut self,
|
||||
text: String,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.lock_password_draft = text;
|
||||
self.lock_status = self.tr("lockScreen.passwordPlaceholder").to_string();
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(in crate::features) fn reveal_log_dir(&mut self, cx: &mut Context<Self>) {
|
||||
match std::fs::create_dir_all(self.runtime.log_dir()) {
|
||||
Ok(()) => {
|
||||
|
||||
@@ -31,7 +31,7 @@ impl NyaTermApp {
|
||||
self.security.unlock.prompt_open = false;
|
||||
self.security.unlock.master_required_prompt_open = true;
|
||||
self.security.unlock.draft.clear();
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.forget_text_inputs("security.unlock.password");
|
||||
self.security.unlock.error = None;
|
||||
self.security.status = "master password required".to_string();
|
||||
cx.notify();
|
||||
@@ -40,15 +40,17 @@ impl NyaTermApp {
|
||||
self.security.unlock.master_required_prompt_open = false;
|
||||
self.security.unlock.prompt_open = true;
|
||||
self.security.unlock.draft.clear();
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.forget_text_inputs("security.unlock.password");
|
||||
let field = self.text_input("security.unlock.password", "", TextInputSetup::masked(), cx);
|
||||
self.security.unlock.error = None;
|
||||
self.security.status = "enter master password to unlock secrets".to_string();
|
||||
window.focus(&self.security.unlock.focus);
|
||||
window.focus(&field.read(cx).focus_handle());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(in crate::features) fn close_security_unlock_prompt(&mut self, cx: &mut Context<Self>) {
|
||||
self.security.close_unlock_prompt();
|
||||
self.forget_text_inputs("security.unlock.password");
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -78,6 +80,7 @@ impl NyaTermApp {
|
||||
|
||||
pub(in crate::features) fn lock_security_secrets(&mut self, cx: &mut Context<Self>) {
|
||||
self.security.lock_secrets();
|
||||
self.forget_text_inputs("security.unlock.password");
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -91,7 +94,7 @@ impl NyaTermApp {
|
||||
self.security.unlock.prompt_open = false;
|
||||
self.security.unlock.master_required_prompt_open = true;
|
||||
self.security.unlock.draft.clear();
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.forget_text_inputs("security.unlock.password");
|
||||
self.security.unlock.error = None;
|
||||
self.security.status = "master password required".to_string();
|
||||
cx.notify();
|
||||
@@ -114,7 +117,7 @@ impl NyaTermApp {
|
||||
}
|
||||
Ok(false) => {
|
||||
self.security.unlock.draft.clear();
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.reset_text_input("security.unlock.password", "", cx);
|
||||
self.security.unlock.error =
|
||||
Some(self.tr("secretUnlock.wrongPassword").to_string());
|
||||
self.security.status = "unlock rejected".to_string();
|
||||
@@ -122,7 +125,7 @@ impl NyaTermApp {
|
||||
}
|
||||
Err(error) => {
|
||||
self.security.unlock.draft.clear();
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.reset_text_input("security.unlock.password", "", cx);
|
||||
self.security.unlock.error = Some(error.to_string());
|
||||
self.security.status = "unlock failed".to_string();
|
||||
cx.notify();
|
||||
@@ -144,30 +147,20 @@ impl NyaTermApp {
|
||||
match keystroke.key.as_str() {
|
||||
"enter" => self.submit_security_unlock(window, cx),
|
||||
"escape" => self.cancel_security_unlock_prompt(cx),
|
||||
"backspace" => {
|
||||
if self.security.unlock.marked_text.is_empty() {
|
||||
self.security.unlock.draft.pop();
|
||||
} else {
|
||||
self.security.unlock.marked_text.clear();
|
||||
}
|
||||
self.security.unlock.error = None;
|
||||
cx.notify();
|
||||
}
|
||||
_ => {
|
||||
if let Some(value) = keystroke
|
||||
.key_char
|
||||
.as_deref()
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.security.unlock.draft.push_str(value);
|
||||
self.security.unlock.error = None;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::features) fn apply_security_unlock_password_input(
|
||||
&mut self,
|
||||
text: String,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.security.unlock.draft = text;
|
||||
self.security.unlock.error = None;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn execute_security_unlock_action(
|
||||
&mut self,
|
||||
action: SecurityUnlockAction,
|
||||
|
||||
@@ -59,7 +59,6 @@ pub(in crate::features) struct SecurityUnlockState {
|
||||
pub prompt_open: bool,
|
||||
pub master_required_prompt_open: bool,
|
||||
pub draft: String,
|
||||
pub marked_text: String,
|
||||
pub error: Option<String>,
|
||||
pub pending_action: Option<SecurityUnlockAction>,
|
||||
pub focus: FocusHandle,
|
||||
@@ -96,7 +95,6 @@ impl SecurityFeatureState {
|
||||
prompt_open: false,
|
||||
master_required_prompt_open: false,
|
||||
draft: String::new(),
|
||||
marked_text: String::new(),
|
||||
error: None,
|
||||
pending_action: None,
|
||||
focus: focus.unlock,
|
||||
@@ -147,7 +145,6 @@ impl SecurityFeatureState {
|
||||
pub(in crate::features) fn close_unlock_prompt(&mut self) {
|
||||
self.unlock.prompt_open = false;
|
||||
self.unlock.draft.clear();
|
||||
self.unlock.marked_text.clear();
|
||||
self.unlock.error = None;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,11 @@ impl NyaTermApp {
|
||||
})
|
||||
}
|
||||
|
||||
pub(in crate::features) fn drive_idle_lock(&mut self) -> bool {
|
||||
pub(in crate::features) fn drive_idle_lock(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
if self.is_locked
|
||||
|| !self.settings.enable_screen_lock
|
||||
|| self.settings.idle_lock_minutes == 0
|
||||
@@ -257,6 +261,7 @@ impl NyaTermApp {
|
||||
}
|
||||
self.is_locked = true;
|
||||
self.lock_password_draft.clear();
|
||||
self.forget_text_inputs("lock-screen.password");
|
||||
self.lock_status = if self.settings.has_master_password {
|
||||
"Enter the master password to unlock.".to_string()
|
||||
} else {
|
||||
@@ -266,6 +271,12 @@ impl NyaTermApp {
|
||||
"screen locked after {} minute(s) idle",
|
||||
self.settings.idle_lock_minutes
|
||||
);
|
||||
if self.settings.has_master_password {
|
||||
let field = self.text_input("lock-screen.password", "", TextInputSetup::masked(), cx);
|
||||
window.focus(&field.read(cx).focus_handle());
|
||||
} else {
|
||||
window.focus(&self.lock_focus);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
@@ -644,7 +644,7 @@ impl NyaTermApp {
|
||||
result.remote_refresh = stage_started_at.elapsed();
|
||||
|
||||
let stage_started_at = Instant::now();
|
||||
dirty |= self.drive_idle_lock();
|
||||
dirty |= self.drive_idle_lock(window, cx);
|
||||
result.idle_lock = stage_started_at.elapsed();
|
||||
result.dirty = dirty;
|
||||
result
|
||||
|
||||
@@ -86,14 +86,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
*adjusted_range = Some(utf16_range_from_bytes(text, &byte_range));
|
||||
return Some(text[byte_range].to_string());
|
||||
}
|
||||
if self.security.unlock.prompt_open && !self.security.unlock.marked_text.is_empty() {
|
||||
let marked = &self.security.unlock.marked_text;
|
||||
let len = marked.encode_utf16().count();
|
||||
let start = range.start.min(len);
|
||||
let end = range.end.min(len).max(start);
|
||||
*adjusted_range = Some(start..end);
|
||||
return Some(marked.clone());
|
||||
}
|
||||
let quick_switch = self.quick_switch_state(cx);
|
||||
if quick_switch.is_open() && !quick_switch.marked_text().is_empty() {
|
||||
let marked = quick_switch.marked_text();
|
||||
@@ -103,14 +95,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
*adjusted_range = Some(start..end);
|
||||
return Some(marked.to_string());
|
||||
}
|
||||
if self.is_locked && !self.lock_password_marked_text.is_empty() {
|
||||
let marked = &self.lock_password_marked_text;
|
||||
let len = marked.encode_utf16().count();
|
||||
let start = range.start.min(len);
|
||||
let end = range.end.min(len).max(start);
|
||||
*adjusted_range = Some(start..end);
|
||||
return Some(marked.clone());
|
||||
}
|
||||
if self.terminal.input.ime_marked_text.is_empty() {
|
||||
return None;
|
||||
}
|
||||
@@ -127,13 +111,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<UTF16Selection> {
|
||||
if self.security.unlock.prompt_open {
|
||||
let cursor = self.security.unlock.draft.encode_utf16().count();
|
||||
return Some(UTF16Selection {
|
||||
range: cursor..cursor,
|
||||
reversed: false,
|
||||
});
|
||||
}
|
||||
let quick_switch = self.quick_switch_state(cx);
|
||||
if quick_switch.is_open() {
|
||||
let cursor = quick_switch.query().encode_utf16().count();
|
||||
@@ -142,13 +119,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
reversed: false,
|
||||
});
|
||||
}
|
||||
if self.is_locked {
|
||||
let cursor = self.lock_password_draft.encode_utf16().count();
|
||||
return Some(UTF16Selection {
|
||||
range: cursor..cursor,
|
||||
reversed: false,
|
||||
});
|
||||
}
|
||||
if self.multi_line_paste_focus.is_focused(window) {
|
||||
let text = self.multi_line_paste_text();
|
||||
let range = self.multi_line_paste_selected_byte_range();
|
||||
@@ -171,19 +141,11 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Range<usize>> {
|
||||
if self.security.unlock.prompt_open {
|
||||
let len = self.security.unlock.marked_text.encode_utf16().count();
|
||||
return (len > 0).then_some(0..len);
|
||||
}
|
||||
let quick_switch = self.quick_switch_state(cx);
|
||||
if quick_switch.is_open() {
|
||||
let len = quick_switch.marked_text().encode_utf16().count();
|
||||
return (len > 0).then_some(0..len);
|
||||
}
|
||||
if self.is_locked {
|
||||
let len = self.lock_password_marked_text.encode_utf16().count();
|
||||
return (len > 0).then_some(0..len);
|
||||
}
|
||||
if self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window) {
|
||||
return self
|
||||
.multi_line_paste_marked_range
|
||||
@@ -195,18 +157,10 @@ impl EntityInputHandler for NyaTermApp {
|
||||
}
|
||||
|
||||
fn unmark_text(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.security.unlock.prompt_open {
|
||||
self.security.unlock.marked_text.clear();
|
||||
return;
|
||||
}
|
||||
if self.quick_switch_open(cx) {
|
||||
self.update_quick_switch_state(cx, |store| store.clear_quick_switch_marked_text());
|
||||
return;
|
||||
}
|
||||
if self.is_locked {
|
||||
self.lock_password_marked_text.clear();
|
||||
return;
|
||||
}
|
||||
if self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window) {
|
||||
self.multi_line_paste_marked_text.clear();
|
||||
self.multi_line_paste_marked_range = None;
|
||||
@@ -222,27 +176,11 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.security.unlock.prompt_open {
|
||||
self.security.unlock.marked_text.clear();
|
||||
self.security.unlock.draft.push_str(text);
|
||||
self.security.unlock.error = None;
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.quick_switch_open(cx) {
|
||||
self.update_quick_switch_state(cx, |store| store.replace_quick_switch_text(text));
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.is_locked {
|
||||
self.lock_password_marked_text.clear();
|
||||
if !text.is_empty() {
|
||||
self.lock_password_draft.push_str(text);
|
||||
self.lock_status = self.tr("lockScreen.passwordPlaceholder").to_string();
|
||||
}
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window) {
|
||||
let range = range
|
||||
.as_ref()
|
||||
@@ -278,11 +216,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.security.unlock.prompt_open {
|
||||
self.security.unlock.marked_text = new_text.to_string();
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.quick_switch_open(cx) {
|
||||
self.update_quick_switch_state(cx, |store| {
|
||||
store.set_quick_switch_marked_text(new_text)
|
||||
@@ -290,11 +223,6 @@ impl EntityInputHandler for NyaTermApp {
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.is_locked {
|
||||
self.lock_password_marked_text = new_text.to_string();
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
if self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window) {
|
||||
let range = range
|
||||
.as_ref()
|
||||
@@ -326,23 +254,8 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Bounds<Pixels>> {
|
||||
if self.security.unlock.prompt_open {
|
||||
return Some(gpui::bounds(
|
||||
Point {
|
||||
x: element_bounds.left(),
|
||||
y: element_bounds.bottom() - px(18.),
|
||||
},
|
||||
Size {
|
||||
width: px(1.),
|
||||
height: px(18.),
|
||||
},
|
||||
));
|
||||
}
|
||||
if self.quick_switch_open(cx)
|
||||
|| self.is_locked
|
||||
|| (self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window))
|
||||
|| (self.rename_session_id.is_some() && self.rename_focus.is_focused(window))
|
||||
|| (self.startup_command_open && self.startup_command_focus.is_focused(window))
|
||||
{
|
||||
return Some(element_bounds);
|
||||
}
|
||||
@@ -384,28 +297,16 @@ impl EntityInputHandler for NyaTermApp {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<usize> {
|
||||
if self.security.unlock.prompt_open {
|
||||
return Some(self.security.unlock.draft.encode_utf16().count());
|
||||
}
|
||||
let quick_switch = self.quick_switch_state(cx);
|
||||
if quick_switch.is_open() {
|
||||
return Some(quick_switch.query().encode_utf16().count());
|
||||
}
|
||||
if self.is_locked {
|
||||
return Some(self.lock_password_draft.encode_utf16().count());
|
||||
}
|
||||
if self.multi_line_paste.is_some() && self.multi_line_paste_focus.is_focused(window) {
|
||||
return Some(utf16_offset_for_byte(
|
||||
self.multi_line_paste_text(),
|
||||
self.multi_line_paste_cursor,
|
||||
));
|
||||
}
|
||||
if self.rename_session_id.is_some() && self.rename_focus.is_focused(window) {
|
||||
return Some(self.rename_draft.encode_utf16().count());
|
||||
}
|
||||
if self.startup_command_open && self.startup_command_focus.is_focused(window) {
|
||||
return Some(self.startup_command_draft.encode_utf16().count());
|
||||
}
|
||||
Some(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use gpui::{
|
||||
App, AppContext as _, Context, Entity, InteractiveElement as _, IntoElement, MouseButton,
|
||||
AppContext, Context, Entity, InteractiveElement as _, IntoElement, MouseButton,
|
||||
ParentElement as _, SharedString, Styled as _, Subscription, div, prelude::FluentBuilder as _,
|
||||
px, rgb,
|
||||
};
|
||||
@@ -197,7 +197,12 @@ impl NyaTermApp {
|
||||
}
|
||||
|
||||
/// Push a value the runtime changed back into its input.
|
||||
pub(in crate::features) fn reset_text_input(&mut self, id: &str, text: &str, cx: &mut App) {
|
||||
pub(in crate::features) fn reset_text_input(
|
||||
&mut self,
|
||||
id: &str,
|
||||
text: &str,
|
||||
cx: &mut impl AppContext,
|
||||
) {
|
||||
if let Some(field) = self.text_inputs.fields.get(id) {
|
||||
field.update(cx, |field, cx| field.set_content(text, cx));
|
||||
}
|
||||
@@ -277,6 +282,10 @@ impl NyaTermApp {
|
||||
self.apply_temporary_ssh_link(text, cx);
|
||||
} else if let Some(field) = id.strip_prefix("session.") {
|
||||
self.apply_session_text_input(field, text, cx);
|
||||
} else if id.as_ref() == "lock-screen.password" {
|
||||
self.apply_lock_password_input(text, cx);
|
||||
} else if id.as_ref() == "security.unlock.password" {
|
||||
self.apply_security_unlock_password_input(text, cx);
|
||||
} else if let Some(rest) = id.strip_prefix("ai.credential.") {
|
||||
self.apply_ai_credential_input(rest, text, cx);
|
||||
} else if let Some(field) = id
|
||||
|
||||
Reference in New Issue
Block a user