diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py
index 9811bfb953e42db34c4e21142937bbd5a6e46e23..0aedab1f0c2c7c90a3d296871bdf15f23c240075 100644
--- a/mesh_snap_utilities_line/__init__.py
+++ b/mesh_snap_utilities_line/__init__.py
@@ -33,6 +33,7 @@ if "bpy" in locals():
     import importlib
     importlib.reload(preferences)
     importlib.reload(ops_line)
+    importlib.reload(common_classes)
 else:
     from . import preferences
     from . import ops_line
@@ -64,11 +65,11 @@ def tool_make_line():
             "Connect them to split faces"
         ),
         icon=os.path.join(icons_dir, "ops.mesh.make_line"),
-        widget=None,
+        widget="MESH_GGT_mouse_point",
         operator="mesh.make_line",
-        keymap=(
-            ("mesh.make_line", None, dict(type='ACTIONMOUSE', value='PRESS')),
-        ),
+#        keymap=(
+#            ("mesh.make_line", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
+#        ),
         draw_settings=draw_settings,
     )
 
@@ -81,6 +82,8 @@ def register():
 
     bpy.utils.register_class(preferences.SnapUtilitiesLinePreferences)
     bpy.utils.register_class(ops_line.SnapUtilitiesLine)
+    bpy.utils.register_class(common_classes.MousePointWidget)
+    bpy.utils.register_class(common_classes.MousePointWidgetGroup)
 
     bpy.utils.register_tool('VIEW_3D', 'EDIT_MESH', tool_make_line)
 
@@ -94,6 +97,8 @@ def register():
 def unregister():
     bpy.utils.unregister_tool('VIEW_3D', 'EDIT_MESH', tool_make_line)
 
+    bpy.utils.unregister_class(common_classes.MousePointWidgetGroup)
+    bpy.utils.unregister_class(common_classes.MousePointWidget)
     bpy.utils.unregister_class(ops_line.SnapUtilitiesLine)
     bpy.utils.unregister_class(preferences.SnapUtilitiesLinePreferences)
 
diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py
index 09fc3a0283bc0ffd96cd1a2a393af9eb90163f25..9a968862d2aab98142fde516c3714273cdd109a0 100644
--- a/mesh_snap_utilities_line/common_classes.py
+++ b/mesh_snap_utilities_line/common_classes.py
@@ -20,6 +20,8 @@ import bgl
 import gpu
 import numpy as np
 
+from .common_utilities import snap_utilities
+
 
 class SnapDrawn():
     def __init__(self, out_color, face_color,
@@ -161,19 +163,20 @@ class SnapDrawn():
         gpu.matrix.multiply_matrix(snap_obj.mat)
 
         if isinstance(elem, BMVert):
-            color = self.vert_color
-            edges = np.empty((len(elem.link_edges), 2), [("pos", "f4", 3), ("color", "f4", 4)])
-            edges["pos"][:, 0] = elem.co
-            edges["pos"][:, 1] = [e.other_vert(elem).co for e in elem.link_edges]
-            edges["color"][:, 0] = color
-            edges["color"][:, 1] = (color[0], color[1], color[2], 0.0)
-            edges.shape = -1
-
-            self._program_smooth_col.bind()
-            bgl.glLineWidth(3.0)
-            batch = self.batch_lines_smooth_color_create(edges["pos"], edges["color"])
-            batch.draw(self._program_smooth_col)
-            bgl.glLineWidth(1.0)
+            if elem.link_edges:
+                color = self.vert_color
+                edges = np.empty((len(elem.link_edges), 2), [("pos", "f4", 3), ("color", "f4", 4)])
+                edges["pos"][:, 0] = elem.co
+                edges["pos"][:, 1] = [e.other_vert(elem).co for e in elem.link_edges]
+                edges["color"][:, 0] = color
+                edges["color"][:, 1] = (color[0], color[1], color[2], 0.0)
+                edges.shape = -1
+
+                self._program_smooth_col.bind()
+                bgl.glLineWidth(3.0)
+                batch = self.batch_lines_smooth_color_create(edges["pos"], edges["color"])
+                batch.draw(self._program_smooth_col)
+                bgl.glLineWidth(1.0)
         else:
             self._program_unif_col.bind()
 
@@ -332,3 +335,104 @@ class CharMap:
             elif event.type == 'RIGHT_ARROW':
                 self.line_pos = (self.line_pos + 1) % (len(self.length_entered) + 1)
 
+
+class MousePointWidget(bpy.types.Gizmo):
+    bl_idname = "VIEW3D_GT_mouse_point"
+
+    __slots__ = (
+        "sctx",
+        "bm",
+        "draw_cache",
+        "geom",
+        "incremental",
+        "preferences",
+        "loc",
+        "snap_obj",
+        "snap_to_grid",
+        "type",
+    )
+
+    def test_select(self, context, mval):
+        #print('test_select', mval)
+        self.snap_obj, prev_loc, self.loc, self.type, self.bm, self.geom, len = snap_utilities(
+                self.sctx,
+                None,
+                mval,
+                increment=self.incremental
+        )
+        context.area.tag_redraw()
+        return False
+
+    def draw(self, context):
+        if self.bm:
+            self.draw_cache.draw_elem(self.snap_obj, self.bm, self.geom)
+        self.draw_cache.draw(self.type, self.loc, None, None, None)
+
+    def setup(self):
+        if not hasattr(self, "sctx"):
+            context = bpy.context
+
+            self.preferences = preferences = context.user_preferences.addons[__package__].preferences
+
+            #Configure the unit of measure
+            self.snap_to_grid = preferences.increments_grid
+            self.incremental = bpy.utils.units.to_value(
+                    context.scene.unit_settings.system, 'LENGTH', str(preferences.incremental))
+
+            self.draw_cache = SnapDrawn(
+                preferences.out_color,
+                preferences.face_color,
+                preferences.edge_color,
+                preferences.vert_color,
+                preferences.center_color,
+                preferences.perpendicular_color,
+                preferences.constrain_shift_color,
+                (*context.user_preferences.themes[0].user_interface.axis_x, 1.0),
+                (*context.user_preferences.themes[0].user_interface.axis_y, 1.0),
+                (*context.user_preferences.themes[0].user_interface.axis_z, 1.0)
+            )
+
+            #Init Snap Context
+            from .snap_context_l import SnapContext
+            from mathutils import Vector
+
+            self.sctx = SnapContext(context.region, context.space_data)
+            self.sctx.set_pixel_dist(12)
+            self.sctx.use_clip_planes(True)
+
+            if preferences.outer_verts:
+                for base in context.visible_bases:
+                    self.sctx.add_obj(base.object, base.object.matrix_world)
+
+            self.sctx.set_snap_mode(True, True, True)
+            self.bm = None
+            self.type = 'OUT'
+            self.loc = Vector()
+
+    def __del__(self):
+        self.sctx.free()
+        del self.draw_cache
+
+
+class MousePointWidgetGroup(bpy.types.GizmoGroup):
+    bl_idname = "MESH_GGT_mouse_point"
+    bl_label = "Draw Mouse Point"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'WINDOW'
+    bl_options = {'3D'}
+
+    __slots__ = (
+        "snap_widget",
+    )
+
+    def setup(self, context):
+        if not hasattr(self, "snap_widget"):
+            self.snap_widget = self.gizmos.new(MousePointWidget.bl_idname)
+            props = self.snap_widget.target_set_operator("mesh.make_line")
+            props.wait_for_input = False
+
+            b_sctx_ptr = id(self.snap_widget).to_bytes(8, 'big')
+            props.snap_widget_ptr[0] = int.from_bytes(b_sctx_ptr[0:2], 'big')
+            props.snap_widget_ptr[1] = int.from_bytes(b_sctx_ptr[2:4], 'big')
+            props.snap_widget_ptr[2] = int.from_bytes(b_sctx_ptr[4:6], 'big')
+            props.snap_widget_ptr[3] = int.from_bytes(b_sctx_ptr[6:8], 'big')
diff --git a/mesh_snap_utilities_line/ops_line.py b/mesh_snap_utilities_line/ops_line.py
index 2fe01ef9b627620e49e33a528afc8ba8174078cf..ecef5a86f466309e1942df379899fe9eab8dc4cd 100644
--- a/mesh_snap_utilities_line/ops_line.py
+++ b/mesh_snap_utilities_line/ops_line.py
@@ -83,12 +83,12 @@ def draw_line(self, bm_geom, location):
     bm = self.main_bm
     split_faces = set()
 
-    drawing_is_dirt = False
     update_edit_mesh = False
 
     if bm_geom is None:
         vert = bm.verts.new(location)
         self.list_verts.append(vert)
+        update_edit_mesh = True
 
     elif isinstance(bm_geom, bmesh.types.BMVert):
         if (bm_geom.co - location).length_squared < .001:
@@ -97,7 +97,7 @@ def draw_line(self, bm_geom, location):
         else:
             vert = bm.verts.new(location)
             self.list_verts.append(vert)
-            drawing_is_dirt = True
+            update_edit_mesh = True
 
     elif isinstance(bm_geom, bmesh.types.BMEdge):
         self.list_edges.append(bm_geom)
@@ -110,7 +110,8 @@ def draw_line(self, bm_geom, location):
                 vert = bm_geom.verts[1]
             else:
                 edge, vert = bmesh.utils.edge_split(bm_geom, bm_geom.verts[0], ret[1])
-                drawing_is_dirt = True
+                update_edit_mesh = True
+
             self.list_verts.append(vert)
             self.geom = vert # hack to highlight in the drawing
             # self.list_edges.append(edge)
@@ -118,27 +119,25 @@ def draw_line(self, bm_geom, location):
         else:  # constrain point is near
             vert = bm.verts.new(location)
             self.list_verts.append(vert)
-            drawing_is_dirt = True
+            update_edit_mesh = True
 
     elif isinstance(bm_geom, bmesh.types.BMFace):
         split_faces.add(bm_geom)
         vert = bm.verts.new(location)
         self.list_verts.append(vert)
-        drawing_is_dirt = True
+        update_edit_mesh = True
 
     # draw, split and create face
     if len(self.list_verts) >= 2:
         v1, v2 = self.list_verts[-2:]
-        # v2_link_verts = [x for y in [a.verts for a in v2.link_edges] for x in y if x != v2]
         edge = bm.edges.get([v1, v2])
         if edge:
                 self.list_edges.append(edge)
 
-        else:  # if v1 not in v2_link_verts:
+        else:
             if not v2.link_edges:
                 edge = bm.edges.new([v1, v2])
                 self.list_edges.append(edge)
-                drawing_is_dirt = True
             else:  # split face
                 v1_link_faces = v1.link_faces
                 v2_link_faces = v2.link_faces
@@ -166,7 +165,6 @@ def draw_line(self, bm_geom, location):
                     for face in split_faces:
                         facesp = bmesh.utils.face_split_edgenet(face, ed_list)
                     del split_faces
-                    update_edit_mesh = True
                 else:
                     if self.intersect:
                         facesp = bmesh.ops.connect_vert_pair(bm, verts=[v1, v2], verts_exclude=bm.verts)
@@ -174,11 +172,10 @@ def draw_line(self, bm_geom, location):
                     if not self.intersect or not facesp['edges']:
                         edge = bm.edges.new([v1, v2])
                         self.list_edges.append(edge)
-                        drawing_is_dirt = True
                     else:
                         for edge in facesp['edges']:
                             self.list_edges.append(edge)
-                            update_edit_mesh = True
+            update_edit_mesh = True
 
         # create face
         if self.create_face:
@@ -198,7 +195,8 @@ def draw_line(self, bm_geom, location):
             bmesh.ops.edgenet_fill(bm, edges=list(ed_list))
             update_edit_mesh = True
             # print('face created')
-    if update_edit_mesh or drawing_is_dirt:
+
+    if update_edit_mesh:
         obj.data.update_gpu_tag()
         obj.data.update_tag()
         obj.update_from_editmode()
@@ -207,6 +205,9 @@ def draw_line(self, bm_geom, location):
         self.sctx.tag_update_drawn_snap_object(self.main_snap_obj)
         #bm.verts.index_update()
 
+        if not self.wait_for_input:
+            bpy.ops.ed.undo_push(message="Undo draw line*")
+
     return [obj.matrix_world @ v.co for v in self.list_verts]
 
 
@@ -216,6 +217,13 @@ class SnapUtilitiesLine(bpy.types.Operator):
     bl_label = "Line Tool"
     bl_options = {'REGISTER'}
 
+    wait_for_input: bpy.props.BoolProperty(name="Wait for Input", default=True)
+    snap_widget_ptr: bpy.props.IntVectorProperty(
+        name="Adress of a SnapContext object",
+        size=4,
+        default=(0, 0, 0, 0),
+        )
+
     constrain_keys = {
         'X': Vector((1,0,0)),
         'Y': Vector((0,1,0)),
@@ -224,6 +232,28 @@ class SnapUtilitiesLine(bpy.types.Operator):
         'LEFT_SHIFT': 'shift',
     }
 
+    def _exit(self, context):
+        del self.main_bm #avoids unpredictable crashs
+        del self.bm
+        del self.list_edges
+        del self.list_verts
+        del self.list_verts_co
+
+        bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+        context.area.header_text_set(None)
+
+        if not self.snap_widget:
+            self.sctx.free()
+            del self.draw_cache
+        else:
+            self.sctx = None
+            self.draw_cache = None
+
+        #Restore initial state
+        context.tool_settings.mesh_select_mode = self.select_mode
+        context.user_preferences.view.use_rotate_around_active = self.use_rotate_around_active
+        context.space_data.overlay.show_face_center = self.show_face_center
+
     def modal(self, context, event):
         if self.navigation_ops.run(context, event, self.prevloc if self.vector_constrain else self.location):
             return {'RUNNING_MODAL'}
@@ -336,7 +366,6 @@ class SnapUtilitiesLine(bpy.types.Operator):
 
                 self.vector_constrain = None
                 self.list_verts_co = draw_line(self, geom2, point)
-                bpy.ops.ed.undo_push(message="Undo draw line*")
 
             elif event.type == 'TAB':
                 self.keytab = self.keytab is False
@@ -367,26 +396,13 @@ class SnapUtilitiesLine(bpy.types.Operator):
                     except:  # ValueError:
                         self.report({'INFO'}, "Operation not supported yet")
 
-            elif event.type in {'RIGHTMOUSE', 'ESC'}:
-                if not is_making_lines or event.type == 'ESC':
-                    del self.main_bm #avoids unpredictable crashs
-                    del self.bm
-                    del self.list_edges
-                    del self.list_verts
-                    del self.list_verts_co
-
-                    bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-                    context.area.header_text_set(None)
-                    self.sctx.free()
-                    del self.draw_cache
-
-                    #Restore initial state
-                    context.tool_settings.mesh_select_mode = self.select_mode
-                    context.user_preferences.view.use_rotate_around_active = self.use_rotate_around_active
-                    context.space_data.overlay.show_face_center = self.show_face_center
-                    if not self.is_editmode:
-                        bpy.ops.object.editmode_toggle()
+                if not self.wait_for_input:
+                    self._exit(context)
+                    return {'FINISHED'}
 
+            elif event.type in {'RIGHTMOUSE', 'ESC'}:
+                if not self.wait_for_input or not is_making_lines or event.type == 'ESC':
+                    self._exit(context)
                     return {'FINISHED'}
                 else:
                     snap_utilities.cache.snp_obj = None # hack for snap edge elemens update
@@ -420,108 +436,128 @@ class SnapUtilitiesLine(bpy.types.Operator):
     def invoke(self, context, event):
         if context.space_data.type == 'VIEW_3D':
             # print('name', __name__, __package__)
-            preferences = context.user_preferences.addons[__package__].preferences
-
-            #Store the preferences that will be used in modal
-            self.intersect = preferences.intersect
-            self.create_face = preferences.create_face
-            self.outer_verts = preferences.outer_verts
-            self.snap_to_grid = preferences.increments_grid
-
-            self.draw_cache = SnapDrawn(
-                preferences.out_color,
-                preferences.face_color,
-                preferences.edge_color,
-                preferences.vert_color,
-                preferences.center_color,
-                preferences.perpendicular_color,
-                preferences.constrain_shift_color,
-                tuple(context.user_preferences.themes[0].user_interface.axis_x) + (1.0,),
-                tuple(context.user_preferences.themes[0].user_interface.axis_y) + (1.0,),
-                tuple(context.user_preferences.themes[0].user_interface.axis_z) + (1.0,)
-            )
-
-            obj = context.active_object
-
-            #Create a new object
-            if obj is None or obj.type != 'MESH':
-                mesh = bpy.data.meshes.new("")
-                obj = bpy.data.objects.new("", mesh)
-                context.scene.objects.link(obj)
-                context.scene.objects.active = obj
-            else:
-                mesh = obj.data
 
             #Store current state
-            self.is_editmode = mesh.is_editmode
             self.use_rotate_around_active = context.user_preferences.view.use_rotate_around_active
             self.select_mode = context.tool_settings.mesh_select_mode[:]
             self.show_face_center = context.space_data.overlay.show_face_center
 
             #Modify the current state
-            bpy.ops.object.mode_set(mode='EDIT')
             bpy.ops.mesh.select_all(action='DESELECT')
             context.user_preferences.view.use_rotate_around_active = True
             context.tool_settings.mesh_select_mode = (True, True, True)
             context.space_data.overlay.show_face_center = True
-            context.scene.update_tag()
+
+            #Store values from 3d view context
+            self.rv3d = context.region_data
+            self.rotMat = self.rv3d.view_matrix.copy()
+            # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4], self.obj_matrix.transposed())
+
+            #Init event variables
+            self.keytab = False
+            self.keyf8 = False
+            self.snap_face = True
+
+            snap_widget_ptr = (self.snap_widget_ptr[0] << 48) |\
+                              (self.snap_widget_ptr[1] << 32) |\
+                              (self.snap_widget_ptr[2] << 16) |\
+                              (self.snap_widget_ptr[3] << 00)
+
+            if snap_widget_ptr is not 0:
+                import ctypes
+                self.snap_widget = ctypes.cast(snap_widget_ptr, ctypes.py_object).value
+                self.draw_cache = self.snap_widget.draw_cache
+                self.sctx = self.snap_widget.sctx
+
+                preferences = self.snap_widget.preferences
+            else:
+                self.snap_widget = None
+
+                preferences = context.user_preferences.addons[__package__].preferences
+
+                #Init DrawCache
+                self.draw_cache = SnapDrawn(
+                    preferences.out_color,
+                    preferences.face_color,
+                    preferences.edge_color,
+                    preferences.vert_color,
+                    preferences.center_color,
+                    preferences.perpendicular_color,
+                    preferences.constrain_shift_color,
+                    tuple(context.user_preferences.themes[0].user_interface.axis_x) + (1.0,),
+                    tuple(context.user_preferences.themes[0].user_interface.axis_y) + (1.0,),
+                    tuple(context.user_preferences.themes[0].user_interface.axis_z) + (1.0,)
+                )
+
+                #Init Snap Context
+                from .snap_context_l import SnapContext
+
+                self.sctx = SnapContext(context.region, context.space_data)
+                self.sctx.set_pixel_dist(12)
+                self.sctx.use_clip_planes(True)
+
+                if self.outer_verts:
+                    for base in context.visible_bases:
+                        self.sctx.add_obj(base.object, base.object.matrix_world)
+
+                self.sctx.set_snap_mode(True, True, self.snap_face)
 
             #Configure the unit of measure
-            scale = context.scene.unit_settings.scale_length
             self.unit_system = context.scene.unit_settings.system
+            scale = context.scene.unit_settings.scale_length
             separate_units = context.scene.unit_settings.use_separate
             self.uinfo = get_units_info(scale, self.unit_system, separate_units)
-
             scale /= context.space_data.overlay.grid_scale * preferences.relative_scale
             self.rd = bpy.utils.units.to_value(self.unit_system, 'LENGTH', str(1 / scale))
 
+            self.intersect = preferences.intersect
+            self.create_face = preferences.create_face
+            self.outer_verts = preferences.outer_verts
+            self.snap_to_grid = preferences.increments_grid
             self.incremental = bpy.utils.units.to_value(self.unit_system, 'LENGTH', str(preferences.incremental))
 
-            #Store values from 3d view context
-            self.rv3d = context.region_data
-            self.rotMat = self.rv3d.view_matrix.copy()
-            # self.obj_glmatrix = bgl.Buffer(bgl.GL_FLOAT, [4, 4], self.obj_matrix.transposed())
-            self.main_bm = self.bm = bmesh.from_edit_mesh(mesh) #remove at end
+            if self.snap_widget:
+                self.geom = self.snap_widget.geom
+                self.type = self.snap_widget.type
+                self.location = self.snap_widget.loc
+                if self.snap_widget.snap_obj:
+                    context.view_layer.objects.active = self.snap_widget.snap_obj.data[0]
+            else:
+                #init these variables to avoid errors
+                self.geom = None
+                self.type = 'OUT'
+                self.location = Vector()
 
-            #init these variables to avoid errors
             self.prevloc = Vector()
-            self.location = Vector()
             self.list_verts = []
             self.list_edges = []
             self.list_verts_co = []
             self.bool_update = False
             self.vector_constrain = ()
-            self.navigation_ops = SnapNavigation(context, True)
-            self.type = 'OUT'
             self.len = 0
             self.length_entered = ""
             self.line_pos = 0
-            self.geom = None
 
-            #Init event variables
-            self.keytab = False
-            self.keyf8 = False
-
-            #Init Snap Context
-            from .snap_context_l import SnapContext
-
-            self.sctx = SnapContext(context.region, context.space_data)
-            self.sctx.set_pixel_dist(12)
-            self.sctx.use_clip_planes(True)
-
-            act_base = context.active_base
+            self.navigation_ops = SnapNavigation(context, True)
 
-            if self.outer_verts:
-                for base in context.visible_bases:
-                    if base != act_base:
-                        self.sctx.add_obj(base.object, base.object.matrix_world)
+            active_object = context.active_object
 
-            self.main_snap_obj = self.snap_obj = self.sctx.add_obj(act_base.object, act_base.object.matrix_world)
+            #Create a new object
+            if active_object is None or active_object.type != 'MESH':
+                mesh = bpy.data.meshes.new("")
+                active_object = bpy.data.objects.new("", mesh)
+                context.scene.objects.link(obj)
+                context.scene.objects.active = active_object
+            else:
+                mesh = active_object.data
 
-            self.snap_face = True
-            self.sctx.set_snap_mode(True, True, self.snap_face)
+            self.main_snap_obj = self.snap_obj = self.sctx._get_snap_obj_by_obj(active_object)
+            self.main_bm = self.bm = bmesh.from_edit_mesh(mesh) #remove at end
 
             #modals
+            if not self.wait_for_input:
+                self.modal(context, event)
+
             self._handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_callback_px, (), 'WINDOW', 'POST_VIEW')
             context.window_manager.modal_handler_add(self)
 
@@ -530,6 +566,7 @@ class SnapUtilitiesLine(bpy.types.Operator):
             self.report({'WARNING'}, "Active space must be a View3d")
             return {'CANCELLED'}
 
+
 def register():
     bpy.utils.register_class(SnapUtilitiesLine)