Como gerenciar janelas

Um PWA fora do navegador gerencia a própria janela. Saiba mais sobre as APIs e os recursos para gerenciar uma janela no sistema operacional.

Executar na sua própria janela, gerenciada pelo PWA, tem todas as vantagens e responsabilidades de qualquer janela nesse sistema operacional, como:

  • A capacidade de mover e redimensionar a janela em sistemas operacionais com várias janelas, como Windows ou ChromeOS.
  • Compartilhar a tela com outras janelas de apps, como no modo de tela dividida do iPadOS ou do Android.
  • Eles aparecem em docks, barras de tarefas e no menu Alt+Tab em computadores, além de listas de janelas multitarefa em dispositivos móveis.
  • A capacidade de minimizar, mover a janela entre telas e áreas de trabalho e fechá-la a qualquer momento.

Mover e redimensionar a janela

A janela do PWA pode ter qualquer tamanho e ser posicionada em qualquer lugar da tela em sistemas operacionais para computador. Por padrão, quando o usuário abre o PWA pela primeira vez após a instalação, ele recebe um tamanho de janela padrão de uma porcentagem da tela atual, com uma resolução máxima de 1920x1080 posicionada no canto superior esquerdo da tela.

O usuário pode mover e redimensionar a janela, e o navegador vai lembrar da última preferência. Na próxima vez que o usuário abrir o app, a janela vai manter o tamanho e a posição do uso anterior.

Não é possível definir o tamanho e a posição preferidos do PWA no manifesto. Só é possível reposicionar e redimensionar a janela usando a API JavaScript. No seu código, é possível mover e redimensionar a janela do PWA usando as funções moveTo(x, y) e resizeTo(x, y) do objeto window.

Por exemplo, é possível redimensionar e mover a janela do PWA quando ele é carregado usando:

document.addEventListener("DOMContentLoaded", event => {
   // we can move only if we are not in a browser's tab
   isBrowser = matchMedia("(display-mode: browser)").matches;
   if (!isBrowser) {
      window.moveTo(16, 16);
      window.resizeTo(800, 600);
   }
});

É possível consultar o tamanho e a posição atuais da tela usando o objeto window.screen. Para detectar quando a janela é redimensionada, use o evento resize do objeto window. Não há um evento para capturar a movimentação da janela. Portanto, sua opção é consultar a posição com frequência.

Em vez de mover e redimensionar a janela de forma absoluta, você pode mover e redimensionar de forma relativa usando moveBy() e resizeBy().

Navegar em outros sites

Se você quiser enviar o usuário para um site externo que está fora do escopo do seu PWA, faça isso com um elemento HTML <a href> padrão. Use location.href ou abra uma nova janela em plataformas compatíveis.

Quando você acessa um URL que está fora do escopo do manifesto, o mecanismo do navegador do PWA renderiza um navegador no app no contexto da janela.

Um navegador no app em um PWA para computador ao navegar por um URL fora do escopo.

Alguns recursos dos navegadores no app:

  • Eles aparecem acima do seu conteúdo.
  • Elas têm uma barra de endereço estática que mostra a origem atual, o título da janela e um menu. Normalmente, eles são temáticos com o theme_color do seu manifesto.
  • No menu contextual, você pode abrir o URL no navegador.
  • Os usuários podem fechar o navegador ou voltar.

Enquanto o navegador no app está na tela, o PWA fica aguardando em segundo plano, como se outra janela estivesse obscurecendo ele.

Um navegador no app em um iPhone ao navegar por um URL fora do escopo em um PWA independente.
Um navegador no app em um dispositivo Android ao navegar por um URL fora do escopo em um PWA independente.

Fluxos de autorização

Muitos fluxos de autenticação e autorização da Web exigem o redirecionamento do usuário para um URL diferente em uma origem diferente para adquirir um token que retorne à origem do PWA, como com o OAuth 2.0.

Nesses casos, o navegador no app segue este processo:

  1. O usuário abre seu PWA e clica em "Fazer login".
  2. O PWA redireciona o usuário para um URL fora do escopo do PWA para que o mecanismo de renderização abra um navegador no app dentro do PWA.
  3. O usuário pode cancelar o navegador in-app e voltar ao seu PWA a qualquer momento.
  4. O usuário faz login no navegador no app. O servidor de autenticação redireciona o usuário para a origem do PWA, enviando o token como um argumento.
  5. O navegador no app se fecha quando detecta um URL que faz parte do escopo do PWA.
  6. O mecanismo redireciona a navegação da janela principal do PWA para o URL que o servidor de autenticação acessou no navegador in-app.
  7. O PWA recebe e armazena o token e renderiza o PWA.

Forçar a navegação de um navegador

Se você quiser forçar a abertura do navegador com um URL e não um navegador no app, use o destino _blank dos elementos <a href>. Isso funciona apenas em PWAs para computador. Em dispositivos móveis, não há opção para abrir um navegador com um URL.

function openBrowser(url) {
    window.open("url", "_blank", "");
}

Abrir novas janelas

No computador, os usuários podem abrir mais de uma janela do mesmo PWA. Cada janela tem uma navegação diferente para o mesmo start_url, como se você estivesse abrindo duas guias do navegador do mesmo URL. No menu do PWA, os usuários podem selecionar Arquivo e Nova janela. No código do PWA, é possível abrir uma nova janela com a função open().

function openNewWindow() {
    window.open("/", "new-window", "width=600,height=600");
}

O mesmo PWA instalado com várias janelas abertas em um sistema operacional de computador.

Quando você chama open() em uma janela de PWA no iOS ou iPadOS, ele retorna null e não abre uma janela. Abrir novas janelas no Android cria um novo navegador no app para o URL, mesmo que ele esteja no escopo do seu PWA, o que normalmente não aciona uma experiência de navegação externa.

Título da janela

O elemento <title> era usado principalmente para fins de SEO, já que o espaço em uma guia do navegador é limitado. Quando você passa do navegador para a janela em um PWA, todo o espaço da barra de título fica disponível.

É possível definir o conteúdo da barra de título:

  • De forma estática no elemento <title> do HTML.
  • Mudar dinamicamente a propriedade de string document.title a qualquer momento.

Em PWAs para computador, o título é essencial e é usado na barra de título da janela e, às vezes, no gerenciador de tarefas ou na seleção multitarefa. Se você tiver um aplicativo de página única, talvez queira atualizar o título em todas as rotas.

Modo com guias

O modo com guias é um recurso experimental que permite que seu PWA tenha um design baseado em guias, semelhante a um navegador da Web. Nesse caso, o usuário pode abrir várias guias no mesmo PWA, mas todas vinculadas na mesma janela do sistema operacional.

Saiba mais sobre esse recurso experimental em Modo de aplicativo com guias para PWA.

Sobreposição de controles da janela

Mencionamos que é possível mudar o título da janela definindo o valor do elemento <title> ou da propriedade document.title. mas é sempre um valor de string. E se pudéssemos projetar a barra de título com HTML, CSS e imagens? A sobreposição de controles de janela, um recurso experimental no Microsoft Edge e no Google Chrome para PWAs de computador, pode ajudar.

Saiba mais sobre esse recurso em Personalizar a sobreposição de controles da janela da barra de título do PWA.

Com a sobreposição de controles da janela, é possível renderizar conteúdo na barra de título.

Como gerenciar janelas

Com várias telas, os usuários querem usar todo o espaço disponível. Por exemplo:

  • Editores gráficos com várias janelas, como o Gimp, podem colocar várias ferramentas de edição em janelas posicionadas com precisão.
  • As mesas de negociação virtuais podem mostrar tendências de mercado em várias janelas, e qualquer uma delas pode ser exibida no modo de tela cheia.
  • Os apps de apresentação de slides podem mostrar anotações do apresentador na tela principal interna e a apresentação em um projetor externo.

A API Window Management permite que PWAs façam isso e muito mais.

Como conseguir detalhes da tela

A API Window Management adiciona um novo método, window.getScreenDetails(), que retorna um objeto com telas como uma matriz imutável de telas anexadas. Há também um objeto ativo acessível em ScreenDetails.currentScreen, correspondente ao window.screen atual.

O objeto retornado também dispara um evento screenschange quando a matriz screens muda. Isso não acontece quando os atributos em telas individuais são alterados. As telas individuais, window.screen ou uma tela na matriz screens, também acionam um evento change quando os atributos mudam.

// Request an object with a screen objects
const screenDetails = await window.getScreenDetails();
screenDetails.screens[0].isPrimary;  // e.g. true
screenDetails.screens[0].isInternal;  // e.g. true
screenDetails.screens[0].label;  // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.
// The object is updated on cross-screen window placements or device changes.
screenDetails.currentScreen;
screenDetails.addEventListener('screenschange', function() {
 // NOTE: Does not fire on changes to attributes of individual screens.
  const screenCount = screenDetails.screens.length;
  const currentScreen screenDetails.currentScreen.id;
});

Se o usuário ou o sistema operacional mover a janela do seu PWA de uma tela para outra, um evento currentscreenchange também será disparado do objeto de detalhes da tela.

Wake lock de tela

Imagine o seguinte: Você está na cozinha seguindo uma receita no tablet. Você acabou de preparar os ingredientes. Suas mãos estão sujas, e você volta para o dispositivo para ler a próxima etapa. É um desastre! A tela ficou preta! A API Screen Wake Lock está disponível para você e permite que um PWA impeça que as telas escureçam, entrem em suspensão ou sejam bloqueadas, permitindo que os usuários parem, iniciem, saiam e voltem sem preocupações.

// Request a screen wake lock
const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release
wakeLock.addEventListener('release', () => {
 console.log(`Screen Wake Lock released: ${wakeLock.released}`);
});
// Manually release the wake lock
wakeLock.release();

Teclado virtual

Dispositivos touch, como smartphones e tablets, oferecem um teclado virtual na tela para que o usuário possa digitar quando os elementos de formulário do PWA estiverem em foco.

Com a API VirtualKeyboard, seu PWA pode ter mais controle do teclado em plataformas compatíveis usando a interface navigator.virtualKeyboard.

  • Mostre e oculte o teclado virtual com navigator.virtualKeyboard.show() e navigator.virtualKeyboard.hide().
  • Informe ao navegador que você está fechando o teclado virtual definindo navigator.virtualKeyboard.overlaysContent como true.
  • Saiba quando o teclado aparece e desaparece com o evento geometrychange.
  • Defina a política de teclado virtual ao editar elementos de host definindo contenteditable como auto ou manual, com o atributo virtualkeyboardpolicy HTML. Uma política permite decidir se você quer que o teclado virtual seja processado automaticamente pelo navegador (auto) ou pelo seu script (manual).
  • Use variáveis de ambiente CSS para receber informações sobre a aparência do teclado virtual, como keyboard-inset-height e keyboard-inset-top.

Leia mais sobre essa API em Controle total com a API VirtualKeyboard.