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