diff --git a/b_asic/GUI/_preferences.py b/b_asic/GUI/_preferences.py
index c1fa14062d99ec3480ae1bd114c185f470fca202..8ec13464dfbe6742f22f147168bb0255db9f227b 100644
--- a/b_asic/GUI/_preferences.py
+++ b/b_asic/GUI/_preferences.py
@@ -14,3 +14,4 @@ MIN_HEIGHT_SCENE = 520
 
 # Interface
 LINECOLOR = QColor(*SIGNAL_COLOR)
+GRID = 19
diff --git a/b_asic/GUI/arrow.py b/b_asic/GUI/arrow.py
index 66805a432ce970ae2852f965d587bb760e8de1c1..1c3fcce263082213a81e6c6893c3852c347c4123 100644
--- a/b_asic/GUI/arrow.py
+++ b/b_asic/GUI/arrow.py
@@ -1,12 +1,12 @@
 from qtpy.QtCore import QPointF
-from qtpy.QtGui import QPen, QPolygonF
-from qtpy.QtWidgets import QGraphicsPolygonItem, QMenu
+from qtpy.QtGui import QPen, QPainterPath
+from qtpy.QtWidgets import QGraphicsPathItem, QMenu
 
 from b_asic.GUI._preferences import LINECOLOR, PORTHEIGHT, PORTWIDTH
 from b_asic.signal import Signal
 
 
-class Arrow(QGraphicsPolygonItem):
+class Arrow(QGraphicsPathItem):
     """Arrow/connection in signal flow graph GUI."""
 
     def __init__(self, source, destination, window, signal=None, parent=None):
@@ -80,10 +80,29 @@ class Arrow(QGraphicsPolygonItem):
         """
         Draw a line connecting self.source with self.destination. Used as callback when moving operations.
         """
+        ORTHOGONAL = True
+        OFFSET = 2 * PORTWIDTH
         self.setPen(QPen(LINECOLOR, 3))
         x0 = self.source.operation.x() + self.source.x() + PORTWIDTH
-        y0 = self.source.operation.y() + self.source.y() + PORTHEIGHT/2
+        y0 = self.source.operation.y() + self.source.y() + PORTHEIGHT / 2
         x1 = self.destination.operation.x() + self.destination.x()
-        y1 = self.destination.operation.y() + self.destination.y() + PORTHEIGHT/2
-        p = QPolygonF() << QPointF(x0, y0) << QPointF(x1, y1)
-        self.setPolygon(p)
+        y1 = (
+            self.destination.operation.y()
+            + self.destination.y()
+            + PORTHEIGHT / 2
+        )
+        xmid = (x0 + x1) / 2
+        ymid = (y0 + y1) / 2
+        p = QPainterPath(QPointF(x0, y0))
+        if y0 == y1 or not ORTHOGONAL:
+            pass
+        elif abs(x0 - x1) <= OFFSET / 2:
+            p.lineTo(QPointF(x0 + OFFSET, y0))
+            p.lineTo(QPointF(x0 + OFFSET, ymid))
+            p.lineTo(QPointF(x0 - OFFSET, ymid))
+            p.lineTo(QPointF(x0 - OFFSET, y1))
+        else:
+            p.lineTo(QPointF(xmid, y0))
+            p.lineTo(QPointF(xmid, y1))
+        p.lineTo(QPointF(x1, y1))
+        self.setPath(p)
diff --git a/b_asic/GUI/drag_button.py b/b_asic/GUI/drag_button.py
index 3b258c621ca0983fbc9e1c83aefac042be147232..79a03c9a37244cfe1cae63dfb62601eb66902fa6 100644
--- a/b_asic/GUI/drag_button.py
+++ b/b_asic/GUI/drag_button.py
@@ -12,7 +12,7 @@ from qtpy.QtWidgets import QAction, QMenu, QPushButton
 
 from b_asic.GUI.properties_window import PropertiesWindow
 from b_asic.GUI.utils import decorate_class, handle_error
-from b_asic.GUI._preferences import MINBUTTONSIZE
+from b_asic.GUI._preferences import GRID, MINBUTTONSIZE
 
 
 @decorate_class(handle_error)
@@ -105,6 +105,15 @@ class DragButton(QPushButton):
         else:
             self.select_button(event.modifiers())
 
+        # Snap
+        point = self.pos()
+        x = point.x()
+        y = point.y()
+        newx = GRID * round(x / GRID)
+        newy = GRID * round(y / GRID)
+        self.move(newx, newy)
+        self._window.scene.update()
+        self._window.graphic_view.update()
         super().mouseReleaseEvent(event)
 
     def _toggle_button(self, pressed=False):
@@ -117,7 +126,9 @@ class DragButton(QPushButton):
         path_to_image = os.path.join(
             os.path.dirname(__file__),
             "operation_icons",
-            f"{self.operation_path_name}{'_grey.png' if self.pressed else '.png'}",
+            (
+                f"{self.operation_path_name}{'_grey.png' if self.pressed else '.png'}"
+            ),
         )
         self.setIcon(QIcon(path_to_image))
         self.setIconSize(QSize(MINBUTTONSIZE, MINBUTTONSIZE))
diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py
index ac0ecb687f98d310a32c23ea3de22742abb4623d..a7d6ee88d639fec2e1cf4514c07dd32e3d04aff4 100644
--- a/b_asic/GUI/main_window.py
+++ b/b_asic/GUI/main_window.py
@@ -37,6 +37,7 @@ from b_asic.GUI.port_button import PortButton
 from b_asic.GUI.select_sfg_window import SelectSFGWindow
 from b_asic.GUI._preferences import (
     GAP,
+    GRID,
     MINBUTTONSIZE,
     PORTHEIGHT,
     PORTWIDTH,
@@ -540,7 +541,7 @@ class MainWindow(QMainWindow):
                 op.graph_id, op, op.type_name().lower(), True, window=self
             )
             if position is None:
-                attr_button.move(250, 100)
+                attr_button.move(GRID * 3, GRID * 2)
             else:
                 attr_button.move(*position)