diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp
index e324917674cd2e1773ee23a9411ab28f6eb0d684..b66e4e6579d887f3beee5cdd20c88dff361bd3b9 100644
--- a/include/vkcv/Event.hpp
+++ b/include/vkcv/Event.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <functional>
+#include <mutex>
 
 namespace vkcv {
 	
@@ -26,6 +27,7 @@ namespace vkcv {
     private:
         std::vector< event_function<T...> > m_functions;
         uint32_t m_id_counter;
+        std::mutex m_mutex;
 
     public:
 
@@ -34,9 +36,13 @@ namespace vkcv {
          * @param arguments of the given function
          */
         void operator()(T... arguments) {
+			lock();
+
             for (auto &function : this->m_functions) {
 				function.callback(arguments...);
-            }
+			}
+            
+            unlock();
         }
 
         /**
@@ -64,6 +70,20 @@ namespace vkcv {
                     this->m_functions.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 bc5223826bca406e8d44142cff0f3829a3ea6208..7dc6c1b7dc8fef4d5de7de5b0a9976bf714e6ac2 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -7,6 +7,7 @@
 
 #define NOMINMAX
 #include <algorithm>
+
 #include "Event.hpp"
 
 struct GLFWwindow;
@@ -23,8 +24,6 @@ namespace vkcv {
          */
 		explicit Window(GLFWwindow *window);
 		
-		static GLFWwindow* createGLFWWindow(const char *windowTitle, int width, int height, bool resizable);
-		
     private:
         /**
          * mouse callback for moving the mouse on the screen
@@ -99,11 +98,6 @@ namespace vkcv {
         [[nodiscard]]
         bool isWindowOpen() const;
 
-        /**
-         * binds windowEvents to lambda events
-         */
-        void initEvents();
-
         /**
          * polls all events on the GLFWwindow
          */
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 4834e4b85e09f1eca123e40f684a464d40ec9a0d..dc43c905784525a34732bc0e66343fbdcc17a639 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -18,8 +18,6 @@ int main(int argc, const char** argv) {
 		true
 	);
 
-	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 89e1b8d43d71685a6cdd2e2f7c10fda90716ce60..20cfdddf5c1baa9e8727312daa36de94bd56672f 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -19,8 +19,6 @@ int main(int argc, const char** argv) {
 		false
 	);
 
-	window.initEvents();
-	
 	vkcv::Core core = vkcv::Core::create(
 		window,
 		applicationName,
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index bca207443e4462405229bfd502adbacaee9e37e8..03ac915aea5e89e2c5b0927cafe52e56454d49b5 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -9,64 +9,74 @@
 
 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);
+		glfwSetCharCallback(m_window, Window::onCharEvent);
+	
+		glfwSetJoystickCallback(nullptr);
+		glfwSetJoystickUserPointer(GLFW_JOYSTICK_1, this);
     }
 
     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();
         }
     }
-	
-    GLFWwindow* Window::createGLFWWindow(const char *windowTitle, int width, int height, bool resizable) {
-		if(s_WindowCount == 0) {
+
+    Window Window::create( const char *windowTitle, int width, int height, bool resizable) {
+		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);
-		
-		return glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
-    }
-
-    Window Window::create( const char *windowTitle, int width, int height, bool resizable) {
-        return Window(createGLFWWindow(windowTitle, width, height, resizable));
-    }
-
-    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);
+		GLFWwindow *window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
 	
-		glfwSetCharCallback(m_window, Window::onCharEvent);
-
-        glfwSetJoystickCallback(nullptr);   // use this before to avoid crashing
-        glfwSetJoystickUserPointer(GLFW_JOYSTICK_1, this);
+		s_Windows.push_back(window);
+	
+		return Window(window);
     }
 
     void Window::pollEvents() {
-        onGamepadEvent(GLFW_JOYSTICK_1);
+		onGamepadEvent(GLFW_JOYSTICK_1);
+    	
+    	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) {