mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Android/iOS backgrounding fixes; pause on focus lost
This commit is contained in:
@@ -83,6 +83,7 @@ typedef struct {
|
||||
bool vsync;
|
||||
bool startFullscreen;
|
||||
bool allowJoystickBackgroundEvents;
|
||||
bool pauseOnFocusLost;
|
||||
bool allowTextureReplacements;
|
||||
bool allowTextureDumps;
|
||||
int32_t windowPosX;
|
||||
@@ -124,6 +125,8 @@ bool aurora_begin_frame();
|
||||
void aurora_end_frame();
|
||||
|
||||
void aurora_set_log_level(AuroraLogLevel level);
|
||||
void aurora_set_pause_on_focus_lost(bool value);
|
||||
void aurora_set_background_input(bool value);
|
||||
|
||||
AuroraBackend aurora_get_backend();
|
||||
const AuroraBackend* aurora_get_available_backends(size_t* count);
|
||||
|
||||
+26
-8
@@ -92,6 +92,7 @@ AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config) noexce
|
||||
|
||||
g_sdlCustomEventsStart = SDL_RegisterEvents(2);
|
||||
ASSERT(g_sdlCustomEventsStart, "Failed to allocate user events: {}", SDL_GetError());
|
||||
ASSERT(window::initialize_event_watch(), "Error initializing SDL event watch");
|
||||
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
/* Attempt to create a window using the calling application's desired backend */
|
||||
@@ -162,8 +163,6 @@ AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config) noexce
|
||||
};
|
||||
}
|
||||
|
||||
void aurora_set_log_level(AuroraLogLevel level) noexcept { g_config.logLevel = level; }
|
||||
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
wgpu::TextureView g_currentView;
|
||||
#endif
|
||||
@@ -194,6 +193,13 @@ const AuroraEvent* update() noexcept {
|
||||
bool begin_frame() noexcept {
|
||||
ZoneScoped;
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
if (!window::is_presentable()) {
|
||||
webgpu::release_surface();
|
||||
return false;
|
||||
}
|
||||
if (window::is_paused()) {
|
||||
return false;
|
||||
}
|
||||
if (!g_surface) {
|
||||
webgpu::refresh_surface(true);
|
||||
if (!g_surface) {
|
||||
@@ -216,8 +222,8 @@ bool begin_frame() noexcept {
|
||||
return false;
|
||||
case wgpu::SurfaceGetCurrentTextureStatus::Lost:
|
||||
case wgpu::SurfaceGetCurrentTextureStatus::Error:
|
||||
Log.warn("Surface texture is {}, recreating surface", magic_enum::enum_name(surfaceTexture.status));
|
||||
webgpu::refresh_surface(true);
|
||||
Log.warn("Surface texture is {}, releasing surface", magic_enum::enum_name(surfaceTexture.status));
|
||||
webgpu::release_surface();
|
||||
return false;
|
||||
default:
|
||||
Log.error("Failed to get surface texture: {}", magic_enum::enum_name(surfaceTexture.status));
|
||||
@@ -298,9 +304,13 @@ void end_frame() noexcept {
|
||||
const auto buffer = encoder.Finish(&cmdBufDescriptor);
|
||||
g_queue.Submit(1, &buffer);
|
||||
gfx::after_submit();
|
||||
auto presentStatus = g_surface.Present();
|
||||
if (presentStatus != wgpu::Status::Success) {
|
||||
Log.warn("Surface present failed: {}", static_cast<int>(presentStatus));
|
||||
if (window::is_presentable()) {
|
||||
auto presentStatus = g_surface.Present();
|
||||
if (presentStatus != wgpu::Status::Success) {
|
||||
Log.warn("Surface present failed: {}", static_cast<int>(presentStatus));
|
||||
}
|
||||
} else {
|
||||
Log.info("Skipping present; window not presentable");
|
||||
}
|
||||
g_currentView = {};
|
||||
|
||||
@@ -335,6 +345,14 @@ bool aurora_begin_frame() { return aurora::begin_frame(); }
|
||||
void aurora_end_frame() { aurora::end_frame(); }
|
||||
AuroraBackend aurora_get_backend() { return aurora::g_config.desiredBackend; }
|
||||
const AuroraBackend* aurora_get_available_backends(size_t* count) {
|
||||
*count = aurora::PreferredBackendOrder.size();
|
||||
if (count != nullptr) {
|
||||
*count = aurora::PreferredBackendOrder.size();
|
||||
}
|
||||
return aurora::PreferredBackendOrder.data();
|
||||
}
|
||||
void aurora_set_log_level(AuroraLogLevel level) { aurora::g_config.logLevel = level; }
|
||||
void aurora_set_pause_on_focus_lost(bool value) { aurora::g_config.pauseOnFocusLost = value; }
|
||||
void aurora_set_background_input(bool value) {
|
||||
aurora::g_config.allowJoystickBackgroundEvents = value;
|
||||
aurora::window::set_background_input(value);
|
||||
}
|
||||
|
||||
+1
-10
@@ -48,15 +48,6 @@ Rml::Vector2i presentation_dimensions_from_window_size(const AuroraWindowSize& s
|
||||
return dimensions_from_viewport(viewport);
|
||||
}
|
||||
|
||||
float density_ratio_for_window(const AuroraWindowSize& size) noexcept {
|
||||
if (size.width == 0 || size.height == 0 || size.native_fb_width == 0 || size.native_fb_height == 0) {
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
return std::min(static_cast<float>(size.native_fb_width) / static_cast<float>(size.width),
|
||||
static_cast<float>(size.native_fb_height) / static_cast<float>(size.height));
|
||||
}
|
||||
|
||||
void sync_context_metrics(Rml::Vector2i dimensions) noexcept {
|
||||
if (g_context == nullptr || dimensions.x <= 0 || dimensions.y <= 0) {
|
||||
return;
|
||||
@@ -64,7 +55,7 @@ void sync_context_metrics(Rml::Vector2i dimensions) noexcept {
|
||||
if (g_context->GetDimensions() != dimensions) {
|
||||
g_context->SetDimensions(dimensions);
|
||||
}
|
||||
const float ratio = density_ratio_for_window(window::get_window_size());
|
||||
const float ratio = window::get_window_size().scale;
|
||||
if (g_context->GetDensityIndependentPixelRatio() != ratio) {
|
||||
g_context->SetDensityIndependentPixelRatio(ratio);
|
||||
}
|
||||
|
||||
+13
-2
@@ -390,6 +390,7 @@ static bool create_surface() {
|
||||
.nextInChain = chainedDescriptor.get(),
|
||||
.label = "Surface",
|
||||
};
|
||||
release_surface();
|
||||
g_surface = g_instance.CreateSurface(&surfaceDescriptor);
|
||||
if (!g_surface) {
|
||||
Log.error("Failed to create surface");
|
||||
@@ -655,10 +656,21 @@ void shutdown() {
|
||||
cache_shutdown();
|
||||
}
|
||||
|
||||
void release_surface() noexcept {
|
||||
if (g_surface) {
|
||||
g_surface.Unconfigure();
|
||||
}
|
||||
g_surface = {};
|
||||
}
|
||||
|
||||
bool refresh_surface(bool recreate) {
|
||||
if (!g_instance || !g_device) {
|
||||
return false;
|
||||
}
|
||||
if (!window::is_presentable()) {
|
||||
release_surface();
|
||||
return false;
|
||||
}
|
||||
if ((!g_surface || recreate) && !create_surface()) {
|
||||
return false;
|
||||
}
|
||||
@@ -707,6 +719,5 @@ void resize_swapchain(uint32_t width, uint32_t height, uint32_t native_width, ui
|
||||
|
||||
void aurora_enable_vsync(const bool enabled) {
|
||||
aurora::webgpu::g_graphicsConfig.surfaceConfiguration.presentMode = aurora::webgpu::best_present_mode(enabled);
|
||||
SDL_Event event{.type = aurora::g_sdlCustomEventsStart + 1};
|
||||
SDL_PushEvent(&event);
|
||||
aurora::window::push_custom_event(aurora::window::CustomEvent::RefreshSurface);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ extern wgpu::Instance g_instance;
|
||||
|
||||
bool initialize(AuroraBackend backend);
|
||||
void shutdown();
|
||||
void release_surface() noexcept;
|
||||
bool refresh_surface(bool recreate = true);
|
||||
void resize_swapchain(uint32_t width, uint32_t height, uint32_t native_width, uint32_t native_height,
|
||||
bool force = false);
|
||||
|
||||
+153
-113
@@ -21,7 +21,7 @@
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include "rmlui.hpp"
|
||||
@@ -37,6 +37,8 @@ float g_frameBufferScale = 0.f;
|
||||
bool g_frameBufferAspectFit = false;
|
||||
AuroraWindowSize g_windowSize;
|
||||
std::vector<AuroraEvent> g_events;
|
||||
std::atomic_bool g_backgrounded = false;
|
||||
bool g_lastPaused = false;
|
||||
|
||||
bool operator==(const AuroraWindowSize& lhs, const AuroraWindowSize& rhs) {
|
||||
return lhs.width == rhs.width && lhs.height == rhs.height && lhs.fb_width == rhs.fb_width &&
|
||||
@@ -99,6 +101,118 @@ void set_window_icon() noexcept {
|
||||
TRY_WARN(SDL_SetWindowIcon(g_window, iconSurface), "Failed to set window icon: {}", SDL_GetError());
|
||||
SDL_DestroySurface(iconSurface);
|
||||
}
|
||||
|
||||
bool SDLCALL lifecycle_event_watch(void*, SDL_Event* event) {
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_WILL_ENTER_BACKGROUND:
|
||||
g_backgrounded.store(true, std::memory_order_relaxed);
|
||||
break;
|
||||
case SDL_EVENT_WILL_ENTER_FOREGROUND:
|
||||
g_backgrounded.store(false, std::memory_order_relaxed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void sync_paused() {
|
||||
const bool paused = is_paused();
|
||||
if (g_lastPaused == paused) {
|
||||
return;
|
||||
}
|
||||
g_lastPaused = paused;
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = paused ? AURORA_PAUSED : AURORA_UNPAUSED,
|
||||
});
|
||||
}
|
||||
|
||||
void process_event(SDL_Event& event) {
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
imgui::process_event(event);
|
||||
#endif
|
||||
#ifdef AURORA_ENABLE_RMLUI
|
||||
rmlui::handle_event(event);
|
||||
#endif
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_RENDER_DEVICE_RESET: {
|
||||
Log.info("Render device reset, recreating surface");
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
webgpu::refresh_surface(true);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MOVED: {
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_MOVED,
|
||||
.windowPos = {.x = event.window.data1, .y = event.window.data2},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: {
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_DISPLAY_SCALE_CHANGED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: {
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_RESIZED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_ADDED: {
|
||||
auto instance = input::add_controller(event.gdevice.which);
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_CONTROLLER_ADDED,
|
||||
.controller = instance,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_REMOVED: {
|
||||
input::remove_controller(event.gdevice.which);
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_CONTROLLER_REMOVED,
|
||||
.controller = event.gdevice.which,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
input::set_mouse_scroll(event.wheel.x, event.wheel.y);
|
||||
break;
|
||||
case SDL_EVENT_QUIT:
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_EXIT,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
if (event.type == g_sdlCustomEventsStart + CustomEvent::FutureResize) {
|
||||
// Future resize event
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_RESIZED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
} else if (event.type == g_sdlCustomEventsStart + CustomEvent::RefreshSurface) {
|
||||
// Refresh surface (vsync changed)
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
webgpu::refresh_surface(false);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sync_paused();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_SDL_EVENT,
|
||||
.sdl = event,
|
||||
});
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const AuroraEvent* poll_events() {
|
||||
@@ -107,117 +221,15 @@ const AuroraEvent* poll_events() {
|
||||
SDL_Event event;
|
||||
// Clear out the previous scroll values to prevent ghost input
|
||||
input::set_mouse_scroll(0, 0);
|
||||
if (is_paused()) {
|
||||
if (SDL_WaitEvent(&event)) {
|
||||
process_event(event);
|
||||
} else {
|
||||
Log.warn("SDL_WaitEvent failed: {}", SDL_GetError());
|
||||
}
|
||||
}
|
||||
while (SDL_PollEvent(&event)) {
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
imgui::process_event(event);
|
||||
#endif
|
||||
#ifdef AURORA_ENABLE_RMLUI
|
||||
rmlui::handle_event(event);
|
||||
#endif
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_WINDOW_MINIMIZED: {
|
||||
// Android/iOS: Application backgrounded
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_PAUSED,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_RESTORED: {
|
||||
// Android/iOS: Application focused
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_UNPAUSED,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_RENDER_DEVICE_RESET: {
|
||||
Log.info("Render device reset, recreating surface");
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
webgpu::refresh_surface(true);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if defined(ANDROID)
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST: {
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_PAUSED,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED: {
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_UNPAUSED,
|
||||
});
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SDL_EVENT_WINDOW_MOVED: {
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_MOVED,
|
||||
.windowPos = {.x = event.window.data1, .y = event.window.data2},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: {
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_DISPLAY_SCALE_CHANGED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: {
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_RESIZED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_ADDED: {
|
||||
auto instance = input::add_controller(event.gdevice.which);
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_CONTROLLER_ADDED,
|
||||
.controller = instance,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_REMOVED: {
|
||||
input::remove_controller(event.gdevice.which);
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_CONTROLLER_REMOVED,
|
||||
.controller = event.gdevice.which,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
input::set_mouse_scroll(event.wheel.x, event.wheel.y);
|
||||
break;
|
||||
case SDL_EVENT_QUIT:
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_EXIT,
|
||||
});
|
||||
default:
|
||||
if (event.type == g_sdlCustomEventsStart) {
|
||||
// Future resize event
|
||||
resize_swapchain();
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_WINDOW_RESIZED,
|
||||
.windowSize = get_window_size(),
|
||||
});
|
||||
} else if (event.type == g_sdlCustomEventsStart + 1) {
|
||||
// Refresh surface (vsync changed)
|
||||
#ifdef AURORA_ENABLE_GX
|
||||
webgpu::refresh_surface(false);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_SDL_EVENT,
|
||||
.sdl = event,
|
||||
});
|
||||
process_event(event);
|
||||
}
|
||||
g_events.push_back(AuroraEvent{
|
||||
.type = AURORA_NONE,
|
||||
@@ -336,6 +348,8 @@ void show_window() {
|
||||
|
||||
bool initialize() {
|
||||
/* We don't want to initialize anything input related here, otherwise the add events will get lost to the void */
|
||||
TRY(SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"), "Error setting {}: {}", SDL_HINT_ORIENTATIONS,
|
||||
SDL_GetError());
|
||||
TRY(SDL_InitSubSystem(SDL_INIT_EVENTS | SDL_INIT_VIDEO), "Error initializing SDL: {}", SDL_GetError());
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
@@ -356,7 +370,13 @@ bool initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initialize_event_watch() {
|
||||
TRY(SDL_AddEventWatch(lifecycle_event_watch, nullptr), "Error adding SDL event watch: {}", SDL_GetError());
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
SDL_RemoveEventWatch(lifecycle_event_watch, nullptr);
|
||||
destroy_window();
|
||||
TRY_WARN(SDL_EnableScreenSaver(), "Error enabling screensaver: {}", SDL_GetError());
|
||||
SDL_Quit();
|
||||
@@ -407,6 +427,24 @@ SDL_Window* get_sdl_window() { return g_window; }
|
||||
|
||||
SDL_Renderer* get_sdl_renderer() { return g_renderer; }
|
||||
|
||||
bool is_paused() noexcept {
|
||||
if (!is_presentable()) {
|
||||
return true;
|
||||
}
|
||||
const auto flags = SDL_GetWindowFlags(g_window);
|
||||
if ((flags & SDL_WINDOW_HIDDEN) != 0u) {
|
||||
return true;
|
||||
}
|
||||
return g_config.pauseOnFocusLost && ((flags & SDL_WINDOW_INPUT_FOCUS) == 0u || (flags & SDL_WINDOW_MINIMIZED) != 0u);
|
||||
}
|
||||
|
||||
bool is_presentable() noexcept { return g_window != nullptr && !g_backgrounded.load(std::memory_order_relaxed); }
|
||||
|
||||
bool push_custom_event(CustomEvent eventType) {
|
||||
SDL_Event event{.type = g_sdlCustomEventsStart + eventType};
|
||||
return SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void set_title(const char* title) {
|
||||
TRY_WARN(SDL_SetWindowTitle(g_window, title), "Failed to set window title: {}", SDL_GetError());
|
||||
}
|
||||
@@ -432,8 +470,8 @@ void center_window() {
|
||||
}
|
||||
|
||||
static void push_future_resize_event() {
|
||||
SDL_Event event{.type = g_sdlCustomEventsStart};
|
||||
TRY_WARN(SDL_PushEvent(&event), "Failed to push SDL event for future resize: {}", SDL_GetError());
|
||||
TRY_WARN(push_custom_event(CustomEvent::FutureResize), "Failed to push SDL event for future resize: {}",
|
||||
SDL_GetError());
|
||||
}
|
||||
|
||||
void request_frame_buffer_resize() {
|
||||
@@ -463,4 +501,6 @@ void set_frame_buffer_aspect_fit(bool fit) {
|
||||
request_frame_buffer_resize();
|
||||
}
|
||||
|
||||
void set_background_input(bool value) { SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, value ? "1" : "0"); }
|
||||
|
||||
} // namespace aurora::window
|
||||
|
||||
@@ -7,7 +7,17 @@ struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
|
||||
namespace aurora::window {
|
||||
|
||||
enum class CustomEvent {
|
||||
FutureResize,
|
||||
RefreshSurface,
|
||||
End,
|
||||
};
|
||||
static Uint32 operator+(Uint32 lhs, CustomEvent rhs) { return lhs + static_cast<Uint32>(rhs); }
|
||||
|
||||
bool initialize();
|
||||
bool initialize_event_watch();
|
||||
bool push_custom_event(CustomEvent eventType);
|
||||
void shutdown();
|
||||
bool create_window(AuroraBackend backend);
|
||||
bool create_renderer();
|
||||
@@ -17,6 +27,8 @@ AuroraWindowSize get_window_size();
|
||||
const AuroraEvent* poll_events();
|
||||
SDL_Window* get_sdl_window();
|
||||
SDL_Renderer* get_sdl_renderer();
|
||||
bool is_paused() noexcept;
|
||||
bool is_presentable() noexcept;
|
||||
void set_title(const char* title);
|
||||
void set_fullscreen(bool fullscreen);
|
||||
bool get_fullscreen();
|
||||
@@ -26,4 +38,5 @@ void center_window();
|
||||
void request_frame_buffer_resize();
|
||||
void set_frame_buffer_scale(float scale);
|
||||
void set_frame_buffer_aspect_fit(bool fit);
|
||||
void set_background_input(bool value);
|
||||
}; // namespace aurora::window
|
||||
|
||||
Reference in New Issue
Block a user