diff --git a/b_asic/scheduler-gui/graphics_graph_event.py b/b_asic/scheduler-gui/graphics_graph_event.py
index c04827593c1d0fbef8a158375a43a49c700b400e..f239a53e437eb54ab9a128dddd6d026d6b497856 100644
--- a/b_asic/scheduler-gui/graphics_graph_event.py
+++ b/b_asic/scheduler-gui/graphics_graph_event.py
@@ -74,13 +74,13 @@ class GraphicsGraphEvent(QGraphicsItem):
         sceneEventFilter() function."""
         for item in self._components:
             item.installSceneEventFilter(self)
-        self.setFiltersChildEvents(True)    # default false
+        # self.setFiltersChildEvents(True)    # default false
         
     def removeSceneEventFilters(self) -> None:
         """Removes an event filter on 'item' from 'self'."""
         for item in self._components:
             item.removeSceneEventFilter(self)
-        self.setFiltersChildEvents(False)
+        # self.setFiltersChildEvents(False)
         
     
     # def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
@@ -88,17 +88,9 @@ class GraphicsGraphEvent(QGraphicsItem):
         """Returns true if the event was filtered (i.e. stopped), otherwise false.
         If false is returned, the event is forwarded to the appropriate child in
         the event chain."""
-        # type_ = type(event)
-        # if type_ != QEvent.GraphicsSceneHoverMove: print(f'Graph -->\t{type(item).__name__}\t{type_}')
-        # if event.button():
-        #     # print(f'Graph -->\t{type_}\t{item}')
-        #     print(f'-------->\t{event.button()}')
-        # scene = self.scene()
-        # mouse_grabber = scene.mouseGrabberItem()
-        # print(f'mouseGrabberItem() before: {mouse_grabber}')
+        handler = None
 
         if isinstance(item, GraphicsComponentItem):
-        
             switch = {
                 QEvent.FocusIn:                         self.comp_focusInEvent,
                 QEvent.GraphicsSceneContextMenu:        self.comp_contextMenuEvent,
@@ -116,14 +108,13 @@ class GraphicsGraphEvent(QGraphicsItem):
                 QEvent.GraphicsSceneWheel:              self.comp_wheelEvent
             }
 
-            handler = switch.get(event.type(), lambda x,y : False)
-            # ret = handler(item, event)
-            # print(f'mouseGrabberItem() after:  {mouse_grabber}')
-            # return ret
-            return handler(item, event)
-        # else: 
-        #     print(f'Graph -->\t{type(item).__name__}\t{type_}')
+            handler = switch.get(event.type())
+        else:
+            raise TypeError
         
+        if handler:
+            handler(event)
+            return True
         return False    # returns False if event is ignored and pass through event to its child
 
     # def sceneEvent(self, event: QEvent) -> bool:
@@ -136,32 +127,24 @@ class GraphicsGraphEvent(QGraphicsItem):
     ###############################################
     #### Event Handlers: GraphicsComponentItem ####
     ###############################################
-    def comp_focusInEvent(self, item: QGraphicsItem, event: QFocusEvent) -> bool: 
-        return False
-    def comp_contextMenuEvent(self, item: QGraphicsItem, event: QGraphicsSceneContextMenuEvent) -> bool:
-        return False
-    def comp_dragEnterEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
-        return False
-    def comp_dragMoveEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
-        return False
-    def comp_dragLeaveEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
-        return False
-    def comp_dropEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
-        return False
+    def comp_focusInEvent(self, event: QFocusEvent) -> None: ...
+    def comp_contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: ...
+    def comp_dragEnterEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
+    def comp_dragMoveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
+    def comp_dragLeaveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
+    def comp_dropEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
     
-    def comp_hoverEnterEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
+    def comp_hoverEnterEvent(self, event: QGraphicsSceneHoverEvent) -> None:
         """Changes the cursor to OpenHandCursor when hovering an object."""
         self.setCursor(QCursor(Qt.OpenHandCursor))
-        return True
     
-    def comp_hoverMoveEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
-        return False
-    def comp_hoverLeaveEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
+    def comp_hoverMoveEvent(self, event: QGraphicsSceneHoverEvent) -> None: ...
+    
+    def comp_hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent) -> None:
         """Changes the cursor to ArrowCursor when leaving an object."""
         self.setCursor(QCursor(Qt.ArrowCursor))
-        return True
 
-    def comp_mouseMoveEvent(self, item_: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
+    def comp_mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None:
         """Set the position of the graphical element in the graphic scene, 
         translate coordinates of the cursor within the graphic element 
         in the coordinate system of the parent object."""
@@ -172,34 +155,30 @@ class GraphicsGraphEvent(QGraphicsItem):
         if dx > 5.05:
             pos = item.x() + 10.0
             if self.is_valid_pos(pos):
+                self.prepareGeometryChange()
                 item.setX(pos)
                 self._current_pos.setX(self._current_pos.x() + 10.0)
         elif dx < -5.05:
             pos = item.x() - 10.0
             if self.is_valid_pos(pos):
+                self.prepareGeometryChange()
                 item.setX(pos)
                 self._current_pos.setX(self._current_pos.x() - 10.0)
-        return True
     
-    def comp_mousePressEvent(self, item_: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
+    def comp_mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None:
         """Changes the cursor to ClosedHandCursor when grabbing an object."""
         item = self.scene().mouseGrabberItem()
         self._current_pos = item.mapToParent(event.pos())
-        item.setCursor(QCursor(Qt.ClosedHandCursor))
+        self.setCursor(QCursor(Qt.ClosedHandCursor))
         event.accept()
-        return True
     
-    def comp_mouseReleaseEvent(self, item: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
+    def comp_mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent) -> None:
         """Changes the cursor to OpenHandCursor when releasing an object."""
-        item.setCursor(QCursor(Qt.OpenHandCursor))
+        self.setCursor(QCursor(Qt.OpenHandCursor))
         event.accept()
-        return True
-         
 
-    def comp_mouseDoubleClickEvent(self, item: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
-        return False
-    def comp_wheelEvent(self, item: QGraphicsItem, event: QGraphicsSceneWheelEvent) -> bool:
-        return False
+    def comp_mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None: ...
+    def comp_wheelEvent(self, event: QGraphicsSceneWheelEvent) -> None: ...
     
     ###############################################
     #### Event Handlers: GraphicsComponentItem ####
diff --git a/b_asic/scheduler-gui/graphics_graph_item.py b/b_asic/scheduler-gui/graphics_graph_item.py
index 5f1951d049bf937ac7553760a566d1da1b224fd8..c9a95ed0cccc45a7764d48cb8de36f22366e0ab3 100644
--- a/b_asic/scheduler-gui/graphics_graph_item.py
+++ b/b_asic/scheduler-gui/graphics_graph_item.py
@@ -97,6 +97,9 @@ class GraphicsGraphItem(QGraphicsItemGroup, GraphicsGraphEvent):
     def is_valid_pos(self, pos: float) -> bool:
         """Returns true if component new pos is valid, false otherwise."""
         # TODO: implement
+        # item = self.scene().mouseGrabberItem()
+        if pos < 0:
+            return False
         return True
     
     def update_(self) -> None:
@@ -104,7 +107,7 @@ class GraphicsGraphItem(QGraphicsItemGroup, GraphicsGraphEvent):
         # self.removeFromGroup(self._axis)
         self._axis.update(40 + 6, self._components_height, self._x_axis_indent)
         # self.addToGroup(self._axis)
-
+        
     @property
     def schedule(self) -> Schedule:
         return self._schedule
diff --git a/b_asic/scheduler-gui/logger.py b/b_asic/scheduler-gui/logger.py
index 8f552c979e9774126b5b452d815490738f2a2046..113b631c534fb3e8c6cb5bac8bf147006252052e 100644
--- a/b_asic/scheduler-gui/logger.py
+++ b/b_asic/scheduler-gui/logger.py
@@ -24,26 +24,35 @@ Usage:
 The last `exception(str)` is used to capture exceptions output, that normally
 won't be captured.  
 See https://docs.python.org/3/howto/logging.html for more information.
-"""
+
+Log Uncaught Exceptions:
+------------------------
+To log uncaught exceptions, implement the following in your program.  
+  `sys.excepthook = logger.log_exceptions`"""
 import os
 import sys
+from typing import Type, Optional
+from types import TracebackType
 from logging import Logger
 import logging
 import logging.handlers
+import traceback
 
 
-def getLogger(name: str='scheduler-gui.log', loglevel: str='INFO') -> Logger:
+def getLogger(filename: str='scheduler-gui.log', loglevel: str='INFO') -> Logger:
     """This function creates console- and filehandler and from those, creates a logger object.
 
     Args:
-        name (str, optional): Logger-id and output filename. Defaults to 'scheduler-gui.log'.
-        loglevel (str, optional): The minimum level that the logger will log. Defaults to 'DEBUG'.
+        filename (str, optional): Output filename. Defaults to 'scheduler-gui.log'.
+        loglevel (str, optional): The minimum level that the logger will log. Defaults to 'INFO'.
 
     Returns:
         Logger: 'logging.Logger' object.
     """
 
-    logger = logging.getLogger(name)
+    # logger = logging.getLogger(name)
+    # logger = logging.getLogger('root')
+    logger = logging.getLogger()
 
     # if logger 'name' already exists, return it to avoid logging duplicate
     # messages by attaching multiple handlers of the same type
@@ -68,7 +77,7 @@ def getLogger(name: str='scheduler-gui.log', loglevel: str='INFO') -> Logger:
         f_fmt_date = '%Y-%m-%dT%T%Z'
         f_fmt = '%(asctime)s %(filename)18s:%(lineno)-4s %(funcName)20s() %(levelname)-8s: %(message)s'
         f_formatter = logging.Formatter(f_fmt, f_fmt_date)
-        f_handler = logging.FileHandler(name, mode = 'w')
+        f_handler = logging.FileHandler(filename, mode = 'w')
         f_handler.setFormatter(f_formatter)
         f_handler.setLevel(logging.DEBUG)
         logger.addHandler(f_handler)
@@ -79,3 +88,15 @@ def getLogger(name: str='scheduler-gui.log', loglevel: str='INFO') -> Logger:
                     ' '.join(sys.argv[1:]))
         
     return logger
+
+
+# log uncaught exceptions
+def handle_exceptions(exc_type: Type[BaseException], exc_value: BaseException, exc_traceback: TracebackType | None) -> None:
+# def log_exceptions(type, value, tb):
+    """This function is a helper function to log uncaught exceptions. Install with:  
+    `sys.excepthook = <module>.handle_exceptions`"""
+    if issubclass(exc_type, KeyboardInterrupt):
+        sys.__excepthook__(exc_type, exc_value, exc_traceback)
+        return
+
+    logging.exception("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
diff --git a/b_asic/scheduler-gui/main_window.py b/b_asic/scheduler-gui/main_window.py
index 4134efbaee6157d55cbe0b389ad8cbbade340f79..07b5a1ff58ad769c81d5cea794a580730c9ea1ed 100644
--- a/b_asic/scheduler-gui/main_window.py
+++ b/b_asic/scheduler-gui/main_window.py
@@ -15,7 +15,7 @@ import os
 import sys
 from pathlib        import Path
 from types          import ModuleType
-from typing         import Any
+from typing         import Any, Iterable, List
 from pprint         import pprint
 #from matplotlib.pyplot import bar
 #from diagram import *
@@ -34,7 +34,7 @@ from qtpy.QtWidgets import (
 
 # QGraphics and QPainter imports
 from qtpy.QtCore    import (
-    QRect, QRectF, QPoint, QSize, QByteArray, QMarginsF)
+    QRect, QRectF, QPoint, QSize, QByteArray, QMarginsF, QObject)
 from qtpy.QtGui     import (
     QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap,
     QLinearGradient)
@@ -50,8 +50,12 @@ from graphics_graph_item        import GraphicsGraphItem
 from graphics_axis_item         import GraphicsAxisItem
 from graphics_component_item    import GraphicsComponentItem
 
+# if sys.version_info >= (3, 9):
+#     List = list
+#     #Dict = dict
 
 log = logger.getLogger()
+sys.excepthook = logger.handle_exceptions
 
 # Debug struff
 if __debug__:
@@ -172,14 +176,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
     def _init_graphics(self) -> None:
         """Initialize the QGraphics framework"""
         self._scene = QGraphicsScene()
-        self.graphics_view.setScene(self._scene)
-        self.graphics_view.scale(self._scale, self._scale)
+        self.view.setScene(self._scene)
+        self.view.scale(self._scale, self._scale)
         # self.setMouseTracking(True)
         GraphicsComponentItem._scale = self._scale
         GraphicsAxisItem._scale = self._scale
+        self._scene.changed.connect(self.shrink_scene_to_min_size)
         
-        
-
+    
 
     ###############
     #### Slots ####
@@ -215,7 +219,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             log.exception('Exception occurred. Could not load module from file \'{}\'.'.format(abs_path_filename))
             return
 
-        schedule_obj_list = dict(inspect.getmembers(module, (lambda x: type(x) == Schedule)))
+        schedule_obj_list = dict(inspect.getmembers(module, (lambda x: isinstance(x, Schedule))))
         
         if not schedule_obj_list:       # return if no Schedule objects in script
             QMessageBox.warning(self,
@@ -244,7 +248,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
     
     #@Slot()
     def open(self, schedule: Schedule) -> None:
-        """Takes in an Schedule and place it in the schedule list."""
+        """Takes in an Schedule and creates a GraphicsGraphItem object."""
 
         self._graph = GraphicsGraphItem(schedule)
         self._scene.addItem(self._graph)
@@ -319,6 +323,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.menu_node_info.setChecked(False)
         else:
             self.menu_node_info.setChecked(True)
+        
+    @Slot(list)
+    def shrink_scene_to_min_size(self, region: list[QRectF]) -> None:
+        self._scene.setSceneRect(self._scene.itemsBoundingRect())
     
 
 
diff --git a/b_asic/scheduler-gui/main_window.ui b/b_asic/scheduler-gui/main_window.ui
index 55dc51a10ead3f69167ce108c2ffb0a6f7f34fc8..7844ba5864ce85193cbd6678f049628b37685f2a 100644
--- a/b_asic/scheduler-gui/main_window.ui
+++ b/b_asic/scheduler-gui/main_window.ui
@@ -49,7 +49,7 @@
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
-      <widget class="QGraphicsView" name="graphics_view">
+      <widget class="QGraphicsView" name="view">
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
        </property>