diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp
index 0836e836e84ff7dfc4931a7cedd65497bf9a89cf..dfa1325a0d06be309e24712d2115279dad171825 100644
--- a/include/vkcv/Event.hpp
+++ b/include/vkcv/Event.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <functional>
+#include <mutex>
 
 namespace vkcv {
 
@@ -17,6 +18,7 @@ namespace vkcv {
     struct event {
     private:
         std::vector<typename event_function<T...>::type> m_handles;
+        std::mutex m_mutex;
 
     public:
 
@@ -25,9 +27,13 @@ namespace vkcv {
          * @param arguments of the given function
          */
         void operator()(T... arguments) {
+			lock();
+        	
             for (auto &handle : this->m_handles) {
                 handle(arguments...);
             }
+            
+            unlock();
         }
 
         /**
@@ -49,6 +55,20 @@ namespace vkcv {
                     this->m_handles.end()
             );
         }
+        
+        /**
+         * locks the event so its function handles won't be called
+         */
+        void lock() {
+        	m_mutex.lock();
+        }
+	
+		/**
+		* unlocks the event so its function handles can be called after locking
+		*/
+        void unlock() {
+        	m_mutex.unlock();
+        }
 
         event() = default;
 
diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp
index f71671c935a0a5e17bb517c726d75ffff2973532..f11a38b797f9666815478b7596b63e6bfd0c0296 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -7,6 +7,7 @@
 
 #define NOMINMAX
 #include <algorithm>
+
 #include "Event.hpp"
 
 struct GLFWwindow;
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 01d8b74fe39a15459169926645f429805299a786..723bc9a5fed150d8be94c4c97ba83cfacccc6d4d 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -17,8 +17,6 @@ int main(int argc, const char** argv) {
 
 	vkcv::CameraManager cameraManager(window, static_cast<float>(window.getWidth()), static_cast<float>(window.getHeight()));
 
-	window.initEvents();
-
 	vkcv::Core core = vkcv::Core::create(
 		window,
 		applicationName,
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 397498e60375ee34497b60fef7d27cbb2c0c7989..6c3b2272e32ebdc7844ebd16441f6e17c9429495 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -18,8 +18,6 @@ int main(int argc, const char** argv) {
 
 	vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
 
-	window.initEvents();
-
 	vkcv::Core core = vkcv::Core::create(
 		window,
 		applicationName,
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index c21271b78f7501721d5c0496d0344dd68e2e7e52..210178fa0545caea061c8673323fe7e11f3ef2c8 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -10,55 +10,68 @@
 
 namespace vkcv {
 
-    static uint32_t s_WindowCount = 0;
+	static std::vector<GLFWwindow*> s_Windows;
 
     Window::Window(GLFWwindow *window)
             : m_window(window) {
+		glfwSetWindowUserPointer(m_window, this);
+	
+		// combine Callbacks with Events
+		glfwSetMouseButtonCallback(m_window, Window::onMouseButtonEvent);
+		glfwSetCursorPosCallback(m_window, Window::onMouseMoveEvent);
+		glfwSetWindowSizeCallback(m_window, Window::onResize);
+		glfwSetKeyCallback(m_window, Window::onKeyEvent);
+		glfwSetScrollCallback(m_window, Window::onMouseScrollEvent);
     }
 
     Window::~Window() {
+		s_Windows.erase(std::find(s_Windows.begin(), s_Windows.end(), m_window));
         glfwDestroyWindow(m_window);
-        s_WindowCount--;
 
-        if(s_WindowCount == 0) {
+        if(s_Windows.empty()) {
             glfwTerminate();
         }
     }
 
     Window Window::create( const char *windowTitle, int width, int height, bool resizable) {
-        if(s_WindowCount == 0) {
+        if(s_Windows.empty()) {
             glfwInit();
         }
-        s_WindowCount++;
 
         width = std::max(width, 1);
         height = std::max(height, 1);
 
         glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
         glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE);
-        GLFWwindow *window;
-        window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
+		GLFWwindow *window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
+		
+		s_Windows.push_back(window);
 
         return Window(window);
     }
 
-    void Window::initEvents() {
-        glfwSetWindowUserPointer(m_window, this);
-
-        // combine Callbacks with Events
-        glfwSetMouseButtonCallback(m_window, Window::onMouseButtonEvent);
-
-        glfwSetCursorPosCallback(m_window, Window::onMouseMoveEvent);
-
-        glfwSetWindowSizeCallback(m_window, Window::onResize);
-
-        glfwSetKeyCallback(m_window, Window::onKeyEvent);
-
-        glfwSetScrollCallback(m_window, Window::onMouseScrollEvent);
-    }
-
     void Window::pollEvents() {
+    	for (auto glfwWindow : s_Windows) {
+			auto window = static_cast<Window *>(glfwGetWindowUserPointer(glfwWindow));
+			
+			window->e_mouseButton.unlock();
+			window->e_mouseMove.unlock();
+			window->e_resize.unlock();
+			window->e_key.unlock();
+			window->e_mouseScroll.unlock();
+    	}
+    	
         glfwPollEvents();
+	
+		for (auto glfwWindow : s_Windows) {
+			auto window = static_cast<Window *>(glfwGetWindowUserPointer(glfwWindow));
+		
+			window->e_mouseButton.lock();
+			window->e_mouseMove.lock();
+			window->e_resize.lock();
+			window->e_key.lock();
+			window->e_mouseScroll.lock();
+		}
     }
 
     void Window::onMouseButtonEvent(GLFWwindow *callbackWindow, int button, int action, int mods) {