Detect window resize events and update editor main

This commit is contained in:
2025-04-12 10:11:48 +10:00
parent 6e1393ce64
commit 1849593dfc
4 changed files with 48 additions and 27 deletions

View File

@@ -15,16 +15,23 @@ using namespace Nova;
int main() { int main() {
Debug::get_logger()->set_level(spdlog::level::trace); Debug::get_logger()->set_level(spdlog::level::trace);
const auto wd = WindowDriver::create(); auto wd = WindowDriver::create();
const auto rd = RenderDriver::create(RenderAPI::VULKAN, wd); auto rd = RenderDriver::create(RenderAPI::VULKAN, wd);
auto window = wd->create_window("Nova", 1280, 720);
auto surface = rd->create_surface(window);
// TODO: select_device should probably consider what surface is
// being used as not all devices support all surfaces. alternatively
// the caller chould check if the device supports the surface
rd->select_device(RenderDevice::AUTO); rd->select_device(RenderDevice::AUTO);
wd->create_window("Nova", 1280, 720);
while (wd->get_window_count() > 0) { while (wd->get_window_count() > 0) {
wd->poll_events(); wd->poll_events();
} }
rd->destroy_surface(surface);
delete rd; delete rd;
delete wd; delete wd;
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@@ -97,14 +97,12 @@ void VulkanRenderDriver::select_device(u32 index) {
SurfaceID VulkanRenderDriver::create_surface(const WindowID window) { SurfaceID VulkanRenderDriver::create_surface(const WindowID window) {
NOVA_AUTO_TRACE(); NOVA_AUTO_TRACE();
NOVA_ASSERT(m_instance);
NOVA_ASSERT(m_window_driver); NOVA_ASSERT(m_window_driver);
return m_window_driver->create_surface(window, this); return m_window_driver->create_surface(window, this);
} }
void VulkanRenderDriver::destroy_surface(const SurfaceID surface) { void VulkanRenderDriver::destroy_surface(const SurfaceID surface) {
NOVA_AUTO_TRACE(); NOVA_AUTO_TRACE();
NOVA_ASSERT(m_instance);
SurfaceData* data = reinterpret_cast<SurfaceData*>(surface); SurfaceData* data = reinterpret_cast<SurfaceData*>(surface);
vkDestroySurfaceKHR(m_instance, data->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR)); vkDestroySurfaceKHR(m_instance, data->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR));
delete data; delete data;

View File

@@ -16,6 +16,7 @@
#endif #endif
#include <nova/core/debug.h> #include <nova/core/debug.h>
#include <nova/render/render_driver.h>
#include <ranges> #include <ranges>
@@ -46,28 +47,40 @@ X11WindowDriver::~X11WindowDriver() {
} }
void X11WindowDriver::poll_events() { void X11WindowDriver::poll_events() {
NOVA_AUTO_TRACE(); while (XPending(m_display)) {
XEvent event; XEvent event;
XNextEvent(m_display, &event); XNextEvent(m_display, &event);
const WindowID window = event.xany.window; const WindowID window = event.xany.window;
NOVA_ASSERT(m_windows.contains(window)); WindowData& data = m_windows[window];
switch (event.type) { switch (event.type) {
case Expose: case ConfigureNotify: {
XConfigureEvent xce = event.xconfigure;
if (xce.width != data.width || xce.height != data.height) {
data.width = xce.width;
data.height = xce.height;
NOVA_DEBUG("Window event: RESIZED ({}x{})", xce.width, xce.height);
}
break; break;
}
case ClientMessage: { case ClientMessage: {
if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) { if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) {
NOVA_DEBUG("Window event: CLOSED");
destroy_window(window); destroy_window(window);
} }
break; break;
} }
case MapNotify:
case ReparentNotify:
// Ignore these events
break;
default: default:
NOVA_WARN("Unhandled X11 event: {}", event.type); NOVA_WARN("Unhandled X11 event: {}", event.type);
break; break;
} }
} }
}
void X11WindowDriver::beep() { void X11WindowDriver::beep() {
XBell(m_display, 100); XBell(m_display, 100);
@@ -81,11 +94,12 @@ WindowID X11WindowDriver::create_window(const std::string_view title, const u32
NOVA_AUTO_TRACE(); NOVA_AUTO_TRACE();
const WindowID window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, width, height, 0, 0, 0); const WindowID window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, width, height, 0, 0, 0);
const WindowData& data = m_windows[window]; WindowData& data = m_windows[window];
(void)data; // TODO: Initialize window data data.width = width;
data.height = height;
XSetWMProtocols(m_display, window, &m_window_close_atom, 1); XSetWMProtocols(m_display, window, &m_window_close_atom, 1);
XSelectInput(m_display, window, ExposureMask); XSelectInput(m_display, window, StructureNotifyMask);
XStoreName(m_display, window, title.data()); XStoreName(m_display, window, title.data());
XMapWindow(m_display, window); XMapWindow(m_display, window);
XFlush(m_display); XFlush(m_display);
@@ -147,9 +161,10 @@ SurfaceID X11WindowDriver::create_surface(const WindowID window, RenderDriver* r
!= VK_SUCCESS) { != VK_SUCCESS) {
throw std::runtime_error("Failed to create Vulkan surface"); throw std::runtime_error("Failed to create Vulkan surface");
} }
return reinterpret_cast<SurfaceID>(surface);
return SurfaceID(surface);
#else #else
return SurfaceID(); return SurfaceID(nullptr);
#endif #endif
} }

View File

@@ -15,7 +15,8 @@
namespace Nova { namespace Nova {
struct WindowData { struct WindowData {
// TODO: Add stuff here int width = 0;
int height = 0;
}; };
class X11WindowDriver final : public WindowDriver { class X11WindowDriver final : public WindowDriver {