diff --git a/src/main.cpp b/src/main.cpp
index 76f98c0..9b9b9ba 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -83,6 +83,7 @@ private:
     std::vector<vk::raii::Semaphore> m_renderFinishedSemaphores;
     std::vector<vk::raii::Fence> m_inFlightFences;
     uint32_t m_currentFrame = 0;
+    bool m_framebufferResized = false;
     /////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////
@@ -91,9 +92,15 @@ private:
         glfwInit();
 
         glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
 
         m_window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
+        glfwSetWindowUserPointer(m_window, this);
+        glfwSetFramebufferSizeCallback(m_window, framebufferResizeCallback);
+    }
+
+    static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
+        const auto app = static_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
+        app->m_framebufferResized = true;
     }
 
     void initVulkan() {
@@ -616,9 +623,17 @@ private:
             res != vk::Result::eSuccess
         ) throw std::runtime_error{ "waitForFences in drawFrame was failed" };
 
-        m_device.resetFences( *m_inFlightFences[m_currentFrame] );
+        uint32_t imageIndex;
+        try{
+            // std::pair<vk::Result, uint32_t>
+            const auto [res, idx] = m_swapChain.acquireNextImage(UINT64_MAX, m_imageAvailableSemaphores[m_currentFrame]);
+            imageIndex = idx;
+        } catch (const vk::OutOfDateKHRError&){
+            recreateSwapChain();
+            return;
+        }
 
-        auto [nxtRes, imageIndex] = m_swapChain.acquireNextImage(std::numeric_limits<uint64_t>::max(),  m_imageAvailableSemaphores[m_currentFrame]);
+        m_device.resetFences( *m_inFlightFences[m_currentFrame] );
 
         m_commandBuffers[m_currentFrame].reset();
         recordCommandBuffer(m_commandBuffers[m_currentFrame], imageIndex);
@@ -636,12 +651,42 @@ private:
         presentInfo.setWaitSemaphores( *m_renderFinishedSemaphores[m_currentFrame] );
         presentInfo.setSwapchains( *m_swapChain );
         presentInfo.pImageIndices = &imageIndex;
-        if (const auto res = m_presentQueue.presentKHR( presentInfo );
-            res != vk::Result::eSuccess
-        ) throw std::runtime_error{ "presentKHR in drawFrame was failed" };
+        try{
+            const auto res = m_presentQueue.presentKHR(presentInfo);
+            if( res == vk::Result::eSuboptimalKHR ) {
+                recreateSwapChain();
+            }
+        } catch (const vk::OutOfDateKHRError&){
+            recreateSwapChain();
+        }
+
+        if( m_framebufferResized ){
+            recreateSwapChain();
+        }
 
         m_currentFrame = (m_currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
     }
+    void recreateSwapChain() {
+        int width = 0, height = 0;
+        glfwGetFramebufferSize(m_window, &width, &height);
+        while (width == 0 || height == 0) {
+            glfwGetFramebufferSize(m_window, &width, &height);
+            glfwWaitEvents();
+        }
+
+        m_device.waitIdle();
+
+        m_swapChainFramebuffers.clear();
+        m_swapChainImageViews.clear();
+        m_swapChainImages.clear(); // optional
+        m_swapChain = nullptr;
+
+        createSwapChain();
+        createImageViews();
+        createFramebuffers();
+
+        m_framebufferResized = false;
+    }
     /////////////////////////////////////////////////////////////
 };
 
