载入中...
搜索中...
未找到
EventSink.cpp
浏览该文件的文档.
1// Keeps the window settings and the render surface aligned with the platform.
2//
3// Two things used to live in the SDL event pump and forced it to depend on both
4// window and graphics: resize handling, and the app background/foreground
5// callback that tears down and rebuilds the Vulkan surface on mobile.
6
7#include "common/Capability.h"
8#include "common/Module.h"
11#include "window/Window.h"
12#include "window/sdl/Window.h"
13
14#include <SDL2/SDL.h>
15#include <SDL2/SDL_vulkan.h>
16
17#include <algorithm>
18
20namespace {
21
23void syncWindowPixelSize() {
24 auto *win = eve::ModuleManager::getInstance<eve::window::Window>("Window");
25 if (!win) return;
26 auto *sdlWin = dynamic_cast<Window *>(win);
27 if (!sdlWin) return;
28 SDL_Window *native = static_cast<SDL_Window *>(sdlWin->getHandle());
29 if (!native) return;
30
31 int lw = 0, lh = 0, pw = 0, ph = 0;
32 SDL_GetWindowSize(native, &lw, &lh);
33 SDL_Vulkan_GetDrawableSize(native, &pw, &ph);
34 if (pw <= 0 || ph <= 0) {
35 pw = lw;
36 ph = lh;
37 }
38 WindowSettings s = win->getWindowSettings();
39 s.width = static_cast<uint16_t>(std::max(lw, 1));
40 s.height = static_cast<uint16_t>(std::max(lh, 1));
41 // Keep settings + graphics viewport aligned after rotation / resume.
42 sdlWin->updateSettings(s, true);
43}
44
51int SDLCALL watchAppEvents(void * /*udata*/, SDL_Event *event) {
52 auto *surfaceHost = eve::cap::query<IWindowSurfaceHost>();
53 if (!surfaceHost) return 1;
54
55 switch (event->type) {
56 case SDL_APP_DIDENTERBACKGROUND:
57 // Stop presenting: the native surface is being torn down.
58 surfaceHost->setActive(false);
59 break;
60 case SDL_APP_WILLENTERFOREGROUND:
61 case SDL_APP_DIDENTERFOREGROUND:
62 // The native window is recreated on resume; rebuild the render
63 // surface and swapchain, then resume presenting.
64 surfaceHost->requestSurfaceRecreate();
65 surfaceHost->setActive(true);
66 syncWindowPixelSize();
67 break;
68 default:
69 break;
70 }
71 return 1;
72}
73
74class WindowEventSink : public eve::event::IPlatformEventSink {
75public:
76 bool observePlatformEvent(const void *nativeEvent) override {
77 const auto &e = *static_cast<const SDL_Event *>(nativeEvent);
78 if (e.type == SDL_WINDOWEVENT && (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
79 e.window.event == SDL_WINDOWEVENT_RESIZED))
80 syncWindowPixelSize();
81 // Never consume: SDL_WINDOWEVENT_CLOSE still has to reach the pump,
82 // which turns it into "quit".
83 return false;
84 }
85
86 void onPumpFinished() override {
87 // Deferred to the first pump because the watch can only be added once
88 // SDL is initialized, which is later than static registration.
89 if (watchInstalled_) return;
90 watchInstalled_ = true;
91 SDL_AddEventWatch(watchAppEvents, nullptr);
92 }
93
94private:
95 bool watchInstalled_ = false;
96};
97
98struct Register {
99 Register() {
100 static WindowEventSink sink;
103 }
104} g_register;
105
106} // namespace
107} // namespace eve::window::sdl
uint32_t s
Definition Weather.cpp:28
Platform window interface (SDL implementation on desktop/mobile). Script: win <- eve....
Definition Window.h:46
I * query()
Definition Capability.h:77
Display settings for window creation/resize. width/height == 0 selects the desktop display mode size.
Definition Window.h:17