From 5c8a87faa0300e4658f5746467317fc9338e387f Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 17 Jun 2026 01:54:59 +0200 Subject: [PATCH] Bind Win32 app shell and move more legacy platform state --- docs/modernization/roadmap.md | 11 +++ docs/modernization/tasks.md | 9 +++ .../legacy_platform_services.cpp | 67 ++----------------- src/platform_legacy/legacy_platform_state.cpp | 60 +++++++++++++++++ src/platform_legacy/legacy_platform_state.h | 3 + .../windows_lifecycle_shell.cpp | 12 ++-- .../windows_runtime_shell.cpp | 44 ++++++++---- src/platform_windows/windows_runtime_shell.h | 3 + src/platform_windows/windows_stylus_input.cpp | 12 ++-- src/platform_windows/windows_vr_shell.h | 21 +++--- src/platform_windows/windows_window_shell.cpp | 66 +++++++++--------- 11 files changed, 185 insertions(+), 123 deletions(-) diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index d23063d5..20d03de3 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -92,6 +92,17 @@ Current hotspot files: Latest slice: +- The retained Web fallback service object and the Apple storage-path + preparation helper now also live in + `src/platform_legacy/legacy_platform_state.*` instead of being built inline + inside `src/platform_legacy/legacy_platform_services.cpp`, which trims + another process-global fallback/service pocket out of the legacy platform + shell. +- The Win32 window procedure, stylus state updates, lifecycle shutdown path, + and VR shell callback wiring no longer reach `App::I` directly; the live + Windows shell now binds the active `App*` explicitly through + `src/platform_windows/windows_runtime_shell.*`, leaving `App::I` only at + the entry/shutdown composition edge in the touched Win32 path. - The full retained Apple document bridge construction no longer lives inline in `src/platform_legacy/legacy_platform_services.cpp`; it now lives behind `active_legacy_apple_document_platform_services()` in diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index ca0a9287..39aa34e9 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -1202,6 +1202,15 @@ Why now: platform-handle state on `App`, which blocks a real `pp_platform_*` shell split. Current slice: +- The retained Web fallback service object and the Apple storage-path + preparation helper now also live in + `src/platform_legacy/legacy_platform_state.*` instead of being built inline + in `src/platform_legacy/legacy_platform_services.cpp`, which trims another + retained fallback/state pocket out of the legacy platform shell. +- The touched Win32 shell path no longer reaches `App::I` directly for + window-procedure dispatch, stylus state updates, lifecycle shutdown, or VR + callback/thread setup; `src/platform_windows/windows_runtime_shell.*` now + binds the active `App*` explicitly and clears that binding on shutdown. - Windows VR session snapshot ownership no longer lives on `App`. - `VrSessionSnapshot` now lives behind `src/platform_windows/windows_vr_shell.h` and diff --git a/src/platform_legacy/legacy_platform_services.cpp b/src/platform_legacy/legacy_platform_services.cpp index 213cde77..18a67c4d 100644 --- a/src/platform_legacy/legacy_platform_services.cpp +++ b/src/platform_legacy/legacy_platform_services.cpp @@ -43,70 +43,15 @@ void webgl_sync(); namespace { -#ifdef __WEB__ -class RetainedWebPlatformServices final : public pp::platform::WebPlatformServices { -public: - void publish_exported_image(std::string_view path) override - { - (void)path; - } - - void flush_persistent_storage() override - { - webgl_sync(); - } - - [[nodiscard]] int default_canvas_resolution() override - { - return pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::webgl); - } - - void save_prepared_file( - std::string_view path, - std::string_view suggested_name, - pp::platform::PreparedFileCallback callback) override - { - const std::string value(path); - const std::string name(suggested_name); - webgl_pick_file_save(value, name, [callback = std::move(callback), value](bool success) { - callback(value, success); - }); - } -}; -#endif - -[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services() -{ -#ifdef __WEB__ - static RetainedWebPlatformServices services; - return pp::platform::resolve_web_platform_services(services); -#else - return pp::platform::active_web_platform_services(); -#endif -} - -#if defined(__IOS__) || defined(__OSX__) -[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths() -{ - const auto& apple_state = pp::platform::legacy::active_legacy_apple_state(); -#ifdef __IOS__ - [apple_state.ios_view init_dirs]; -#elif defined(__OSX__) - [apple_state.osx_app init_dirs]; -#endif - return pp::platform::legacy::active_legacy_storage_paths(); -} -#endif - // DEBT-0017: fallback for platforms that do not inject PlatformServices yet. class LegacyPlatformServices final : public pp::platform::PlatformServices { public: [[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override { #if defined(__IOS__) - return prepare_legacy_apple_storage_paths(); + return pp::platform::legacy::prepare_legacy_apple_storage_paths(); #elif defined(__OSX__) - return prepare_legacy_apple_storage_paths(); + return pp::platform::legacy::prepare_legacy_apple_storage_paths(); #elif __LINUX__ const std::string data_path = linux_home_path() + "/PanoPainter"; mkpath(data_path + "/brushes"); @@ -316,7 +261,7 @@ public: const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::webgl) { - active_legacy_web_platform_services().publish_exported_image(path); + pp::platform::legacy::active_legacy_web_platform_services().publish_exported_image(path); return; } if (!pp::platform::platform_publishes_exported_images(family)) @@ -336,7 +281,7 @@ public: const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::webgl) { - active_legacy_web_platform_services().flush_persistent_storage(); + pp::platform::legacy::active_legacy_web_platform_services().flush_persistent_storage(); return; } if (!pp::platform::platform_flushes_persistent_storage(family)) @@ -505,7 +450,7 @@ public: { const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::webgl) - return active_legacy_web_platform_services().default_canvas_resolution(); + return pp::platform::legacy::active_legacy_web_platform_services().default_canvas_resolution(); return pp::platform::platform_default_canvas_resolution(family); } @@ -584,7 +529,7 @@ public: const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::webgl) { - active_legacy_web_platform_services().save_prepared_file( + pp::platform::legacy::active_legacy_web_platform_services().save_prepared_file( path, suggested_name, std::move(callback)); diff --git a/src/platform_legacy/legacy_platform_state.cpp b/src/platform_legacy/legacy_platform_state.cpp index 97f9a462..58a10949 100644 --- a/src/platform_legacy/legacy_platform_state.cpp +++ b/src/platform_legacy/legacy_platform_state.cpp @@ -10,6 +10,12 @@ #include #endif +void webgl_pick_file_save( + const std::string& path, + const std::string& name, + std::function callback); +void webgl_sync(); + namespace pp::platform::legacy { namespace { @@ -204,6 +210,43 @@ struct RetainedLegacyAppleDocumentPlatformState final { } #endif +class RetainedWebPlatformServices final : public pp::platform::WebPlatformServices { +public: + void publish_exported_image(std::string_view path) override + { + (void)path; + } + + void flush_persistent_storage() override + { +#ifdef __WEB__ + webgl_sync(); +#endif + } + + [[nodiscard]] int default_canvas_resolution() override + { + return pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::webgl); + } + + void save_prepared_file( + std::string_view path, + std::string_view suggested_name, + pp::platform::PreparedFileCallback callback) override + { + const std::string value(path); + const std::string name(suggested_name); +#ifdef __WEB__ + webgl_pick_file_save(value, name, [callback = std::move(callback), value](bool success) { + callback(value, success); + }); +#else + (void)name; + callback(value, false); +#endif + } +}; + } #if defined(__LINUX__) || defined(__WEB__) @@ -254,6 +297,17 @@ active_legacy_apple_document_platform_services() return *retained.services; } +[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths() +{ + const auto& apple_state = active_legacy_apple_state(); +#ifdef __IOS__ + [apple_state.ios_view init_dirs]; +#elif defined(__OSX__) + [apple_state.osx_app init_dirs]; +#endif + return active_legacy_storage_paths(); +} + void set_legacy_apple_state( #ifdef __IOS__ GameViewController* ios_view, @@ -294,6 +348,12 @@ void set_legacy_apple_state( } #endif +[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services() +{ + static RetainedWebPlatformServices services; + return pp::platform::resolve_web_platform_services(services); +} + [[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths() { return retained_legacy_storage_paths().storage_paths; diff --git a/src/platform_legacy/legacy_platform_state.h b/src/platform_legacy/legacy_platform_state.h index 1073506c..65f25d0d 100644 --- a/src/platform_legacy/legacy_platform_state.h +++ b/src/platform_legacy/legacy_platform_state.h @@ -50,6 +50,7 @@ struct RetainedLegacyAppleState final { [[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state(); [[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& active_legacy_apple_document_platform_services(); +[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths(); void set_legacy_apple_state( #ifdef __IOS__ GameViewController* ios_view, @@ -61,6 +62,8 @@ void set_legacy_apple_state( ); #endif +[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services(); + [[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths(); void set_legacy_storage_paths(pp::platform::PlatformStoragePaths paths); diff --git a/src/platform_windows/windows_lifecycle_shell.cpp b/src/platform_windows/windows_lifecycle_shell.cpp index a4fbdae4..33968b0b 100644 --- a/src/platform_windows/windows_lifecycle_shell.cpp +++ b/src/platform_windows/windows_lifecycle_shell.cpp @@ -46,13 +46,17 @@ void request_window_close(HWND hWnd) void handle_window_close_message(VrShellState& vr) { + auto* app = bound_app(); + auto* runtime = bound_runtime(); mark_lifecycle_stopped(); request_stop_and_join_vr_thread(vr); - App::I->runtime().ui_thread_stop(); - App::I->runtime().render_thread_stop(); - App::I->terminate(); + runtime->ui_thread_stop(); + runtime->render_thread_stop(); + app->terminate(); + App::I = nullptr; + bind_app(nullptr); bind_runtime(nullptr); - delete App::I; + delete app; PostQuitMessage(0); } diff --git a/src/platform_windows/windows_runtime_shell.cpp b/src/platform_windows/windows_runtime_shell.cpp index 671b35eb..8584ffed 100644 --- a/src/platform_windows/windows_runtime_shell.cpp +++ b/src/platform_windows/windows_runtime_shell.cpp @@ -18,6 +18,7 @@ namespace pp::platform::windows { namespace { struct RetainedWindowsRuntimeState final { + App* app = nullptr; AppRuntime* runtime = nullptr; }; @@ -38,9 +39,11 @@ void register_touch_window(HWND hWnd) void initialize_runtime_threads() { + auto* app = bound_app(); + auto* runtime = bound_runtime(); mark_lifecycle_running(); - App::I->runtime().render_thread_start(*App::I); - App::I->runtime().ui_thread_start(*App::I); + runtime->render_thread_start(*app); + runtime->ui_thread_start(*app); } void install_debug_gl_callbacks() @@ -85,10 +88,11 @@ void restore_window_placement(HWND hWnd, int show_command) void run_main_message_loop() { MSG msg; + auto* app = bound_app(); LOG("start main loop"); while (lifecycle_is_running()) { - auto present = App::I->animate || App::I->redraw ? + auto present = app->animate || app->redraw ? PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0); if (msg.message == WM_QUIT) @@ -113,6 +117,16 @@ void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTAN } +void bind_app(App* app) noexcept +{ + retained_runtime_state().app = app; +} + +App* bound_app() noexcept +{ + return retained_runtime_state().app; +} + void bind_runtime(AppRuntime* runtime) noexcept { retained_runtime_state().runtime = runtime; @@ -128,10 +142,12 @@ int run_main_application(int argc, char** argv) auto& state = retained_state(); state.hInst = GetModuleHandle(NULL); - App::I = new App(); - bind_runtime(&App::I->runtime()); - App::I->set_platform_services(&pp::platform::windows::platform_services()); - App::I->initLog(); + auto* app = new App(); + App::I = app; + bind_app(app); + bind_runtime(&app->runtime()); + app->set_platform_services(&pp::platform::windows::platform_services()); + app->initLog(); pp::platform::windows::init_shcore_API(); pp::platform::windows::initialize_stylus_input(); @@ -149,7 +165,7 @@ int run_main_application(int argc, char** argv) pp::platform::windows::read_WMI_info(); - App::I->create(); + app->create(); auto startup = pp::platform::windows::initialize_main_window_startup_state(); auto context = pp::platform::windows::OpenGlWindowContext {}; @@ -158,9 +174,11 @@ int run_main_application(int argc, char** argv) case pp::platform::windows::MainStartupResult::Ok: break; case pp::platform::windows::MainStartupResult::GladLoadFailure: + bind_app(nullptr); bind_runtime(nullptr); return 0; case pp::platform::windows::MainStartupResult::MissingCoreContextSupport: + bind_app(nullptr); bind_runtime(nullptr); return -1; } @@ -173,8 +191,9 @@ int run_main_application(int argc, char** argv) switch (const_hash(argv[1])) { case const_hash("convert"): - App::I->initShaders(); - App::I->cmd_convert(argv[2], argv[3]); + app->initShaders(); + app->cmd_convert(argv[2], argv[3]); + bind_app(nullptr); bind_runtime(nullptr); return 0; case const_hash("-vrmode"): @@ -192,6 +211,7 @@ int run_main_application(int argc, char** argv) void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash) { auto& state = retained_state(); + auto* app = bound_app(); register_touch_window(state.hWnd); wglMakeCurrent(NULL, NULL); @@ -201,11 +221,11 @@ void run_main_window_runtime(const MainWindowStartupState& startup, bool start_i initialize_wintab(state.hWnd, state.sandboxed); set_main_window_icon(state.hWnd); - App::I->ui_sync(); + app->ui_sync(); restore_window_placement(state.hWnd, startup.show_command); if (start_in_vr) - App::I->vr_start(); + app->vr_start(); LOG("show main window"); SetForegroundWindow(state.hWnd); diff --git a/src/platform_windows/windows_runtime_shell.h b/src/platform_windows/windows_runtime_shell.h index d3f9388d..0f51b293 100644 --- a/src/platform_windows/windows_runtime_shell.h +++ b/src/platform_windows/windows_runtime_shell.h @@ -3,12 +3,15 @@ #include "platform_windows/windows_bootstrap_helpers.h" #include "platform_windows/windows_splash.h" +class App; class AppRuntime; namespace pp::platform::windows { int run_main_application(int argc, char** argv); void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash); +void bind_app(App* app) noexcept; +[[nodiscard]] App* bound_app() noexcept; void bind_runtime(AppRuntime* runtime) noexcept; [[nodiscard]] AppRuntime* bound_runtime() noexcept; diff --git a/src/platform_windows/windows_stylus_input.cpp b/src/platform_windows/windows_stylus_input.cpp index 8fdcaae1..d14bb91e 100644 --- a/src/platform_windows/windows_stylus_input.cpp +++ b/src/platform_windows/windows_stylus_input.cpp @@ -4,6 +4,7 @@ #include "app.h" #include "log.h" +#include "platform_windows/windows_runtime_shell.h" #include "wacom.h" namespace pp::platform::windows { @@ -53,6 +54,7 @@ void initialize_stylus_input() void update_stylus_state(float dt) { auto& state = stylus_input_state(); + auto* app = bound_app(); state.timer_stylus += dt; state.timer_ink_touch += dt; state.timer_ink_pen += dt; @@ -61,24 +63,24 @@ void update_stylus_state(float dt) { WacomTablet::I.m_stylus = false; WacomTablet::I.m_eraser = false; - App::I->redraw = true; + app->redraw = true; } if (state.timer_ink_pen > 0.1f && WacomTablet::I.m_ink_pen) { WacomTablet::I.m_ink_pen = false; - App::I->redraw = true; + app->redraw = true; } if (state.timer_ink_touch > 0.1f && WacomTablet::I.m_ink_touch) { WacomTablet::I.m_ink_touch = false; - App::I->redraw = true; + app->redraw = true; } } void note_wintab_packet() { auto& state = stylus_input_state(); - App::I->set_stylus(); + bound_app()->set_stylus(); state.timer_stylus = 0.0f; } @@ -118,7 +120,7 @@ void handle_pointer_update_message(WPARAM wp) state.timer_ink_pen = 0.0f; WacomTablet::I.m_ink_pen = true; WacomTablet::I.m_pen_pres = static_cast(pen_info.pressure) / 1024.0f; - App::I->set_stylus(); + bound_app()->set_stylus(); return; default: diff --git a/src/platform_windows/windows_vr_shell.h b/src/platform_windows/windows_vr_shell.h index 61dd501b..7c26df79 100644 --- a/src/platform_windows/windows_vr_shell.h +++ b/src/platform_windows/windows_vr_shell.h @@ -13,6 +13,8 @@ namespace pp::platform::windows { +[[nodiscard]] App* bound_app() noexcept; + struct VrShellState final { std::mutex snapshot_mutex; VrSessionSnapshot session; @@ -72,9 +74,10 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic if (sandboxed) return false; + auto* app = bound_app(); state.vive = std::make_unique(); - state.vive->on_draw = [](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) { - App::I->vr_draw(proj, view, pose); + state.vive->on_draw = [app](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) { + app->vr_draw(proj, view, pose); }; if (!state.vive->Initialize()) { @@ -89,7 +92,7 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic state.hmd_renderer.join(); } - state.hmd_renderer = std::jthread([&state, &running](std::stop_token stop_token) { + state.hmd_renderer = std::jthread([app, &state, &running](std::stop_token stop_token) { if (!state.vive) return; @@ -98,13 +101,13 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic clear_vr_session_snapshot(state, true); state.vr_running.store(true, std::memory_order_relaxed); - state.vive->on_analog_button = std::bind(&App::vr_analog, App::I, std::placeholders::_1, + state.vive->on_analog_button = std::bind(&App::vr_analog, app, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); - state.vive->on_button = std::bind(&App::vr_digital, App::I, std::placeholders::_1, + state.vive->on_button = std::bind(&App::vr_digital, app, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); - App::I->render_task([] { - App::I->vr_draw_ui(); + app->render_task([app] { + app->vr_draw_ui(); }); const float target_tick_rate = 90; @@ -136,11 +139,11 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic state.vive->m_active, state.vive->m_controllers[0], state.vive->m_pose); - App::I->vr_update(dt); + app->vr_update(dt); if (state.vr_running.load(std::memory_order_relaxed) && state.vive->m_active) { - App::I->render_task([&state] { + app->render_task([&state] { state.vive->Draw(); }); } diff --git a/src/platform_windows/windows_window_shell.cpp b/src/platform_windows/windows_window_shell.cpp index 3249c2c2..2961ccb8 100644 --- a/src/platform_windows/windows_window_shell.cpp +++ b/src/platform_windows/windows_window_shell.cpp @@ -5,6 +5,7 @@ #include "app.h" #include "platform_windows/windows_lifecycle_shell.h" #include "platform_windows/windows_platform_services.h" +#include "platform_windows/windows_runtime_shell.h" #include "platform_windows/windows_stylus_input.h" #include "keymap.h" #include "wacom.h" @@ -47,6 +48,7 @@ RetainedState& retained_state() LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { auto& state = retained_state(); + auto* app = bound_app(); static glm::vec2 lastPoint; auto extra = GetMessageExtraInfo(); @@ -57,15 +59,15 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) handle_window_close_message(state.vr); return 0; case WM_PAINT: - App::I->redraw = true; + app->redraw = true; break; case WM_CREATE: BT_SetTerminate(); break; case WM_CLOSE: { - App::I->ui_task_async([] { - if (App::I->request_close()) + app->ui_task_async([app] { + if (app->request_close()) { destroy_window(); } @@ -79,10 +81,10 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) auto h = (float)HIWORD(lp); if (h != 0 && lifecycle_is_running()) { - App::I->ui_task_async([=] + app->ui_task_async([app, w, h] { - App::I->resize(w, h); - App::I->redraw = true; + app->resize(w, h); + app->redraw = true; }, true); } break; @@ -90,7 +92,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) case WM_ACTIVATE: { platform_services().set_cursor_visible(true); - App::I->ui_task_async([&state, wp, lp] { + app->ui_task_async([app, &state, wp, lp] { int active = GET_WM_ACTIVATE_STATE(wp, lp); WacomTablet::I.set_focus(active); static BYTE keys[256]; @@ -102,10 +104,10 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if (alt && k.first == kKey::KeyTab) continue; bool down = keys[k.second] & 0x80; - if (App::I->keys[(int)k.first] && !down) - App::I->key_up(k.first); - else if (!App::I->keys[(int)k.first] && down) - App::I->key_down(k.first); + if (app->keys[(int)k.first] && !down) + app->key_up(k.first); + else if (!app->keys[(int)k.first] && down) + app->key_down(k.first); } } }); @@ -114,7 +116,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) case WT_PACKET: { note_wintab_packet(); - App::I->ui_task_async([=] { + app->ui_task_async([=] { WacomTablet::I.handle_message(hWnd, msg, wp, lp); }); break; @@ -122,32 +124,32 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) case WM_SYSKEYDOWN: case WM_KEYDOWN: if ((lp >> 30 & 1) == 0 && - !(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt])) + !(wp == VK_TAB && app->keys[(int)kKey::KeyAlt])) { - App::I->ui_task_async([wp] { - App::I->key_down(convert_key((int)wp)); + app->ui_task_async([app, wp] { + app->key_down(convert_key((int)wp)); }); } break; case WM_SYSKEYUP: case WM_KEYUP: - if (!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt])) + if (!(wp == VK_TAB && app->keys[(int)kKey::KeyAlt])) { - App::I->ui_task_async([wp] { - App::I->key_up(convert_key((int)wp)); + app->ui_task_async([app, wp] { + app->key_up(convert_key((int)wp)); }); } break; case WM_CHAR: - App::I->ui_task_async([wp] { - App::I->key_char((int)wp); + app->ui_task_async([app, wp] { + app->key_char((int)wp); }); break; case WM_MOUSEMOVE: lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) }; { auto pt = lastPoint; - App::I->ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()] { + app->ui_task_async([app, pt, extra, p = WacomTablet::I.get_pressure()] { kEventSource pointer_source; if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch) { @@ -159,7 +161,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if ((extra & 0xFFFFFF00) == 0xFF515700) pointer_source = kEventSource::Touch; } - App::I->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser); + app->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser); }); } break; @@ -167,7 +169,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { SetCapture(hWnd); auto pt = lastPoint; - App::I->ui_task_async([pt, extra, hWnd, p = WacomTablet::I.get_pressure()] { + app->ui_task_async([app, pt, extra, p = WacomTablet::I.get_pressure()] { kEventSource pointer_source; if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch) { @@ -179,7 +181,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if ((extra & 0xFFFFFF00) == 0xFF515700) pointer_source = kEventSource::Touch; } - App::I->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser); + app->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser); }); } break; @@ -187,7 +189,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { ReleaseCapture(); auto pt = lastPoint; - App::I->ui_task_async([pt, extra] { + app->ui_task_async([app, pt, extra] { WacomTablet::I.reset_pressure(); kEventSource pointer_source; if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch) @@ -200,7 +202,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if ((extra & 0xFFFFFF00) == 0xFF515700) pointer_source = kEventSource::Touch; } - App::I->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser); + app->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser); }); } break; @@ -208,7 +210,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { SetCapture(hWnd); auto pt = lastPoint; - App::I->ui_task_async([pt, extra, hWnd] { + app->ui_task_async([app, pt, extra] { kEventSource pointer_source; if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch) { @@ -220,7 +222,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if ((extra & 0xFFFFFF00) == 0xFF515700) pointer_source = kEventSource::Touch; } - App::I->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0); + app->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0); }); } break; @@ -228,7 +230,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { ReleaseCapture(); auto pt = lastPoint; - App::I->ui_task_async([pt, extra] { + app->ui_task_async([app, pt, extra] { kEventSource pointer_source; if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch) { @@ -240,7 +242,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) if ((extra & 0xFFFFFF00) == 0xFF515700) pointer_source = kEventSource::Touch; } - App::I->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0); + app->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0); }); } break; @@ -250,8 +252,8 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) pt.x = GET_X_LPARAM(lp); pt.y = GET_Y_LPARAM(lp); ScreenToClient(hWnd, &pt); - App::I->ui_task_async([pt, wp] { - App::I->mouse_scroll((float)pt.x, (float)pt.y, + app->ui_task_async([app, pt, wp] { + app->mouse_scroll((float)pt.x, (float)pt.y, (float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA); }); break;