diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 69b58791..f84b3e25 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -36,7 +36,7 @@ jobs: # unzip linux-x64-embedder # mv libflutter_engine.so ${{github.workspace}}/build run: | - curl -L https://github.com/sony/flutter-embedded-linux/releases/latest/download/elinux-x64-release.zip > elinux-x64-release.zip + curl -L https://github.com/flutter-elinux/flutter-embedded-linux/releases/latest/download/elinux-x64-release.zip > elinux-x64-release.zip unzip elinux-x64-release.zip mv libflutter_engine.so ${{github.workspace}}/build diff --git a/AUTHORS b/AUTHORS index 6a816263..3ebdf2f6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -18,3 +18,6 @@ Sebastian Urban Athaariq Ardhiansyah Anton Sakhon Bari Rao +Frede Emil Hoey Braendstrup +Dominique Martinet +Jón Bjarni Bjarnason diff --git a/README.md b/README.md index c5c6bd64..f1c87efb 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ # Embedded Linux (eLinux) embedding for Flutter -![image](https://github.com/sony/flutter-elinux/blob/main/doc/images/overview.png) +![image](https://github.com/flutter-elinux/flutter-elinux/blob/main/doc/images/overview.png) -[![build-test](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml/badge.svg)](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml) +[![build-test](https://github.com/flutter-elinux/flutter-embedded-linux/actions/workflows/build-test.yml/badge.svg)](https://github.com/flutter-elinux/flutter-embedded-linux/actions/workflows/build-test.yml) This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux (eLinux) system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. -If you develop flutter apps for eLinux, use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. +If you develop flutter apps for eLinux, use [flutter-elinux](https://github.com/flutter-elinux/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. ### Repositories -- [flutter-elinux](https://github.com/sony/flutter-elinux): Flutter tools for eLinux -- [flutter-elinux-plugins](https://github.com/sony/flutter-elinux-plugins): Flutter plugins for eLinux -- [flutter-embedded-linux](https://github.com/sony/flutter-embedded-linux): eLinux embedding for Flutter -- [meta-flutter](https://github.com/sony/meta-flutter): Yocto recipes of eLinux embedding for Flutter +- [flutter-elinux](https://github.com/flutter-elinux/flutter-elinux): Flutter tools for eLinux +- [flutter-elinux-plugins](https://github.com/flutter-elinux/flutter-elinux-plugins): Flutter plugins for eLinux +- [flutter-embedded-linux](https://github.com/flutter-elinux/flutter-embedded-linux): eLinux embedding for Flutter +- [meta-flutter](https://github.com/flutter-elinux/meta-flutter): Yocto recipes of eLinux embedding for Flutter ## Objective & Goal Our objective is to use Flutter in embedded systems. We're developing this embedder to use Flutter in embedded products. Ultimately we would like to propose and contribute this software to the mainline of [Flutter Engine](https://github.com/flutter/engine), which means we would like to add an embedded systems version into the Flutter repo for all embedded developers. Please note that this is just our ideal, not the official opinion of the Flutter community. @@ -37,7 +37,11 @@ We would be grateful if you could give us feedback on bugs and new feature reque - APIs such as MethodChannel and EventChannel are completely the same with them ## Documentation -Documentation for this software can be found at [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). +Documentation for this software can be found at [Wiki](https://github.com/flutter-elinux/flutter-embedded-linux/wiki). ## Supported platforms -This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. See [Support status](https://github.com/sony/flutter-elinux/wiki/Support-status) for details. +This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. See [Support status](https://github.com/flutter-elinux/flutter-elinux/wiki/Support-status) for details. + +## Thanks + +This repository was previously hosted on [sony/flutter-embedded-linux](https://github.com/sony/flutter-embedded-linux). Thanks to sony for creating this fork and maintaining it for 4 years. diff --git a/examples/README.md b/examples/README.md index ef2e517e..0a626c21 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,11 +4,11 @@ These are an example of how to use embedded Linux embedding for Flutter. ## Each backend examples -- [flutter-wayland-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-wayland-client): Wayland client app -- [flutter-drm-gbm-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-gbm-backend): Fullscreen app on DRM backend with GBM -- [flutter-drm-eglstream-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-eglstream-backend): Fullscreen app on DRM backend with EGLStream -- [flutter-x11-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-x11-client): X11 client app +- [flutter-wayland-client](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-wayland-client): Wayland client app +- [flutter-drm-gbm-backend](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-drm-gbm-backend): Fullscreen app on DRM backend with GBM +- [flutter-drm-eglstream-backend](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-drm-eglstream-backend): Fullscreen app on DRM backend with EGLStream +- [flutter-x11-client](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-x11-client): X11 client app ## Examples using Flutter Plugins -- [flutter-video-player-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-video-player-plugin): Flutter video player plugin -- [flutter-external-texture-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-external-texture-plugin): Flutter external texture plugin +- [flutter-video-player-plugin](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-video-player-plugin): Flutter video player plugin +- [flutter-external-texture-plugin](https://github.com/flutter-elinux/flutter-embedded-linux/tree/master/examples/flutter-external-texture-plugin): Flutter external texture plugin diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake index 4d2cb636..9e948f5c 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-EGLSTREAM) set(USE_GLES3 OFF) diff --git a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake index a3a5931e..c5d1935d 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-GBM) set(USE_GLES3 OFF) diff --git a/examples/flutter-external-texture-plugin/cmake/user_config.cmake b/examples/flutter-external-texture-plugin/cmake/user_config.cmake index 5f72786b..ade6aa1c 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_config.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(USE_GLES3 OFF) diff --git a/examples/flutter-video-player-plugin/README.md b/examples/flutter-video-player-plugin/README.md index 4e643a99..21122727 100644 --- a/examples/flutter-video-player-plugin/README.md +++ b/examples/flutter-video-player-plugin/README.md @@ -1,7 +1,7 @@ # Overview Flutter video player example using video player plugin for Embedded Linux. The interface of the plugin is compatible with [the Flutter official video player plugin](https://github.com/flutter/plugins/tree/master/packages/video_player/video_player). -Note that this is just example for eLinux embedder, so please use [sony/flutter-elinux-plugins/packages/video_player](https://github.com/sony/flutter-elinux-plugins/tree/main/packages/video_player) +Note that this is just example for eLinux embedder, so please use [sony/flutter-elinux-plugins/packages/video_player](https://github.com/flutter-elinux/flutter-elinux-plugins/tree/main/packages/video_player) ![image](https://user-images.githubusercontent.com/62131389/124210378-43f06400-db26-11eb-8723-40dad0eb67b0.png) diff --git a/examples/flutter-video-player-plugin/cmake/user_config.cmake b/examples/flutter-video-player-plugin/cmake/user_config.cmake index 5f72786b..ade6aa1c 100644 --- a/examples/flutter-video-player-plugin/cmake/user_config.cmake +++ b/examples/flutter-video-player-plugin/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(USE_GLES3 OFF) diff --git a/examples/flutter-wayland-client/cmake/user_config.cmake b/examples/flutter-wayland-client/cmake/user_config.cmake index 5f72786b..ade6aa1c 100644 --- a/examples/flutter-wayland-client/cmake/user_config.cmake +++ b/examples/flutter-wayland-client/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(USE_GLES3 OFF) diff --git a/examples/flutter-x11-client/cmake/user_config.cmake b/examples/flutter-x11-client/cmake/user_config.cmake index aa0196fc..7a60b713 100644 --- a/examples/flutter-x11-client/cmake/user_config.cmake +++ b/examples/flutter-x11-client/cmake/user_config.cmake @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +# See: https://github.com/flutter-elinux/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE X11) set(USE_GLES3 OFF) diff --git a/release/.gitignore b/release/.gitignore new file mode 100644 index 00000000..0743ec92 --- /dev/null +++ b/release/.gitignore @@ -0,0 +1,5 @@ +/home +/build-embedder +/depot_tools +/output* +/work-* diff --git a/release/Dockerfile b/release/Dockerfile new file mode 100644 index 00000000..c4958ec5 --- /dev/null +++ b/release/Dockerfile @@ -0,0 +1,18 @@ +FROM debian:trixie-slim + +ENV DEBIAN_FRONTEND noninteractive + +RUN </dev/null || true + +echo "" +echo "Engine version: ${ENGINE_VERSION}" +echo "Channel: ${CHANNEL}" +echo "" +echo "Output packages:" +echo " - elinux-common.zip" +echo " - elinux-x64-debug.zip" +echo " - elinux-x64-profile.zip" +echo " - elinux-x64-release.zip" +echo " - elinux-arm64-debug.zip" +echo " - elinux-arm64-profile.zip" +echo " - elinux-arm64-release.zip" +echo "" +echo "All artifacts are ready for release!" +echo "==========================================" + +# Cleanup option (uncomment if you want to clean up work directories) +# echo "" +# echo "Cleaning up work directories..." +# rm -rf ${WORK_DIR_X64} ${WORK_DIR_ARM64} +# echo "Cleanup completed." diff --git a/release/build-flutter-embedder.sh b/release/build-flutter-embedder.sh new file mode 100755 index 00000000..b675c4e8 --- /dev/null +++ b/release/build-flutter-embedder.sh @@ -0,0 +1,193 @@ +#!/usr/bin/env bash + +set -ex + +# Example) +# +# ./build-flutter-embedder.sh --arch=arm64 --output-dir=artifacts --engine-dir=../build-embedder/flutter/engine +# + +TARGET_ARCH=${TARGET_ARCH:-"x64"} +OUTPUT_DIR=${OUTPUT_DIR:-"artifacts"} +EMBEDDER_REPO=${EMBEDDER_REPO:-"https://github.com/flutter-elinux/flutter-embedded-linux.git"} +ENGINE_DIR=${ENGINE_DIR:-""} +RUNTIME_MODE=${RUNTIME_MODE:-"release"} +INSTALL_DIR=${INSTALL_DIR:-"/usr/lib"} + +export CMAKE_BUILD_PARALLEL_LEVEL=24 + +for i; do + case $i in + --arch=*) + TARGET_ARCH="${i#*=}" + ;; + --output-dir=*) + OUTPUT_DIR="${i#*=}" + ;; + --embedder-repo=*) + EMBEDDER_REPO="${i#*=}" + ;; + --engine-dir=*) + ENGINE_DIR="${i#*=}" + ;; + --runtime-mode=*) + RUNTIME_MODE="${i#*=}" + ;; + --install-dir=*) + INSTALL_DIR="${i#*=}" + esac +done + +# Validate ENGINE_DIR +if [ -z "${ENGINE_DIR}" ]; then + echo "Error: ENGINE_DIR is not set. Please specify --engine-dir=" + echo "Example: --engine-dir=../build-embedder/flutter/engine" + exit 1 +fi + +if [ ! -d "${ENGINE_DIR}" ]; then + echo "Error: ENGINE_DIR does not exist: ${ENGINE_DIR}" + exit 1 +fi + +ABS_INSTALL_DIR=$(realpath ${INSTALL_DIR}) + +echo "Engine directory: ${ENGINE_DIR}" +echo "Target architecture: ${TARGET_ARCH}" +echo "Runtime mode: ${RUNTIME_MODE}" + +# Determine output directories based on architecture +if [ ${TARGET_ARCH} = "arm64" ]; then + ARCH_ARGS="-DCMAKE_TOOLCHAIN_FILE=$PWD/cross-toolchain-aarch64.cmake" + DEBUG_OUTDIR="linux_debug_unopt_arm64" + PROFILE_OUTDIR="linux_profile_arm64" + RELEASE_OUTDIR="linux_release_arm64" +else + DEBUG_OUTDIR="host_debug_unopt" + PROFILE_OUTDIR="host_profile" + RELEASE_OUTDIR="host_release" +fi + +# Install libflutter_engine.so from built engine +install_flutter_engine() { + + echo "Installing Flutter Engine to ${ABS_INSTALL_DIR}" + mkdir -p ${ABS_INSTALL_DIR} + + # Copy libflutter_engine.so files + cp ${ENGINE_DIR}/src/out/${DEBUG_OUTDIR}/libflutter_engine.so ${ABS_INSTALL_DIR}/libflutter_engine-debug.so + cp ${ENGINE_DIR}/src/out/${PROFILE_OUTDIR}/libflutter_engine.so ${ABS_INSTALL_DIR}/libflutter_engine-profile.so + cp ${ENGINE_DIR}/src/out/${RELEASE_OUTDIR}/libflutter_engine.so ${ABS_INSTALL_DIR}/libflutter_engine-release.so + + # Create symlink based on runtime mode + ln -sf ./libflutter_engine-${RUNTIME_MODE}.so ${ABS_INSTALL_DIR}/libflutter_engine.so + + echo "Flutter Engine installed successfully." +} + +# Install build dependencies (uncomment if needed) +# install_dependencies() { +# apt install -y zip equivs clang libgles2-mesa-dev wayland-protocols libegl1-mesa-dev +# apt install -y libdrm-dev libgbm-dev libinput-dev libudev-dev libsystemd-dev +# apt install -y libxkbcommon-dev libwayland-dev +# } + +# Creates artifacts directory +mkdir -p ${OUTPUT_DIR}/${TARGET_ARCH}/debug +mkdir -p ${OUTPUT_DIR}/${TARGET_ARCH}/release +mkdir -p ${OUTPUT_DIR}/common + +# Install libflutter_engine.so from the built engine +install_flutter_engine + +# Get source files +if ! [ -d flutter-embedded-linux ]; then + git clone --filter blob:none ${EMBEDDER_REPO} +else + git -C flutter-embedded-linux fetch + git -C flutter-embedded-linux reset --hard origin/master +fi +cd flutter-embedded-linux +git rev-parse --short HEAD > ../${OUTPUT_DIR}/embedder.version +cat ../${OUTPUT_DIR}/embedder.version +mkdir -p build +cd build + +# Build wayland (for debug mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=WAYLAND -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=ON -DFLUTTER_RELEASE=OFF .. +cmake --build . +cp libflutter_elinux_wayland.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/debug +rm -rf * + +# Build wayland (for release mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=WAYLAND -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=OFF -DFLUTTER_RELEASE=ON .. +cmake --build . +cp libflutter_elinux_wayland.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/release +rm -rf * + +# Build x11 (for debug mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=X11 -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=ON -DFLUTTER_RELEASE=OFF .. +cmake --build . +cp libflutter_elinux_x11.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/debug +rm -rf * + +# Build x11 (for release mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=X11 -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=OFF -DFLUTTER_RELEASE=ON .. +cmake --build . +cp libflutter_elinux_x11.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/release +rm -rf * + +# Build gbm (for debug mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=DRM-GBM -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=ON -DFLUTTER_RELEASE=OFF .. +cmake --build . +cp libflutter_elinux_gbm.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/debug +rm -rf * + +# Build gbm (for release mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=DRM-GBM -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=OFF -DFLUTTER_RELEASE=ON .. +cmake --build . +cp libflutter_elinux_gbm.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/release +rm -rf * + +# Build eglstream (for debug mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=DRM-EGLSTREAM -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=ON -DFLUTTER_RELEASE=OFF .. +cmake --build . +cp libflutter_elinux_eglstream.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/debug +rm -rf * + +# Build eglstream (for release mode) +cp ${ABS_INSTALL_DIR}/libflutter_engine.so . +cmake $ARCH_ARGS -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=DRM-EGLSTREAM -DCMAKE_BUILD_TYPE=Release -DENABLE_ELINUX_EMBEDDER_LOG=OFF -DFLUTTER_RELEASE=ON .. +cmake --build . +cp libflutter_elinux_eglstream.so ../../${OUTPUT_DIR}/${TARGET_ARCH}/release +rm -rf * + +cd ../.. + +# Creates release packages +cd ${OUTPUT_DIR}/${TARGET_ARCH} +zip -jr embedder-${TARGET_ARCH}-debug.zip debug/* +zip -jr embedder-${TARGET_ARCH}-release.zip release/* +cd ../.. + +# Gathers common files +cp -rf flutter-embedded-linux/src/client_wrapper ${OUTPUT_DIR}/common +cp -rf flutter-embedded-linux/src/flutter/shell/platform/common/client_wrapper ${OUTPUT_DIR}/common +cp -rf flutter-embedded-linux/src/flutter/shell/platform/common/public/* ${OUTPUT_DIR}/common +cp -rf flutter-embedded-linux/src/flutter/shell/platform/linux_embedded/public/* ${OUTPUT_DIR}/common + +cd ${OUTPUT_DIR}/common +mv client_wrapper cpp_client_wrapper +zip -r embedder-common.zip * +cd ../.. + +echo "" +echo "Build completed successfully." +echo "Artifacts are in ${OUTPUT_DIR}/" diff --git a/release/build-flutter-engine.sh b/release/build-flutter-engine.sh new file mode 100755 index 00000000..662e0cfc --- /dev/null +++ b/release/build-flutter-engine.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +set -ex + +# Example) +# +#./build-flutter-engine.sh --revision=$(cat embedder.version) --arch=arm64 --build-dir=build-embedder +# + +BUILD_DIR=${BUILD_DIR:-"build-embedder"} +TARGET_ARCH=${TARGET_ARCH:-"x64"} +REVISION=${REVISION:-""} +OUTPUT_DIR="out" +REPO_URL=https://github.com/flutter/flutter.git + +for i; do + case $i in + --revision=*) + REVISION="${i#*=}" + ;; + --arch=*) + TARGET_ARCH="${i#*=}" + ;; + --build-dir=*) + BUILD_DIR="${i#*=}" + ;; + esac +done + + + +# check if need to build. +if [ -z "${REVISION}" ]; then + echo "Warning: No revision specified." +fi + +# Builds Flutter Engine + +install_depot_tools() { + # Get gclient + if [ ! -d depot_tools ]; then + git clone --filter blob:none https://chromium.googlesource.com/chromium/tools/depot_tools.git + fi + export PATH=$PATH:$(pwd)/depot_tools +} + +get_flutter_source() { + echo "Flutter Engine version: "${REVISION} + + # already checked out? + if [ -n "$REVISION" ] && [ "$(git -C flutter rev-parse HEAD "$REVISION" 2>/dev/null | uniq | wc -l)" = 1 ]; then + return + fi + + # Clone flutter repo + if [ ! -d flutter ]; then + git clone --filter blob:none ${REPO_URL} + elif [ -z "$REVISION" ] || ! git -C flutter rev-parse "$REVISION" 2>/dev/null; then + git -C flutter fetch + fi + + if [ -n "${REVISION}" ]; then + git -C flutter checkout "${REVISION}" + fi +} + +set_flutter_path() { + export PATH=$PATH:$(pwd)/flutter/engine/src/flutter/bin + + # patch: https://github.com/flutter/flutter/issues/163487 + export PATH=$(pwd)/flutter/engine/src/flutter/third_party/ninja:$PATH + export PATH=$(pwd)/flutter/engine/src/flutter/third_party/depot_tools/ninja:$PATH +} + +gclient_sync() { + # gclient sync + pushd flutter + + if [ -n "${REVISION}" ]; then + URL="${REPO_URL}@${REVISION}" + else + URL="${REPO_URL}" + fi + + if [ -e .gclient_sync_ok ] && grep -q "$URL" .gclient; then + popd + return + fi + + rm -f .gclient_sync_ok + cat < appropriately for your environment. +set(target_sysroot /) +set(CMAKE_SYSROOT ${target_sysroot}) + +# Specify the cross compiler. +set(triple aarch64-linux-gnu) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER clang++) + +set(CMAKE_FIND_ROOT_PATH ${target_sysroot}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/release/get-flutter-versions.sh b/release/get-flutter-versions.sh new file mode 100755 index 00000000..df93af45 --- /dev/null +++ b/release/get-flutter-versions.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash + +set -ex + +CHANNEL=${CHANNEL:-"stable"} +BUILD_DIR=${BUILD_DIR:-"build-embedder"} + +for i; do + case $i in + --build-dir=*) + BUILD_DIR="${i#*=}" + ;; + --channel=*) + CHANNEL="${i#*=}" + ;; + --flutter-rev=*) + FLUTTER_REV="${i#*=}" + CHANNEL="" + ;; + *) + echo "bad option $1" + exit 1 + ;; + esac +done + +install_depot_tools() { + # Get gclient + if [ ! -d depot_tools ]; then + git clone --filter blob:none https://chromium.googlesource.com/chromium/tools/depot_tools.git + fi + export PATH="$PATH:$PWD/depot_tools" +} + +# required for git checkout in flutter repo +install_depot_tools + +mkdir -p "$BUILD_DIR" + +if [ -n "$CHANNEL" ]; then + [ -z "$FLUTTER_REV" ] || exit 1 + # Get flutter engine version + curl -OL "https://raw.githubusercontent.com/flutter/flutter/$CHANNEL/bin/internal/engine.version" + mv engine.version "$BUILD_DIR/embedder.version" + ENGINE_VERSION=$(cat "$BUILD_DIR/embedder.version") + + # Save channel + echo "$CHANNEL" > "$BUILD_DIR/embedder.channel" + + if [ -n "${USE_FLUTTER_SRC_CACHE}" ] && [ -d "$BUILD_DIR/flutter" ] ; then + echo "Using cached flutter source" + else + # Get flutter source code + if ! [ -d "$BUILD_DIR/flutter" ]; then + git clone --filter blob:none https://github.com/flutter/flutter.git "$BUILD_DIR/flutter" + elif ! git -C "$BUILD_DIR/flutter" rev-parse "$ENGINE_VERSION" 2>/dev/null; then + git -C "$BUILD_DIR/flutter" fetch + fi + git -C "$BUILD_DIR/flutter" checkout "$ENGINE_VERSION" + fi + + # Get SDK version + "$BUILD_DIR/flutter/bin/flutter" channel "$CHANNEL" + "$BUILD_DIR/flutter/bin/flutter" upgrade + "$BUILD_DIR/flutter/bin/flutter" --version > "$BUILD_DIR/sdk.version" + git -C "$BUILD_DIR/flutter" rev-parse HEAD > "$BUILD_DIR/flutter.version" + git -C "$BUILD_DIR/flutter" describe --tags >> "$BUILD_DIR/flutter.version" + +elif [ -n "$FLUTTER_REV" ]; then + + # Get flutter source code + if ! [ -d "$BUILD_DIR/flutter" ]; then + git clone --filter blob:none https://github.com/flutter/flutter.git "$BUILD_DIR/flutter" + elif ! git -C "$BUILD_DIR/flutter" rev-parse "$FLUTTER_REV" 2>/dev/null; then + git -C "$BUILD_DIR/flutter" fetch + fi + git -C "$BUILD_DIR/flutter" checkout "$FLUTTER_REV" + + echo "$FLUTTER_REV" > "$BUILD_DIR/flutter.version" + git -C "$BUILD_DIR/flutter" describe --tags >> "$BUILD_DIR/flutter.version" + cat "$BUILD_DIR/flutter/bin/internal/engine.version" > "$BUILD_DIR/embedder.version" + ENGINE_VERSION=$(cat "$BUILD_DIR/embedder.version") + echo user-branch > "$BUILD_DIR/embedder.channel" + + # run twice to fetch engine first (and not have fetch messages in sdk.version file) + "$BUILD_DIR/flutter/bin/flutter" --version + "$BUILD_DIR/flutter/bin/flutter" --version > "$BUILD_DIR/sdk.version" + # fix repo url + sed -i -e 's#unknown source#https://github.com/flutter/flutter.git#' "$BUILD_DIR/sdk.version" +else + echo "set either --channel or --engine" + exit 1 +fi + + +# Confirm version +SDK_VERSION=$(cat "$BUILD_DIR/sdk.version") +SHORT_VERSION=${ENGINE_VERSION:0:10} +if [[ ${SDK_VERSION} != *"${SHORT_VERSION}"* ]]; then + exit 1 +fi diff --git a/release/package-flutter-engine.sh b/release/package-flutter-engine.sh new file mode 100755 index 00000000..f7e2d8ef --- /dev/null +++ b/release/package-flutter-engine.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -ex + +# Example) +# +#./package-flutter-engine.sh --arch=arm64 --build-dir=build-embedder --artifact-dir=. --output-dir=$(pwd) +# + +BUILD_DIR=${BUILD_DIR:-"build-embedder"} +TARGET_ARCH=${TARGET_ARCH:-"x64"} +ARTIFACTS_PATH=${ARTIFACTS_PATH:-"."} +OUTPUT_DIR=${OUTPUT_DIR:-$(pwd)} + +for i; do + case $i in + --arch=*) + TARGET_ARCH="${i#*=}" + ;; + --build-dir=*) + BUILD_DIR="${i#*=}" + ;; + --artifact-dir=*) + ARTIFACTS_PATH="${i#*=}" + ;; + --output-dir=*) + OUTPUT_DIR="${i#*=}" + ;; + esac +done + +ENGINE_ROOT=${BUILD_DIR}/flutter/engine + +if [ ${TARGET_ARCH} = "arm64" ]; then + DEBUG_OUTDIR="linux_debug_unopt_arm64" + PROFILE_OUTDIR="linux_profile_arm64" + RELEASE_OUTDIR="linux_release_arm64" +else + DEBUG_OUTDIR="host_debug_unopt" + PROFILE_OUTDIR="host_profile" + RELEASE_OUTDIR="host_release" +fi + +## common +mkdir deploy_package +if [ ${TARGET_ARCH} = "x64" ]; then + mkdir deploy_package/icu + cp ${ENGINE_ROOT}/src/out/host_debug_unopt/icudtl.dat deploy_package/icu/ + unzip ${ARTIFACTS_PATH}/../common/embedder-common.zip -d deploy_package/ + + cd deploy_package + zip -r elinux-common.zip * + cd .. + mv deploy_package/elinux-common.zip ${OUTPUT_DIR} + rm -rf deploy_package/* +fi + + +## debug mode +cp ${ENGINE_ROOT}/src/out/${DEBUG_OUTDIR}/libflutter_engine.so deploy_package/ +unzip ${ARTIFACTS_PATH}/embedder-${TARGET_ARCH}-debug.zip -d deploy_package/ +zip -jr ${OUTPUT_DIR}/elinux-${TARGET_ARCH}-debug.zip deploy_package/* +rm -rf deploy_package/* + + +## profile mode +cp ${ENGINE_ROOT}/src/out/${PROFILE_OUTDIR}/libflutter_engine.so deploy_package/ +mkdir deploy_package/linux-x64 +if [ ${TARGET_ARCH} = "x64" ]; then + cp ${ENGINE_ROOT}/src/out/${PROFILE_OUTDIR}/gen_snapshot deploy_package/linux-x64/ +else + cp ${ENGINE_ROOT}/src/out/${PROFILE_OUTDIR}/clang_x64/gen_snapshot deploy_package/linux-x64/ +fi + +pushd deploy_package +zip -r elinux-${TARGET_ARCH}-profile.zip * +mv elinux-${TARGET_ARCH}-profile.zip ${OUTPUT_DIR} +popd + +rm -rf deploy_package/* + +## release mode +cp ${ENGINE_ROOT}/src/out/${RELEASE_OUTDIR}/libflutter_engine.so deploy_package/ +mkdir deploy_package/linux-x64 +if [ ${TARGET_ARCH} = "x64" ]; then + cp ${ENGINE_ROOT}/src/out/${RELEASE_OUTDIR}/gen_snapshot deploy_package/linux-x64/ +else + cp ${ENGINE_ROOT}/src/out/${RELEASE_OUTDIR}/clang_x64/gen_snapshot deploy_package/linux-x64/ +fi +unzip ${ARTIFACTS_PATH}/embedder-${TARGET_ARCH}-release.zip -d deploy_package/ + +pushd deploy_package +zip -r elinux-${TARGET_ARCH}-release.zip * +mv elinux-${TARGET_ARCH}-release.zip ${OUTPUT_DIR} +popd + + +rm -rf deploy_package diff --git a/release/prepare-release.sh b/release/prepare-release.sh new file mode 100755 index 00000000..be2b1e08 --- /dev/null +++ b/release/prepare-release.sh @@ -0,0 +1,81 @@ +#!/usr/bin/bash + +error() { + printf "%s\n" "$@" >&2 + exit 1 +} + +print_tag() { + local dir="$1" + + ( + cd "$dir" || exit + [ -e embedder.version ] || error "Missing embedder.version, not a release dir?" + [ -e elinux-arm64-debug.zip ] || error "release incomplete: missing elinux-arm64-debug.zip" + [ -e elinux-arm64-profile.zip ] || error "release incomplete: missing elinux-arm64-profile.zip" + [ -e elinux-arm64-release.zip ] || error "release incomplete: missing elinux-arm64-release.zip" + [ -e elinux-common.zip ] || error "release incomplete: missing elinux-common.zip" + [ -e elinux-x64-debug.zip ] || error "release incomplete: missing elinux-x64-debug.zip" + [ -e elinux-x64-profile.zip ] || error "release incomplete: missing elinux-x64-profile.zip" + [ -e elinux-x64-release.zip ] || error "release incomplete: missing elinux-x64-release.zip" + [ -e embedder.channel ] || error "release incomplete: missing embedder.channel" + [ -e flutter.version ] || error "release incomplete: missing flutter.version" + [ -e sdk.version ] || error "release incomplete: missing sdk.version" + + # check zip files content are sane-ish? not-empty, valid zips? + # For now manually check sizes are in the correct ballpark in below output.. + + ENGINE_VER=$(cat embedder.version) + TAG=${ENGINE_VER:0:10} + + cat < #include #include +#include namespace flutter { diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/message_codec.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/message_codec.h index c84d25f2..c7c20f64 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/message_codec.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/message_codec.h @@ -5,9 +5,11 @@ #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_ #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_ +#include #include #include #include +#include namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc index 3cc932c9..8eee76ea 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc @@ -117,9 +117,9 @@ void TextInputPlugin::HandleMethodCall( const std::string& method = method_call.method_name(); if (method.compare(kShowMethod) == 0) { - delegate_->UpdateVirtualKeyboardStatus(true); + delegate_->UpdateVirtualKeyboardStatus(true, input_type_); } else if (method.compare(kHideMethod) == 0) { - delegate_->UpdateVirtualKeyboardStatus(false); + delegate_->UpdateVirtualKeyboardStatus(false, input_type_); } else if (method.compare(kClearClientMethod) == 0) { active_model_ = nullptr; } else if (method.compare(kSetClientMethod) == 0) { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index fa1fb9e9..05fcf644 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -197,8 +197,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { << "Normal mode is not supported, use fullscreen mode."; view_properties_.view_mode = FlutterDesktopViewMode::kFullscreen; } - view_properties_.width = native_window_->Width(); - view_properties_.height = native_window_->Height(); + view_properties_.width = native_window_->Width() / current_scale_; + view_properties_.height = native_window_->Height() / current_scale_; ELINUX_LOG(INFO) << "Display output resolution: " << view_properties_.width << "x" << view_properties_.height; @@ -249,7 +249,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - void UpdateVirtualKeyboardStatus(const bool show) override { + void UpdateVirtualKeyboardStatus(const bool show, + const std::string& input_type = "") override { // currently not supported. } @@ -393,8 +394,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } if (self->view_properties_.width != width || self->view_properties_.height != height) { - self->view_properties_.width = width; - self->view_properties_.height = height; + self->view_properties_.width = width / self->current_scale_; + self->view_properties_.height = height / self->current_scale_; ELINUX_LOG(INFO) << "Display output resolution: " << self->view_properties_.width << "x" << self->view_properties_.height; @@ -565,8 +566,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnPointerMotion(libinput_event* event) { DetectPointerDevice(event); if (binding_handler_delegate_) { - auto width = view_properties_.width; - auto height = view_properties_.height; + auto width = GetCurrentWidth(); + auto height = GetCurrentHeight(); if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width, height); } @@ -589,8 +590,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerMotionAbsolute(libinput_event* event) { - auto width = view_properties_.width; - auto height = view_properties_.height; + auto width = GetCurrentWidth(); + auto height = GetCurrentHeight(); if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width, height); } @@ -693,8 +694,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnTouchDown(libinput_event* event) { if (binding_handler_delegate_) { - auto width = view_properties_.width; - auto height = view_properties_.height; + auto width = GetCurrentWidth(); + auto height = GetCurrentHeight(); if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width, height); } @@ -719,8 +720,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnTouchMotion(libinput_event* event) { if (binding_handler_delegate_) { - auto width = view_properties_.width; - auto height = view_properties_.height; + auto width = GetCurrentWidth(); + auto height = GetCurrentHeight(); if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width, height); } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 6467bf94..c9fa0400 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1068,6 +1068,7 @@ ELinuxWindowWayland::ELinuxWindowWayland( wl_data_offer_(nullptr), wl_data_source_(nullptr), serial_(0), + text_input_serial_(0), zwp_text_input_manager_v1_(nullptr), zwp_text_input_manager_v3_(nullptr), zwp_text_input_v1_(nullptr), @@ -1505,12 +1506,15 @@ void ELinuxWindowWayland::DestroyRenderSurface() { } } -void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { +void ELinuxWindowWayland::UpdateVirtualKeyboardStatus( + const bool show, + const std::string& input_type) { // Not supported virtual keyboard. if (!(zwp_text_input_v1_ || zwp_text_input_v3_) || seat_inputs_map_.empty()) { return; } + text_input_type_ = input_type; is_requested_show_virtual_keyboard_ = show; if (is_requested_show_virtual_keyboard_) { ShowVirtualKeyboard(); @@ -1869,16 +1873,52 @@ void ELinuxWindowWayland::ShowVirtualKeyboard() { zwp_text_input_v3_enable(zwp_text_input_v3_); zwp_text_input_v3_commit(zwp_text_input_v3_); - zwp_text_input_v3_set_content_type( - zwp_text_input_v3_, ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, - ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL); + // Map Flutter input types to Wayland content purposes. + uint32_t hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE; + uint32_t purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL; + + if (text_input_type_ == "TextInputType.number") { + purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER; + } else if (text_input_type_ == "TextInputType.phone") { + purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE; + } else if (text_input_type_ == "TextInputType.emailAddress") { + purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL; + } else if (text_input_type_ == "TextInputType.url") { + purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL; + } else if (text_input_type_ == "TextInputType.visiblePassword") { + purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PASSWORD; + } else if (text_input_type_ == "TextInputType.multiline") { + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_MULTILINE; + } + + zwp_text_input_v3_set_content_type(zwp_text_input_v3_, hint, purpose); // Untested code path zwp_text_input_v3_commit(zwp_text_input_v3_); } else { if (native_window_) { - zwp_text_input_v1_show_input_panel(zwp_text_input_v1_); + // Map Flutter input types to Wayland v1 content purposes. + uint32_t hint = ZWP_TEXT_INPUT_V1_CONTENT_HINT_NONE; + uint32_t purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL; + + if (text_input_type_ == "TextInputType.number") { + purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER; + } else if (text_input_type_ == "TextInputType.phone") { + purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PHONE; + } else if (text_input_type_ == "TextInputType.emailAddress") { + purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_EMAIL; + } else if (text_input_type_ == "TextInputType.url") { + purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL; + } else if (text_input_type_ == "TextInputType.visiblePassword") { + purpose = ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD; + } else if (text_input_type_ == "TextInputType.multiline") { + hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_MULTILINE; + } + zwp_text_input_v1_activate(zwp_text_input_v1_, seat_inputs_map_.begin()->first, native_window_->Surface()); + zwp_text_input_v1_set_content_type(zwp_text_input_v1_, hint, purpose); + zwp_text_input_v1_commit_state(zwp_text_input_v1_, ++text_input_serial_); + zwp_text_input_v1_show_input_panel(zwp_text_input_v1_); } } } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 8ccb84ba..ec8dce63 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -82,7 +82,8 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void UpdateFlutterCursor(const std::string& cursor_name) override; // |FlutterWindowBindingHandler| - void UpdateVirtualKeyboardStatus(const bool show) override; + void UpdateVirtualKeyboardStatus(const bool show, + const std::string& input_type = "") override; // |FlutterWindowBindingHandler| std::string GetClipboardData() override; @@ -215,6 +216,11 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_data_source* wl_data_source_; uint32_t wl_data_device_manager_version_; uint32_t serial_; + + // The current text input type (e.g., "TextInputType.number"). + std::string text_input_type_; + + uint32_t text_input_serial_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 862c4d64..bfb32662 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -179,7 +179,9 @@ void ELinuxWindowX11::UpdateFlutterCursor(const std::string& cursor_name) { // TODO: implement here } -void ELinuxWindowX11::UpdateVirtualKeyboardStatus(const bool show) { +void ELinuxWindowX11::UpdateVirtualKeyboardStatus( + const bool show, + const std::string& input_type) { // currently not supported. } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index eb11171e..42ec5ad0 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -55,7 +55,8 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { void UpdateFlutterCursor(const std::string& cursor_name) override; // |FlutterWindowBindingHandler| - void UpdateVirtualKeyboardStatus(const bool show) override; + void UpdateVirtualKeyboardStatus(const bool show, + const std::string& input_type = "") override; // |FlutterWindowBindingHandler| std::string GetClipboardData() override; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 34499df8..ae2c7d35 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -70,7 +70,10 @@ class WindowBindingHandler { // Sets the virtual keyboard status when the virtual keyboard needs to be // shown by Flutter events. - virtual void UpdateVirtualKeyboardStatus(const bool show) = 0; + // @param[in] show Whether to show or hide the virtual keyboard. + // @param[in] input_type The Flutter input type (e.g., "TextInputType.number"). + virtual void UpdateVirtualKeyboardStatus(const bool show, + const std::string& input_type = "") = 0; // Returns the clipboard data. virtual std::string GetClipboardData() = 0;