창 관리

브라우저 외부의 PWA는 자체 창을 관리합니다. 이 장에서는 운영체제 내에서 창을 관리하기 위한 API와 기능을 이해합니다.

PWA 창

PWA에서 관리하는 자체 창에서 실행하면 해당 운영체제의 모든 창의 장점과 책임이 있습니다(예:

  • Windows 또는 ChromeOS와 같은 멀티 윈도우 운영체제에서 창의 크기를 조절하고 창을 움직이는 기능
  • iPadOS 분할 모드 또는 Android 화면 분할 모드와 같이 다른 앱 창과 화면 공유
  • 데스크톱의 도크, 작업 표시줄, Alt-Tab 메뉴, 휴대기기의 멀티태스킹 창 목록에 표시됩니다.
  • 언제든지 창을 최소화하고, 화면과 데스크톱 간에 창을 이동하고, 창을 닫을 수 있는 기능

창 이동 및 크기 조절

PWA 창은 크기와 상관없이 데스크톱 운영체제의 화면 어디에나 배치할 수 있습니다. 기본적으로 사용자가 설치 후 PWA를 처음 열면 PWA는 현재 화면의 비율로 기본 창 크기를 가져오며 최대 해상도는 1920x1080으로 화면 왼쪽 상단에 배치됩니다.

사용자는 창을 이동하고 크기를 조절할 수 있으며 브라우저는 마지막 환경설정을 기억하므로 사용자가 다음에 앱을 열면 창이 이전 사용의 크기와 위치를 유지합니다.

매니페스트 내에서 PWA의 기본 크기와 위치를 정의할 방법은 없습니다. JavaScript API를 사용하여만 창의 위치를 변경하고 크기를 조절할 수 있습니다. 코드에서 window 객체의 moveTo(x, y)resizeTo(x, y) 함수를 사용하여 자체 PWA 창을 이동하고 크기를 조절할 수 있습니다.

예를 들어 다음을 사용하여 PWA가 로드될 때 PWA 창의 크기를 조절하고 이동할 수 있습니다.

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);
   }
});

window.screen 객체를 사용하여 현재 화면 크기와 위치를 쿼리할 수 있습니다. window 객체의 resize 이벤트를 사용하여 창 크기가 조절될 때를 감지할 수 있습니다. 창 이동을 캡처하는 이벤트가 없으므로 위치를 자주 쿼리하는 옵션을 사용할 수 있습니다.

다른 사이트 탐색

PWA의 범위에 해당하지 않는 외부 사이트로 사용자를 보내려면 표준 <a href> HTML 요소를 사용하거나 location.href를 사용하거나 호환되는 플랫폼에서 새 창을 열면 됩니다.

현재 모든 브라우저에서 PWA가 설치된 경우 매니페스트 범위를 벗어난 URL로 탐색하면 PWA의 브라우저 엔진이 창 컨텍스트 내에서 인앱 브라우저를 렌더링합니다.

인앱 브라우저의 기능은 다음과 같습니다.

  • 콘텐츠 위에 표시됩니다.
  • 현재 출처, 창 제목, 메뉴를 보여주는 정적 URL 표시줄이 있습니다. 일반적으로 매니페스트의 theme_color로 테마가 설정됩니다.
  • 컨텍스트 메뉴에서 브라우저에서 해당 URL을 열 수 있습니다.
  • 사용자는 브라우저를 닫거나 뒤로 이동할 수 있습니다.

지원 범위 외 URL을 탐색할 때 데스크톱 PWA의 인앱 브라우저

독립형 PWA의 범위에 해당하지 않는 URL을 탐색할 때 iPhone의 인앱 브라우저

독립형 PWA의 범위를 벗어난 URL을 탐색할 때 Android의 인앱 브라우저

승인 흐름

많은 웹 인증 및 승인 흐름은 OAuth 2.0 사용과 같이 사용자를 다른 출처의 다른 URL로 리디렉션하여 PWA의 출처로 반환할 토큰을 획득하는 것을 포함합니다.

이 경우 인앱 브라우저는 다음 프로세스를 따릅니다.

  1. 사용자가 PWA를 열고 로그인을 클릭합니다.
  2. 렌더링 엔진이 PWA 내에서 인앱 브라우저를 열 수 있도록 PWA가 사용자를 PWA 범위 밖의 URL로 리디렉션합니다.
  3. 사용자는 언제든지 인앱 브라우저를 취소하고 PWA로 돌아갈 수 있습니다.
  4. 사용자가 인앱 브라우저에 로그인합니다. 인증 서버는 사용자를 PWA 출처로 리디렉션하여 토큰을 인수로 전송합니다.
  5. 인앱 브라우저는 PWA 범위에 속하는 URL을 감지하면 자동으로 닫힙니다.
  6. 엔진은 기본 PWA 창 탐색을 인앱 브라우저에 있는 동안 인증 서버가 이동한 URL로 리디렉션합니다.
  7. PWA는 토큰을 가져와 저장하고 PWA를 렌더링합니다.

브라우저 탐색 강제

인앱 브라우저가 아닌 URL로 브라우저를 강제로 열려면 <a href> 요소의 _blank 타겟을 사용하면 됩니다. 이 방법은 데스크톱 PWA에서만 작동합니다. 휴대기기에서는 URL로 브라우저를 여는 옵션이 없습니다.

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

새 창 열기

데스크톱에서는 사용자가 동일한 PWA의 창을 두 개 이상 열 수 있습니다. 각 창은 동일한 URL의 브라우저 탭 두 개를 여는 것처럼 동일한 start_url로 이동하는 다른 경로입니다. 사용자는 PWA의 메뉴에서 '파일'과 '새 창'을 차례로 선택할 수 있으며, PWA 코드에서는 open() 함수를 사용하여 새 창을 열 수 있습니다. 자세한 내용은 문서를 확인하세요.

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

데스크톱 운영체제에서 여러 창이 열려 있는 동일한 설치된 PWA

iOS 또는 iPadOS의 PWA 창 내에서 open()를 호출하면 null이 반환되고 창이 열리지 않습니다. Android에서 새 창을 열면 URL이 PWA의 범위 내에 있더라도 URL의 새 인앱 브라우저가 생성되며, 이 브라우저는 일반적으로 외부 탐색 환경을 트리거하지 않습니다.

창 제목

<title> 요소는 브라우저 탭 내 공간이 제한되어 있으므로 주로 SEO 목적으로 사용되었습니다. PWA에서 브라우저에서 창으로 이동하면 모든 제목 표시줄 공간을 사용할 수 있습니다.

제목 표시줄의 콘텐츠를 정의할 수 있습니다.

  • HTML <title> 요소에 정적으로
  • 언제든지 document.title 문자열 속성을 동적으로 변경합니다.

데스크톱 PWA에서는 제목이 필수이며 창의 제목 표시줄에 사용되며 경우에 따라 작업 관리자 또는 멀티태스킹 선택에도 사용됩니다. 싱글페이지 애플리케이션이 있는 경우 모든 경로에서 제목을 업데이트하는 것이 좋습니다.

탭 모드

탭 모드​라는 실험용 기능을 사용하면 PWA에 웹브라우저와 유사한 탭 기반 디자인을 적용할 수 있습니다. 이 경우 사용자는 동일한 PWA에서 여러 탭을 열 수 있지만 다음 동영상에서 볼 수 있듯이 모두 동일한 운영체제 창에 연결됩니다.

이 실험용 기능에 관한 자세한 내용은 PWA용 탭형 애플리케이션 모드를 참고하세요.

창 컨트롤 오버레이

<title> 요소 또는 document.title 속성의 값을 정의하여 창의 제목을 변경할 수 있다고 설명했습니다. 하지만 항상 문자열 값입니다. HTML, CSS, 이미지를 사용하여 원하는 대로 제목 표시줄을 디자인할 수 있다면 어떨까요? 여기에서 데스크톱 PWA용 Microsoft Edge 및 Google Chrome의 새로운 실험용 기능인 창 컨트롤 오버레이가 사용됩니다.

이 기능에 관한 자세한 내용은 PWA 제목 표시줄의 창 컨트롤 오버레이 맞춤설정을 참고하세요.

창 컨트롤 오버레이를 사용하면 제목 표시줄에 콘텐츠를 렌더링할 수 있습니다.

창 관리

사용자는 여러 화면을 사용할 때 사용 가능한 모든 공간을 사용하려 합니다. 예를 들면 다음과 같습니다.

  • Gimp와 같은 멀티 윈도우 그래픽 편집기를 사용하면 정확하게 배치된 창에 다양한 편집 도구를 배치할 수 있습니다.
  • 가상 거래소는 여러 창에 시장 동향을 표시할 수 있으며, 이러한 창은 모두 전체 화면 모드로 볼 수 있습니다.
  • 슬라이드쇼 앱은 내부 기본 화면에 발표자 노트를 표시하고 외부 프로젝터에 프레젠테이션을 표시할 수 있습니다.

Window Management API를 사용하면 PWA에서 이 작업을 비롯한 다양한 작업을 할 수 있습니다.

화면 세부정보 가져오기

Window Management API에 화면이 있는 객체를 연결된 화면의 변경 불가능한 배열로 반환하는 새 메서드 window.getScreenDetails()가 추가되었습니다. ScreenDetails.currentScreen에서 액세스할 수 있는 실시간 객체도 있으며, 이 객체는 현재 window.screen에 해당합니다.

반환된 객체는 screens 배열이 변경될 때 screenschange 이벤트도 실행합니다. 개별 화면의 속성이 변경되는 경우에는 이러한 일이 발생하지 않습니다. 개별 화면(window.screen 또는 screens 배열의 화면)도 속성이 변경될 때 change 이벤트를 실행합니다.

// 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;
});

사용자 또는 운영체제가 PWA의 창을 한 화면에서 다른 화면으로 이동하면 화면 세부정보 객체에서도 currentscreenchange 이벤트가 실행됩니다.

화면 wake lock

태블릿에서 레시피를 보며 주방에서 요리하고 있다고 가정해 보겠습니다. 재료 준비를 마쳤습니다. 손이 지저분해져 기기로 돌아가 다음 단계를 확인합니다. 큰일이에요! 화면이 검게 변했습니다. Screen Wake Lock API를 사용하면 PWA에서 화면이 어두워지거나 절전 모드로 전환되거나 잠기지 않도록 할 수 있으므로 사용자가 걱정 없이 앱을 중지, 시작, 종료, 다시 시작할 수 있습니다.

// 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();

가상 키보드

휴대전화 및 태블릿과 같은 터치 기반 기기는 사용자가 PWA의 양식 요소에 포커스가 있을 때 입력할 수 있도록 가상 화면 키보드를 제공합니다.

VirtualKeyboard API 덕분에 이제 PWA는 다음을 비롯하여 navigator.virtualKeyboard 인터페이스를 사용하여 호환되는 플랫폼에서 키보드를 더 효과적으로 제어할 수 있습니다.

  • navigator.virtualKeyboard.show()navigator.virtualKeyboard.hide() 함수를 사용하여 가상 키보드를 표시하고 숨깁니다.
  • navigator.virtualKeyboard.overlaysContenttrue로 설정하여 가상 키보드를 직접 닫겠다고 브라우저에 알립니다.
  • navigator.virtualKeyboardgeometrychange 이벤트를 사용하여 키보드가 표시되고 사라지는 시점을 알 수 있습니다.
  • virtualkeyboardpolicy HTML 속성을 사용하여 호스트 요소 수정 (contenteditable 사용)에 가상 키보드 정책을 설정합니다. 정책을 사용하면 가상 키보드를 auto 값을 사용하여 브라우저에서 자동으로 처리할지 아니면 manual 값을 사용하여 스크립트에서 처리할지 결정할 수 있습니다.
  • CSS 환경 변수를 사용하여 keyboard-inset-heightkeyboard-inset-top와 같은 가상 키보드 모양에 관한 정보를 가져옵니다.

VirtualKeyboard API로 전체 제어에서 이 API에 대해 자세히 알아보세요.

리소스