Spec-Zone.ru › Deno 2

Окна

Доступно в Deno 2.9

deno desktop доступен начиная с Deno v2.9.0. Если у вас более ранняя версия, обновите Deno, чтобы использовать его.

Класс Deno.BrowserWindow управляет нативными окнами. Окно открывается автоматически при запуске вашего бинарного файла и переходит на локальный HTTP-сервер. **Первый** созданный вами new Deno.BrowserWindow() использует это начальное окно; каждое последующее создание открывает новое. Все окна используют одну среду выполнения Deno: на процесс приходится одна асинхронная среда выполнения, независимо от количества открытых окон.

Полный пример приложения, которое управляет окном, меню приложения и упаковкой, см. в примере denidian.

Создание окон

// The first construction adopts the implicit startup window.
const win = new Deno.BrowserWindow({ title: "My App" });

// Subsequent constructions open additional windows.
const base = Deno.env.get("DENO_SERVE_ADDRESS")!; // "tcp:127.0.0.1:<port>"
const port = base.split(":").pop();

const settings = new Deno.BrowserWindow({
  title: "Settings",
  width: 420,
  height: 320,
});
settings.navigate(`http://127.0.0.1:${port}/settings`);

Конструктор принимает объект BrowserWindowOptions:

Параметр Тип По умолчанию Примечания
title string нет Заголовок окна.
width number 800 Начальная ширина в логических пикселях.
height number 600 Начальная высота в логических пикселях.
x, y number нет Начальное положение; если не указано, окно располагается по центру.
resizable boolean true Можно ли изменять размер окна.
alwaysOnTop boolean false Закрепить окно поверх остальных.
frameless boolean false Убрать строку заголовка и рамку окна. Задаётся только при создании.
noActivate boolean false Плавающая панель, которая не активируется и не перехватывает фокус. Задаётся только при создании.
transparentTitlebar boolean false Слить строку заголовка с содержимым. Задаётся только при создании.

new Deno.BrowserWindow() немедленно открывает (или использует) окно. Окно остаётся открытым, пока не будет вызван close() или пока пользователь не закроет его средствами ОС.

frameless, noActivate и transparentTitlebar можно задать только при создании. frameless + noActivate — основные компоненты всплывающих окон области уведомлений / строки меню; см. Tray.attachPanel.

Несколько окон независимы: у каждого свои размер, положение, состояние фокуса и веб-представление. Они могут переходить по разным путям или к разным источникам, задавать собственные привязки и генерировать собственные события.

Жизненный цикл

win.show();
win.hide();
win.focus();
win.close(); // sends close request, fires "close" event
win.reload(); // reload the webview's current document

if (win.isClosed()) { /* … */ }
if (win.isVisible()) { /* … */ }

У каждого окна есть постоянный числовой идентификатор:

console.log(win.windowId);

Закрытие окна не останавливает среду выполнения; процесс продолжает работать, пока не будут закрыты все окна (или пока вы не вызовете Deno.exit()).

Размер и положение

const [w, h] = win.getSize();
win.setSize(800, 600);

const [x, y] = win.getPosition();
win.setPosition(100, 100);

if (win.isResizable()) { /* … */ }
win.setResizable(false);

if (win.isAlwaysOnTop()) { /* … */ }
win.setAlwaysOnTop(true);

Размеры указаны в логических пикселях. Масштабирование HiDPI обрабатывается ОС.

Сохранение размера и положения

Deno не запоминает размер и положение окна между запусками, и не следует рассчитывать на то, что ОС восстановит их: некоторые оконные менеджеры это делают, но многие — нет (например, в Linux/KDE при каждом запуске окно открывается с параметрами конструктора по умолчанию). Если вы хотите, чтобы окно повторно открывалось там, где его оставил пользователь, сохраните его геометрию в конфигурации приложения и восстановите при следующем запуске.

Передайте сохранённые значения конструктору, а затем записывайте геометрию при каждом её изменении:

const file = `${Deno.env.get("HOME")}/.myapp-window.json`;

let saved: { width?: number; height?: number; x?: number; y?: number } = {};
try {
  saved = JSON.parse(await Deno.readTextFile(file));
} catch {
  // First run, or no saved state yet — fall back to defaults.
}

const win = new Deno.BrowserWindow({
  title: "My App",
  width: saved.width ?? 800,
  height: saved.height ?? 600,
  x: saved.x,
  y: saved.y,
});

async function save() {
  const [width, height] = win.getSize();
  const [x, y] = win.getPosition();
  await Deno.writeTextFile(file, JSON.stringify({ width, height, x, y }));
}

win.addEventListener("resize", save);
win.addEventListener("move", save);

Заголовок

win.setTitle("My App: Untitled");

Используйте постоянный префикс и уникальный для документа суффикс: именно это пользователи видят в переключателях окон, доке и на панели задач.

Навигация

const port = Deno.env.get("DENO_SERVE_ADDRESS")!.split(":").pop();
win.navigate(`http://127.0.0.1:${port}`);

Навигация работает с любыми URL, которые может загрузить встроенное веб-представление, чаще всего — с локальным HTTP-сервером (см. раздачу по HTTP), а также с URL https://, URL file:// и URL data:.

В многостраничных приложениях используйте маршрутизацию локального HTTP-сервера, а не переключение окон. Для модальных диалогов лучше создать дочернее окно, а не переходить на другую страницу.

События

Deno.BrowserWindow — это EventTarget. Подписывайтесь с помощью addEventListener или присвойте обработчик соответствующему свойству on<event>.

win.addEventListener("resize", (e) => {
  console.log("resized to", e.detail.width, e.detail.height);
});

win.onfocus = () => console.log("focused");
win.onblur = () => console.log("blurred");
Событие Когда возникает
resize Изменился размер окна.
move Изменилось положение окна.
focus Окно получило фокус.
blur Окно потеряло фокус.
close Пользователь запросил закрытие окна.
keydown При активном окне была нажата клавиша.
keyup Клавиша была отпущена.
mousemove Указатель переместился над окном.
mouseenter Указатель вошёл в область окна.
mouseleave Указатель покинул область окна.
mousedown Была нажата кнопка мыши.
mouseup Была отпущена кнопка мыши.
click Щелчок мышью пришёлся на окно.
dblclick Двойной щелчок пришёлся на окно.
wheel Была прокручена колёсиком мыши или тачпадом.
menuclick Был выбран пункт меню приложения.
contextmenuclick Был выбран пункт контекстного меню.

События указателя и клавиатуры соответствуют их аналогам в браузере (KeyboardEvent, MouseEvent, WheelEvent). resize, move, menuclick и contextmenuclick — это CustomEvents с данными detail; описание событий меню см. в разделе Меню.

win.addEventListener("keydown", (e) => {
  if (e.key === "Escape") win.close();
});

Выполнение JavaScript в веб-представлении

const result = await win.executeJs(
  "document.querySelectorAll('li').length",
);
console.log(result); // number of <li> on the current page

executeJs выполняет код в основном мире веб-представления и возвращает результат. Значение пересекает границу между областями выполнения, поэтому оно должно быть сериализуемым в JSON; если скрипт выбрасывает исключение, возвращённый промис отклоняется с этим значением.

Для более гибкого взаимодействия между Deno и веб-представлением используйте привязки.

Дескриптор нативного окна

const surface = win.getNativeWindow();

getNativeWindow() оборачивает нативную поверхность окна в Deno.UnsafeWindowSurface, чтобы вы могли выполнять отрисовку в ней с помощью WebGPU. Сначала запросите графический адаптер; вызов выбрасывает исключение, если активного контекста WebGPU нет:

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter!.requestDevice();
const surface = win.getNativeWindow();
const context = surface.getContext("webgpu");
// configure `context` with `device` and draw…

После получения поверхности close() понижается до hide(), чтобы нативные дескрипторы, на которых основана поверхность, не были уничтожены во время работы WebGPU.

Полное пошаговое руководство — настройка контекста, отрисовка геометрии и запуск цикла отрисовки — см. в разделе Отрисовка с помощью WebGPU.

Инструменты разработчика

win.openDevtools(); // both isolates
win.openDevtools({ deno: false }); // renderer only
win.openDevtools({ renderer: false }); // Deno runtime only

См. раздел Инструменты разработчика.

Закрытие приложения

Среда выполнения завершает работу, когда не остаётся открытых окон и других активных асинхронных задач (таймеров, ожидающих запросов fetch и т. д.). Чтобы завершить работу явно:

Deno.exit(0);

Чтобы отменить закрытие (например, показать диалог «Сохранить?»), подпишитесь на close и вызовите event.preventDefault():

win.addEventListener("close", async (e) => {
  if (hasUnsavedChanges) {
    e.preventDefault();
    const ok = await win.executeJs("confirm('Discard changes?')");
    if (ok) win.close();
  }
});

Последнее обновление: 27 июля 2026 г.

© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/desktop/windows

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API