diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp
index 6741a26c9f484d94241aa8ffd368101390d9c5f6..f8867227abf143e02eba87a3c2c3d91b07544518 100644
--- a/projects/first_scene/src/main.cpp
+++ b/projects/first_scene/src/main.cpp
@@ -13,14 +13,15 @@ int main(int argc, const char** argv) {
 	uint32_t windowWidth = 800;
 	uint32_t windowHeight = 600;
 
-	vkcv::Window window (
-		applicationName,
-		windowWidth,
-		windowHeight,
-		true
+	vkcv::Core core = vkcv::Core::create(
+			applicationName,
+			VK_MAKE_VERSION(0, 0, 1),
+			{vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute},
+			{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }
 	);
-
+	vkcv::Window window = core.getWindow();
 	vkcv::camera::CameraManager cameraManager(window);
+
 	uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
 	uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
 	
@@ -28,15 +29,7 @@ int main(int argc, const char** argv) {
 	cameraManager.getCamera(camIndex0).setNearFar(0.1f, 30.0f);
 	
 	cameraManager.getCamera(camIndex1).setNearFar(0.1f, 30.0f);
-	
-	vkcv::Core core = vkcv::Core::create(
-		window,
-		applicationName,
-		VK_MAKE_VERSION(0, 0, 1),
-		{ vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer },
-		{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }
-	);
-	
+
 	vkcv::scene::Scene scene = vkcv::scene::Scene::load(core, std::filesystem::path(
 			argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf"
 	));
@@ -104,7 +97,7 @@ int main(int argc, const char** argv) {
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 	
 	auto start = std::chrono::system_clock::now();
-	while (window.isOpen()) {
+	while (vkcv::WindowManager::hasOpenWindow()) {
         vkcv::Window::pollEvents();
 		
 		if(window.getHeight() == 0 || window.getWidth() == 0)
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 79bdd67b085338072094b7a8948b0e8a523b33cd..c8b691708d5392c68cf8d663ee08faa7e2be4ed5 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -10,20 +10,16 @@ int main(int argc, const char** argv) {
 
 	const int windowWidth = 800;
 	const int windowHeight = 600;
-	vkcv::Window window (
-		applicationName,
-		windowWidth,
-		windowHeight
-	);
 	
 	vkcv::Core core = vkcv::Core::create(
-		window,
 		applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
 		{ vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute },
 		{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }
 	);
 
+	vkcv::Window window = core.getWindow();
+
 	auto triangleIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3, vkcv::BufferMemoryType::DEVICE_LOCAL);
 	uint16_t indices[3] = { 0, 1, 2 };
 	triangleIndexBuffer.fill(&indices[0], sizeof(indices));
@@ -96,7 +92,7 @@ int main(int argc, const char** argv) {
     cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, 0.0f));
     cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, -1.0f));
 
-	while (window.isOpen())
+	while (vkcv::WindowManager::hasOpenWindow())
 	{
         vkcv::Window::pollEvents();
 
diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp
index 5927970333d63d7e0c3bbbda4b7ccbf321c48a48..d8551bce3826bef56e6cec54e8e83ebdba392a20 100644
--- a/projects/indirect_dispatch/src/App.cpp
+++ b/projects/indirect_dispatch/src/App.cpp
@@ -8,17 +8,12 @@ App::App() :
 	m_applicationName("Indirect Dispatch"),
 	m_windowWidth(AppConfig::defaultWindowWidth),
 	m_windowHeight(AppConfig::defaultWindowHeight),
-	m_window(vkcv::Window::create(
-		m_applicationName,
-		m_windowWidth,
-		m_windowHeight,
-		true)),
 	m_core(vkcv::Core::create(
-		m_window,
 		m_applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
 		{ vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer },
 		{ VK_KHR_SWAPCHAIN_EXTENSION_NAME })),
+	m_window(m_core.getWindow()),
 	m_cameraManager(m_window){}
 
 bool App::initialize() {
@@ -138,7 +133,7 @@ void App::run() {
 
 	auto frameEndTime = std::chrono::system_clock::now();
 
-	while (m_window.isWindowOpen()) {
+	while (vkcv::WindowManager::hasOpenWindow()) {
 
 		vkcv::Window::pollEvents();
 
diff --git a/projects/indirect_dispatch/src/App.hpp b/projects/indirect_dispatch/src/App.hpp
index d580793b0fdc4e7dc8c8654d29a75f04e14ea422..098078631c6061eaa7513a3d0731d3211141d37c 100644
--- a/projects/indirect_dispatch/src/App.hpp
+++ b/projects/indirect_dispatch/src/App.hpp
@@ -15,8 +15,8 @@ private:
 	int m_windowWidth;
 	int m_windowHeight;
 
-	vkcv::Window                m_window;
 	vkcv::Core                  m_core;
+	vkcv::Window                m_window;
 	vkcv::camera::CameraManager m_cameraManager;
 
 	MotionBlur m_motionBlur;
diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp
index 0f602b8d7a9580480f5b59fba71b3677cf740ea2..e2856a57fa16170c44e2613b4cab1cac902847a3 100644
--- a/projects/mesh_shader/src/main.cpp
+++ b/projects/mesh_shader/src/main.cpp
@@ -80,11 +80,6 @@ int main(int argc, const char** argv) {
 
 	const int windowWidth = 1280;
 	const int windowHeight = 720;
-	vkcv::Window window (
-		applicationName,
-		windowWidth,
-		windowHeight
-	);
 	
 	vkcv::Features features;
 	features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
@@ -95,13 +90,14 @@ int main(int argc, const char** argv) {
 	});
 
 	vkcv::Core core = vkcv::Core::create(
-		window,
 		applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
 		{ vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute },
 		features
 	);
 
+	vkcv::Window &window = core.getWindow();
+
     vkcv::gui::GUI gui (core, window);
 
     vkcv::asset::Scene mesh;
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index 9550cdd7b33ec31a5a4d9ea13ae0dd97f5bdb93d..3543e73ab1ff4ab3154ab8a887750d60daf24587 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -6,7 +6,7 @@
 #include "ParticleSystem.hpp"
 #include <random>
 #include <glm/gtc/matrix_access.hpp>
-#include <time.h>
+#include <ctime>
 #include <vkcv/shader/GLSLCompiler.hpp>
 #include "BloomAndFlares.hpp"
 
@@ -15,22 +15,15 @@ int main(int argc, const char **argv) {
 
     uint32_t windowWidth = 800;
     uint32_t windowHeight = 600;
-    vkcv::Window window (
-            applicationName,
-            windowWidth,
-            windowHeight,
-            true
-    );
-
-    vkcv::camera::CameraManager cameraManager(window);
 	
     vkcv::Core core = vkcv::Core::create(
-            window,
             applicationName,
             VK_MAKE_VERSION(0, 0, 1),
             {vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute},
 			{ VK_KHR_SWAPCHAIN_EXTENSION_NAME }
     );
+    vkcv::Window window = core.getWindow();
+	vkcv::camera::CameraManager cameraManager(window);
 
     auto particleIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3,
                                                            vkcv::BufferMemoryType::DEVICE_LOCAL);
@@ -186,7 +179,7 @@ int main(int argc, const char **argv) {
     auto pos = glm::vec2(0.f);
     auto spawnPosition = glm::vec3(0.f);
 
-    window.e_mouseMove.add([&](double offsetX, double offsetY) {
+	window.e_mouseMove.add([&](double offsetX, double offsetY) {
         pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY));
         pos.x = (-2 * pos.x + static_cast<float>(window.getWidth())) / static_cast<float>(window.getWidth());
         pos.y = (-2 * pos.y + static_cast<float>(window.getHeight())) / static_cast<float>(window.getHeight());
@@ -234,7 +227,7 @@ int main(int argc, const char **argv) {
 
     std::uniform_real_distribution<float> rdm = std::uniform_real_distribution<float>(0.95f, 1.05f);
     std::default_random_engine rdmEngine;
-    while (window.isOpen()) {
+    while (vkcv::WindowManager::hasOpenWindow()) {
         vkcv::Window::pollEvents();
 
         uint32_t swapchainWidth, swapchainHeight;
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index ad1cc4556d82d23a29c06adfd74e05a0b7cdbc69..712040ba08f7e1f1b723fde3693e73282c970fbe 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -21,14 +21,21 @@ int main(int argc, const char** argv) {
 	uint32_t windowHeight = 720;
 	const vkcv::Multisampling   msaa        = vkcv::Multisampling::MSAA4X;
 	const bool                  usingMsaa   = msaa != vkcv::Multisampling::None;
-	
-	vkcv::Window window (
-		applicationName,
-		windowWidth,
-		windowHeight,
-		true
+
+	vkcv::Features features;
+	features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+	features.requireExtension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
+	features.requireExtension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
+
+	vkcv::Core core = vkcv::Core::create(
+			applicationName,
+			VK_MAKE_VERSION(0, 0, 1),
+			{ vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute },
+			features
 	);
 
+	vkcv::Window& window = core.getWindow();
+
 	bool     isFullscreen            = false;
 	uint32_t windowedWidthBackup     = windowWidth;
 	uint32_t windowedHeightBackup    = windowHeight;
@@ -80,19 +87,6 @@ int main(int argc, const char** argv) {
 	cameraManager.getCamera(camIndex).setFov(glm::radians(37.8));	// fov of a 35mm lens
 	
 	cameraManager.getCamera(camIndex2).setNearFar(0.1f, 30.0f);
-	
-	vkcv::Features features;
-	features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
-	features.requireExtension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
-	features.requireExtension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
-	
-	vkcv::Core core = vkcv::Core::create(
-		window,
-		applicationName,
-		VK_MAKE_VERSION(0, 0, 1),
-		{ vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute },
-		features
-	);
 
 	vkcv::asset::Scene mesh;