diff --git a/crates/egui/src/widgets/label.rs b/crates/egui/src/widgets/label.rs index 526ff571..a6a0e048 100644 --- a/crates/egui/src/widgets/label.rs +++ b/crates/egui/src/widgets/label.rs @@ -377,7 +377,7 @@ fn process_selection_key_events( } event => { - cursor_range.on_event(event, galley, widget_id); + cursor_range.on_event(ui.ctx().os(), event, galley, widget_id); } } } diff --git a/crates/egui/src/widgets/text_edit/builder.rs b/crates/egui/src/widgets/text_edit/builder.rs index 400aea51..155d6344 100644 --- a/crates/egui/src/widgets/text_edit/builder.rs +++ b/crates/egui/src/widgets/text_edit/builder.rs @@ -2,7 +2,9 @@ use std::sync::Arc; use epaint::text::{cursor::*, Galley, LayoutJob}; -use crate::{output::OutputEvent, text_edit::cursor_interaction::cursor_rect, *}; +use crate::{ + os::OperatingSystem, output::OutputEvent, text_edit::cursor_interaction::cursor_rect, *, +}; use super::{ cursor_interaction::{ccursor_next_word, ccursor_previous_word, find_line_start}, @@ -773,6 +775,8 @@ fn events( char_limit: usize, event_filter: EventFilter, ) -> (bool, CursorRange) { + let os = ui.ctx().os(); + let mut cursor_range = state.cursor.range(galley).unwrap_or(default_cursor_range); // We feed state to the undoer both before and after handling input @@ -794,7 +798,7 @@ fn events( for event in &events { let did_mutate_text = match event { // First handle events that only changes the selection cursor, not the text: - event if cursor_range.on_event(event, galley, id) => None, + event if cursor_range.on_event(os, event, galley, id) => None, Event::Copy => { if cursor_range.is_empty() { @@ -909,7 +913,7 @@ fn events( key, pressed: true, .. - } => check_for_mutating_key_press(&mut cursor_range, text, galley, modifiers, *key), + } => check_for_mutating_key_press(os, &mut cursor_range, text, galley, modifiers, *key), Event::CompositionStart => { state.has_ime = true; @@ -1143,6 +1147,7 @@ fn delete_paragraph_after_cursor( /// Returns `Some(new_cursor)` if we did mutate `text`. fn check_for_mutating_key_press( + os: OperatingSystem, cursor_range: &mut CursorRange, text: &mut dyn TextBuffer, galley: &Galley, @@ -1166,7 +1171,7 @@ fn check_for_mutating_key_press( Some(CCursorRange::one(ccursor)) } - Key::Delete if !modifiers.shift || !cfg!(target_os = "windows") => { + Key::Delete if !modifiers.shift || os != OperatingSystem::Windows => { let ccursor = if modifiers.mac_cmd { delete_paragraph_after_cursor(text, galley, cursor_range) } else if let Some(cursor) = cursor_range.single() { diff --git a/crates/egui/src/widgets/text_edit/cursor_range.rs b/crates/egui/src/widgets/text_edit/cursor_range.rs index e0ddfd69..1d5db9d0 100644 --- a/crates/egui/src/widgets/text_edit/cursor_range.rs +++ b/crates/egui/src/widgets/text_edit/cursor_range.rs @@ -1,6 +1,6 @@ use epaint::{text::cursor::*, Galley}; -use crate::{Event, Id, Key, Modifiers}; +use crate::{os::OperatingSystem, Event, Id, Key, Modifiers}; use super::cursor_interaction::{ccursor_next_word, ccursor_previous_word, slice_char_range}; @@ -115,7 +115,13 @@ impl CursorRange { /// Check for key presses that are moving the cursor. /// /// Returns `true` if we did mutate `self`. - pub fn on_key_press(&mut self, galley: &Galley, modifiers: &Modifiers, key: Key) -> bool { + pub fn on_key_press( + &mut self, + os: OperatingSystem, + galley: &Galley, + modifiers: &Modifiers, + key: Key, + ) -> bool { match key { Key::A if modifiers.command => { *self = Self::select_all(galley); @@ -137,7 +143,7 @@ impl CursorRange { | Key::ArrowDown | Key::Home | Key::End => { - move_single_cursor(&mut self.primary, galley, key, modifiers); + move_single_cursor(os, &mut self.primary, galley, key, modifiers); if !modifiers.shift { self.secondary = self.primary; } @@ -145,9 +151,9 @@ impl CursorRange { } Key::P | Key::N | Key::B | Key::F | Key::A | Key::E - if cfg!(target_os = "macos") && modifiers.ctrl && !modifiers.shift => + if os == OperatingSystem::Mac && modifiers.ctrl && !modifiers.shift => { - move_single_cursor(&mut self.primary, galley, key, modifiers); + move_single_cursor(os, &mut self.primary, galley, key, modifiers); self.secondary = self.primary; true } @@ -159,14 +165,20 @@ impl CursorRange { /// Check for events that modify the cursor range. /// /// Returns `true` if such an event was found and handled. - pub fn on_event(&mut self, event: &Event, galley: &Galley, _widget_id: Id) -> bool { + pub fn on_event( + &mut self, + os: OperatingSystem, + event: &Event, + galley: &Galley, + _widget_id: Id, + ) -> bool { match event { Event::Key { modifiers, key, pressed: true, .. - } => self.on_key_press(galley, modifiers, *key), + } => self.on_key_press(os, galley, modifiers, *key), #[cfg(feature = "accesskit")] Event::AccessKitActionRequest(accesskit::ActionRequest { @@ -287,8 +299,14 @@ fn ccursor_from_accesskit_text_position( // ---------------------------------------------------------------------------- /// Move a text cursor based on keyboard -fn move_single_cursor(cursor: &mut Cursor, galley: &Galley, key: Key, modifiers: &Modifiers) { - if cfg!(target_os = "macos") && modifiers.ctrl && !modifiers.shift { +fn move_single_cursor( + os: OperatingSystem, + cursor: &mut Cursor, + galley: &Galley, + key: Key, + modifiers: &Modifiers, +) { + if os == OperatingSystem::Mac && modifiers.ctrl && !modifiers.shift { match key { Key::A => *cursor = galley.cursor_begin_of_row(cursor), Key::E => *cursor = galley.cursor_end_of_row(cursor), diff --git a/scripts/lint.py b/scripts/lint.py index 366f65fa..59322ad2 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -66,6 +66,15 @@ def lint_lines(filepath, lines_in): ) lines_out.append("#[inline]") + if ( + "(target_os" in line + and filepath.startswith("./crates/egui/") + and filepath != "./crates/egui/src/os.rs" + ): + errors.append( + f"{filepath}:{line_nr}: Don't use `target_os` - use ctx.os() instead." + ) + lines_out.append(line) prev_line = line