目录

Window Development FAQs

How to Launch Application B During the Startup of Application A

Solution

Application A can call the on('windowStageEvent') API to listen for the WindowStageEvent.ACTIVE event and then call the startAbility API to launch application B.

Code Example

// applicationA EntryAbility.ts
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { Want, StartOptions } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: window.WindowStage): void {
        let want: Want = {
            deviceId: '',
            bundleName: 'com.example.applicationB',
            abilityName: 'EntryAbility'
        };

        let options: StartOptions = {
            displayId: 0
        };

        windowStage.on('windowStageEvent', (data) => {
            let eventType: window.WindowStageEventType = data;
            // Listen for application A switching to the ACTIVE state.
            if (eventType === window.WindowStageEventType.ACTIVE) {
                try {
                    // Launch application B.
                    this.context.startAbility(want, options, (err: BusinessError) => {
                        if (err.code) {
                            // Handle service logic errors.
                            console.error(`Failed to start ability, code is ${err.code}, message is ${err.message}.`);
                            return;
                        }
                        // Carry out normal service processing.
                        console.info('Succeeded in starting Ability.');
                    });
                } catch (err) {
                    // Handle input parameter errors.
                    let code = (err as BusinessError).code;
                    let message = (err as BusinessError).message;
                    console.error(`Failed to start ability, code is ${code}, message is ${message}.`);
                }
            }
        });
    }
}

How to Dynamically Obtain the Window Width and Height

In application development, dynamically obtaining the window width and height is mainly used to implement responsive layout to adapt to devices of different sizes or window status changes (such as split-screen, maximization, restoration, and drag resizing).

You are advised to use getMainWindowSync(), getMainWindow(), or getSubWindow() to obtain the window instance (windowClass), and then call the getWindowProperties() API through the instance to obtain the WindowProperties attribute. You can obtain the window width and height based on the attribute. The sample code is as follows:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    let windowClass: window.Window = windowStage.getMainWindowSync(); // Obtain the main window of the application.
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      let properties = windowClass.getWindowProperties();
      let rect = properties.windowRect;
      let windowWidth = rect.width;  // Window width, in px.
      let windowHeight = rect.height; // Window height, in px.
      console.info(`Window Size: ${windowWidth} x ${windowHeight}`);
    } catch (exception) {
      console.error('Failed to obtain the window properties. Cause: ' + JSON.stringify(exception));
    }
  }
}

How to Obtain the Soft Keyboard Height

The fixed soft keyboard is a specific type of avoid area, which corresponds to the TYPE_KEYBOARD type in AvoidAreaType. You can use getWindowAvoidArea() and on('avoidAreaChange') to dynamically listen for changes in the soft keyboard avoid area height.

You can also use the on('keyboardHeightChange') API to listen for changes in the soft keyboard height. Unlike the avoid area, the callback of this API returns only the height (number) of the soft keyboard, while the on('avoidAreaChange') callback returns the entire soft keyboard area (Rect).

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // Obtain the main window.
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // Obtain the height of the soft keyboard avoid area.
      let keyboardHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD).bottomRect.height;
      // Dynamically listen for changes in the soft keyboard avoid area height.
      windowClass.on('avoidAreaChange', (data) => {
        if (data.type == window.AvoidAreaType.TYPE_KEYBOARD) {
          keyboardHeight = data.area.bottomRect.height;
        }
      });
    } catch (exception) {
      console.error(`Failed to enable the listener for system avoid area changes. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }
}

How to Obtain the Height of the PC's Default System Title Bar

Call getWindowDecorHeight() to obtain the height of the title bar.

The example code is as follows:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // Obtain the main window.
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    windowClass.setUIContent('pages/WindowPage').then(() => {
      try {
        let height = windowClass?.getWindowDecorHeight();
        console.info(`Succeeded in getting the height of window decor: ${height}`);
      } catch (exception) {
        console.error(`Failed to get the height of window decor. Cause code: ${exception.code}, message: ${exception.message}`);
      }
    })
  }
}

How to Implement or Determine Immersive Window Layout

Immersive layout is a state that allows the app's layout area to extend to the entire window display area.

For a non-freeform window, immersive layout can be set by calling setWindowLayoutFullScreen(). For a freeform window, the visibility of the window title bar can be controlled through the setWindowDecorVisible() API. When the title bar is hidden, the window is in immersive layout.

You can use isImmersiveLayout() to check whether the window is in immersive layout.

The example code is as follows:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // Obtain the main window.
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // Set the immersive layout.
      let promise = windowClass.setWindowLayoutFullScreen(true);
      // Check whether the current window is in immersive layout.
      let isImmersiveLayout = windowClass.isImmersiveLayout();
      console.info(`isImmersiveLayout: ${isImmersiveLayout}`);
    } catch (exception) {
      console.error('Failed to obtain isImmersiveLayout. Cause: ' + JSON.stringify(exception));
    }
  }
}

How to Hide the Status Bar and Bottom Navigation Area

Call setSpecificSystemBarEnabled() to hide the status bar and bottom navigation bar.

The example code is as follows:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // Obtain the main window.
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // Hide the status bar.
      windowClass.setSpecificSystemBarEnabled('status', false);
      // Hide the bottom navigation area.
      windowClass.setSpecificSystemBarEnabled('navigationIndicator', false);
    } catch (exception) {
      console.error('Failed to set status bar or navigation indicator bar invisible. Cause: ' + JSON.stringify(exception));
    }
  }
}

How to Obtain the Status Bar Height

The status bar is a specific avoid area type, which corresponds to the system bar (TYPE_SYSTEM) in AvoidAreaType.

When the main window is displayed in full screen, you can obtain the avoid area that includes a status bar through getWindowAvoidArea() to indirectly obtain the height of the status bar.

The example code is as follows:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    let windowClass: window.Window = windowStage.getMainWindowSync(); // Obtain the main window of the application.
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // Obtain the height of the status bar avoid area.
      let statusBarHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height;
    } catch (exception) {
      console.error(`Failed to get window avoid area. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }
}

How to Set the Window Background to Transparent

To make the window background transparent, call setWindowBackgroundColor and pass '#00XXXXXX' (where X represents any hexadecimal digit) or a transparent ColorMetrics value.

  • On devices that support freeform windows, a window container is available. Its background color covers the entire window, including both the title bar and the content area. Calling setWindowBackgroundColor only sets the background color of the app content area, through which the window container background color is visible.

  • On PC/2-in-1 and tablet devices, you can call setWindowContainerColor() to make the container transparent. On other devices, setting the container background color is not supported.

The example code is as follows:

import { BusinessError } from '@kit.BasicServicesKit';
import { ColorMetrics } from '@kit.ArkUI';
import { window } from '@kit.ArkUI';

let storage: LocalStorage = new LocalStorage();
storage.setOrCreate('storageSimpleProp', 121);
windowClass.loadContent("pages/page2", storage, (err: BusinessError) => {
  let errCode: number = err.code;
  if (errCode) {
  console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`);
  return;
  }
  console.info('Succeeded in loading the content.');
  // Use the ARGB mode.
  let color1: string = '#0000FF33';
  // Use the ColorMetrics mode.
  let color2: ColorMetrics = ColorMetrics.numeric(0x00112233);
  try {
    windowClass?.setWindowBackgroundColor(color1);
    windowClass?.setWindowBackgroundColor(color2);
  } catch (exception) {
    console.error(`Failed to set the background color. Cause code: ${exception.code}, message: ${exception.message}`);
  };
});

How to Implement Landscape/Portrait Switching

Obtain the main window instance and call the setPreferredOrientation() API to set the window orientation. For details, see Window Rotation.

The example code is as follows:

import { BusinessError } from '@kit.BasicServicesKit'
import { common } from '@kit.AbilityKit'
import { window } from '@kit.ArkUI'

@Entry
@Component
struct OrientationTestView {
  private orientation: number =  1;
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  private windowClass = (this.context as common.UIAbilityContext).windowStage.getMainWindowSync();
  setOrientation(orientation: number) {
    this.windowClass.setPreferredOrientation(orientation).then(() => {
      console.info('setWindowOrientation: ' + orientation + ' Succeeded.');
    }).catch((err: BusinessError) => {
      console.error('setWindowOrientation: ' + orientation + ' Failed. Cause: ' + JSON.stringify(err));
    })
  }
  build() {
    Column() {
      Button('changeOrientation')
        .onClick(() => {
          this.setOrientation(this.orientation++ % 4 + 1)
        })
    }
    .height('100%')
    .width('100%')
    .margin({'top' : 100})
  }
}

For more information, see:

How to Keep the Screen in Landscape/Portrait Mode Without Rotating with the Sensors

Set the application's rotation policy to LANDSCAPE via the setPreferredOrientation() API to keep the application in landscape mode; set it to PORTRAIT to keep it in portrait mode; set it to LOCKED to lock the current application orientation without rotating with the screen (using LOCKED is not recommended as it may cause unexpected orientation changes).

To disable rotation for a single page (Navigation), you can set the preferredOrientation attribute of the component. If the attribute is set to a specific orientation such as landscape, portrait, reverse landscape, or reverse portrait, the page cannot be rotated to other directions.

How to Obtain the Screen Orientation

Call display.getDefaultDisplaySync() to obtain the default display instance.

Then, obtain the Orientation attribute of the instance to determine the screen orientation of the device.

The following table lists the values of the Orientation attribute.

Name Value Description
PORTRAIT 0 The screen is in portrait mode.
LANDSCAPE 1 The screen is in landscape mode.
PORTRAIT_INVERTED 2 The screen is in reverse portrait mode.
LANDSCAPE_INVERTED 3 The screen is in reverse landscape mode.

If you set the rotation policy to LANDSCAPE through the setPreferredOrientation API, the Orientation attribute obtained in the preceding steps is LANDSCAPE_INVERTED. This is because the window direction is different from the screen direction. You can also use convertOrientationAndRotation() to obtain the rotation result.

The example code is as follows:

import { display } from '@kit.ArkUI';

let displayClass: display.Display | null = null;
try {
  displayClass = display.getDefaultDisplaySync();
  let orientation = displayClass.Orientation;
} catch (exception) {
  console.error(`Failed to get default display. Code: ${exception.code}, message: ${exception.message}`);
}

How to Set the Default Aspect Ratio of an Application in Landscape Mode

You are advised to use setContentAspectRatio() to set the aspect ratio of the window content layout.

  • When you adjust the window width and height using the same ratio parameter, the window dimensions will adjust according to changes in the border decoration size or visibility.

  • When the window title bar is set to invisible by using setWindowDecorVisible, the window content area will occupy the height space originally taken by the title bar.

  • When the window size is set by using other APIs such as resize and resizeAsync, the window size is not restricted by the ratio.

  • This setting is available only for the main window and takes effect only in floating window mode (window.WindowStatusType.FLOATING mode).

  • For versions earlier than API version 21, use setAspectRatio() to set the window content layout.

The sample code snippet is as follows:

// EntryAbility.ets
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    try {
      let windowClass = windowStage.getMainWindowSync();
      let ratio = 1.0;
      let promise = windowClass.setContentAspectRatio(ratio, true, true);
      promise.then(() => {
        console.info('Succeeded in setting aspect ratio of window.');
      }).catch((err: BusinessError) => {
        console.error(`Failed to set the aspect ratio of window. Cause code: ${err.code}, message: ${err.message}`);
      });
    } catch (exception) {
      console.error(`Failed to set the aspect ratio of window. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }
}

How to Set the Display Modes Supported by a Window

During application development, it is recommended that the supportWindowMode field in the abilities tag within the module.json5 configuration file be used to set the display mode supported by the window.

The options are as follows:

Value Description
"fullscreen" Full screen.
"split" Split screen.
"floating" Floating window mode.
  • The supportWindowMode field is of the string array type and can be left unspecified. The default value is ["fullscreen", "split", "floating"].

  • When both fullscreen and split are configured in the freeform window state, if the app's targetAPIVersion is earlier than 15, the window starts in floating window mode. If the app's targetAPIVersion is 15 or later, the window starts in full screen mode.

The following is a configuration example of the module.json5 file:

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "displayName": "$string:EntryAbility_displayName",
        "windowSize": {
          "minWidth": 320,
          "minHeight": 240
        },
        // Control the window modes supported.
        "supportWindowMode": ["fullscreen", "split", "floating"],
        "launchType": "standard",
        "excludeFromMissions": false
      }
    ]
  }
}

In addition to the preceding configuration methods, you can also configure the window modes supported by the application in the following ways:

Supported window modes in free windows mode can be configured using multiple methods. The configuration priority is:

Configuration via the setSupportedWindowModes API > Configuration via the SupportWindowMode in StartOption using StartAbility > Configuration using metadata > Configuration via the SupportWindowMode property under the abilities tag in module.json5

How to Determine If the Current Window is in Floating Window Mode

In application development, there are two ways to determine whether an application is in floating window mode.

Both on('windowStatusChange') and on('windowStatusDidChange') are called when the window status changes. on('windowStatusChange') does not ensure that the window attributes are updated when the callback is called. If your application needs to obtain the new window size and position immediately after receiving the window status change notification, you are advised to use on('windowStatusDidChange').

How to Set the Global Floating Window Background to Transparent

To make the window background transparent, call setWindowBackgroundColor and pass '#00XXXXXX' (where X represents any hexadecimal digit) or a transparent ColorMetrics value.

How to Determine Whether an Application is Partially or Fully Obscured

Currently, there are two APIs for determining whether the current window is obscured:

How to Determine Whether the Free Windows Mode Is Enabled

Call the isInFreeWindowMode() API to check whether the freeform window mode is enabled. If the return value is true, the current window is in the freeform window mode. If the return value is false, the current window is not in the freeform window mode.

Call the on('freeWindowModeChange') API to listen for freeform window mode changes.

How to Set a Privacy Window

The setWindowPrivacyMode API can be called to set a window to privacy mode. When a window is in privacy mode, its content cannot be captured through screenshots or screen recording.

For the PiP and floating ball windows, their privacy mode follows the parent window.

To take a screenshot of a privacy window, you can use the snapshotIgnorePrivacy() API.

How to Implement a Blur Effect When the App Goes to the Background and Appears in the Multitasking Window

Your app can listen to the main window lifecycle state and store the state using AppStorage. When the state is the foreground non-interactive state or the background state, set the foregroundBlurStyle attribute for the component.

The example code is as follows:

// EntryAbility.ets
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`);
        return;
      }
      console.info('Succeeded in loading the content.');
    });
    AppStorage.setOrCreate('windowStage', windowStage);
    windowStage.on('windowStageEvent', (data) => {
      console.info('Succeeded in enabling the listener for window stage event changes. Data : ' +
        JSON.stringify(data));
      // Perform corresponding processing based on the event state type.
      if (data == window.WindowStageEventType.SHOWN) {
        console.info('current window stage event is SHOWN');
        AppStorage.setOrCreate('interact', true);
        // When the app enters the foreground, it is in the interactive state by default.
        // ...
      } else if (data == window.WindowStageEventType.HIDDEN) {
        console.info('current window stage event is HIDDEN');
        AppStorage.setOrCreate('interact', false);
        // When the app enters the background, it is in the non-interactive state by default.
        // ...
      } else if (data == window.WindowStageEventType.PAUSED) {
        console.info('current window stage event is PAUSED');
        AppStorage.setOrCreate('interact', false);
        // When the foreground app enters the multitasking view and becomes non-interactive in the foreground, switch to the non-interactive state.
        // ...
      } else if (data == window.WindowStageEventType.RESUMED) {
        console.info('current window stage event is RESUMED');
        AppStorage.setOrCreate('interact', true);
        // When the app returns to the foreground from the multitasking view and becomes interactive again, restore the interactive state.
        // ...
      }
    });
  }
}
// ets/pages/Index.ets
@Entry
@Component
struct Index {
  @StorageLink('interact') interact: boolean = true;
  build() {
    Column() {
      Text('Text('Text Text')')
        .fontSize(60)
    }
    .foregroundBlurStyle(this.interact ? BlurStyle.NONE : BlurStyle.COMPONENT_ULTRA_THICK) // The blur level can be customized.
  }
}

What Are the Position/Size Restrictions for APIs Such as resize and moveWindowTo

When calling the resize() API to adjust the window size, the window size range is constrained by WindowLimits. The specific size limit range can be queried via the getWindowLimits API.

There is no restriction on the window position when moveWindowTo() is called to adjust the window position.

Other restrictions on the resize API:

  • In the freeform window state, the API takes effect only when the window is in floating window mode (that is, the window mode is window.WindowStatusType.FLOATING, which can be obtained through getWindowStatus()). Otherwise, error code 1300002 is thrown.

  • In the non-freeform window state, the API does not take effect for the main window.

Other restrictions on the moveWindowTo API:

  • It is not recommended to use this API in window modes other than floating window mode (that is, the window mode is window.WindowStatusType.FLOATING, which can be obtained through getWindowStatus()).

  • In the freeform window state, the window moves relative to the screen. In the non-freeform window state, the window moves relative to the parent window.

  • To move the window relative to the screen in the non-freeform window state, use moveWindowToGlobal().

  • In the non-freeform window state, the API does not take effect for the main window.

How to Set or Remove Watermarks

How to Move a Created Window to an Extended Screen

How to Achieve a Semi-Transparent Background for a Child Window

For a child window, call setWindowBackgroundColor and pass '#XXYYYYYY' (where XX represents any non-zero hexadecimal value and Y represents any hexadecimal digit) or a semi-transparent ColorMetrics value.

The example code is as follows:

import { BusinessError } from '@kit.BasicServicesKit';
import { ColorMetrics } from '@kit.ArkUI';
import { window } from '@kit.ArkUI';

let storage: LocalStorage = new LocalStorage();
storage.setOrCreate('storageSimpleProp', 121);
windowClass.loadContent("pages/page2", storage, (err: BusinessError) => {
  let errCode: number = err.code;
  if (errCode) {
  console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`);
  return;
  }
  console.info('Succeeded in loading the content.');
  let color1: string = '#8800FF33'; // Use the ARGB format.
  let color2: ColorMetrics = ColorMetrics.numeric(0x88112233);  // Use the ColorMetrics format.
  try {
    windowClass?.setWindowBackgroundColor(color1);
    windowClass?.setWindowBackgroundColor(color2);
  } catch (exception) {
    console.error(`Failed to set the background color. Cause code: ${exception.code}, message: ${exception.message}`);
  };
});

How to Set Page-Level Brightness

Currently, brightness can be set only at the window level.

To achieve page-level brightness adjustment, an app can call setWindowBrightness() on the main window to adjust the brightness when entering a specific page, and call setWindowBrightness() with -1 on the main window to restore the system default brightness when exiting that page.

How to Restore System Default Brightness

For phones and tablets, the app can call setWindowBrightness() with -1 passed to restore the system default brightness.

For PCs and 2-in-1 devices, the window brightness and system brightness have been normalized. Therefore, after the setWindowBrightness() API is called, the system brightness is directly changed. Currently, there is no method to restore the window brightness to the value before the call.

How to Properly Obtain the Topmost Window

Symptom

When getLastWindow() is called to obtain the topmost window of the app, a child window that is being destroyed is obtained.

Possible Causes

When destroyWindow() is called to destroy a child window, getLastWindow() is called before the destruction is complete, resulting in obtaining a child window that is being destroyed.

Solution

Before calling getLastWindow() to obtain the topmost window of the app, ensure that operations such as child window destruction and window creation have been completed.

Sample Code

import { BusinessError } from '@kit.BasicServicesKit';
import { window } from '@kit.ArkUI';

let lastWindow: window.Window | undefined = undefined;
// Not recommended approach.
try {
  // Obtain the window instance first.
  windowClass.destroyWindow();
  try {
    window.getLastWindow(this.context).then((topWindow) => {
      lastWindow = topWindow;
    }).catch((err: BusinessError) => {
      console.error(`Failed to obtain the last window. Cause code: ${err.code}, message: ${err.message}`);
    });
  } catch (exception) {
    console.error(`Failed to obtain the last window. Cause code: ${exception.code}, message: ${exception.message}`);
  }
} catch (exception) {
  console.error(`Failed to destroy. Cause code: ${exception.code}, message: ${exception.message}`);
};

// Recommended approach.
try {
  // Obtain the window instance first.
  windowClass.destroyWindow().then(() => {
    try {
      window.getLastWindow(this.context).then((topWindow) => {
        lastWindow = topWindow;
      }).catch((err: BusinessError) => {
        console.error(`Failed to obtain the last window. Cause code: ${err.code}, message: ${err.message}`);
      });
    } catch (exception) {
      console.error(`Failed to obtain the last window. Cause code: ${exception.code}, message: ${exception.message}`);
    }
  }).catch((err: BusinessError) => {
    console.error(`Failed to destroy the window. Cause code: ${err.code}, message: ${err.message}`);
  });
} catch (exception) {
  console.error(`Failed to destroy. Cause code: ${exception.code}, message: ${exception.message}`);
};

Window Type (type Field) Returned by getWindowProperties Does Not Meet Expectations

Symptom

Due to historical reasons, when getWindowProperties() is called in the main window scenario, the obtained window type, that is, WindowType, is TYPE_SYSTEM_ALERT instead of TYPE_MAIN.

Solution

A new field will be provided in a future API version to fix this issue.

When creating a window within an app, the window type must be specified. You can directly perceive the window type and do not need to actively obtain it through this API.

Avoid Area Data Obtained Through getWindowAvoidArea in Callbacks Such as on('windowSizeChange') Is Not Up-to-Date

Symptom

In window property change callbacks such as on('windowSizeChange') and on('windowRectChange'), the avoid area data obtained through the getWindowAvoidArea() API is inaccurate.

Possible Causes

The update of the avoid area depends on both the update of window position/size properties and the update of the position/size of system UI elements (such as the status bar). When the window property update callback is triggered, the system UI elements may not have been updated yet. Therefore, the accurate avoid area cannot be obtained through the getWindowAvoidArea() API at this point.

Solution

Use the dedicated avoid area listener on('avoidAreaChange') to listen for avoid area changes, and avoid actively obtaining the avoid area through the getWindowAvoidArea() API in other window property change event callbacks.

Sample Code

import { window } from '@kit.ArkUI';

// In the code, windowClass is assumed to be an obtained Window instance.

// Incorrect: Listen for the windowSizeChange event to proactively obtain the avoid area.
windowClass.on('windowSizeChange', () => {
  try {
    const systemAvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);  // The obtained avoid area is inaccurate.
  } catch (exception) {
    console.error(`Failed to get window avoid area. Cause code: ${exception.code}, message: ${exception.message}`);
  }
});

// Correct: Listen for the avoidAreaChange event.
windowClass.on('avoidAreaChange', (data) => {
  if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
    const systemAvoidArea = data.area;  // The data in the callback always contains the accurate avoid area.
  }
});

Window size and application layout are briefly out of sync when the window size changes rapidly in free multi-window mode

Symptom

On devices that support free windows mode, when the window border is dragged rapidly, the window border follows the mouse in real time, but the layout refresh of the application content inside the window is delayed, resulting in a brief out-of-sync between the window size and the application layout. After the drag ends, the application layout becomes consistent with the window size.

Possible Causes

This behavior is a system specification. Window management adopts a client-server architecture. During the dragging of the window border, the window size update and the application layout refresh are handled by independent links in two processes:

Based on the preceding design, the brief out-of-sync between the window frame and the application layout during rapid dragging of the window border is by design. After the drag ends, the system synchronizes the final window size to the application process, and the two become consistent after the application side completes the layout re-layout.