diff --git a/src/input.rs b/src/input.rs
index 27701b576d26378e8bfa67e2b4e69cb47020a404..8d441010f2ea3a4fc958bbb411ef618e6ecce3b5 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -3,7 +3,7 @@
 use std::time::Duration;
 
 use bevy::{
-    input::mouse::{MouseScrollUnit, MouseWheel},
+    input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel},
     prelude::*,
     window::PrimaryWindow,
 };
@@ -16,28 +16,50 @@ use crate::{
     XOffset,
 };
 
+#[derive(Resource)]
+pub struct ClickTimer(pub Timer);
+
 pub(crate) fn input_mouse(
-    windows: Query<&Window, With<PrimaryWindow>>, // Mouse
-    active_editor: Res<Focus>,                    // Both
-    keys: Res<Input<KeyCode>>,                    // Both
-    buttons: Res<Input<MouseButton>>,             // Mouse
+    windows: Query<&Window, With<PrimaryWindow>>,
+    active_editor: Res<Focus>,
+    keys: Res<Input<KeyCode>>,
+    buttons: Res<Input<MouseButton>>,
     mut cosmic_edit_query: Query<(
-        &mut CosmicEditor,   // Both
-        &GlobalTransform,    // Mouse
-        &CosmicTextPosition, // Mouse, to determine point
-        Entity,              // Both
-        &XOffset,            // Mouse
+        &mut CosmicEditor,
+        &GlobalTransform,
+        &CosmicTextPosition,
+        Entity,
+        &XOffset,
         Option<&mut Node>,
         Option<&mut Sprite>,
     )>,
-    mut font_system: ResMut<CosmicFontSystem>,    // Both
-    mut scroll_evr: EventReader<MouseWheel>,      // Mouse
-    camera_q: Query<(&Camera, &GlobalTransform)>, // Mouse
+    mut font_system: ResMut<CosmicFontSystem>,
+    mut scroll_evr: EventReader<MouseWheel>,
+    camera_q: Query<(&Camera, &GlobalTransform)>,
+    mut click_timer: ResMut<ClickTimer>,
+    mut click_count: Local<usize>,
+    time: Res<Time>,
+    evr_mouse_motion: EventReader<MouseMotion>,
 ) {
+    click_timer.0.tick(time.delta());
+
     if active_editor.0.is_none() {
         return;
     }
 
+    if click_timer.0.finished() || !evr_mouse_motion.is_empty() {
+        *click_count = 0;
+    }
+
+    if buttons.just_pressed(MouseButton::Left) {
+        click_timer.0.reset();
+        *click_count += 1;
+    }
+
+    if *click_count > 3 {
+        *click_count = 0;
+    }
+
     let primary_window = windows.single();
     let scale_factor = primary_window.scale_factor() as f32;
     let (camera, camera_transform) = camera_q.iter().find(|(c, _)| c.is_active).unwrap();
@@ -98,12 +120,32 @@ pub(crate) fn input_mouse(
                 if shift {
                     editor.0.action(&mut font_system.0, Action::Drag { x, y });
                 } else {
-                    editor.0.action(&mut font_system.0, Action::Click { x, y });
+                    match *click_count {
+                        1 => {
+                            editor.0.action(&mut font_system.0, Action::Click { x, y });
+                        }
+                        2 => {
+                            // select word
+                            editor.0.action(&mut font_system.0, Action::LeftWord);
+                            let cursor = editor.0.cursor();
+                            editor.0.set_select_opt(Some(cursor));
+                            editor.0.action(&mut font_system.0, Action::RightWord);
+                        }
+                        3 => {
+                            // select paragraph
+                            editor.0.action(&mut font_system.0, Action::ParagraphStart);
+                            let cursor = editor.0.cursor();
+                            editor.0.set_select_opt(Some(cursor));
+                            editor.0.action(&mut font_system.0, Action::ParagraphEnd);
+                        }
+                        _ => {}
+                    }
                 }
             }
             return;
         }
-        if buttons.pressed(MouseButton::Left) {
+
+        if buttons.pressed(MouseButton::Left) && *click_count == 0 {
             if let Some(node_cursor_pos) = get_node_cursor_pos(
                 primary_window,
                 node_transform,
@@ -122,6 +164,7 @@ pub(crate) fn input_mouse(
             }
             return;
         }
+
         for ev in scroll_evr.iter() {
             match ev.unit {
                 MouseScrollUnit::Line => {
@@ -148,23 +191,23 @@ pub(crate) fn input_mouse(
 
 /// Handles undo/redo, copy/paste and char input
 pub(crate) fn input_kb(
-    active_editor: Res<Focus>,                    // Both
-    keys: Res<Input<KeyCode>>,                    // Both
-    mut char_evr: EventReader<ReceivedCharacter>, // Kb
+    active_editor: Res<Focus>,
+    keys: Res<Input<KeyCode>>,
+    mut char_evr: EventReader<ReceivedCharacter>,
     mut cosmic_edit_query: Query<(
-        &mut CosmicEditor,      // Both
-        &mut CosmicEditHistory, // Kb - Undo
-        &CosmicAttrs,           // Kb - Undo
-        &CosmicMaxLines,        // Kb
-        &CosmicMaxChars,        // Kb
-        Entity,                 // Both
+        &mut CosmicEditor,
+        &mut CosmicEditHistory,
+        &CosmicAttrs,
+        &CosmicMaxLines,
+        &CosmicMaxChars,
+        Entity,
         Option<&ReadOnly>,
     )>,
-    mut evw_changed: EventWriter<CosmicTextChanged>, // Kb
-    mut font_system: ResMut<CosmicFontSystem>,       // Both
-    mut is_deleting: Local<bool>,                    // Kb
-    mut edits_duration: Local<Option<Duration>>,     // Kb - Undo
-    mut undoredo_duration: Local<Option<Duration>>,  // Kb - Undo
+    mut evw_changed: EventWriter<CosmicTextChanged>,
+    mut font_system: ResMut<CosmicFontSystem>,
+    mut is_deleting: Local<bool>,
+    mut edits_duration: Local<Option<Duration>>,
+    mut undoredo_duration: Local<Option<Duration>>,
 ) {
     for (mut editor, mut edit_history, attrs, max_lines, max_chars, entity, readonly_opt) in
         &mut cosmic_edit_query.iter_mut()
@@ -436,13 +479,6 @@ pub(crate) fn input_kb(
             }
         }
 
-        // fix for issue #8
-        if let Some(select) = editor.0.select_opt() {
-            if editor.0.cursor().line == select.line && editor.0.cursor().index == select.index {
-                editor.0.set_select_opt(None);
-            }
-        }
-
         let mut is_edit = is_clipboard;
         let mut is_return = false;
         if keys.just_pressed(KeyCode::Return) && !readonly {
@@ -460,6 +496,14 @@ pub(crate) fn input_kb(
             for char_ev in char_evr.iter() {
                 is_edit = true;
                 if *is_deleting {
+                    // fix for issue #8
+                    if let Some(select) = editor.0.select_opt() {
+                        if editor.0.cursor().line == select.line
+                            && editor.0.cursor().index == select.index
+                        {
+                            editor.0.set_select_opt(None);
+                        }
+                    }
                     editor.0.action(&mut font_system.0, Action::Backspace);
                 } else if max_chars.0 == 0 || editor.get_text().len() < max_chars.0 {
                     editor
diff --git a/src/lib.rs b/src/lib.rs
index 20297bab27b33a15e6d4a8b3ac7b006dd17747ff..cd5740683004dc9cbe946b45a7aea1d1d33849f3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,7 +23,7 @@ use cosmic_text::{
 use cursor::{change_cursor, hover_sprites, hover_ui};
 pub use cursor::{TextHoverIn, TextHoverOut};
 use image::{imageops::FilterType, GenericImageView};
-use input::{input_kb, input_mouse};
+use input::{input_kb, input_mouse, ClickTimer};
 
 #[derive(Clone, Component, PartialEq, Debug)]
 pub enum CosmicText {
@@ -416,6 +416,7 @@ impl Plugin for CosmicEditPlugin {
                 swash_cache: SwashCache::new(),
             })
             .insert_resource(CosmicFontSystem(font_system))
+            .insert_resource(ClickTimer(Timer::from_seconds(0.5, TimerMode::Once)))
             .add_event::<CosmicTextChanged>();
 
         match self.change_cursor {