Skip to content

Commit

Permalink
Improve selection behaviour on focus change
Browse files Browse the repository at this point in the history
On windows, we persist the existing selection when focus
changes. On mac, the behaviour depends on whether or not there
was a click. If there was a click, we use the click to determine
the selection; otherwise we select the whole buffer.

In addition, on mac, we no longer draw the cursor if the selection
is not a caret.

- fixes #1225 (again)
  • Loading branch information
cmyr committed Oct 5, 2020
1 parent 10160ed commit c8ef792
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
5 changes: 5 additions & 0 deletions druid/src/text/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ impl<T: TextStorage + EditableText> Editor<T> {
self.do_edit(EditAction::Paste(t), data)
}

/// Set the selection to the entire buffer.
pub fn select_all(&mut self, data: &T) {
self.selection = Selection::new(0, data.len());
}

fn mouse_action_for_event(&self, event: &MouseEvent) -> MouseAction {
let pos = self.layout.text_position_for_point(event.pos);
MouseAction {
Expand Down
7 changes: 0 additions & 7 deletions druid/src/text/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ impl Selection {
Selection { start, end }
}

/// Create a selection that starts at the beginning and ends at text length.
/// TODO: can text length be at a non-codepoint or a non-grapheme?
pub fn all(&mut self, text: &impl EditableText) {
self.start = 0;
self.end = text.len();
}

/// Create a caret, which is just a selection with the same and start and end.
pub fn caret(pos: usize) -> Self {
Selection {
Expand Down
28 changes: 26 additions & 2 deletions druid/src/widget/textbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ pub struct TextBox<T> {
cursor_timer: TimerToken,
cursor_on: bool,
multiline: bool,
/// true if a click event caused us to gain focus.
///
/// On macOS, if focus happens via click then we set the selection based
/// on the click position; if focus happens automatically (e.g. on tab)
/// then we select our entire contents.
was_focused_from_click: bool,
}

impl TextBox<()> {
Expand All @@ -67,6 +73,7 @@ impl<T> TextBox<T> {
cursor_on: false,
placeholder,
multiline: false,
was_focused_from_click: false,
}
}

Expand Down Expand Up @@ -166,6 +173,17 @@ impl<T: TextStorage + EditableText> TextBox<T> {
self.cursor_on = true;
self.cursor_timer = token;
}

// on macos we only draw the cursor if the selection is non-caret
#[cfg(target_os = "macos")]
fn should_draw_cursor(&self) -> bool {
self.cursor_on && self.editor.selection().is_caret()
}

#[cfg(not(target_os = "macos"))]
fn should_draw_cursor(&self) -> bool {
self.cursor_on
}
}

impl<T: TextStorage + EditableText> Widget<T> for TextBox<T> {
Expand All @@ -177,6 +195,7 @@ impl<T: TextStorage + EditableText> Widget<T> for TextBox<T> {
ctx.set_active(true);

if !mouse.focus {
self.was_focused_from_click = true;
self.reset_cursor_blink(ctx.request_timer(CURSOR_BLINK_DURATION));
self.editor.click(mouse, data);
}
Expand Down Expand Up @@ -250,7 +269,12 @@ impl<T: TextStorage + EditableText> Widget<T> for TextBox<T> {
self.editor.set_text(data.to_owned());
self.editor.rebuild_if_needed(ctx.text(), env);
}
LifeCycle::FocusChanged(_) => {
LifeCycle::FocusChanged(_is_focused) => {
#[cfg(target_os = "macos")]
if *_is_focused && !self.was_focused_from_click {
self.editor.select_all(data);
}
self.was_focused_from_click = false;
self.reset_cursor_blink(ctx.request_timer(CURSOR_BLINK_DURATION));
ctx.request_paint();
}
Expand Down Expand Up @@ -339,7 +363,7 @@ impl<T: TextStorage + EditableText> Widget<T> for TextBox<T> {
}

// Paint the cursor if focused and there's no selection
if is_focused && self.cursor_on {
if is_focused && self.should_draw_cursor() {
// the cursor position can extend past the edge of the layout
// (commonly when there is trailing whitespace) so we clamp it
// to the right edge.
Expand Down

0 comments on commit c8ef792

Please sign in to comment.