///|
fn RuntimeSession::RuntimeSession(
  runtime : @native.Runtime,
  event_pump : RuntimeEventPump,
  locale_preferences : @locale.LocalePreferences,
  definitions : Array[PreparedWindow],
  windows : Array[RunningWindow],
  command_host : CommandHostRuntime?,
  wakeup : RuntimeWakeup,
  forward_menu_events : Bool,
  monitor_bridge : Bool,
  launch_input_handlers : Array[
    async (ApplicationContext, RuntimeLaunchInput) -> Unit noraise,
  ],
  window_event_handlers : Array[
    async (WindowHandle, WindowEvent) -> Unit noraise,
  ],
  application_tasks : @async.TaskGroup[Unit],
  last_window_closed_policy : LastWindowClosedPolicy,
  window_tasks : @async.TaskGroup[Unit],
  view_event_handlers : Array[async (ViewHandle, ViewEvent) -> Unit noraise],
  browser_event_handlers : Array[
    async (BrowserHandle, BrowserEvent) -> Unit noraise,
  ],
  window_close_handler : (async (WindowHandle) -> WindowCloseDecision noraise)?,
  window_lifecycle_hooks : Array[WindowLifecycleHook],
  lifecycle_failures : Array[AppCleanupError],
  bridge_startup_timeout_ms : Int,
  navigation_handler : (async (BrowserHandle, NavigationRequest) -> NavigationDecision noraise)?,
  popup_handler : (async (BrowserHandle, PopupRequest) -> PopupDecision noraise)?,
  download_handler : (async (BrowserHandle, DownloadRequest) -> DownloadDecision noraise)?,
  certificate_handler : (async (BrowserHandle, CertificateError) -> BrowserPermissionDecision noraise)?,
  media_handler : (async (BrowserHandle, MediaPermissionRequest) -> BrowserPermissionDecision noraise)?,
  download_event_handlers : Array[
    async (BrowserHandle, DownloadEvent) -> Unit noraise,
  ],
  application_identifier? : String = "",
  application_executable? : String = "",
  application_arguments? : Array[String] = [],
  url_schemes? : Array[String] = [],
) -> RuntimeSession {
  RuntimeSession::{
    runtime,
    event_pump,
    locale_preferences,
    definitions,
    windows,
    has_created_window: windows.length() > 0,
    command_host,
    pending_bridge: [],
    wakeup,
    forward_menu_events,
    monitor_bridge,
    application_tasks,
    last_window_closed_policy,
    launch_input_handlers,
    window_event_handlers,
    view_event_handlers,
    browser_event_handlers,
    window_close_handler,
    window_tasks,
    window_lifecycle_hooks,
    lifecycle_failures,
    bridge_startup_timeout_ms,
    window_commands: [],
    pending_window_opens: [],
    pending_browser_requests: [],
    pending_resource_requests: [],
    navigation_handler,
    popup_handler,
    download_handler,
    certificate_handler,
    media_handler,
    download_event_handlers,
    close_coordinator: CloseCoordinator(),
    application_identifier,
    application_executable,
    application_arguments,
    url_schemes,
  }
}

///|
fn CloseCoordinator::CloseCoordinator() -> CloseCoordinator {
  CloseCoordinator::{ state: CloseRunning, pending: [], }
}

///|
fn CloseCoordinator::request_quit(self : CloseCoordinator) -> Bool {
  guard self.state == CloseRunning else { return false }
  self.state = CloseQuitRequested
  true
}

///|
fn CloseCoordinator::is_quitting(self : CloseCoordinator) -> Bool {
  self.state != CloseRunning
}

///|
fn CloseCoordinator::find(
  self : CloseCoordinator,
  window_id : Int64,
) -> PendingCloseDecision? {
  for pending in self.pending {
    if pending.window == window_id {
      return Some(pending)
    }
  }
  None
}

///|
fn CloseCoordinator::cancel(
  self : CloseCoordinator,
  window_id : Int64?,
) -> Unit {
  let remaining : Array[PendingCloseDecision] = []
  for pending in self.pending {
    if window_id == Some(pending.window) {
      pending.task.cancel()
    } else {
      remaining.push(pending)
    }
  }
  self.pending.clear()
  for pending in remaining {
    self.pending.push(pending)
  }
}

///|
fn CloseCoordinator::cancel_all(self : CloseCoordinator) -> Unit {
  for pending in self.pending {
    pending.task.cancel()
  }
  self.pending.clear()
}

///|
fn RuntimeSession::window_manager(self : RuntimeSession) -> WindowManager {
  WindowManager::{
    open_window: id => self.request_open_window(id),
    find_window: id => {
      self.find_active_window(id).map(window => self.window_handle(window))
    },
  }
}

///|
fn RuntimeSession::application_context(
  self : RuntimeSession,
) -> ApplicationContext {
  ApplicationContext(
    self.application_tasks,
    self.window_manager(),
    self.locale_preferences,
    request_quit=() => self.request_quit(),
    application_identifier=self.application_identifier,
    application_executable=self.application_executable,
    application_arguments=self.application_arguments,
    url_schemes=self.url_schemes,
  )
}

///|
fn RuntimeSession::window_handle(
  self : RuntimeSession,
  window : RunningWindow,
) -> WindowHandle {
  let id = window.id
  let native_id = window.window.id()
  WindowHandle::{
    id,
    native_id,
    show_window: () => {
      self.control_window(id, native_id, "show", window => window.show())
    },
    show_window_inactive: () => {
      self.control_window(id, native_id, "show inactive", window => {
        window.show_inactive()
      })
    },
    hide_window: () => {
      self.control_window(id, native_id, "hide", window => window.hide())
    },
    close_window: () => self.close_window(id, native_id),
    focus_window: () => {
      self.control_window(id, native_id, "focus", window => window.focus())
    },
    set_window_title: title => {
      self.control_window(id, native_id, "set title", window => {
        window.set_title(title)
      })
    },
    set_window_icon: path => {
      self.control_window(id, native_id, "set icon", window => {
        window.set_icon(path)
      })
    },
    set_window_parent: (parent, modal) => {
      let parent_native_id = parent.map(parent => parent.native_id)
      self.set_window_parent(id, native_id, parent_native_id, modal)
    },
    set_window_size: (width, height) => {
      self.control_window(id, native_id, "set size", window => {
        window.set_size(width, height)
      })
    },
    set_window_content_size: (width, height) => {
      self.control_window(id, native_id, "set content size", window => {
        window.set_content_size(width, height)
      })
    },
    read_window_content_size: () => self.read_window_content_size(id, native_id),
    minimize_window: () => {
      self.control_window(id, native_id, "minimize", window => window.minimize())
    },
    maximize_window: () => {
      self.control_window(id, native_id, "maximize", window => window.maximize())
    },
    restore_window: () => {
      self.control_window(id, native_id, "restore", window => window.restore())
    },
    set_window_fullscreen: fullscreen => {
      self.control_window(id, native_id, "set fullscreen", window => {
        window.set_fullscreen(fullscreen)
      })
    },
    set_window_kiosk: kiosk => {
      self.control_window(id, native_id, "set kiosk", window => {
        window.set_kiosk(kiosk)
      })
    },
    set_window_position: (x, y) => {
      self.control_window(id, native_id, "set position", window => {
        window.set_position(x, y)
      })
    },
    set_window_always_on_top: always_on_top => {
      self.control_window(id, native_id, "set always on top", window => {
        window.set_always_on_top(always_on_top)
      })
    },
    set_window_resizable: resizable => {
      self.control_window(id, native_id, "set resizable", window => {
        window.set_resizable(resizable)
      })
    },
    set_window_minimum_size: (width, height) => {
      self.control_window(id, native_id, "set minimum size", window => {
        window.set_minimum_size(width, height)
      })
    },
    set_window_maximum_size: (width, height) => {
      self.control_window(id, native_id, "set maximum size", window => {
        window.set_maximum_size(width, height)
      })
    },
    set_window_aspect_ratio: aspect_ratio => {
      self.control_window(id, native_id, "set aspect ratio", window => {
        window.set_aspect_ratio(aspect_ratio)
      })
    },
    set_window_movable: movable => {
      self.control_window(id, native_id, "set movable", window => {
        window.set_movable(movable)
      })
    },
    set_window_opacity: opacity => {
      self.control_window(id, native_id, "set opacity", window => {
        window.set_opacity(opacity)
      })
    },
    set_window_skip_taskbar: skip => {
      self.control_window(id, native_id, "set taskbar visibility", window => {
        window.set_skip_taskbar(skip)
      })
    },
    set_window_content_protection: enabled => {
      self.control_window(id, native_id, "set content protection", window => {
        window.set_content_protection(enabled)
      })
    },
    set_window_minimizable: minimizable => {
      self.control_window(id, native_id, "set minimizable", window => {
        window.set_minimizable(minimizable)
      })
    },
    set_window_maximizable: maximizable => {
      self.control_window(id, native_id, "set maximizable", window => {
        window.set_maximizable(maximizable)
      })
    },
    set_window_closable: closable => {
      self.control_window(id, native_id, "set closable", window => {
        window.set_closable(closable)
      })
    },
    set_window_button_visibility: visible => {
      self.control_window(id, native_id, "set window button visibility", window => {
        window.set_button_visibility(visible)
      })
    },
    set_window_focusable: focusable => {
      self.control_window(id, native_id, "set focusable", window => {
        window.set_focusable(focusable)
      })
    },
    set_window_fullscreenable: fullscreenable => {
      self.control_window(id, native_id, "set fullscreenable", window => {
        window.set_fullscreenable(fullscreenable)
      })
    },
    set_window_has_shadow: has_shadow => {
      self.control_window(id, native_id, "set window shadow", window => {
        window.set_has_shadow(has_shadow)
      })
    },
    set_window_ignore_mouse_events: (ignore, forward) => {
      self.control_window(id, native_id, "set ignore mouse events", window => {
        window.set_ignore_mouse_events(ignore, forward)
      })
    },
    set_window_background_color: color => {
      self.control_window(id, native_id, "set background color", window => {
        window.set_background_color(color)
      })
    },
    set_window_visible_on_all_workspaces: visible => {
      self.control_window(id, native_id, "set workspace visibility", window => {
        window.set_visible_on_all_workspaces(visible)
      })
    },
    set_window_enabled: enabled => {
      self.control_window(id, native_id, "set enabled", window => {
        window.set_enabled(enabled)
      })
    },
    set_window_menu: menu => {
      try {
        match menu {
          Some(menu) => self.runtime.set_menu(menu.to_native())
          None => self.runtime.set_menu(@native.MenuBar(menus=[]))
        }
      } catch {
        error =>
          raise window_operation_failed("set menu in window " + id, error)
      }
    },
    set_window_zoom_percent: zoom_percent => {
      self.control_window(id, native_id, "set zoom", window => {
        window.set_zoom_percent(zoom_percent)
      })
    },
    set_window_progress_bar: progress => {
      self.control_window(id, native_id, "set progress bar", window => {
        window.set_progress_bar(progress)
      })
    },
    flash_window_frame: flash => {
      self.control_window(id, native_id, "flash frame", window => {
        window.flash_frame(flash)
      })
    },
    popup_window_menu: (menu, x, y) => {
      self.control_window(id, native_id, "popup menu in", window => {
        window.popup_menu(@native.MenuBar(menus=[menu.to_native()]), x, y)
      })
    },
    read_window_state: () => self.read_window_state(id, native_id),
    browser: self.browser_handle(window),
    add_view: (view_id, config) => {
      self.add_window_view(id, native_id, view_id, config.to_native())
    },
    remove_view: view_id => self.remove_window_view(id, native_id, view_id),
    list_views: () => self.list_window_views(id, native_id),
    find_view: view_id => self.find_window_view(id, native_id, view_id),
  }
}

///|
fn RuntimeSession::view_handle(
  self : RuntimeSession,
  window : RunningWindow,
  view : RunningView,
) -> ViewHandle {
  let window_id = window.id
  let window_native_id = window.window.id()
  let id = view.id
  let native_id = view.view.id()
  ViewHandle::{
    id,
    native_id,
    set_view_bounds: (x, y, width, height) => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "set bounds of",
        view => view.set_bounds(x~, y~, width~, height~),
      )
    },
    set_view_visible: visible => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "set visibility of",
        view => view.set_visible(visible),
      )
    },
    set_view_z_order: z_order => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "set z-order of",
        view => view.set_z_order(z_order),
      )
    },
    set_view_zoom_percent: zoom_percent => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "set zoom of",
        view => view.set_zoom_percent(zoom_percent),
      )
    },
    read_view_zoom_percent: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.zoom_percent() catch {
        error =>
          raise window_operation_failed(
            "read zoom of view " + id + " in window " + window_id,
            error,
          )
      }
    },
    set_view_audio_muted: muted => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "set audio mute of",
        view => view.set_audio_muted(muted),
      )
    },
    read_view_audio_muted: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.is_audio_muted() catch {
        error =>
          raise window_operation_failed(
            "read audio mute of view " + id + " in window " + window_id,
            error,
          )
      }
    },
    load_view_url: url => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "load URL in",
        view => view.load_url(url),
      )
    },
    load_view_html: (html, base_url) => {
      self.load_view_html(
        window_id, window_native_id, id, native_id, html, base_url,
      )
    },
    eval_view_script: script => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "evaluate script in",
        view => view.eval(script),
      )
    },
    focus_view: () => {
      self.control_window(
        window_id,
        window_native_id,
        "focus for view " + id + " in",
        window => window.focus(),
      )
      self.control_view(window_id, window_native_id, id, native_id, "focus", view => {
        view.browser_command("focus")
      })
    },
    send_view_command: (command, download_id) => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        command + " in",
        view => view.browser_command(command, download_id?),
      )
    },
    find_view_in_page: (text, forward, match_case, find_next) => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.find_in_page(text, forward, match_case, find_next) catch {
        error =>
          raise window_operation_failed(
            "find in view " + id + " in window " + window_id,
            error,
          )
      }
    },
    stop_view_find: clear_selection => {
      self.control_view(
        window_id,
        window_native_id,
        id,
        native_id,
        "stop find in",
        view => view.stop_find_in_page(clear_selection),
      )
    },
    read_view_navigation_state: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.navigation_state() catch {
        error =>
          raise window_operation_failed(
            "read navigation state of view " + id + " in window " + window_id,
            error,
          )
      }
    },
    read_view_focused: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.browser_is_focused() catch {
        error =>
          raise window_operation_failed(
            "read focus of view " + id + " in window " + window_id,
            error,
          )
      }
    },
    read_view_devtools_opened: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      running.view.is_devtools_opened() catch {
        error =>
          raise window_operation_failed(
            "read DevTools state of view " + id + " in window " + window_id,
            error,
          )
      }
    },
    read_view_state: () => {
      let running = self.resolve_view(
        window_id, window_native_id, id, native_id,
      )
      ViewState::from_native(running.view.state()) catch {
        error =>
          raise window_operation_failed(
            "read view " + id + " state in window " + window_id,
            error,
          )
      }
    },
    close_view: () => self.remove_window_view(window_id, window_native_id, id),
  }
}

///|
/// Resolves a live view instance by window id, view id, and both native
/// instance ids. The pair of ids keeps stale handles from targeting a later
/// view or window that reuses the same declarative id.
fn RuntimeSession::resolve_view(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
  view_native_id : Int64,
) -> RunningView raise WindowSessionError {
  let running = match self.find_active_window(window_id) {
    Some(running) if running.window.id() == window_native_id => running
    _ => raise StaleWindow(id=window_id)
  }
  for view in running.views {
    if view.id == view_id {
      if view.view.id() != view_native_id {
        raise StaleView(id=view_id)
      }
      return view
    }
  }
  raise UnknownView(id=view_id)
}

///|
fn RuntimeSession::control_view(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
  view_native_id : Int64,
  action : String,
  operation : (@native.View) -> Unit raise @native.NativeError,
) -> Unit raise WindowSessionError {
  let running = self.resolve_view(
    window_id, window_native_id, view_id, view_native_id,
  )
  operation(running.view) catch {
    error =>
      raise window_operation_failed(
        action + " view " + view_id + " in window " + window_id,
        error,
      )
  }
}

///|
fn RuntimeSession::add_window_view(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
  config : @native.ViewConfig,
) -> ViewHandle raise WindowSessionError {
  let running = match self.find_active_window(window_id) {
    Some(running) if running.window.id() == window_native_id => running
    _ => raise StaleWindow(id=window_id)
  }
  let running_view = add_view_to_running_window(running, view_id, config)
  self.view_handle(running, running_view)
}

///|
fn add_view_to_running_window(
  running : RunningWindow,
  view_id : String,
  config : @native.ViewConfig,
) -> RunningView raise WindowSessionError {
  if view_id.is_empty() {
    raise window_operation_failed(
      "add view to window " + running.id,
      @native.NativeError::InvalidArgument(message="view id must not be empty"),
    )
  }
  for view in running.views {
    if view.id == view_id {
      raise AlreadyExists(id=view_id)
    }
  }
  let created = @native.View::View(running.window, config) catch {
    error =>
      raise window_operation_failed(
        "add view " + view_id + " to window " + running.id,
        error,
      )
  }
  let running_view = RunningView::{
    id: view_id,
    view: created,
    document: None,
  }
  running.views.push(running_view)
  running_view
}

///|
fn RuntimeSession::remove_window_view(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
) -> Unit raise WindowSessionError {
  let running = match self.find_active_window(window_id) {
    Some(running) if running.window.id() == window_native_id => running
    _ => raise StaleWindow(id=window_id)
  }
  let mut index = -1
  for i, view in running.views {
    if view.id == view_id {
      index = i
      break
    }
  }
  if index < 0 {
    raise UnknownView(id=view_id)
  }
  let view = running.views[index]
  view.view.destroy() catch {
    error =>
      raise window_operation_failed(
        "remove view " + view_id + " from window " + window_id,
        error,
      )
  }
  ignore(running.views.remove(index))
}

///|
fn RuntimeSession::list_window_views(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
) -> Array[ViewHandle] {
  match self.find_active_window(window_id) {
    Some(running) if running.window.id() == window_native_id =>
      running.views.map(view => self.view_handle(running, view))
    _ => []
  }
}

///|
fn RuntimeSession::find_window_view(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
) -> ViewHandle? {
  match self.find_active_window(window_id) {
    Some(running) if running.window.id() == window_native_id =>
      for view in running.views {
        if view.id == view_id {
          return Some(self.view_handle(running, view))
        }
      } nobreak {
        None
      }
    _ => None
  }
}

///|
fn RuntimeSession::browser_handle(
  self : RuntimeSession,
  window : RunningWindow,
) -> BrowserHandle {
  let id = window.id
  let native_id = window.window.id()
  let session_handle = self.session_handle(window)
  BrowserHandle::{
    id,
    native_id,
    load_browser_url: url => {
      self.control_window(id, native_id, "load URL in", window => {
        window.load_url(url)
      })
    },
    load_browser_html: (html, base_url) => {
      self.load_window_html(id, native_id, html, base_url)
    },
    eval_browser_script: script => {
      self.control_window(id, native_id, "evaluate script in", window => {
        window.eval(script)
      })
    },
    focus_browser: () => {
      self.control_window(id, native_id, "focus browser in", window => {
        window.focus()
        window.browser_command("focus")
      })
    },
    send_browser_command: (command, download_id) => {
      self.control_window(id, native_id, command + " in", window => {
        window.browser_command(command, download_id?)
      })
    },
    download_browser_url: url => {
      self.control_window(id, native_id, "download URL in", window => {
        window.download_url(url)
      })
    },
    print_browser: () => {
      self.control_window(id, native_id, "print browser in", window => {
        window.print()
      })
    },
    print_browser_to_pdf: (path, options) => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.print_to_pdf(path, options.to_native()) catch {
        error =>
          raise window_operation_failed(
            "print browser to PDF in window " + id,
            error,
          )
      }
    },
    find_browser_in_page: (text, forward, match_case, find_next) => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.find_in_page(text, forward, match_case, find_next) catch {
        error =>
          raise window_operation_failed(
            "find in browser for window " + id,
            error,
          )
      }
    },
    stop_browser_find: clear_selection => {
      self.control_window(id, native_id, "stop browser find in", window => {
        window.stop_find_in_page(clear_selection)
      })
    },
    set_browser_zoom_percent: zoom_percent => {
      self.control_window(id, native_id, "set browser zoom", window => {
        window.set_zoom_percent(zoom_percent)
      })
    },
    read_browser_zoom_percent: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.state().zoom_percent catch {
        error =>
          raise window_operation_failed(
            "read browser zoom in window " + id,
            error,
          )
      }
    },
    set_browser_audio_muted: muted => {
      self.control_window(id, native_id, "set browser audio mute", window => {
        window.set_audio_muted(muted)
      })
    },
    read_browser_audio_muted: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.is_audio_muted() catch {
        error =>
          raise window_operation_failed(
            "read browser audio mute in window " + id,
            error,
          )
      }
    },
    read_browser_navigation_state: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.navigation_state() catch {
        error =>
          raise window_operation_failed(
            "read browser navigation state in window " + id,
            error,
          )
      }
    },
    read_browser_focused: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.browser_is_focused() catch {
        error =>
          raise window_operation_failed(
            "read browser focus in window " + id,
            error,
          )
      }
    },
    read_browser_devtools_opened: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      running.window.is_devtools_opened() catch {
        error =>
          raise window_operation_failed(
            "read browser DevTools state in window " + id,
            error,
          )
      }
    },
    read_browser_state: () => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      BrowserState::from_native(running.window.browser_state()) catch {
        error =>
          raise window_operation_failed(
            "read browser state in window " + id,
            error,
          )
      }
    },
    session_handle,
  }
}

///|
fn PdfPrintOptions::to_native(
  self : PdfPrintOptions,
) -> @native.PdfPrintSettings {
  let (margin_type, margin_top, margin_right, margin_bottom, margin_left) = match
    self.margins {
    PdfPrintMargins::Default => (0, 0.0, 0.0, 0.0, 0.0)
    PdfPrintMargins::NoMargins => (1, 0.0, 0.0, 0.0, 0.0)
    PdfPrintMargins::Custom(top~, right~, bottom~, left~) =>
      (2, top, right, bottom, left)
  }
  {
    landscape: self.landscape,
    print_background: self.print_background,
    scale: self.scale,
    paper_width: self.paper_width,
    paper_height: self.paper_height,
    prefer_css_page_size: self.prefer_css_page_size,
    margin_type,
    margin_top,
    margin_right,
    margin_bottom,
    margin_left,
    page_ranges: self.page_ranges,
    display_header_footer: self.display_header_footer,
    header_template: self.header_template,
    footer_template: self.footer_template,
    generate_tagged_pdf: self.generate_tagged_pdf,
    generate_document_outline: self.generate_document_outline,
  }
}

///|
fn RuntimeSession::session_handle(
  self : RuntimeSession,
  window : RunningWindow,
) -> SessionHandle {
  let id = window.id
  let native_id = window.window.id()
  SessionHandle::{
    id,
    native_id,
    read_cookies: (url, include_http_only) => {
      let running = match self.find_active_window(id) {
        Some(running) if running.window.id() == native_id => running
        _ => raise StaleWindow(id~)
      }
      let request_id = running.window.cookie_begin_get(url, include_http_only) catch {
        error =>
          raise window_operation_failed("read cookies in window " + id, error)
      }
      let payload = self.event_pump.cookie_completions.wait(request_id)
      decode_cookies(payload) catch {
        CookieDecodeError(detail) =>
          raise OperationFailed(
            action="decode cookies in window " + id,
            status=-1,
            detail~,
          )
      }
    },
    write_cookie: (url, name, value, domain, path, secure, http_only, same_site) => {
      self.control_window(id, native_id, "set cookie in", window => {
        window.cookie_set(
          url,
          name,
          value,
          domain?,
          path?,
          secure~,
          http_only~,
          same_site=same_site.to_native(),
        )
      })
    },
    remove_cookies: (url, name) => {
      self.control_window(id, native_id, "delete cookies in", window => {
        window.cookie_delete(url, name)
      })
    },
    flush_cookie_store: () => {
      self.control_window(id, native_id, "flush cookies in", window => {
        window.cookie_flush()
      })
    },
    clear_http_cache: () => {
      self.control_window(id, native_id, "clear cache in", window => {
        window.clear_cache()
      })
    },
  }
}

///|
fn RunningWindow::is_active(self : RunningWindow) -> Bool {
  match self.state {
    WindowStarting | WindowOpen => true
    WindowCloseRequested | WindowClosed => false
  }
}

///|
fn RunningWindow::is_closed(self : RunningWindow) -> Bool {
  self.state is WindowClosed
}

///|
fn preferred_active_window(windows : Array[RunningWindow]) -> RunningWindow? {
  preferred_active_windows(windows).get(0)
}

///|
fn preferred_active_windows(
  windows : Array[RunningWindow],
) -> Array[RunningWindow] {
  let candidates : Array[RunningWindow] = []
  let fallback : Array[RunningWindow] = []
  for running in windows {
    if running.is_active() {
      if running.id == "main" {
        candidates.push(running)
      } else {
        fallback.push(running)
      }
    }
  }
  for running in fallback {
    candidates.push(running)
  }
  candidates
}

///|
fn RuntimeSession::close_window(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
) -> Unit raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  running.window.close() catch {
    error => raise window_operation_failed("close window " + id, error)
  }
  running.state = WindowCloseRequested
}

///|
fn RuntimeSession::control_window(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
  action : String,
  operation : (@native.Window) -> Unit raise @native.NativeError,
) -> Unit raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  operation(running.window) catch {
    error => raise window_operation_failed(action + " window " + id, error)
  }
}

///|
fn RuntimeSession::load_window_html(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
  html : String,
  base_url : String,
) -> Unit raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  guard resource_document_url_is_supported(base_url) else {
    raise window_operation_failed(
      "load HTML in window " + id,
      @native.NativeError::InvalidArgument(
        message="base_url must use a Proton application origin",
      ),
    )
  }
  let previous = running.document
  running.document = Some({ url: base_url, content: @utf8.encode(html), })
  running.window.load_url(base_url) catch {
    error => {
      running.document = previous
      raise window_operation_failed("load HTML in window " + id, error)
    }
  }
}

///|
fn RuntimeSession::load_view_html(
  self : RuntimeSession,
  window_id : String,
  window_native_id : Int64,
  view_id : String,
  view_native_id : Int64,
  html : String,
  base_url : String,
) -> Unit raise WindowSessionError {
  let running = self.resolve_view(
    window_id, window_native_id, view_id, view_native_id,
  )
  guard resource_document_url_is_supported(base_url) else {
    raise window_operation_failed(
      "load HTML in view " + view_id + " in window " + window_id,
      @native.NativeError::InvalidArgument(
        message="base_url must use a Proton application origin",
      ),
    )
  }
  let previous = running.document
  running.document = Some({ url: base_url, content: @utf8.encode(html), })
  running.view.load_url(base_url) catch {
    error => {
      running.document = previous
      raise window_operation_failed(
        "load HTML in view " + view_id + " in window " + window_id,
        error,
      )
    }
  }
}

///|
fn RuntimeSession::read_window_state(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
) -> WindowState raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  WindowState::from_native(running.window.state()) catch {
    error =>
      raise window_operation_failed("read window " + id + " state", error)
  }
}

///|
fn RuntimeSession::read_window_content_size(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
) -> (Int, Int) raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  running.window.content_size() catch {
    error =>
      raise window_operation_failed("read content size of window " + id, error)
  }
}

///|
fn RuntimeSession::set_window_parent(
  self : RuntimeSession,
  id : String,
  native_id : Int64,
  parent_native_id : Int64?,
  modal : Bool,
) -> Unit raise WindowSessionError {
  let running = match self.find_active_window(id) {
    Some(running) if running.window.id() == native_id => running
    _ => raise StaleWindow(id~)
  }
  let parent = match parent_native_id {
    Some(parent_id) => {
      let mut found : RunningWindow? = None
      for candidate in self.windows {
        if candidate.is_active() && candidate.window.id() == parent_id {
          found = Some(candidate)
          break
        }
      }
      match found {
        Some(parent) => Some(parent.window.as_ref())
        None => raise StaleWindow(id="parent")
      }
    }
    None => None
  }
  running.window.set_parent(parent, modal) catch {
    error => raise window_operation_failed("set parent of window " + id, error)
  }
}

///|
fn RuntimeSession::find_definition(
  self : RuntimeSession,
  id : String,
) -> PreparedWindow? {
  for definition in self.definitions {
    if definition.plan.id == id {
      return Some(definition)
    }
  }
  None
}

///|
fn RuntimeSession::find_active_window(
  self : RuntimeSession,
  id : String,
) -> RunningWindow? {
  for running in self.windows {
    if running.id == id && running.is_active() {
      return Some(running)
    }
  }
  None
}

///|
fn RuntimeSession::create_window(
  self : RuntimeSession,
  definition : PreparedWindow,
) -> RunningWindow raise AppRunError {
  let plan = definition.plan
  if self.find_active_window(plan.id) is Some(_) {
    raise ConfigurationError(
      InvalidSetting(
        name="window.id",
        message="window is already open: " + plan.id,
      ),
    )
  }
  let created_window = @native.Window::Window(
    self.runtime,
    config=native_window_config(
      plan.window,
      definition.bridge,
      definition.browser_policy,
      self.locale_preferences,
    ),
  ) catch {
    error => raise native_run_error("create window " + plan.id, error)
  }
  let (document, asset_root) = match definition.entry {
    RemoteEntry(_) => (None, None)
    DocumentEntry(document, asset_root) => (Some(document), asset_root)
  }
  let running = RunningWindow::{
    id: plan.id,
    window: created_window,
    permissions: definition.permissions,
    lifetime: WindowLifetime(),
    views: [],
    document,
    asset_root,
    bridge_ready: !self.monitor_bridge,
    state: WindowStarting,
  }
  errdefer (created_window.destroy() catch {
    error =>
      self.lifecycle_failures.push(
        WindowDestroy(status=error.status(), detail=error.message()),
      )
  })
  if self.window_close_handler is Some(_) {
    created_window.set_close_interception(true) catch {
      error =>
        raise native_run_error(
          "enable close interception for " + plan.id,
          error,
        )
    }
  }
  load_prepared_entry(created_window, definition.entry) catch {
    error => raise EntryLoadError(error)
  }
  for view_plan in definition.views {
    let (view_id, view_config) = view_plan
    ignore(
      add_view_to_running_window(running, view_id, view_config) catch {
        error =>
          raise match error {
            OperationFailed(action~, status~, detail~) =>
              RuntimeOperationFailed(action~, status~, detail~)
            other => UnexpectedTaskFailure(detail=other.message())
          }
      },
    )
  }
  self.windows.push(running)
  self.has_created_window = true
  @xlog.info(category="proton.window")  Unit raise AppRunError {
  if running.lifetime.ready {
    running.lifetime.wait_until_ready()
    return
  }
  let window_events = WindowEventEmitter(
    typed_event_sender(running.window, None),
  )
  let manager = self.window_manager()
  let handle = self.window_handle(running)
  ignore(
    self.window_tasks.spawn(
      () => {
        run_window_lifecycle_scope(
          running,
          handle,
          manager,
          window_events,
          self.window_lifecycle_hooks,
          self.lifecycle_failures,
          self.locale_preferences,
        )
      },
      no_wait=true,
      allow_failure=true,
    ),
  )
  running.lifetime.wait_until_ready()
  if !running.is_active() {
    return
  }
  running.window.show() catch {
    error => raise native_run_error("show window " + running.id, error)
  }
  running.state = WindowOpen
}

///|
async fn RuntimeSession::request_open_window(
  self : RuntimeSession,
  id : String,
) -> WindowHandle raise WindowSessionError {
  if self.is_quitting() {
    raise ApplicationQuitting
  }
  let completion = WindowOpenCompletion()
  self.window_commands.push(Open(id, completion))
  self.wakeup.signal.notify()
  completion.wait()
}

///|
fn WindowOpenCompletion::WindowOpenCompletion() -> WindowOpenCompletion {
  WindowOpenCompletion::{
    state: WindowOpenPending,
    changed: @async.CondVar::Cond(),
  }
}

///|
fn WindowOpenCompletion::succeed(
  self : WindowOpenCompletion,
  handle : WindowHandle,
) -> Unit {
  if self.state is WindowOpenPending {
    self.state = WindowOpenSucceeded(handle)
    self.changed.broadcast()
  }
}

///|
fn WindowOpenCompletion::fail(
  self : WindowOpenCompletion,
  error : WindowSessionError,
) -> Unit {
  if self.state is WindowOpenPending {
    self.state = WindowOpenFailed(error)
    self.changed.broadcast()
  }
}

///|
async fn WindowOpenCompletion::wait(
  self : WindowOpenCompletion,
) -> WindowHandle raise WindowSessionError {
  while self.state is WindowOpenPending {
    self.changed.wait() catch {
      _ => raise Cancelled
    }
  }
  match self.state {
    WindowOpenSucceeded(handle) => handle
    WindowOpenFailed(error) => raise error
    WindowOpenPending => abort("unreachable pending window completion")
  }
}

///|
fn RuntimeSession::process_window_commands(self : RuntimeSession) -> Bool {
  guard self.window_commands.length() > 0 else { return false }
  let commands = self.window_commands.copy()
  self.window_commands.clear()
  for command in commands {
    let Open(id, completion) = command
    if self.is_quitting() {
      completion.fail(ApplicationQuitting)
      continue
    }
    let definition = match self.find_definition(id) {
      Some(definition) => definition
      None => {
        completion.fail(UnknownWindow(id~))
        continue
      }
    }
    if self.find_active_window(id) is Some(_) {
      completion.fail(AlreadyOpen(id~))
      continue
    }
    let running = self.create_window(definition) catch {
      error => {
        completion.fail(StartupFailed(id~, error~))
        continue
      }
    }
    let timeout = self.window_tasks.spawn(
      () => {
        defer self.wakeup.signal.notify()
        @async.sleep(self.bridge_startup_timeout_ms) catch {
          _ => ()
        }
      },
      no_wait=true,
      allow_failure=true,
    )
    self.pending_window_opens.push(PendingWindowOpen::{
      id,
      running,
      completion,
      activation: None,
      timeout,
    })
  }
  true
}

///|
fn RuntimeSession::advance_window_opens(self : RuntimeSession) -> Bool {
  let remaining : Array[PendingWindowOpen] = []
  let mut did_work = false
  for pending in self.pending_window_opens {
    let timed_out = pending.timeout.try_wait() catch { _ => Some(()) }
    if timed_out is Some(_) {
      did_work = true
      let state = Some(pending.running.window.bridge_lifecycle_state()) catch {
        _ => None
      }
      let error = match state {
        Some(state) =>
          BridgeStartupError(
            BridgeDiagnostic::from_native(
              bridge_startup_timeout_diagnostic(
                state,
                self.bridge_startup_timeout_ms,
              ),
            ),
          )
        None =>
          RuntimeOperationFailed(
            action="open window " + pending.id,
            status=-1,
            detail="bridge startup: window startup timed out",
          )
      }
      self.fail_window_open(pending, error)
      continue
    }
    match pending.activation {
      Some(task) => {
        let completed = task.try_wait() catch {
          error => {
            did_work = true
            self.fail_window_open(pending, normalize_async_run_error(error))
            None
          }
        }
        if pending.completion.state is WindowOpenFailed(_) {
          continue
        }
        match completed {
          Some(_) => {
            did_work = true
            pending.timeout.cancel()
            if !pending.running.is_active() {
              pending.completion.fail(Cancelled)
            } else {
              pending.completion.succeed(self.window_handle(pending.running))
            }
          }
          None => remaining.push(pending)
        }
      }
      None => {
        let ready = if self.monitor_bridge {
          refresh_window_bridge_startup_state(pending.running) catch {
            error => {
              did_work = true
              self.fail_window_open(pending, error)
              false
            }
          }
        } else {
          true
        }
        if pending.completion.state is WindowOpenFailed(_) {
          continue
        }
        if ready {
          did_work = true
          pending.activation = Some(
            self.window_tasks.spawn(
              () => {
                defer self.wakeup.signal.notify()
                self.activate_window(pending.running)
              },
              no_wait=true,
              allow_failure=true,
            ),
          )
        }
        remaining.push(pending)
      }
    }
  }
  self.pending_window_opens.clear()
  for pending in remaining {
    self.pending_window_opens.push(pending)
  }
  did_work
}

///|
fn RuntimeSession::fail_window_open(
  _self : RuntimeSession,
  pending : PendingWindowOpen,
  error : AppRunError,
) -> Unit {
  pending.timeout.cancel()
  match pending.activation {
    Some(task) => task.cancel()
    None => ()
  }
  pending.running.window.destroy() catch {
    _ => ()
  }
  pending.running.state = WindowClosed
  pending.running.lifetime.close()
  pending.completion.fail(StartupFailed(id=pending.id, error~))
}

///|
/// Opens one declared window that is not currently active.
pub async fn WindowManager::open(
  self : WindowManager,
  id : String,
) -> WindowHandle raise WindowSessionError {
  (self.open_window)(id)
}

///|
/// Returns the active instance for a declared window id.
pub fn WindowManager::find(self : WindowManager, id : String) -> WindowHandle? {
  (self.find_window)(id)
}

///|
/// Returns the declarative id of this window.
pub fn WindowHandle::id(self : WindowHandle) -> String {
  self.id
}

///|
pub fn WindowHandle::show(self : WindowHandle) -> Unit raise WindowSessionError {
  (self.show_window)()
}

///|
/// Shows the window without activating it.
pub fn WindowHandle::show_inactive(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.show_window_inactive)()
}

///|
pub fn WindowHandle::is_visible(
  self : WindowHandle,
) -> Bool raise WindowSessionError {
  (self.read_window_state)().visible
}

///|
pub fn WindowHandle::is_focused(
  self : WindowHandle,
) -> Bool raise WindowSessionError {
  (self.read_window_state)().focused
}

///|
pub fn WindowHandle::hide(self : WindowHandle) -> Unit raise WindowSessionError {
  (self.hide_window)()
}

///|
pub fn WindowHandle::close(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.close_window)()
}

///|
pub fn WindowHandle::focus(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.focus_window)()
}

///|
pub fn WindowHandle::set_title(
  self : WindowHandle,
  title : String,
) -> Unit raise WindowSessionError {
  (self.set_window_title)(title)
}

///|
/// Sets the native window icon from an image file path.
pub fn WindowHandle::set_icon(
  self : WindowHandle,
  path : String,
) -> Unit raise WindowSessionError {
  (self.set_window_icon)(path)
}

///|
/// Establishes or clears this window's native parent relationship.
pub fn WindowHandle::set_parent(
  self : WindowHandle,
  parent : WindowHandle?,
  modal? : Bool = false,
) -> Unit raise WindowSessionError {
  (self.set_window_parent)(parent, modal)
}

///|
pub fn WindowHandle::set_size(
  self : WindowHandle,
  width : Int,
  height : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_size)(width, height)
}

///|
/// Sets the renderer content area in logical pixels.
pub fn WindowHandle::set_content_size(
  self : WindowHandle,
  width : Int,
  height : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_content_size)(width, height)
}

///|
/// Returns the renderer content area in logical pixels.
pub fn WindowHandle::content_size(
  self : WindowHandle,
) -> (Int, Int) raise WindowSessionError {
  (self.read_window_content_size)()
}

///|
/// Returns `(x, y, width, height)` in logical screen pixels, matching
/// Electron's `getBounds` coordinate order.
pub fn WindowHandle::bounds(
  self : WindowHandle,
) -> (Int, Int, Int, Int) raise WindowSessionError {
  let state = (self.read_window_state)()
  (state.x, state.y, state.width, state.height)
}

///|
/// Sets `(x, y, width, height)` in logical screen pixels, matching Electron's
/// `setBounds` coordinate order.
pub fn WindowHandle::set_bounds(
  self : WindowHandle,
  x~ : Int,
  y~ : Int,
  width~ : Int,
  height~ : Int,
) -> Unit raise WindowSessionError {
  self.set_position(x, y)
  self.set_size(width, height)
}

///|
pub fn WindowHandle::minimize(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.minimize_window)()
}

///|
pub fn WindowHandle::maximize(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.maximize_window)()
}

///|
pub fn WindowHandle::restore(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  (self.restore_window)()
}

///|
pub fn WindowHandle::set_fullscreen(
  self : WindowHandle,
  fullscreen : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_fullscreen)(fullscreen)
}

///|
/// Enters or leaves kiosk mode.
///
/// Kiosk uses the full display and hides system chrome where the platform
/// supports it. Call with `false` to provide a programmatic exit path.
pub fn WindowHandle::set_kiosk(
  self : WindowHandle,
  kiosk : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_kiosk)(kiosk)
}

///|
pub fn WindowHandle::set_position(
  self : WindowHandle,
  x : Int,
  y : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_position)(x, y)
}

///|
/// Centers the window in the work area of the monitor containing it.
///
/// The current native frame size is preserved. Work-area coordinates exclude
/// taskbars, docks, and other reserved desktop regions, and use Proton's
/// top-left coordinate convention on every platform.
pub fn WindowHandle::center(
  self : WindowHandle,
) -> Unit raise WindowSessionError {
  let state = self.state()
  let monitor = state.monitor
  let x = monitor.work_x + (monitor.work_width - state.width) / 2
  let y = monitor.work_y + (monitor.work_height - state.height) / 2
  self.set_position(x, y)
}

///|
pub fn WindowHandle::set_always_on_top(
  self : WindowHandle,
  always_on_top : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_always_on_top)(always_on_top)
}

///|
/// Sets whether the user can manually resize this window.
///
/// This changes the live native window on macOS, Windows, and Linux. Existing
/// minimum or maximum size hints remain in effect. Headless runtimes raise
/// `WindowSessionError`.
pub fn WindowHandle::set_resizable(
  self : WindowHandle,
  resizable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_resizable)(resizable)
}

///|
/// Sets the minimum live native window size.
///
/// Both dimensions must be positive, or both must be zero to clear the
/// constraint. Existing maximum size and resizable state remain unchanged.
/// Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_minimum_size(
  self : WindowHandle,
  width : Int,
  height : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_minimum_size)(width, height)
}

///|
/// Sets the maximum live native window size.
///
/// Both dimensions must be positive, or both must be zero to clear the
/// constraint. Existing minimum size and resizable state remain unchanged.
/// Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_maximum_size(
  self : WindowHandle,
  width : Int,
  height : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_maximum_size)(width, height)
}

///|
/// Sets the live native window aspect ratio used while the user resizes it.
/// Pass `0.0` to clear the constraint. Programmatic `set_size` calls are not
/// constrained by the ratio, matching Electron's `setAspectRatio` behavior.
/// Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_aspect_ratio(
  self : WindowHandle,
  aspect_ratio : Double,
) -> Unit raise WindowSessionError {
  (self.set_window_aspect_ratio)(aspect_ratio)
}

///|
/// Sets whether the user can move this live native window.
///
/// macOS and Windows prevent manual frame movement when `movable` is false;
/// programmatic `set_position` and `center` calls remain available. Linux
/// follows Electron and treats this as a no-op. Headless runtimes raise
/// `WindowSessionError` because they have no native frame.
pub fn WindowHandle::set_movable(
  self : WindowHandle,
  movable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_movable)(movable)
}

///|
/// Sets the live native window opacity.
///
/// Values are clamped to the Electron-compatible `0.0..1.0` range, where
/// `0.0` is fully transparent and `1.0` is fully opaque. Headless runtimes
/// raise `WindowSessionError` because they have no native frame.
pub fn WindowHandle::set_opacity(
  self : WindowHandle,
  opacity : Double,
) -> Unit raise WindowSessionError {
  (self.set_window_opacity)(opacity)
}

///|
/// Sets whether this live native window is omitted from the taskbar or dock.
///
/// Windows removes or restores the taskbar tab. macOS and Linux follow
/// Electron and treat this as a no-op. Headless runtimes raise
/// `WindowSessionError` because they have no native window shell.
pub fn WindowHandle::set_skip_taskbar(
  self : WindowHandle,
  skip : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_skip_taskbar)(skip)
}

///|
/// Sets whether other applications should be prevented from capturing this
/// live native window.
///
/// macOS applies `NSWindowSharingNone`, although ScreenCaptureKit-based apps
/// on recent macOS releases may still capture the window. Windows uses display
/// affinity to exclude the window from capture. Linux follows Electron and
/// treats this as a no-op. Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_content_protection(
  self : WindowHandle,
  enabled : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_content_protection)(enabled)
}

///|
/// Sets whether the user can manually minimize this live native window.
/// macOS and Windows update the native minimize control; Linux follows
/// Electron and treats this as a successful no-op. Headless runtimes raise
/// `WindowSessionError`.
pub fn WindowHandle::set_minimizable(
  self : WindowHandle,
  minimizable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_minimizable)(minimizable)
}

///|
/// Sets whether the user can manually maximize this live native window.
/// macOS and Windows update the native maximize/zoom control; Linux follows
/// Electron and treats this as a successful no-op. Headless runtimes raise
/// `WindowSessionError`.
pub fn WindowHandle::set_maximizable(
  self : WindowHandle,
  maximizable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_maximizable)(maximizable)
}

///|
/// Sets whether the user can manually close this live native window.
///
/// macOS and Windows update the native close control; programmatic `close`
/// calls remain available. Linux follows Electron and treats this as a
/// successful no-op. Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_closable(
  self : WindowHandle,
  closable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_closable)(closable)
}

///|
/// Sets visibility of the standard close, minimize, and maximize buttons.
/// On macOS this updates the native traffic-light controls. Other platforms
/// apply the equivalent live capability controls where available.
pub fn WindowHandle::set_window_button_visibility(
  self : WindowHandle,
  visible : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_button_visibility)(visible)
}

///|
/// Sets whether this live native window can receive focus.
///
/// macOS and Windows update the native window behavior. On macOS, disabling
/// focus does not remove focus from a window that is already focused, matching
/// Electron. Linux follows Electron and treats this as a successful no-op.
/// Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_focusable(
  self : WindowHandle,
  focusable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_focusable)(focusable)
}

///|
/// Sets whether this live native window can enter fullscreen mode.
///
/// When disabled, attempts to enter fullscreen are ignored. An already
/// fullscreen window can still exit fullscreen.
pub fn WindowHandle::set_fullscreenable(
  self : WindowHandle,
  fullscreenable : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_fullscreenable)(fullscreenable)
}

///|
/// Sets whether this live native window draws a frame shadow.
///
/// macOS applies this directly to the native window. Linux and Windows accept
/// the setting as a successful no-op when the platform frame owns the shadow.
/// Headless runtimes raise `WindowSessionError`.
pub fn WindowHandle::set_has_shadow(
  self : WindowHandle,
  has_shadow : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_has_shadow)(has_shadow)
}

///|
/// Sets whether this live native window ignores mouse events.
///
/// When `ignore` is true, mouse input passes through to the window below while
/// keyboard input remains available to the focused window. `forward` requests
/// mouse-move forwarding to Chromium where the platform supports it. Forwarding
/// is disabled automatically when `ignore` is false.
pub fn WindowHandle::set_ignore_mouse_events(
  self : WindowHandle,
  ignore : Bool,
  forward : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_ignore_mouse_events)(ignore, forward)
}

///|
/// Sets the live native window background color.
///
/// Accepts `#RRGGBB` or `#AARRGGBB`, matching Proton view configuration.
pub fn WindowHandle::set_background_color(
  self : WindowHandle,
  color : String,
) -> Unit raise WindowSessionError {
  (self.set_window_background_color)(color)
}

///|
/// Sets whether the live window appears on every workspace.
///
/// This maps to Spaces on macOS and sticky windows on Linux. It is a
/// successful no-op on Windows, matching Electron.
pub fn WindowHandle::set_visible_on_all_workspaces(
  self : WindowHandle,
  visible : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_visible_on_all_workspaces)(visible)
}

///|
/// Enables or disables user interaction with the live native window.
pub fn WindowHandle::set_enabled(
  self : WindowHandle,
  enabled : Bool,
) -> Unit raise WindowSessionError {
  (self.set_window_enabled)(enabled)
}

///|
/// Replaces the native menu for the application runtime containing this window.
/// Passing `None` clears the menu.
pub fn WindowHandle::set_menu(
  self : WindowHandle,
  menu : MenuBar?,
) -> Unit raise WindowSessionError {
  (self.set_window_menu)(menu)
}

///|
pub fn WindowHandle::set_zoom_percent(
  self : WindowHandle,
  zoom_percent : Int,
) -> Unit raise WindowSessionError {
  (self.set_window_zoom_percent)(zoom_percent)
}

///|
/// Returns the main browser zoom percentage.
pub fn WindowHandle::zoom_percent(
  self : WindowHandle,
) -> Int raise WindowSessionError {
  (self.read_window_state)().zoom_percent
}

///|
/// Sets the platform progress indicator using Electron-compatible values.
///
/// Pass a negative value to clear the indicator, a value from `0.0` through
/// `1.0` for determinate progress, or a value above `1.0` for indeterminate
/// progress. The current native implementation displays this in the macOS
/// Dock as one application-level indicator; the most recent window call wins,
/// and any negative value clears it. Unsupported platforms raise
/// `WindowSessionError`.
pub fn WindowHandle::set_progress_bar(
  self : WindowHandle,
  progress : Double,
) -> Unit raise WindowSessionError {
  (self.set_window_progress_bar)(progress)
}

///|
/// Starts or stops flashing the window to attract the user's attention.
///
/// On macOS, `true` continuously bounces the application Dock icon until the
/// application becomes active or `flash_frame(false)` cancels the request. On
/// Windows it flashes the taskbar button until the window becomes active, and
/// on Linux it sets the desktop window urgency hint. Headless runtimes raise
/// `WindowSessionError`.
pub fn WindowHandle::flash_frame(
  self : WindowHandle,
  flash : Bool,
) -> Unit raise WindowSessionError {
  (self.flash_window_frame)(flash)
}

///|
pub fn WindowHandle::state(
  self : WindowHandle,
) -> WindowState raise WindowSessionError {
  (self.read_window_state)()
}

///|
fn WindowHandle::popup_menu(
  self : WindowHandle,
  menu : Menu,
  x : Int,
  y : Int,
) -> Unit raise WindowSessionError {
  (self.popup_window_menu)(menu, x, y)
}

///|
pub fn WindowHandle::browser(self : WindowHandle) -> BrowserHandle {
  self.browser
}

///|
/// Adds a web contents view to this window, following the Electron
/// `WebContentsView` model: the view renders its own page above the window's
/// main browser content at explicit bounds. `id` is unique within the window
/// and lets the session reject stale handles.
pub fn WindowHandle::add_view(
  self : WindowHandle,
  id : String,
  config : ViewConfig,
) -> ViewHandle raise WindowSessionError {
  (self.add_view)(id, config)
}

///|
/// Removes and destroys a web contents view previously added with `add_view`.
pub fn WindowHandle::remove_view(
  self : WindowHandle,
  id : String,
) -> Unit raise WindowSessionError {
  (self.remove_view)(id)
}

///|
/// Lists the live web contents views of this window.
pub fn WindowHandle::views(self : WindowHandle) -> Array[ViewHandle] {
  (self.list_views)()
}

///|
/// Returns the live view with the given declarative id, if one exists.
pub fn WindowHandle::view(self : WindowHandle, id : String) -> ViewHandle? {
  (self.find_view)(id)
}

///|
/// Returns the declarative id of this view.
pub fn ViewHandle::id(self : ViewHandle) -> String {
  self.id
}

///|
/// Moves and resizes the view. `x`/`y` use a top-left origin in the owning
/// window's content coordinate space, matching Electron's `setBounds`.
pub fn ViewHandle::set_bounds(
  self : ViewHandle,
  x~ : Int,
  y~ : Int,
  width~ : Int,
  height~ : Int,
) -> Unit raise WindowSessionError {
  (self.set_view_bounds)(x, y, width, height)
}

///|
pub fn ViewHandle::set_visible(
  self : ViewHandle,
  visible : Bool,
) -> Unit raise WindowSessionError {
  (self.set_view_visible)(visible)
}

///|
/// Stacks the view relative to the window's other views; higher `z_order`
/// renders above lower values.
pub fn ViewHandle::set_z_order(
  self : ViewHandle,
  z_order : Int,
) -> Unit raise WindowSessionError {
  (self.set_view_z_order)(z_order)
}

///|
/// Sets this view's browser zoom from 25% through 500%.
pub fn ViewHandle::set_zoom_percent(
  self : ViewHandle,
  zoom_percent : Int,
) -> Unit raise WindowSessionError {
  (self.set_view_zoom_percent)(zoom_percent)
}

///|
/// Returns this view's browser zoom percentage.
pub fn ViewHandle::zoom_percent(
  self : ViewHandle,
) -> Int raise WindowSessionError {
  (self.read_view_zoom_percent)()
}

///|
/// Mutes or unmutes audio produced by this view's page.
pub fn ViewHandle::set_audio_muted(
  self : ViewHandle,
  muted : Bool,
) -> Unit raise WindowSessionError {
  (self.set_view_audio_muted)(muted)
}

///|
/// Returns whether audio produced by this view's page is muted.
pub fn ViewHandle::is_audio_muted(
  self : ViewHandle,
) -> Bool raise WindowSessionError {
  (self.read_view_audio_muted)()
}

///|
/// Navigates the view's page, the Electron `view.webContents.loadURL`
/// equivalent.
pub fn ViewHandle::load_url(
  self : ViewHandle,
  url : String,
) -> Unit raise WindowSessionError {
  (self.load_view_url)(url)
}

///|
/// Loads inline HTML into the view, served from `base_url` on the
/// `proton://` scheme, mirroring `WindowHandle::load_html`.
pub fn ViewHandle::load_html(
  self : ViewHandle,
  html : String,
  base_url : String,
) -> Unit raise WindowSessionError {
  (self.load_view_html)(html, base_url)
}

///|
/// Executes JavaScript in the view's main frame without awaiting a result.
pub fn ViewHandle::eval(
  self : ViewHandle,
  script : String,
) -> Unit raise WindowSessionError {
  (self.eval_view_script)(script)
}

///|
/// Starts or advances a page search and returns its request id. Set
/// `find_next=true` to begin a new search session, matching Electron's
/// `findInPage` option; leave it false to advance the current session.
pub fn ViewHandle::find_in_page(
  self : ViewHandle,
  text : String,
  forward? : Bool = true,
  match_case? : Bool = false,
  find_next? : Bool = false,
) -> Int raise WindowSessionError {
  (self.find_view_in_page)(text, forward, match_case, find_next)
}

///|
/// Stops the active page search. Set `clear_selection=false` to preserve the
/// current match highlight.
pub fn ViewHandle::stop_find_in_page(
  self : ViewHandle,
  clear_selection? : Bool = true,
) -> Unit raise WindowSessionError {
  (self.stop_view_find)(clear_selection)
}

///|
pub fn ViewHandle::back(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("back", None)
}

///|
pub fn ViewHandle::forward(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("forward", None)
}

///|
/// Returns whether the view can navigate to a previous history entry.
pub fn ViewHandle::can_go_back(
  self : ViewHandle,
) -> Bool raise WindowSessionError {
  (self.read_view_navigation_state)().0
}

///|
/// Returns whether the view can navigate to a later history entry.
pub fn ViewHandle::can_go_forward(
  self : ViewHandle,
) -> Bool raise WindowSessionError {
  (self.read_view_navigation_state)().1
}

///|
pub fn ViewHandle::reload(
  self : ViewHandle,
  ignore_cache? : Bool = false,
) -> Unit raise WindowSessionError {
  (self.send_view_command)(
    if ignore_cache {
      "reload_ignore_cache"
    } else {
      "reload"
    },
    None,
  )
}

///|
pub fn ViewHandle::stop(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("stop", None)
}

///|
/// Undoes the most recent edit in the focused frame.
pub fn ViewHandle::undo(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("undo", None)
}

///|
/// Redoes the most recently undone edit in the focused frame.
pub fn ViewHandle::redo(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("redo", None)
}

///|
/// Cuts the current selection in the focused frame.
pub fn ViewHandle::cut(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("cut", None)
}

///|
/// Copies the current selection in the focused frame.
pub fn ViewHandle::copy(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("copy", None)
}

///|
/// Pastes clipboard contents into the focused frame.
pub fn ViewHandle::paste(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("paste", None)
}

///|
/// Pastes clipboard contents using the destination's current style.
pub fn ViewHandle::paste_and_match_style(
  self : ViewHandle,
) -> Unit raise WindowSessionError {
  (self.send_view_command)("paste_and_match_style", None)
}

///|
/// Deletes the current selection in the focused frame.
pub fn ViewHandle::delete(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.send_view_command)("delete", None)
}

///|
/// Selects all editable content in the focused frame.
pub fn ViewHandle::select_all(
  self : ViewHandle,
) -> Unit raise WindowSessionError {
  (self.send_view_command)("select_all", None)
}

///|
/// Focuses this view's web page, matching Electron `webContents.focus()`.
pub fn ViewHandle::focus(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.focus_view)()
}

///|
/// Returns whether this view's web page currently owns focus.
pub fn ViewHandle::is_focused(
  self : ViewHandle,
) -> Bool raise WindowSessionError {
  (self.read_view_focused)()
}

///|
pub fn ViewHandle::open_devtools(
  self : ViewHandle,
) -> Unit raise WindowSessionError {
  (self.send_view_command)("open_devtools", None)
}

///|
pub fn ViewHandle::close_devtools(
  self : ViewHandle,
) -> Unit raise WindowSessionError {
  (self.send_view_command)("close_devtools", None)
}

///|
/// Toggles the DevTools view for this web contents.
pub fn ViewHandle::toggle_devtools(
  self : ViewHandle,
) -> Unit raise WindowSessionError {
  (self.send_view_command)("toggle_devtools", None)
}

///|
/// Returns whether this web contents currently has an open DevTools view.
pub fn ViewHandle::is_devtools_opened(
  self : ViewHandle,
) -> Bool raise WindowSessionError {
  (self.read_view_devtools_opened)()
}

///|
/// Reads the current view state from the native runtime.
pub fn ViewHandle::state(
  self : ViewHandle,
) -> ViewState raise WindowSessionError {
  (self.read_view_state)()
}

///|
/// Removes and destroys the view, the Electron `removeChildView` equivalent.
pub fn ViewHandle::close(self : ViewHandle) -> Unit raise WindowSessionError {
  (self.close_view)()
}

///|
pub fn BrowserHandle::window_id(self : BrowserHandle) -> String {
  self.id
}

///|
pub fn BrowserHandle::load_url(
  self : BrowserHandle,
  url : String,
) -> Unit raise WindowSessionError {
  (self.load_browser_url)(url)
}

///|
pub fn BrowserHandle::load_html(
  self : BrowserHandle,
  html : String,
  base_url : String,
) -> Unit raise WindowSessionError {
  (self.load_browser_html)(html, base_url)
}

///|
pub fn BrowserHandle::eval(
  self : BrowserHandle,
  script : String,
) -> Unit raise WindowSessionError {
  (self.eval_browser_script)(script)
}

///|
/// Starts or advances a page search and returns its request id. Set
/// `find_next=true` to begin a new search session, matching Electron's
/// `findInPage` option; leave it false to advance the current session.
pub fn BrowserHandle::find_in_page(
  self : BrowserHandle,
  text : String,
  forward? : Bool = true,
  match_case? : Bool = false,
  find_next? : Bool = false,
) -> Int raise WindowSessionError {
  (self.find_browser_in_page)(text, forward, match_case, find_next)
}

///|
/// Stops the active page search. Set `clear_selection=false` to preserve the
/// current match highlight.
pub fn BrowserHandle::stop_find_in_page(
  self : BrowserHandle,
  clear_selection? : Bool = true,
) -> Unit raise WindowSessionError {
  (self.stop_browser_find)(clear_selection)
}

///|
/// Starts downloading `url` without navigating the page. The request uses the
/// app's download approval and progress handlers. CEF does not support
/// Electron's optional custom request headers for this operation.
pub fn BrowserHandle::download_url(
  self : BrowserHandle,
  url : String,
) -> Unit raise WindowSessionError {
  (self.download_browser_url)(url)
}

///|
/// Opens the platform print flow for the main browser contents.
pub fn BrowserHandle::print(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.print_browser)()
}

///|
/// Starts printing the main browser contents to `path` and returns a request
/// id. Completion is delivered as `BrowserEvent::PdfPrinted`.
pub fn BrowserHandle::print_to_pdf(
  self : BrowserHandle,
  path : String,
  options? : PdfPrintOptions = PdfPrintOptions(),
) -> Int raise WindowSessionError {
  (self.print_browser_to_pdf)(path, options)
}

///|
pub fn BrowserHandle::back(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("back", None)
}

///|
pub fn BrowserHandle::forward(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("forward", None)
}

///|
/// Sets the main browser zoom from 25% through 500%.
pub fn BrowserHandle::set_zoom_percent(
  self : BrowserHandle,
  zoom_percent : Int,
) -> Unit raise WindowSessionError {
  (self.set_browser_zoom_percent)(zoom_percent)
}

///|
/// Returns the main browser zoom percentage.
pub fn BrowserHandle::zoom_percent(
  self : BrowserHandle,
) -> Int raise WindowSessionError {
  (self.read_browser_zoom_percent)()
}

///|
/// Mutes or unmutes audio produced by the main browser page.
pub fn BrowserHandle::set_audio_muted(
  self : BrowserHandle,
  muted : Bool,
) -> Unit raise WindowSessionError {
  (self.set_browser_audio_muted)(muted)
}

///|
/// Returns whether audio produced by the main browser page is muted.
pub fn BrowserHandle::is_audio_muted(
  self : BrowserHandle,
) -> Bool raise WindowSessionError {
  (self.read_browser_audio_muted)()
}

///|
/// Returns whether the main browser can navigate to a previous history entry.
pub fn BrowserHandle::can_go_back(
  self : BrowserHandle,
) -> Bool raise WindowSessionError {
  (self.read_browser_navigation_state)().0
}

///|
/// Returns whether the main browser can navigate to a later history entry.
pub fn BrowserHandle::can_go_forward(
  self : BrowserHandle,
) -> Bool raise WindowSessionError {
  (self.read_browser_navigation_state)().1
}

///|
/// Reads the current main browser page state.
pub fn BrowserHandle::state(
  self : BrowserHandle,
) -> BrowserState raise WindowSessionError {
  (self.read_browser_state)()
}

///|
/// Returns the browser session used by this main page.
pub fn BrowserHandle::session(self : BrowserHandle) -> SessionHandle {
  self.session_handle
}

///|
pub fn BrowserHandle::reload(
  self : BrowserHandle,
  ignore_cache? : Bool = false,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)(
    if ignore_cache {
      "reload_ignore_cache"
    } else {
      "reload"
    },
    None,
  )
}

///|
pub fn BrowserHandle::stop(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("stop", None)
}

///|
/// Undoes the most recent edit in the focused frame.
pub fn BrowserHandle::undo(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("undo", None)
}

///|
/// Redoes the most recently undone edit in the focused frame.
pub fn BrowserHandle::redo(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("redo", None)
}

///|
/// Cuts the current selection in the focused frame.
pub fn BrowserHandle::cut(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("cut", None)
}

///|
/// Copies the current selection in the focused frame.
pub fn BrowserHandle::copy(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("copy", None)
}

///|
/// Pastes clipboard contents into the focused frame.
pub fn BrowserHandle::paste(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("paste", None)
}

///|
/// Pastes clipboard contents using the destination's current style.
pub fn BrowserHandle::paste_and_match_style(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("paste_and_match_style", None)
}

///|
/// Deletes the current selection in the focused frame.
pub fn BrowserHandle::delete(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("delete", None)
}

///|
/// Selects all editable content in the focused frame.
pub fn BrowserHandle::select_all(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("select_all", None)
}

///|
/// Focuses the web page, matching Electron `webContents.focus()`.
pub fn BrowserHandle::focus(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.focus_browser)()
}

///|
/// Returns whether the web page currently owns focus.
pub fn BrowserHandle::is_focused(
  self : BrowserHandle,
) -> Bool raise WindowSessionError {
  (self.read_browser_focused)()
}

///|
pub fn BrowserHandle::open_devtools(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("open_devtools", None)
}

///|
pub fn BrowserHandle::close_devtools(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("close_devtools", None)
}

///|
/// Toggles the DevTools view for this web contents.
pub fn BrowserHandle::toggle_devtools(
  self : BrowserHandle,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("toggle_devtools", None)
}

///|
/// Returns whether this web contents currently has an open DevTools view.
pub fn BrowserHandle::is_devtools_opened(
  self : BrowserHandle,
) -> Bool raise WindowSessionError {
  (self.read_browser_devtools_opened)()
}

///|
pub fn BrowserHandle::cancel_download(
  self : BrowserHandle,
  download_id : Int,
) -> Unit raise WindowSessionError {
  (self.send_browser_command)("cancel_download", Some(download_id))
}

///|
fn RuntimeSession::command_host(self : RuntimeSession) -> @core.AppCommandHost? {
  self.command_host.map(host => host.host)
}

///|
async fn RuntimeSession::wait_for_bridge_startup(
  self : RuntimeSession,
  timeout_ms : Int,
) -> Unit raise AppRunError {
  let completed = @async.with_timeout_opt(timeout_ms, () => {
    drive_wakeup_until(
      self.wakeup,
      () => {
        self.is_quitting() ||
        refresh_bridge_startup_states(self.windows) is None
      },
      () => self.pump_once(monitor_bridge=false),
    )
  }) catch {
    error => raise normalize_async_run_error(error)
  }
  match completed {
    Some(_) => ()
    None => {
      ignore(self.pump_once(monitor_bridge=false))
      if self.is_quitting() {
        return
      }
      match refresh_bridge_startup_states(self.windows) {
        None => return
        Some(state) =>
          raise BridgeStartupError(
            BridgeDiagnostic::from_native(
              bridge_startup_timeout_diagnostic(state, timeout_ms),
            ),
          )
      }
    }
  }
}

///|
async fn RuntimeSession::run(self : RuntimeSession) -> Unit raise AppRunError {
  drive_wakeup_until(self.wakeup, () => self.quit_complete(), () => {
    self.pump_once(monitor_bridge=self.monitor_bridge)
  })
  self.cancel_all_bridge_tasks()
  self.close_coordinator.cancel_all()
  self.cancel_all_browser_requests()
  self.cancel_all_resource_requests()
}

///|
async fn RuntimeSession::drive_until_complete(
  self : RuntimeSession,
  task : @async.Task[Unit],
) -> Unit raise AppRunError {
  drive_wakeup_until(
    self.wakeup,
    () => {
      let completed = task.try_wait() catch {
        error => raise normalize_async_run_error(error)
      }
      completed is Some(_)
    },
    () => self.pump_once(monitor_bridge=self.monitor_bridge),
  )
}

///|
fn RuntimeSession::pump_once(
  self : RuntimeSession,
  monitor_bridge? : Bool = true,
) -> Bool raise AppRunError {
  let mut did_work = self.process_window_commands()
  if self.drain_runtime_events() {
    did_work = true
  }
  if self.drain_extension_events() {
    did_work = true
  }
  if monitor_bridge {
    self.check_bridge_failures()
  }
  if self.complete_bridge_requests() {
    did_work = true
  }
  if self.advance_window_opens() {
    did_work = true
  }
  if self.complete_browser_requests() {
    did_work = true
  }
  if self.complete_resource_requests() {
    did_work = true
  }
  if self.advance_application_lifetime() {
    did_work = true
  }
  did_work
}

///|
fn RuntimeSession::start_extension_event_sources(
  self : RuntimeSession,
) -> Unit raise AppRunError {
  match self.command_host {
    None => ()
    Some(host) =>
      start_command_extension_event_sources(
        host.event_sources,
        @native.event_wakeup_callback(),
      )
  }
}

///|
fn start_command_extension_event_sources(
  event_sources : Array[CommandExtensionEventSource],
  wakeup : @proton_extension.EventWakeup,
) -> Unit raise AppRunError {
  for event_source in event_sources {
    guard !event_source.started else { continue }
    event_source.started = true
    event_source.source.start(wakeup) catch {
      error => {
        event_source.source.stop()
        event_source.started = false
        raise CommandExtensionLifecycleError(
          EventSourceStartFailed(
            extension_id=event_source.extension_id,
            detail=@debug.render(Repr(error)),
          ),
        )
      }
    }
  }
}

///|
fn RuntimeSession::drain_extension_events(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let mut did_work = false
  match self.command_host {
    None => ()
    Some(host) =>
      for event_source in host.event_sources {
        guard event_source.started else { continue }
        let events = event_source.drain()
        if !events.is_empty() {
          did_work = true
        }
        for event in events {
          guard event.extension_id() == event_source.extension_id &&
            event.extension_namespace() == event_source.extension_namespace else {
            event_source.disable(
              "event descriptor belongs to " +
              event.extension_id() +
              " (" +
              event.extension_namespace() +
              ")",
            )
            break
          }
          self.forward_extension_event_to_granted_windows(
            event_source.extension_id,
            event_source.extension_namespace,
            event.name(),
            event.payload(),
          )
        }
      }
  }
  did_work
}

///|
fn CommandExtensionEventSource::drain(
  self : CommandExtensionEventSource,
) -> Array[@proton_extension.Event] {
  guard self.started else { return [] }
  self.source.drain() catch {
    error => {
      self.disable(@debug.render(Repr(error)))
      []
    }
  }
}

///|
fn CommandExtensionEventSource::disable(
  self : CommandExtensionEventSource,
  detail : String,
) -> Unit {
  self.stop()
  @xlog.error(category="proton.extension")  Unit raise AppRunError {
  for running in self.windows {
    guard running.is_active() &&
      running.bridge_ready &&
      running.permissions.grants_extension(extension_id) else {
      continue
    }
    forward_extension_event(running.window, extension_namespace, name, payload)
  }
}

///|
fn RuntimeSession::drain_runtime_events(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  self.event_pump.drain_session_events(event => {
    self.dispatch_runtime_event(event)
  })
}

///|
fn RuntimeSession::dispatch_runtime_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  if event.is_quit_requested() {
    self.request_quit()
  }
  self.dispatch_window_event(event)
  self.dispatch_view_event(event)
  self.dispatch_browser_event(event)
  self.dispatch_resource_event(event)
  self.dispatch_notification_event(event)
  self.dispatch_launch_input_event(event)
  self.dispatch_menu_event(event)
  match event.bridge_request() {
    Some(request) => self.start_bridge_request(request)
    None => ()
  }
  self.cancel_bridge_request(event.bridge_request_cancellation())
}

///|
fn RuntimeSession::dispatch_window_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  if event.is_window_closed() {
    let window_id = event.window_id()
    runtime_session_cancel_window_bridge_tasks(self.pending_bridge, window_id)
    self.close_coordinator.cancel(window_id)
    self.cancel_browser_requests(window_id)
    self.cancel_resource_requests_for_window(window_id)
    self.retire_closed_window(window_id)
    return
  }
  match (event.window_id(), event.window_state_change()) {
    (Some(window_id), Some(state)) =>
      match self.find_window_by_native_id(window_id) {
        Some(window) => {
          let handle = self.window_handle(window)
          for handler in self.window_event_handlers {
            ignore(
              self.window_tasks.spawn(
                () => {
                  handler(handle, StateChanged(WindowState::from_native(state)))
                },
                no_wait=true,
              ),
            )
          }
        }
        None => ()
      }
    _ => ()
  }
  match (event.window_id(), event.window_close_request()) {
    (Some(window_id), Some(request_id)) =>
      self.start_window_close_request(window_id, request_id)
    _ => ()
  }
}

///|
fn RuntimeSession::dispatch_view_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  let closes_view = event.is_view_closed()
  if self.view_event_handlers.is_empty() && !closes_view {
    return
  }
  let (window_native_id, view_native_id) = match
    (event.window_id(), event.view_id()) {
    (Some(window_id), Some(view_id)) => (window_id, view_id)
    _ => return
  }
  let running = match self.find_window_by_native_id(window_native_id) {
    Some(running) => running
    None => return
  }
  for index, view in running.views {
    if view.view.id() == view_native_id {
      let handle = self.view_handle(running, view)
      let view_event = match
        (event.event_type(), event.view_event(), event.find_in_page_result()) {
        ("view_loading_changed", Some(info), _) =>
          ViewEvent::LoadingChanged(is_loading=info.is_loading.unwrap_or(false))
        ("view_navigated", Some(info), _) =>
          ViewEvent::Navigated(url=info.url.unwrap_or(""))
        ("view_title_updated", Some(info), _) =>
          ViewEvent::TitleUpdated(title=info.title.unwrap_or(""))
        ("view_load_failed", Some(info), _) =>
          ViewEvent::LoadFailed(
            url=info.url.unwrap_or(""),
            error_code=info.error_code.unwrap_or(0),
            error_text=info.error_text.unwrap_or(""),
          )
        ("view_found_in_page", _, Some(result)) =>
          ViewEvent::FoundInPage(result=FindInPageResult::from_native(result))
        ("view_closed", Some(_), _) => ViewEvent::Closed
        _ => return
      }
      if closes_view {
        view.view.destroy() catch {
          error =>
            raise native_run_error(
              "destroy closed view " + view.id + " in window " + running.id,
              error,
            )
        }
        ignore(running.views.remove(index))
      }
      for handler in self.view_event_handlers {
        ignore(
          self.window_tasks.spawn(
            () => handler(handle, view_event),
            no_wait=true,
          ),
        )
      }
      return
    }
  }
}

///|
fn RuntimeSession::dispatch_browser_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit {
  match
    (
      event.window_id(),
      event.browser_event(),
      event.find_in_page_result(),
      event.pdf_print_result(),
    ) {
    (Some(window_id), info, find_result, pdf_result) =>
      match self.find_window_by_native_id(window_id) {
        Some(window) => {
          let browser = self.browser_handle(window)
          let observed = match
            (event.event_type(), info, find_result, pdf_result) {
            ("browser_loading_changed", Some(info), _, _) =>
              Some(
                BrowserEvent::LoadingChanged(
                  is_loading=info.is_loading.unwrap_or(false),
                ),
              )
            ("browser_navigated", Some(info), _, _) =>
              Some(BrowserEvent::Navigated(url=info.url.unwrap_or("")))
            ("browser_title_updated", Some(info), _, _) =>
              Some(BrowserEvent::TitleUpdated(title=info.title.unwrap_or("")))
            ("browser_load_failed", Some(info), _, _) =>
              Some(
                BrowserEvent::LoadFailed(
                  url=info.url.unwrap_or(""),
                  error_code=info.error_code.unwrap_or(0),
                  error_text=info.error_text.unwrap_or(""),
                ),
              )
            ("browser_found_in_page", _, Some(result), _) =>
              Some(
                BrowserEvent::FoundInPage(
                  result=FindInPageResult::from_native(result),
                ),
              )
            ("browser_pdf_print_finished", _, _, Some(result)) =>
              Some(
                BrowserEvent::PdfPrinted(result={
                  request_id: result.request_id,
                  path: result.path,
                  success: result.success,
                }),
              )
            _ => None
          }
          match observed {
            Some(observed) =>
              for handler in self.browser_event_handlers {
                ignore(
                  self.window_tasks.spawn(
                    () => handler(browser, observed),
                    no_wait=true,
                  ),
                )
              }
            None => ()
          }
        }
        None => ()
      }
    _ => ()
  }
  match event.browser_request() {
    Some(request) => self.start_browser_request(event.window_id(), request)
    None => ()
  }
  match (event.window_id(), event.browser_download_update()) {
    (Some(window_id), Some(update)) =>
      match self.find_window_by_native_id(window_id) {
        Some(window) => {
          let browser = self.browser_handle(window)
          let observed = DownloadEvent::{
            id: update.download_id,
            state: update.state,
            received_bytes: update.received_bytes,
            total_bytes: update.total_bytes,
            percent: update.percent,
          }
          for handler in self.download_event_handlers {
            ignore(
              self.window_tasks.spawn(
                () => handler(browser, observed),
                no_wait=true,
              ),
            )
          }
        }
        None => ()
      }
    _ => ()
  }
}

///|
fn RuntimeSession::start_browser_request(
  self : RuntimeSession,
  window_id : Int64?,
  request : @native.NativeBrowserRequest,
) -> Unit {
  guard window_id is Some(window_id) else { return }
  guard self.find_window_by_native_id(window_id) is Some(window) else { return }
  let browser = self.browser_handle(window)
  let request_id = match request {
    Navigation(request_id~, ..)
    | Popup(request_id~, ..)
    | Download(request_id~, ..)
    | Certificate(request_id~, ..)
    | Media(request_id~, ..) => request_id
  }
  let task = self.window_tasks.spawn(
    () => {
      defer self.wakeup.signal.notify()
      match request {
        Navigation(url~, http_method~, user_gesture~, redirect~, ..) =>
          match self.navigation_handler {
            Some(handler) =>
              match
                handler(browser, { url, http_method, user_gesture, redirect, }) {
                NavigationDecision::Allow =>
                  BrowserResponse::{ action: "allow", path: None, }
                NavigationDecision::Deny =>
                  BrowserResponse::{ action: "deny", path: None, }
              }
            None => BrowserResponse::{ action: "deny", path: None, }
          }
        Popup(url~, disposition~, user_gesture~, ..) => {
          let decision = match self.popup_handler {
            Some(handler) =>
              handler(browser, { url, disposition, user_gesture, })
            None => PopupDecision::Deny
          }
          match decision {
            PopupDecision::Deny => ()
            PopupDecision::OpenInCurrent =>
              browser.load_url(url) catch {
                _ => ()
              }
            PopupDecision::OpenInWindow(id) => {
              let opened = Some(self.window_manager().open(id)) catch {
                _ => None
              }
              match opened {
                Some(window) => window.browser().load_url(url) catch { _ => () }
                None => ()
              }
            }
          }
          BrowserResponse::{ action: "deny", path: None, }
        }
        Download(download_id~, url~, suggested_name~, ..) =>
          match self.download_handler {
            Some(handler) =>
              match
                handler(browser, { id: download_id, url, suggested_name, }) {
                DownloadDecision::Deny =>
                  BrowserResponse::{ action: "deny", path: None, }
                DownloadDecision::ShowSaveDialog =>
                  BrowserResponse::{ action: "allow", path: None, }
                DownloadDecision::SaveTo(path) =>
                  BrowserResponse::{ action: "allow", path: Some(path), }
              }
            None => BrowserResponse::{ action: "deny", path: None, }
          }
        Certificate(url~, error_code~, ..) =>
          match self.certificate_handler {
            Some(handler) =>
              match handler(browser, { url, error_code, }) {
                BrowserPermissionDecision::Allow =>
                  BrowserResponse::{ action: "allow", path: None, }
                BrowserPermissionDecision::Deny =>
                  BrowserResponse::{ action: "deny", path: None, }
              }
            None => BrowserResponse::{ action: "deny", path: None, }
          }
        Media(origin~, permissions~, ..) =>
          match self.media_handler {
            Some(handler) =>
              match handler(browser, { origin, permissions, }) {
                BrowserPermissionDecision::Allow =>
                  BrowserResponse::{ action: "allow", path: None, }
                BrowserPermissionDecision::Deny =>
                  BrowserResponse::{ action: "deny", path: None, }
              }
            None => BrowserResponse::{ action: "deny", path: None, }
          }
      }
    },
    no_wait=true,
  )
  self.pending_browser_requests.push({ window: window_id, request_id, task, })
}

///|
fn RuntimeSession::complete_browser_requests(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let remaining : Array[PendingBrowserRequest] = []
  let mut did_work = false
  for pending in self.pending_browser_requests {
    let completed = pending.task.try_wait() catch {
      _ => Some(BrowserResponse::{ action: "deny", path: None, })
    }
    match completed {
      None => remaining.push(pending)
      Some(response) => {
        did_work = true
        match self.find_window_by_native_id(pending.window) {
          Some(window) if window.is_active() => {
            let path = response.path
            window.window.respond_browser_request(
              pending.request_id,
              response.action,
              path?,
            ) catch {
              error =>
                if !error.is_stale_browser_request() &&
                  !error.is_stale_window_request() {
                  raise native_run_error("respond to browser request", error)
                }
            }
          }
          _ => ()
        }
      }
    }
  }
  self.pending_browser_requests.clear()
  for pending in remaining {
    self.pending_browser_requests.push(pending)
  }
  did_work
}

///|
fn RuntimeSession::cancel_browser_requests(
  self : RuntimeSession,
  window_id : Int64?,
) -> Unit {
  let remaining : Array[PendingBrowserRequest] = []
  for pending in self.pending_browser_requests {
    if window_id == Some(pending.window) {
      pending.task.cancel()
    } else {
      remaining.push(pending)
    }
  }
  self.pending_browser_requests.clear()
  for pending in remaining {
    self.pending_browser_requests.push(pending)
  }
}

///|
fn RuntimeSession::cancel_all_browser_requests(self : RuntimeSession) -> Unit {
  for pending in self.pending_browser_requests {
    pending.task.cancel()
  }
  self.pending_browser_requests.clear()
}

///|
fn RuntimeSession::dispatch_resource_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit {
  match event.resource_request() {
    Some(request) => self.start_resource_request(request)
    None => ()
  }
  self.cancel_resource_request(event.resource_request_cancellation())
}

///|
fn RuntimeSession::start_resource_request(
  self : RuntimeSession,
  request : @native.NativeResourceRequest,
) -> Unit {
  let (document, asset_root) = match
    self.find_window_by_native_id(request.window) {
    Some(window) if request.view is Some(view_id) => {
      let mut document = None
      for view in window.views {
        if view.view.id() == view_id {
          document = view.document
          break
        }
      }
      (document, None)
    }
    Some(window) => (window.document, window.asset_root)
    None => (None, None)
  }
  let task = self.window_tasks.spawn(
    () => {
      defer self.wakeup.signal.notify()
      resolve_resource_request(document, asset_root, request.url)
    },
    no_wait=true,
  )
  self.pending_resource_requests.push({
    request_id: request.request_id,
    window: request.window,
    task,
  })
}

///|
fn RuntimeSession::complete_resource_requests(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let remaining : Array[PendingResourceRequest] = []
  let mut did_work = false
  for pending in self.pending_resource_requests {
    let completed = pending.task.try_wait() catch {
      _ => Some(resource_text_response(500, "Resource request failed"))
    }
    match completed {
      None => remaining.push(pending)
      Some(response) => {
        did_work = true
        self.runtime.complete_resource_request(
          pending.request_id,
          response.status,
          response.mime_type,
          response.body,
        ) catch {
          error =>
            if !error.is_stale_resource_request() {
              raise native_run_error("complete resource request", error)
            }
        }
      }
    }
  }
  self.pending_resource_requests.clear()
  for pending in remaining {
    self.pending_resource_requests.push(pending)
  }
  did_work
}

///|
fn RuntimeSession::cancel_resource_request(
  self : RuntimeSession,
  request_id : Int64?,
) -> Unit {
  guard request_id is Some(request_id) else { return }
  let remaining : Array[PendingResourceRequest] = []
  for pending in self.pending_resource_requests {
    if pending.request_id == request_id {
      pending.task.cancel()
    } else {
      remaining.push(pending)
    }
  }
  self.pending_resource_requests.clear()
  for pending in remaining {
    self.pending_resource_requests.push(pending)
  }
}

///|
fn RuntimeSession::cancel_resource_requests_for_window(
  self : RuntimeSession,
  window_id : Int64?,
) -> Unit {
  guard window_id is Some(window_id) else { return }
  let remaining : Array[PendingResourceRequest] = []
  for pending in self.pending_resource_requests {
    if pending.window == window_id {
      pending.task.cancel()
    } else {
      remaining.push(pending)
    }
  }
  self.pending_resource_requests.clear()
  for pending in remaining {
    self.pending_resource_requests.push(pending)
  }
}

///|
fn RuntimeSession::cancel_all_resource_requests(self : RuntimeSession) -> Unit {
  for pending in self.pending_resource_requests {
    pending.task.cancel()
  }
  self.pending_resource_requests.clear()
}

///|
fn RuntimeSession::start_window_close_request(
  self : RuntimeSession,
  window_id : Int64,
  request_id : Int64,
) -> Unit {
  guard self.window_close_handler is Some(handler) else { return }
  guard self.find_window_by_native_id(window_id) is Some(window) else { return }
  match self.close_coordinator.find(window_id) {
    Some(pending) => {
      pending.native_request = Some(request_id)
      return
    }
    None => ()
  }
  window.state = WindowCloseRequested
  let handle = self.window_handle(window)
  let task = self.window_tasks.spawn(
    () => {
      defer self.wakeup.signal.notify()
      handler(handle)
    },
    no_wait=true,
  )
  self.close_coordinator.pending.push(PendingCloseDecision::{
    window: window_id,
    task,
    decision: None,
    native_request: Some(request_id),
  })
}

///|
fn RuntimeSession::advance_individual_close_decisions(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let remaining : Array[PendingCloseDecision] = []
  let mut did_work = false
  for pending in self.close_coordinator.pending {
    let completed = pending.task.try_wait() catch { _ => Some(Allow) }
    match completed {
      None => remaining.push(pending)
      Some(decision) => {
        did_work = true
        self.respond_close_decision(pending, decision)
      }
    }
  }
  self.close_coordinator.pending.clear()
  for pending in remaining {
    self.close_coordinator.pending.push(pending)
  }
  did_work
}

///|
fn RuntimeSession::dispatch_notification_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  match event.notification_result() {
    Some(result) => publish_notification_result(result)
    None => ()
  }
  match event.notification_click() {
    Some(payload) =>
      for running in preferred_active_windows(self.windows) {
        guard running.is_active() &&
          running.bridge_ready &&
          running.permissions.grants_extension(notification_extension_id) else {
          continue
        }
        forward_extension_event(
          running.window,
          notification_extension_namespace,
          "click",
          notification_click_payload(payload),
        )
        break
      }
    None => ()
  }
}

///|
fn RuntimeSession::dispatch_launch_input_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  match event.launch_input() {
    Some(native_input) => {
      guard !self.is_quitting() else { return }
      let input = match native_input {
        @native.RuntimeLaunchInput::OpenUrls(urls) =>
          RuntimeLaunchInput::OpenUrls(urls)
        @native.RuntimeLaunchInput::OpenFiles(files) =>
          RuntimeLaunchInput::OpenFiles(files)
        @native.RuntimeLaunchInput::Reopen => RuntimeLaunchInput::Reopen
      }
      self.activate_for_launch_input()
      let context = self.application_context()
      for handler in self.launch_input_handlers {
        ignore(
          self.application_tasks.spawn(
            () => handler(context, input),
            no_wait=true,
          ),
        )
      }
    }
    None => ()
  }
}

///|
fn RuntimeSession::activate_for_launch_input(
  self : RuntimeSession,
) -> Unit raise AppRunError {
  for running in preferred_active_windows(self.windows) {
    if try_activate_window_for_launch_input(running) {
      return
    }
  }
}

///|
fn try_activate_window_for_launch_input(
  running : RunningWindow,
) -> Bool raise AppRunError {
  try_activate_for_launch_input(
    () => running.window.state(),
    () => running.window.restore(),
    () => running.window.show(),
    () => running.window.focus(),
  )
}

///|
fn try_activate_for_launch_input(
  read_state : () -> @native.WindowState raise @native.NativeError,
  restore : () -> Unit raise @native.NativeError,
  show : () -> Unit raise @native.NativeError,
  focus : () -> Unit raise @native.NativeError,
) -> Bool raise AppRunError {
  let state = read_state() catch {
    error => {
      if error.is_invalid_state() || error.is_stale_window_request() {
        return false
      }
      raise native_run_error("read activation window state", error)
    }
  }
  if state.minimized {
    restore() catch {
      error => {
        if error.is_invalid_state() || error.is_stale_window_request() {
          return false
        }
        raise native_run_error("restore activation window", error)
      }
    }
  }
  if !state.visible {
    show() catch {
      error => {
        if error.is_invalid_state() || error.is_stale_window_request() {
          return false
        }
        raise native_run_error("show activation window", error)
      }
    }
  }
  focus() catch {
    error => {
      if error.is_invalid_state() || error.is_stale_window_request() {
        return false
      }
      raise native_run_error("focus activation window", error)
    }
  }
  true
}

///|
fn RuntimeSession::dispatch_menu_event(
  self : RuntimeSession,
  event : @native.RuntimeEvent,
) -> Unit raise AppRunError {
  guard self.forward_menu_events else { return }
  match event.menu_command_id() {
    Some(command_id) => self.forward_menu_command(command_id, event.window_id())
    None => ()
  }
}

///|
fn RuntimeSession::check_bridge_failures(
  self : RuntimeSession,
) -> Unit raise AppRunError {
  guard !self.is_quitting() else { return }
  for running in self.windows {
    if !running.is_active() {
      continue
    }
    let failure = take_runtime_bridge_failure(running.window) catch {
      error =>
        raise native_run_error("read bridge failure for " + running.id, error)
    }
    match failure {
      Some(diagnostic) =>
        raise BridgeRuntimeError(BridgeDiagnostic::from_native(diagnostic))
      None => ()
    }
  }
}

///|
fn RuntimeSession::start_bridge_request(
  self : RuntimeSession,
  request : @native.BridgeRequest,
) -> Unit raise AppRunError {
  let request_id = request.request_id()
  let target = match self.find_window_by_native_id(request.window()) {
    Some(window) if window.is_active() => window
    _ => {
      self.respond_bridge_request(
        @native.BridgeResponse::Err(
          request_id~,
          code="window_closed",
          message="the issuing window is no longer available",
        ),
        "reject bridge request",
      )
      return
    }
  }
  match self.command_host() {
    None =>
      self.respond_bridge_request(
        @native.BridgeResponse::Err(
          request_id~,
          code="command_host_unavailable",
          message="the application command host is not available",
        ),
        "reject bridge request",
      )
    Some(host) => {
      let task = self.window_tasks.spawn(
        () => {
          defer self.wakeup.signal.notify()
          dispatch_bridge_request(
            target.window,
            target.id,
            target.permissions,
            host,
            request,
            self.wakeup.signal,
            self.event_pump.dialog_completions,
            self.locale_preferences,
          )
        },
        no_wait=true,
        allow_failure=true,
      )
      self.pending_bridge.push(BridgeDispatchTask::{
        request_id,
        window: target.window.id(),
        task,
        state: Running,
      })
    }
  }
}

///|
fn RuntimeSession::respond_bridge_request(
  self : RuntimeSession,
  response : @native.BridgeResponse,
  action : String,
) -> Unit raise AppRunError {
  self.runtime.respond_bridge_request(response) catch {
    error =>
      if !is_stale_bridge_response_error(error) {
        raise native_run_error(action, error)
      }
  }
}

///|
fn RuntimeSession::complete_bridge_requests(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let remaining : Array[BridgeDispatchTask] = []
  let mut did_work = false
  for item in self.pending_bridge {
    if item.state == Cancelled {
      continue
    }
    let completed = item.task.try_wait() catch {
      _ =>
        Some(
          @native.BridgeResponse::Err(
            request_id=item.request_id,
            code="handler_failed",
            message="bridge handler task failed",
          ),
        )
    }
    match completed {
      Some(response) => {
        did_work = true
        item.state = Responding
        self.runtime.respond_bridge_request(response) catch {
          error =>
            if is_stale_bridge_response_error(error) {
              item.state = Stale
            } else {
              raise native_run_error("respond bridge request", error)
            }
        }
        if item.state == Responding {
          item.state = Completed
        }
      }
      None => remaining.push(item)
    }
  }
  self.pending_bridge.clear()
  for item in remaining {
    self.pending_bridge.push(item)
  }
  did_work
}

///|
fn RuntimeSession::find_window_by_native_id(
  self : RuntimeSession,
  window_id : Int64,
) -> RunningWindow? {
  for running in self.windows {
    if running.window.id() == window_id {
      return Some(running)
    }
  }
  None
}

///|
fn RuntimeSession::retire_closed_window(
  self : RuntimeSession,
  window_id : Int64?,
) -> Unit raise AppRunError {
  guard window_id is Some(window_id) else { return }
  let mut index = -1
  for i, running in self.windows {
    if running.window.id() == window_id {
      index = i
      break
    }
  }
  guard index >= 0 else { return }
  let running = self.windows[index]
  running.state = WindowClosed
  running.lifetime.close()
  running.window.destroy() catch {
    error =>
      raise native_run_error("destroy closed window " + running.id, error)
  }
  ignore(self.windows.remove(index))
  @xlog.info(category="proton.window")  Bool {
  self.has_created_window && self.windows.all(fn(window) { window.is_closed() })
}

///|
fn should_quit_after_last_window(
  policy : LastWindowClosedPolicy,
  has_windows : Bool,
  all_windows_closed : Bool,
) -> Bool {
  policy == LastWindowClosedPolicy::Quit && has_windows && all_windows_closed
}

///|
fn should_commit_application_close(
  decisions : Array[WindowCloseDecision],
) -> Bool {
  decisions.all(fn(decision) { decision == WindowCloseDecision::Allow })
}

///|
fn RuntimeSession::request_quit(self : RuntimeSession) -> Unit {
  if self.close_coordinator.request_quit() {
    self.wakeup.signal.notify()
  }
}

///|
fn RuntimeSession::is_quitting(self : RuntimeSession) -> Bool {
  self.close_coordinator.is_quitting()
}

///|
fn RuntimeSession::advance_application_lifetime(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let mut did_work = false
  if self.close_coordinator.state == CloseRunning &&
    should_quit_after_last_window(
      self.last_window_closed_policy,
      self.has_created_window,
      self.all_windows_closed(),
    ) {
    self.request_quit()
    did_work = true
  }
  match self.close_coordinator.state {
    CloseRunning =>
      if self.advance_individual_close_decisions() {
        did_work = true
      }
    CloseQuitRequested => {
      self.begin_application_close_decisions()
      did_work = true
    }
    CloseCollecting =>
      if self.advance_application_close_decisions() {
        did_work = true
      }
    CloseCommitted => ()
  }
  did_work
}

///|
fn RuntimeSession::begin_application_close_decisions(
  self : RuntimeSession,
) -> Unit raise AppRunError {
  guard self.window_close_handler is Some(handler) else {
    self.commit_application_close()
    return
  }
  for running in self.windows {
    guard running.is_active() else { continue }
    let window_id = running.window.id()
    guard self.close_coordinator.find(window_id) is None else { continue }
    let handle = self.window_handle(running)
    let task = self.window_tasks.spawn(
      () => {
        defer self.wakeup.signal.notify()
        handler(handle)
      },
      no_wait=true,
    )
    self.close_coordinator.pending.push(PendingCloseDecision::{
      window: window_id,
      task,
      decision: None,
      native_request: None,
    })
  }
  if self.close_coordinator.pending.is_empty() {
    self.commit_application_close()
  } else {
    self.close_coordinator.state = CloseCollecting
  }
}

///|
fn RuntimeSession::advance_application_close_decisions(
  self : RuntimeSession,
) -> Bool raise AppRunError {
  let mut did_work = false
  let mut waiting = false
  let decisions : Array[WindowCloseDecision] = []
  for pending in self.close_coordinator.pending {
    if pending.decision is None {
      let completed = pending.task.try_wait() catch {
        _ => Some(WindowCloseDecision::Allow)
      }
      match completed {
        Some(decision) => {
          pending.decision = Some(decision)
          did_work = true
        }
        None => waiting = true
      }
    }
    match pending.decision {
      Some(decision) => decisions.push(decision)
      None => waiting = true
    }
  }
  if waiting {
    return did_work
  }
  if !should_commit_application_close(decisions) {
    for pending in self.close_coordinator.pending {
      guard pending.decision is Some(decision) else { continue }
      if pending.native_request is Some(_) {
        self.respond_close_decision(pending, decision)
      }
    }
    self.close_coordinator.pending.clear()
    self.close_coordinator.state = CloseRunning
  } else {
    self.commit_application_close()
  }
  true
}

///|
fn RuntimeSession::respond_close_decision(
  self : RuntimeSession,
  pending : PendingCloseDecision,
  decision : WindowCloseDecision,
) -> Unit raise AppRunError {
  match self.find_window_by_native_id(pending.window) {
    Some(window) if !window.is_closed() => {
      match pending.native_request {
        Some(request_id) =>
          window.window.respond_close_request(
            request_id,
            decision == WindowCloseDecision::Allow,
          ) catch {
            error =>
              if !error.is_stale_window_request() {
                raise native_run_error("respond to window close request", error)
              }
          }
        None => ()
      }
      window.state = if decision == WindowCloseDecision::Allow {
        WindowCloseRequested
      } else {
        WindowOpen
      }
    }
    _ => ()
  }
  pending.native_request = None
}

///|
fn RuntimeSession::commit_application_close(
  self : RuntimeSession,
) -> Unit raise AppRunError {
  self.close_coordinator.state = CloseCommitted
  self.close_coordinator.pending.clear()
  for running in self.windows {
    guard running.is_active() else { continue }
    if self.window_close_handler is Some(_) {
      running.window.set_close_interception(false) catch {
        error =>
          raise native_run_error(
            "commit close interception for " + running.id,
            error,
          )
      }
    }
    running.window.close() catch {
      error => raise native_run_error("close window " + running.id, error)
    }
    running.state = WindowCloseRequested
  }
}

///|
fn RuntimeSession::quit_complete(self : RuntimeSession) -> Bool {
  self.close_coordinator.state == CloseCommitted &&
  self.windows.all(fn(window) { window.is_closed() }) &&
  self.window_commands.length() == 0 &&
  self.pending_window_opens.length() == 0 &&
  self.close_coordinator.pending.length() == 0
}

///|
fn RuntimeSession::cancel_all_bridge_tasks(self : RuntimeSession) -> Unit {
  runtime_session_cancel_all_bridge_tasks(self.pending_bridge)
}

///|
fn runtime_session_cancel_all_bridge_tasks(
  pending_bridge : Array[BridgeDispatchTask],
) -> Unit {
  for item in pending_bridge {
    if item.state == Running {
      item.task.cancel()
      item.state = Cancelled
    }
  }
  pending_bridge.clear()
}

///|
fn runtime_session_cancel_window_bridge_tasks(
  pending_bridge : Array[BridgeDispatchTask],
  window_id : Int64?,
) -> Unit {
  match window_id {
    Some(window_id) =>
      for item in pending_bridge {
        if item.window == window_id && item.state == Running {
          item.task.cancel()
          item.state = Cancelled
        }
      }
    None => ()
  }
}

///|
fn RuntimeSession::cancel_bridge_request(
  self : RuntimeSession,
  request_id : Int64?,
) -> Unit {
  runtime_session_cancel_bridge_request(self.pending_bridge, request_id)
}

///|
fn runtime_session_cancel_bridge_request(
  pending_bridge : Array[BridgeDispatchTask],
  request_id : Int64?,
) -> Unit {
  match request_id {
    Some(request_id) =>
      for item in pending_bridge {
        if item.request_id == request_id && item.state == Running {
          item.task.cancel()
          item.state = Cancelled
        }
      }
    None => ()
  }
}

///|
fn RuntimeSession::forward_menu_command(
  self : RuntimeSession,
  command_id : String,
  focused_window : Int64?,
) -> Unit raise AppRunError {
  let target = match focused_window {
    Some(window_id) => self.find_window_by_native_id(window_id)
    None => None
  }
  let target = match target {
    Some(window) => Some(window)
    None => self.windows.get(0)
  }
  match target {
    Some(window) if window.is_active() =>
      forward_menu_command(window.window, command_id, focused_window)
    _ => ()
  }
}