| 250 | } // namespace |
| 251 | |
| 252 | int main(int argc, char** argv) { |
| 253 | // Qt-free host/port parse (mirrors the Qt app's --hostname/--port flags, |
| 254 | // see parse_connection_settings() in src/main.cpp -- not reused here |
| 255 | // since it's Qt-coupled). Defaults match the bridge's default listen |
| 256 | // port. Unrecognized args (e.g. a stray "-style fusion" the bridge may |
| 257 | // still pass on the Qt side) are ignored. |
| 258 | const oid::platform::Endpoint endpoint = |
| 259 | oid::platform::parse_endpoint(argc, argv); |
| 260 | |
| 261 | // Wires the inbound message hook (non-native only; no-op native) so the |
| 262 | // embedding host can push buffer data into the module; must be installed |
| 263 | // before the transport (below) starts polling for inbound messages. |
| 264 | oid::platform::install_platform_hooks(); |
| 265 | |
| 266 | // Load persisted window geometry / UI prefs / previous-buffer list |
| 267 | // (Qt-free JSON settings) before creating the window, so the |
| 268 | // window is created at the saved size directly rather than resized |
| 269 | // after the fact. load() never throws: a missing/corrupt settings file |
| 270 | // just yields AppSettings{} defaults, so this never blocks startup. |
| 271 | oid::platform::SettingsBackend settings_backend; |
| 272 | const oid::host::AppSettings loaded = settings_backend.load(); |
| 273 | |
| 274 | oid::host::GlfwHostBackend backend; |
| 275 | if (!backend.initialize( |
| 276 | "OpenImageDebugger (ImGui)", loaded.window_w, loaded.window_h)) { |
| 277 | return 1; |
| 278 | } |
| 279 | |
| 280 | // Restore the saved window position only if it is still reachable (e.g. |
| 281 | // not on a monitor that has since been unplugged) -- otherwise leave it |
| 282 | // at whatever position the OS/window manager chose for the just-created |
| 283 | // window. |
| 284 | if (loaded.window_x.has_value() && loaded.window_y.has_value() && |
| 285 | oid::host::GlfwHostBackend::window_visible_on(*loaded.window_x, |
| 286 | *loaded.window_y, |
| 287 | loaded.window_w, |
| 288 | loaded.window_h, |
| 289 | backend.monitors())) { |
| 290 | backend.set_window_position(*loaded.window_x, *loaded.window_y); |
| 291 | } |
| 292 | |
| 293 | // HiDPI: query the window's content scale (e.g. 2x on Retina displays) |
| 294 | // up front so ImGuiLayer::initialize can rasterize the UI font atlas at |
| 295 | // physical resolution -- crisp text instead of a blurry upscaled bitmap |
| 296 | // font. Native: thin GLFW pass-through. Non-native: the GLFW shim doesn't |
| 297 | // track devicePixelRatio, so this queries it directly instead. |
| 298 | const float content_scale = |
| 299 | oid::platform::initial_content_scale(backend.window()); |
| 300 | |
| 301 | oid::host::ImGuiLayer imgui; |
| 302 | if (!imgui.initialize(backend.window(), content_scale)) { |
| 303 | return 1; |
| 304 | } |
| 305 | |
| 306 | // Canvas-pane logical size (see the PaneRenderSize comment above), |
| 307 | // seeded to the window's initial logical size so GlfwCanvas's |
| 308 | // SizeProvider below never reports 0x0 before the first draw_canvas_pane |
| 309 | // call updates it to the actual pane size. |
nothing calls this directly
no test coverage detected