载入中...
搜索中...
未找到
Window.cpp
浏览该文件的文档.
1#include "Window.h"
2
3#include <SDL2/SDL_syswm.h>
4#ifndef EVENGINE_WEBGPU
5#include <SDL2/SDL_vulkan.h>
6#endif
7
8#include <algorithm>
9#include <cstdint>
10#include <cstdio>
11#include <iostream>
12#include <vector>
13
14#include "common/Capability.h"
15#include "common/Exception.h"
18#include "common/config.h"
20
21#ifdef EVENGINE_ANDROID
22#include "android/android.h"
23#endif
24
25#ifdef EVENGINE_IOS
26#include "ios/ios.h"
27#endif
28
29#if defined(EVENGINE_WINDOWS)
30#include <windows.h>
31#endif
32
33#ifdef EVENGINE_MACOSX
34#include "macosx/macosx.h"
35#endif
36
37namespace eve {
38
39namespace window {
40namespace sdl {
41
42namespace {
43
44Uint32 messageBoxFlag(const std::string& type) {
45 if (type == "error") return SDL_MESSAGEBOX_ERROR;
46 if (type == "warning") return SDL_MESSAGEBOX_WARNING;
47 return SDL_MESSAGEBOX_INFORMATION;
48}
49
50} // namespace
51
52Window::Window() : open(false) {
54#if defined(__EMSCRIPTEN__)
55 // Bind SDL keyboard to the render canvas instead of the whole window, so
56 // typing in the playground editor / REPL never reaches the game. The
57 // canvas must be focused (tabindex + click) to deliver keys.
58 SDL_SetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT, "canvas");
59#endif
60 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
61 throw Exception("Could not initialize SDL video subsystem (%s)", SDL_GetError());
62}
63
66 SDL_QuitSubSystem(SDL_INIT_VIDEO);
67}
68
69void Window::setSize(int w, int h) {
70 WindowSettings f = settings;
71 f.width = static_cast<uint16_t>(w);
72 f.height = static_cast<uint16_t>(h);
73
75}
76
77int Window::getWidth() const { return settings.width; }
78
79int Window::getHeight() const { return settings.height; }
80
82 f.minwidth = std::max(f.minwidth, (uint16_t)1);
83 f.minheight = std::max(f.minheight, (uint16_t)1);
84
85 if (getDisplayCount() > 0)
86 f.display = static_cast<uint8_t>(std::min(std::max(int(f.display), 0), getDisplayCount() - 1));
87 if (f.width == 0 || f.height == 0) {
88 SDL_DisplayMode mode = {};
89 SDL_GetDesktopDisplayMode(f.display, &mode);
90 f.width = static_cast<uint16_t>(mode.w);
91 f.height = static_cast<uint16_t>(mode.h);
92 }
93
94 Uint32 sdlflags = 0;
95#ifndef EVENGINE_WEBGPU
96 sdlflags = SDL_WINDOW_VULKAN;
97#endif
98
99 // On Android, disable fullscreen first on window creation so it's
100 // possible to change the orientation by specifying portait width and
101 // height, otherwise SDL will pick the current orientation dimensions when
102 // fullscreen flag is set. Don't worry, we'll set it back later when user
103 // also requested fullscreen after the window is created.
104 // See https://github.com/love2d/love-android/issues/196
105#ifdef EVENGINE_ANDROID
106 bool fullscreen = f.fullscreen;
107
108 f.fullscreen = false;
109 f.desktop_mode = true;
110#endif
111
112 if (f.fullscreen) {
113 if (f.desktop_mode)
114 sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
115 else {
116 sdlflags |= SDL_WINDOW_FULLSCREEN;
117 SDL_DisplayMode mode = {0, width, height, 0, nullptr};
118
119 // Fullscreen window creation will bug out if no mode can be used.
120 if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr) {
121 // GetClosestDisplayMode will fail if we request a size larger
122 // than the largest available display mode, so we'll try to use
123 // the largest (first) mode in that case.
124 if (SDL_GetDisplayMode(f.display, 0, &mode) < 0) return false;
125 }
126
127 width = mode.w;
128 height = mode.h;
129 }
130 }
131
132 if (f.resizable) sdlflags |= SDL_WINDOW_RESIZABLE;
133 if (f.borderless) sdlflags |= SDL_WINDOW_BORDERLESS;
134 if (f.high_dpi) sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
135 if (f.always_on_top) sdlflags |= SDL_WINDOW_ALWAYS_ON_TOP;
136
137 int x = f.x;
138 int y = f.y;
139
140 if (f.use_position) {
141 // The position needs to be in the global coordinate space.
142 SDL_Rect displaybounds = {};
143 SDL_GetDisplayBounds(f.display, &displaybounds);
144 x += displaybounds.x;
145 y += displaybounds.y;
146 } else {
147 if (f.centered)
148 x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
149 else
150 x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
151 }
152
153 close();
154
155 {
156 StartupStage stage("window: SDL_CreateWindow");
157 if (!createWindowAndContext(x, y, f.width, f.height, sdlflags, f.msaa, f.stencil, f.depth)) return false;
158 }
159
160 // Make sure the window keeps any previously set icon.
161 if (!iconRgba.empty()) setIconRGBA(iconRgba.data(), iconWidth, iconHeight);
162
163 // Make sure the mouse keeps its previous grab setting.
164 // setMouseGrab(mouseGrabbed);
165
166 // Enforce minimum window dimensions.
167 SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
168
169 if (f.use_position || f.centered) SDL_SetWindowPosition(window, x, y);
170
171 SDL_RaiseWindow(window);
172
173 // setVSync(f.vsync);
174
175#if defined(EVENGINE_ANDROID) || defined(EVENGINE_IOS)
176 // Fullscreen mobile: logical size must match the real window aspect, otherwise
177 // an 800x600 desktop config is stretched onto a portrait (or ultrawide) surface.
178 {
179 int lw = 0, lh = 0;
180 SDL_GetWindowSize(window, &lw, &lh);
181 if (lw > 0 && lh > 0) {
182 f.width = static_cast<uint16_t>(lw);
183 f.height = static_cast<uint16_t>(lh);
184 }
185 }
186#endif
187
188 updateSettings(f, false);
189
190 if (auto* surfaceHost = eve::cap::query<IWindowSurfaceHost>()) {
191 int pw = 0, ph = 0;
192#ifdef EVENGINE_WEBGPU
193 // No Vulkan drawable-size helper on WebGPU; the window size is the
194 // canvas size (the browser applies DPI scaling itself).
195 SDL_GetWindowSize(window, &pw, &ph);
196#else
197 SDL_Vulkan_GetDrawableSize(window, &pw, &ph);
198#endif
199 if (pw <= 0 || ph <= 0) {
200 pw = f.width;
201 ph = f.height;
202 }
203 pixelWidth = pw;
204 pixelHeight = ph;
205 {
206 StartupStage stage("window: graphics initWithWindow");
207 surfaceHost->initWithWindow(window);
208 }
209 surfaceHost->setViewportSize(f.width, f.height, pw, ph);
210 }
211 open = true;
212 return true;
213}
214
216
217bool Window::setFullscreenDesktop(bool fullscreen) {
218 return setFullscreenInternal(fullscreen, true);
219}
220
221bool Window::setFullscreenExclusive(bool fullscreen) {
222 return setFullscreenInternal(fullscreen, false);
223}
224
225bool Window::setFullscreenInternal(bool fullscreen, bool desktop_mode) {
226 if (!window) return false;
227
228 // if (graphics && graphics->isCanvasActive())
229 // throw Exception("love.window.setFullscreen cannot be called while a Canvas is active in love.graphics.");
230
231 WindowSettings newsettings = settings;
232 newsettings.fullscreen = fullscreen;
233 newsettings.desktop_mode = desktop_mode;
234
235 Uint32 sdlflags = 0;
236
237 if (fullscreen) {
238 if (desktop_mode)
239 sdlflags = SDL_WINDOW_FULLSCREEN_DESKTOP;
240 else {
241 sdlflags = SDL_WINDOW_FULLSCREEN;
242
243 SDL_DisplayMode mode = {};
244 mode.w = windowWidth;
245 mode.h = windowHeight;
246
247 SDL_GetClosestDisplayMode(SDL_GetWindowDisplayIndex(window), &mode, &mode);
248 SDL_SetWindowDisplayMode(window, &mode);
249 }
250 }
251
252#ifdef EVENGINE_ANDROID
253 android::setImmersive(fullscreen);
254#endif
255
256 // Freshly-created windows (and CI macOS runners) can refuse FULLSCREEN_* until
257 // the window is shown and the event queue has been pumped.
258 SDL_ShowWindow(window);
259 SDL_RaiseWindow(window);
260 SDL_PumpEvents();
261
262 int rc = SDL_SetWindowFullscreen(window, sdlflags);
263 if (rc != 0) {
264 SDL_Delay(16);
265 SDL_PumpEvents();
266 rc = SDL_SetWindowFullscreen(window, sdlflags);
267 }
268
269 if (rc == 0) {
270 // SDL_GL_MakeCurrent(window, context);
271 updateSettings(newsettings, true);
272
273 // Apparently this gets un-set when we exit fullscreen (at least in OS X).
274 if (!fullscreen) SDL_SetWindowMinimumSize(window, settings.minwidth, settings.minheight);
275
276 return true;
277 }
278
279 return false;
280}
281
282bool Window::isOpen() const { return open; }
283
284void Window::setWindowTitle(const std::string& t) {
285 title = t;
286 if (window) SDL_SetWindowTitle(window, title.c_str());
287}
288
289const std::string& Window::getWindowTitle() const { return title; }
290
291void Window::setPosition(int x, int y, int display) {
292 if (!window) return;
293 int count = SDL_GetNumVideoDisplays();
294 if (display < 0 || display >= count) display = 0;
295 SDL_Rect bounds = {};
296 SDL_GetDisplayBounds(display, &bounds);
297 SDL_SetWindowPosition(window, bounds.x + x, bounds.y + y);
298 settings.x = x;
299 settings.y = y;
300 settings.display = static_cast<uint8_t>(display);
301 settings.use_position = true;
302}
303
304void Window::getPosition(int& x, int& y, int& display) {
305 if (!window) {
306 x = settings.x;
307 y = settings.y;
308 display = settings.display;
309 return;
310 }
311 int wx = 0, wy = 0;
312 SDL_GetWindowPosition(window, &wx, &wy);
313 display = SDL_GetWindowDisplayIndex(window);
314 if (display < 0) display = 0;
315 SDL_Rect bounds = {};
316 SDL_GetDisplayBounds(display, &bounds);
317 x = wx - bounds.x;
318 y = wy - bounds.y;
319}
320
321void Window::minimize() { if (window) SDL_MinimizeWindow(window); }
322void Window::maximize() { if (window) SDL_MaximizeWindow(window); }
323void Window::restore() { if (window) SDL_RestoreWindow(window); }
324
326 return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) != 0;
327}
329 return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0;
330}
331bool Window::hasFocus() const {
332 return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0;
333}
335 return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) != 0;
336}
337bool Window::isVisible() const {
338 return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_SHOWN) != 0
339 && (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) == 0;
340}
341
342void Window::setVSync(int vsync) {
343 settings.vsync = static_cast<uint8_t>(vsync < 0 ? 0 : (vsync > 255 ? 255 : vsync));
344}
345
346int Window::getVSync() const { return settings.vsync; }
347
348int Window::getPixelWidth() const { return window ? pixelWidth : 0; }
349
350int Window::getPixelHeight() const { return window ? pixelHeight : 0; }
351
353 if (!window || windowWidth <= 0) return 1.0;
354 return double(pixelWidth) / double(windowWidth);
355}
356
357double Window::getDPIScale() const {
358 if (!window) return 1.0;
359 if (!settings.use_dpi_scale) return settings.dpi_scale > 0.f ? double(settings.dpi_scale) : 1.0;
360 return getNativeDPIScale();
361}
362
363void Window::windowToPixelCoords(double* x, double* y) const {
364 if (!x || !y) return;
365 double s = getNativeDPIScale();
366 *x *= s;
367 *y *= s;
368}
369
370void Window::pixelToWindowCoords(double* x, double* y) const {
371 if (!x || !y) return;
372 double s = getNativeDPIScale();
373 if (s == 0.0) return;
374 *x /= s;
375 *y /= s;
376}
377
378void Window::windowToDPICoords(double* x, double* y) const {
379 if (!x || !y) return;
380 double s = getDPIScale();
381 if (s == 0.0) return;
382 *x /= s;
383 *y /= s;
384}
385
386void Window::DPIToWindowCoords(double* x, double* y) const {
387 if (!x || !y) return;
388 double s = getDPIScale();
389 *x *= s;
390 *y *= s;
391}
392
393double Window::toPixels(double x) const { return x * getNativeDPIScale(); }
394
395double Window::fromPixels(double x) const {
396 double s = getNativeDPIScale();
397 return s == 0.0 ? x : x / s;
398}
399
400void Window::toPixelsXY(double wx, double wy, double& px, double& py) const {
401 px = toPixels(wx);
402 py = toPixels(wy);
403}
404
405void Window::fromPixelsXY(double px, double py, double& wx, double& wy) const {
406 wx = fromPixels(px);
407 wy = fromPixels(py);
408}
409
411 int n = SDL_GetNumVideoDisplays();
412 return n < 0 ? 0 : n;
413}
414
415std::string Window::getDisplayName(int display) const {
416 if (display < 0 || display >= getDisplayCount()) return {};
417 const char* n = SDL_GetDisplayName(display);
418 return n ? std::string(n) : std::string();
419}
420
421std::string Window::getDisplayOrientation(int display) const {
422 if (display < 0 || display >= getDisplayCount()) return "unknown";
423 switch (SDL_GetDisplayOrientation(display)) {
424 case SDL_ORIENTATION_LANDSCAPE: return "landscape";
425 case SDL_ORIENTATION_LANDSCAPE_FLIPPED: return "landscapeFlipped";
426 case SDL_ORIENTATION_PORTRAIT: return "portrait";
427 case SDL_ORIENTATION_PORTRAIT_FLIPPED: return "portraitFlipped";
428 default: return "unknown";
429 }
430}
431
432std::vector<Window::WindowSize> Window::getFullscreenSizes(int display) const {
433 std::vector<WindowSize> out;
434 if (display < 0 || display >= getDisplayCount()) return out;
435 int modes = SDL_GetNumDisplayModes(display);
436 for (int i = 0; i < modes; ++i) {
437 SDL_DisplayMode mode = {};
438 if (SDL_GetDisplayMode(display, i, &mode) == 0) {
440 s.width = mode.w;
441 s.height = mode.h;
442 if (std::find(out.begin(), out.end(), s) == out.end()) out.push_back(s);
443 }
444 }
445 return out;
446}
447
448void Window::getDesktopDimensions(int display, int& outWidth, int& outHeight) const {
449 outWidth = outHeight = 0;
450 if (display < 0 || display >= getDisplayCount()) return;
451 SDL_DisplayMode mode = {};
452 if (SDL_GetDesktopDisplayMode(display, &mode) == 0) {
453 outWidth = mode.w;
454 outHeight = mode.h;
455 }
456}
457
458bool Window::showMessageBox(const std::string& caption, const std::string& message,
459 const std::string& type, bool attachToWindow) {
460 SDL_Window* parent = (attachToWindow && window) ? window : nullptr;
461 return SDL_ShowSimpleMessageBox(messageBoxFlag(type), caption.c_str(), message.c_str(), parent) == 0;
462}
463
465 if (data.buttons.empty()) return -1;
466 std::vector<SDL_MessageBoxButtonData> buttons;
467 buttons.reserve(data.buttons.size());
468 for (size_t i = 0; i < data.buttons.size(); ++i) {
469 Uint32 flags = 0;
470 if (int(i) == data.enterButtonIndex) flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
471 if (int(i) == data.escapeButtonIndex) flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
472 buttons.push_back({flags, int(i), data.buttons[i].c_str()});
473 }
474 SDL_MessageBoxData sdl = {};
475 sdl.flags = messageBoxFlag(data.type);
476 sdl.window = (data.attachToWindow && window) ? window : nullptr;
477 sdl.title = data.title.c_str();
478 sdl.message = data.message.c_str();
479 sdl.numbuttons = int(buttons.size());
480 sdl.buttons = buttons.data();
481 sdl.colorScheme = nullptr;
482 int buttonid = -1;
483 if (SDL_ShowMessageBox(&sdl, &buttonid) < 0) return -1;
484 return buttonid;
485}
486
487void Window::requestAttention(bool continuous) {
488#ifdef EVENGINE_MACOSX
489 eve::macosx::requestAttention(continuous);
490#else
491 if (!window) return;
492#if SDL_VERSION_ATLEAST(2, 0, 16)
493 SDL_FlashWindow(window, continuous ? SDL_FLASH_UNTIL_FOCUSED : SDL_FLASH_BRIEFLY);
494#endif
495#endif
496}
497
498bool Window::setIconRGBA(const uint8_t* rgba, int w, int h) {
499 if (!rgba || w <= 0 || h <= 0) return false;
500
501#if SDL_BYTEORDER == SDL_BIG_ENDIAN
502 const Uint32 rmask = 0xFF000000;
503 const Uint32 gmask = 0x00FF0000;
504 const Uint32 bmask = 0x0000FF00;
505 const Uint32 amask = 0x000000FF;
506#else
507 const Uint32 rmask = 0x000000FF;
508 const Uint32 gmask = 0x0000FF00;
509 const Uint32 bmask = 0x00FF0000;
510 const Uint32 amask = 0xFF000000;
511#endif
512
513 SDL_Surface* surface =
514 SDL_CreateRGBSurfaceFrom(const_cast<uint8_t*>(rgba), w, h, 32, w * 4, rmask, gmask, bmask, amask);
515 if (!surface) {
516 throw Exception("Could not create window icon surface: %s", SDL_GetError());
517 }
518
519 if (window)
520 SDL_SetWindowIcon(window, surface);
521
522 SDL_FreeSurface(surface);
523
524 iconRgba.assign(rgba, rgba + static_cast<size_t>(w) * h * 4);
525 iconWidth = w;
526 iconHeight = h;
527
528#ifdef EVENGINE_MACOSX
529 // SDL only updates the titlebar/mini window icon on macOS; refresh the Dock icon too.
530 eve::macosx::setIconRGBA(rgba, w, h);
531#endif
532
533 return true;
534}
535
536bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool stencil, int depth) {
537#ifdef EVENGINE_MACOSX
538 // Packaged macOS builds ship the Vulkan loader + MoltenVK next to the
539 // executable (../lib or ../Frameworks) so players do not need the LunarG
540 // Vulkan SDK. Point SDL at the bundled loader explicitly (SDL would
541 // otherwise only search system locations), and let the bootstrap set
542 // VK_ICD_FILENAMES for the bundled ICD manifest. No-op in dev builds
543 // that rely on the SDK environment.
544 const std::string bundledVulkanDir = eve::macosx::bootstrapBundledVulkan();
545 if (!bundledVulkanDir.empty()) {
546 const std::string loader = bundledVulkanDir + "/libvulkan.1.dylib";
547 if (SDL_Vulkan_LoadLibrary(loader.c_str()) < 0)
548 std::fprintf(stderr, "eve: failed to load bundled Vulkan loader %s (%s)\n",
549 loader.c_str(), SDL_GetError());
550 }
551#endif
552
553 window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags);
554
555 if (!window) {
556 throw Exception("Window Create Failed: %s", SDL_GetError());
557 }
558
559 return true;
560}
561
562void Window::close() { close(true); }
563
564void Window::close(bool allowExceptions) {
565 if (window) {
566 // ImGui / swapchain teardown needs the native window and surface still
567 // alive. Destroy the SDL window only after graphics has dropped them.
568 if (auto* surfaceHost = eve::cap::query<IWindowSurfaceHost>()) surfaceHost->onNativeWindowDestroyed();
569
570 SDL_DestroyWindow(window);
571 window = nullptr;
572
573 // The old window may have generated pending events which are no longer
574 // relevant. Destroy them all!
575 SDL_FlushEvent(SDL_WINDOWEVENT);
576 }
577
578 pixelWidth = pixelHeight = 0;
579 windowWidth = windowHeight = 0;
580 open = false;
581}
582
583void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport) {
584 settings = newsettings;
585 if (window) {
586 SDL_GetWindowSize(window, &windowWidth, &windowHeight);
587#ifdef EVENGINE_WEBGPU
588 SDL_GetWindowSize(window, &pixelWidth, &pixelHeight);
589#else
590 SDL_Vulkan_GetDrawableSize(window, &pixelWidth, &pixelHeight);
591#endif
592 }
593 if (updateGraphicsViewport && window) {
594 if (auto* surfaceHost = eve::cap::query<IWindowSurfaceHost>())
595 surfaceHost->setViewportSize(windowWidth, windowHeight, pixelWidth, pixelHeight);
596 }
597}
598
599} // namespace sdl
600} // namespace window
601} // namespace eve
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
const std::string & s
float py
std::string message
glm::vec3 n
Definition Grass.cpp:63
int h
std::vector< Colorf > px
std::int32_t parent
float f
float t
std::uint32_t count
std::uint32_t depth
float wx
float wy
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
StartupStage public API.
void getDesktopDimensions(int display, int &outWidth, int &outHeight) const override
Desktop resolution of a display.
Definition Window.cpp:448
bool hasMouseFocus() const override
True when the window has mouse focus.
Definition Window.cpp:334
bool setFullscreenExclusive(bool fullscreen) override
Switches between exclusive fullscreen and windowed mode.
Definition Window.cpp:221
bool isMaximized() const override
True when the window is maximized.
Definition Window.cpp:325
bool isVisible() const override
True when the window is visible (not hidden).
Definition Window.cpp:337
void maximize() override
Maximizes the window.
Definition Window.cpp:322
bool setIconRGBA(const uint8_t *rgba, int w, int h) override
Sets the window icon from tightly packed RGBA8 pixels (w*h*4 bytes).
Definition Window.cpp:498
void setVSync(int vsync) override
Enables/disables vertical sync (0 = off, 1 = on).
Definition Window.cpp:342
int getVSync() const override
Current vsync setting (0 = off, 1 = on).
Definition Window.cpp:346
int showMessageBoxData(const MessageBoxData &data) override
Shows a configurable message box; returns the pressed button index.
Definition Window.cpp:464
int getHeight() const override
Current logical window height.
Definition Window.cpp:79
void restore() override
Restores from minimized/maximized state.
Definition Window.cpp:323
double getDPIScale() const override
Current UI/logical DPI scale (1.0 on non-retina displays).
Definition Window.cpp:357
int getPixelHeight() const override
Framebuffer (pixel) height of the window.
Definition Window.cpp:350
std::string getDisplayOrientation(int display) const override
Display orientation string (e.g. "landscape").
Definition Window.cpp:421
bool hasFocus() const override
True when the window has keyboard focus.
Definition Window.cpp:331
double fromPixels(double x) const override
Scales a UI-pixel length back to logical units.
Definition Window.cpp:395
int getWidth() const override
Current logical window width.
Definition Window.cpp:77
bool isMinimized() const override
True when the window is minimized.
Definition Window.cpp:328
bool setWindowSettings(WindowSettings settings) override
Applies a full WindowSettings struct (recreates the window when needed).
Definition Window.cpp:81
void setWindowTitle(const std::string &title) override
Sets the window title shown in the OS title bar.
Definition Window.cpp:284
void fromPixelsXY(double px, double py, double &wx, double &wy) const override
Converts a framebuffer pixel XY pair to logical coordinates.
Definition Window.cpp:405
void requestAttention(bool continuous) override
Requests OS attention (flashing taskbar); continuous repeats until focused.
Definition Window.cpp:487
std::vector< WindowSize > getFullscreenSizes(int display) const override
Fullscreen sizes supported by a display.
Definition Window.cpp:432
void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport)
Used by event backend on resize to refresh drawable size / viewport.
Definition Window.cpp:583
void windowToDPICoords(double *x, double *y) const override
Converts window logical coordinates to UI-DPI coordinates.
Definition Window.cpp:378
double getNativeDPIScale() const override
Native DPI scale reported by the OS for this window.
Definition Window.cpp:352
void pixelToWindowCoords(double *x, double *y) const override
Converts framebuffer pixel coordinates to window logical coordinates.
Definition Window.cpp:370
int getPixelWidth() const override
Framebuffer (pixel) width of the window.
Definition Window.cpp:348
bool isOpen() const override
True while the native window exists and has not been closed.
Definition Window.cpp:282
double toPixels(double x) const override
Scales a logical length to UI pixels.
Definition Window.cpp:393
int getDisplayCount() const override
Number of displays attached to the system.
Definition Window.cpp:410
void setPosition(int x, int y, int display) override
Moves the window to a position in logical units on the given display.
Definition Window.cpp:291
bool setFullscreenDesktop(bool fullscreen) override
Switches between desktop fullscreen and windowed mode.
Definition Window.cpp:217
void toPixelsXY(double wx, double wy, double &px, double &py) const override
Converts a logical XY pair to framebuffer pixels.
Definition Window.cpp:400
std::string getDisplayName(int display) const override
Human-readable display name for a display index.
Definition Window.cpp:415
void getPosition(int &x, int &y, int &display) override
Reads the current window position and display index.
Definition Window.cpp:304
void DPIToWindowCoords(double *x, double *y) const override
Converts UI-DPI coordinates to window logical coordinates.
Definition Window.cpp:386
void windowToPixelCoords(double *x, double *y) const override
Converts window logical coordinates to framebuffer pixel coordinates.
Definition Window.cpp:363
WindowSettings getWindowSettings() override
Returns the settings last applied to this window.
Definition Window.cpp:215
void close() override
Closes and destroys the underlying window.
Definition Window.cpp:562
void minimize() override
Minimizes the window.
Definition Window.cpp:321
Window()
Constructs an unopened window module; call setWindowSettings to create.
Definition Window.cpp:52
const std::string & getWindowTitle() const override
Current title string.
Definition Window.cpp:289
void setSize(int w, int h) override
Requests a new logical window size.
Definition Window.cpp:69
bool showMessageBox(const std::string &caption, const std::string &message, const std::string &type, bool attachToWindow) override
Shows a modal message box ("info", "warning", or "error").
Definition Window.cpp:458
~Window()
Destroys the SDL_Window if still open.
Definition Window.cpp:64
WidgetDesc window(std::string title, std::vector< WidgetDesc > children, std::string id)
Top-level window widget with a title bar.
Definition Widget.cpp:292
void bindWindowEventSinkOwner(eve::window::Window *owner) noexcept
Bind the live Window module into the SDL event sink. @ownership Borrowed; cleared when the Window mod...
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
Display settings for window creation/resize. width/height == 0 selects the desktop display mode size.
Definition Window.h:18
Parameters for a multi-button modal message box.
Definition Window.h:61
Logical width/height pair used by fullscreen size queries.
Definition Window.h:52
glm::vec4 bounds