Compare commits

...

129 Commits
main ... 0.28.3

Author SHA1 Message Date
Feodor Fitsner 8d69efec17 Update serious_python dependency override
Enabled the serious_python override with a new git reference 'app-zip-windows-fix' to address issues related to Windows app zipping. Previously, the override was commented out and pointed to 'android-crash-fix'.
2025-12-29 19:53:01 -08:00
Feodor Fitsner 6d3f6dd054 Update serious_python to version 0.9.8
Bumped serious_python dependency from 0.9.6 to 0.9.8 and commented out the previous git override configuration. This ensures the project uses the latest published version of serious_python.
2025-12-22 09:59:04 -08:00
Feodor Fitsner df123d151a Update serious_python to use git dependency
Switched serious_python from version 0.9.6 to a git dependency pointing to the 'android-crash-fix' branch. This change is likely to address specific issues or improvements not available in the published version.
2025-12-10 13:09:15 -08:00
Feodor Fitsner 5232c1cd09 Update serious_python dependency to 0.9.6
Bumped serious_python version from 0.9.2 to 0.9.6 in dependencies and dependency_overrides. Commented out previous git override for serious_python to use the published version.
2025-12-01 16:32:17 -08:00
Feodor Fitsner b4fa882ad0 Switch serious_python dependency to git source
Replaces the serious_python version 0.9.4 with a git dependency pointing to the ios-bundle-id-fix branch. This allows using the latest changes from that branch.
2025-11-16 10:10:07 -08:00
Feodor Fitsner 4a5e2ff2dd Update serious_python dependency to version 0.9.4
Replaces the git-based override for serious_python with the published version 0.9.4 in pubspec.yaml. This simplifies dependency management and ensures compatibility with the latest release.
2025-10-29 13:14:05 -07:00
Feodor Fitsner 424f0921aa Update serious_python dependency to main branch
Changed the serious_python dependency override to use the 'main' branch instead of 'android-16k' for improved stability and access to latest updates.
2025-10-25 09:49:27 -07:00
Feodor Fitsner c81a793fc3
Support 16KB pages for apps targeting Android 15+ (#53)
* Update serious_python dependency ref in pubspec.yaml

Changed the git ref for the serious_python dependency from 'main' to 'android-16k' to use a different branch or commit.

* Update webview_flutter_android to version 4.10.1

Bumped the webview_flutter_android dependency from ^4.0.0 to 4.10.1 in pubspec.yaml to ensure compatibility with the latest features and bug fixes.

* Add conditional override for webview_flutter_android

Introduced a conditional block in pubspec.yaml to override the webview_flutter_android dependency only if 'flet_webview' is present in the dependencies. This improves template flexibility for different dependency configurations.

* Update webview_flutter_android dependency handling

Moved webview_flutter_android to be conditionally included based on the presence of 'flet_webview' in dependencies. Cleaned up commented-out geolocator dependencies.
2025-10-20 10:12:51 -07:00
Feodor Fitsner 992a77781a Update serious_python dependency to main branch
Changed the serious_python dependency override to use the 'main' branch instead of 'hidden-files-fix' for improved stability and alignment with upstream changes.
2025-10-18 16:51:24 -07:00
Feodor Fitsner 2febd14593
Update pubspec.yaml with flet 0.28.3 2025-05-21 14:13:09 -07:00
Feodor Fitsner 16700d5578 flet: 0.28.2 2025-05-10 15:26:17 -07:00
Feodor Fitsner 77a06019fe serious_python with hidden-files-fix 2025-04-10 09:22:11 -07:00
ndonkoHenri f3bb103111 fix typo in AndroidManifest.xml 2025-03-18 18:43:47 +01:00
Feodor Fitsner af83c563d8
Flet 0.27.6 (#45)
* Use serious python from main

* serious_python: 0.9.2, flet 0.27.6
2025-03-11 14:55:59 -07:00
Feodor Fitsner b273f44d6f serious_python: 0.9.1, flet: 0.27.5 2025-03-04 21:39:25 -08:00
Feodor Fitsner e738dd0c87
0.27.4 Android splash and Loading screen (#43)
* Remove splash colors for Android 12

* Set icon_background_color

* Remove icon_background_color

* Splash Screen test

* Fix if

* Splash screen

* get_config_platform()

* Fix package_platform

* Platform-specific splash_screen

* Added trim

* splash_screen_text

* Fix condition

* hide_loading_animation: false

* loading_screen

* Test get_pyproject()

* Declare get_pyproject

* Test my_custom_function

* Test foobar filter

* Fix splash_screen

* Test greeter

* Test context aware function

* Fix get_pyproject

* Remove macros

* Test boot and startup screens

* Fix appBootScreenMessage

* Fix show setting

* Cleanup
2025-03-04 13:52:49 -08:00
Feodor Fitsner f063f13aca
0.27.4 Android ABIs (#44)
* Filter ABIs

* map('string')

* wrap in quotes

* format

* use for
2025-03-03 17:29:52 -08:00
Feodor Fitsner 97910d6a9f flet: 0.27.4 2025-03-03 11:15:26 -08:00
Feodor Fitsner d2198938bc
Added MIMALLOC_LIB (#42) 2025-03-03 09:43:35 -08:00
Feodor Fitsner 18de2d8503
Android minSdkVersion (#41)
* print(flutter.minSdkVersion)

* println

* Test global macros

* Test get_value macro

* Update get_value

* Check cookiecutter.pyproject.tool

* Fix get_value - 1

* Trim white-space

* trim again

* non-existsnt value

* if then

* Check for empty string

* Chec in gradle script

* fix include
2025-02-26 20:49:25 -08:00
Feodor Fitsner af35d4aad3 flet: 0.27.2 2025-02-26 14:05:54 -08:00
Feodor Fitsner 444947a21c macOS fixes for the latest Flutter 3.27 2025-02-26 11:19:58 -08:00
Feodor Fitsner 3ba581d872 Eat another empty line 2025-02-25 10:33:17 -08:00
Feodor Fitsner c13241a5c9 Eat empty line 2025-02-25 10:32:08 -08:00
Feodor Fitsner 2b87de83de Reliably get manifest_application 2025-02-25 10:29:44 -08:00
Feodor Fitsner 7f64dd47f9 Fix cookiecutter.pyproject 2025-02-25 10:25:52 -08:00
Feodor Fitsner 3b88f5e384 Added support for pyproject.tool.flet.android.manifest_application 2025-02-25 10:24:26 -08:00
Feodor Fitsner b0327d5b67 Added pyproject var to template 2025-02-25 10:13:52 -08:00
TheEthicalBoy 504ec17fd6
`flet: 0.27.1` in dependency_overrides 2025-02-23 15:41:39 +01:00
Feodor Fitsner f45821c6af
Create proguard-rules.pro (#40) 2025-02-22 16:12:47 -08:00
Feodor Fitsner 070537e4b0 flet: 0.27.0 2025-02-21 18:59:07 -08:00
Feodor Fitsner 9043b531ab Misc template var fixes for 0.27.0 2025-02-21 16:46:00 -08:00
Feodor Fitsner a49c9f3d86 serious_python: 0.9.0 2025-02-19 17:30:49 -08:00
Feodor Fitsner 2043b4a1cb
for 0.27.0 iOS packaging improved (#39)
* Override serious_python

* Fix yaml

* Manual signing and provisioning profile

* Introduce bundle_id and project_name

* Fix dict checks

* exportOptions.plist

* Output all vars

* Move .vars

* Fix expor options template

* Format template

* Pyodide 0.27.2

* Add teamid

* Added "ios_signing_certificate" var

* serious_python:main

* Fake run script to sign iOS bundle frameworks

* Updated sign script

* Explicitly sign .py files

* Remove custom code signing

* Use serious_python:resources branch

* return to main

* resources branch

* Add build_arch for Android

* Rename build_arch to target_arch

* Fix target_arch def value

* Hide target_arch inside options

* serious_python:main

* .plist to support arrays

* Add closing if

* fix template

* Another template fix

* Remove comments

* macOS plist to support arrays
2025-02-18 15:38:30 -08:00
Feodor Fitsner c99bd8f120
0.26.0 fix for flet-ads and others (#37)
* Relax Flet req

* Flet override
2025-01-27 10:24:48 -08:00
Feodor Fitsner 08844c6e1d Use Flet 0.26.0 2025-01-26 13:13:06 -08:00
Feodor Fitsner a80ff08a9b fix _args list 2025-01-21 13:50:29 -08:00
Feodor Fitsner 29c074847e dependency_overrides.flet 2025-01-21 11:07:08 -08:00
Feodor Fitsner 6a773c37f7 Override webview_flutter_android: ^4.0.0 2025-01-16 10:51:45 -08:00
Feodor Fitsner a090ff82dc
Changes to 0.26.0 (#36)
* serious_python 0.8.4

* flet: 0.25.2

* file_picker: ^8.1.5

* file_picker: 8.1.4

* file_picker: 8.1.5

* file_picker: 8.1.4

* Remove file_picker override

* serious_python 0.8.4

* initialize_ctypes and serious_python 0.8.7 (#34)

* serious_python: 0.8.6

* Added initialize_ctypes override

* serious_python: 0.8.7

* Use Flet package from Git/flutter-extensions

* feodor/flutter-extensions

* Remove NDK, update minSdkVersion

* wakelock_plus: ^1.2.10

* Update gradle.properties

* Changes to 0.26.0-dev (#35)

* Added support for developer mode

* Do not run runPythonApp() in developer mode

* Import crtfifi in try..catch

* Flet ref changed to `main`
2025-01-16 10:01:13 -08:00
Feodor Fitsner d4bb8781d9
serious_python 0.8.3 (#33) 2024-12-04 12:41:42 -08:00
Feodor Fitsner 810cedd458 Merge branch '0.25.0' of https://github.com/flet-dev/flet-build-template into 0.25.0 2024-11-29 16:40:36 -08:00
Feodor Fitsner 7f2e57aa9a flet: 0.25.1 2024-11-29 16:40:35 -08:00
Feodor Fitsner 0d7f36b47c
Fix app close for macOS in 0.25.0 (#31)
* Deep linking settings

* Update web template

* Fix template

* Fix web template again

* Bump dev_dependencies

* Add flutter_bootstrap.js

* Use project_name_slug variable

* web mobile-web-app-capable

* externalNativeBuild

* Remove externalNativeBuild

* serious_python: 0.8.2

* Added sys.argv support

* Pass argv

* pwa_background_color and pwa_theme_color options

* Fix pwa_background_color in template

* Fix pwa_background_color again

* Set default pwa_background_color

* pwa white background

* Use pid for sockets

* Move setupDesktop()

* Update MainFlutterWindow.swift

* Rewrite setupDesktop

* Use windowManager.setSkipTaskbar

* Hide Linux window

* Prevent quit on close

* FLET_HIDE_APP_ON_START

* Default adaptive_icon_background, adaptive_icon_foreground

* FLET_APP_CONSOLE variable

* Add support for android meta-data

* Fix backslash in outLogFilename

* Fix rive_common build on Linux

* Enable logging

* Update AppDelegate.swift

* Enable --debug
2024-11-29 14:31:33 -08:00
Feodor Fitsner 8bcd4e1ee7 Flet 0.25.0 2024-11-28 16:38:22 -08:00
Feodor Fitsner cc5df08f38 Rename FLET_APP_DATA to FLET_APP_STORAGE_DATA 2024-11-26 09:52:37 -08:00
Feodor Fitsner a6f8ef257e
Rive and main.dart fixes for 0.25.0 (#29) 2024-11-25 09:19:39 -08:00
Feodor Fitsner 222dc57a6f
Fix Windows builds for 0.25.0 (#26) 2024-11-08 17:01:10 -08:00
Feodor Fitsner fecd2df8c2
Changes to 0.25.0 (#25)
* Deep linking settings

* Update web template

* Fix template

* Fix web template again

* Bump dev_dependencies

* Add flutter_bootstrap.js

* Use project_name_slug variable

* web mobile-web-app-capable

* externalNativeBuild

* Remove externalNativeBuild

* serious_python: 0.8.2

* Added sys.argv support

* Pass argv

* pwa_background_color and pwa_theme_color options

* Fix pwa_background_color in template

* Fix pwa_background_color again

* Set default pwa_background_color

* pwa white background

* Use pid for sockets

* Move setupDesktop()

* Update MainFlutterWindow.swift

* Rewrite setupDesktop

* Use windowManager.setSkipTaskbar

* Hide Linux window

* Prevent quit on close

* FLET_HIDE_APP_ON_START

* Default adaptive_icon_background, adaptive_icon_foreground

* FLET_APP_CONSOLE variable

* Add support for android meta-data
2024-11-08 09:14:48 -08:00
Feodor Fitsner 893e7d9fd5
Desktop fixes for 0.25.0 (#24)
* Deep linking settings

* Update web template

* Fix template

* Fix web template again

* Bump dev_dependencies

* Add flutter_bootstrap.js

* Use project_name_slug variable

* web mobile-web-app-capable

* externalNativeBuild

* Remove externalNativeBuild

* serious_python: 0.8.2

* Added sys.argv support

* Pass argv

* pwa_background_color and pwa_theme_color options

* Fix pwa_background_color in template

* Fix pwa_background_color again

* Set default pwa_background_color

* pwa white background

* Use pid for sockets

* Move setupDesktop()

* Update MainFlutterWindow.swift

* Rewrite setupDesktop

* Use windowManager.setSkipTaskbar

* Hide Linux window

* Prevent quit on close

* FLET_HIDE_APP_ON_START
2024-11-05 11:29:21 -08:00
Feodor Fitsner 287ee5350f
Changes for 0.25.0 (#23)
* Deep linking settings

* Update web template

* Fix template

* Fix web template again

* Bump dev_dependencies

* Add flutter_bootstrap.js

* Use project_name_slug variable

* web mobile-web-app-capable

* externalNativeBuild

* Remove externalNativeBuild

* serious_python: 0.8.2

* Added sys.argv support

* Pass argv

* pwa_background_color and pwa_theme_color options

* Fix pwa_background_color in template

* Fix pwa_background_color again

* Set default pwa_background_color

* pwa white background
2024-11-05 09:40:08 -08:00
Feodor Fitsner 1a557571ff Set CRYPTOGRAPHY_OPENSSL_NO_LEGACY 2024-10-23 14:09:14 -07:00
Feodor Fitsner 879bc4e2cd
web template updated, `project_name_slug` introduced (#21)
* Deep linking settings

* Update web template

* Fix template

* Fix web template again

* Bump dev_dependencies

* Add flutter_bootstrap.js

* Use project_name_slug variable

* web mobile-web-app-capable
2024-10-15 18:51:15 -07:00
Feodor Fitsner 38c001dd2e serious_python: 0.8.1 2024-10-15 12:49:09 -07:00
Feodor Fitsner 8cf6a6a777 IPHONEOS_DEPLOYMENT_TARGET = 13.0 2024-10-15 09:43:48 -07:00
Feodor Fitsner 2c08be510e Bump iOS to 13.0 2024-10-15 09:37:34 -07:00
Feodor Fitsner 5b00ffb439
For Flet 0.25.0 (#20)
* path to serious_python

* full path to serious_python

* doNotStrip

* change abi filters order

* change order again

* split_per_abi

* make an error in template

* Fix template

* Test info_plist

* info plist complete

* Fix elif

* Another fix

* Another try

* simplify if

* simple test

* no v

* remove everything

* remove other options

* restore infoplist

* equal not is

* one line

* add macos_entitlements

* empty list

* empty array

* macos entitlements

* No hard-coded entitlements

* Android manifest

* Fix manifest

* Fix template again

* Remove hard-coded permissions

* Fix template

* true and false

* remove hard-coded permissions

* Android deep linking

Close #4025

* Template cleanup

* Signing Android builds

* Fix signing options

* Set FLET_APP_DATA and FLET_APP_TEMP dirs for the app

* Pyodide 0.26.2

* serious_python: 0.8.0
2024-10-09 12:18:32 -07:00
Feodor Fitsner 4d4420a369 Pin serious_python and flet packages to 0.7.1 and 0.24.1 2024-10-04 17:32:54 -07:00
Feodor Fitsner a334ffce32 Use Flet 0.24.0 2024-08-31 13:06:35 -07:00
syle 2ef869dcb6
geolocator foreground/background service additions (#19) 2024-08-28 19:16:45 -07:00
syle 751dd24874
Adding Google TV support (#16) 2024-08-06 08:48:19 -07:00
Feodor Fitsner 34c35a5b01 "web" package override 2024-08-05 10:41:14 -07:00
Feodor Fitsner a471e02725 Remove doNotStrip 2024-07-24 20:59:30 +02:00
Feodor Fitsner f8d79be167 Fix packagingOptions. doNotStrip 2024-07-24 20:59:30 +02:00
Feodor Fitsner c3415d600e Disable LLVM stripping of libpythonbundle.so 2024-07-24 20:59:29 +02:00
Feodor Fitsner dd93c8ae6d Disable impeller 2024-07-24 20:59:29 +02:00
Feodor Fitsner b63cdfe089 Remove torch_light override
It should be fixed with torch_light 1.1.0
2024-07-24 20:59:28 +02:00
TheEthicalBoy 73cae4ec99 MacOS: Add more permissions to `DebugProfile.entitlements` 2024-07-24 20:59:28 +02:00
TheEthicalBoy ceaf31531e MacOS: Add more permissions to `Release.entitlements` 2024-07-24 20:59:27 +02:00
TheEthicalBoy fc515f77c5 Add location permission to `Info.plist` 2024-07-24 20:59:27 +02:00
TheEthicalBoy dc8a457647 Add location permissions to `Info.plist` 2024-07-24 20:59:26 +02:00
TheEthicalBoy b5b455d0de Add more Permissions to `AndroidManifest.xml` 2024-07-24 20:59:26 +02:00
Feodor Fitsner 3d0975eb2b Use Flet 0.23.2 2024-07-24 20:59:26 +02:00
Feodor Fitsner c467094581 Squashed commit of the following:
commit 0ab693b566
Author: Feodor Fitsner <feodor@appveyor.com>
Date:   Mon Jun 24 16:15:52 2024 -0700

    Add x86_64 arch
2024-06-24 19:46:52 -07:00
Feodor Fitsner b1c6b15da5
Flet 0.23.1 - disable Impeller, enable legacy packaging, serious_python 0.7.1 (#14)
* serious_python 0.7.1

* useLegacyPackaging true

* Disable impeller

* Remove Flutter test
2024-06-21 13:07:25 -07:00
Feodor Fitsner 652bbfa243
Kotlin 1.9.0, Geolocator bump (#13)
* geolocator: ^12.0.0

* geolocator_android: ^4.6.0

* Kotlin 1.9.0

* Kotlin 1.9.24

* AGP 8.5.0

* Rollback AGP 8.3.1

* torch_light from github

* Add pubspec.lock

* Updated pubspec.lock

* conditional dependencies

* Fix ifs
2024-06-19 22:37:08 -07:00
Feodor Fitsner 6067841b81
Merge pull request #12 from flet-dev/0.23.1-kotlin-1.8
Update Kotlin and NDK for 0.23.1
2024-06-19 17:00:34 -07:00
Feodor Fitsner 24d1a7056e flet: ^0.23.1 2024-06-19 16:54:24 -07:00
Feodor Fitsner a58c6ffa92 ndkVersion "25.1.8937393" 2024-06-19 16:38:03 -07:00
Feodor Fitsner 0ca26dd6b5 ndkVersion "26.3.11579264" 2024-06-19 16:27:40 -07:00
Feodor Fitsner 9c399dfaae Override serious_python_platform_interface 2024-06-19 16:04:30 -07:00
Feodor Fitsner f42393a5ae override serious_python_android only 2024-06-19 16:03:08 -07:00
Feodor Fitsner 6377f131b8 Fix path 2024-06-19 16:01:39 -07:00
Feodor Fitsner 5b39497d20 Use serious_python from github 2024-06-19 16:00:16 -07:00
Feodor Fitsner e7ecd3baff Bump gradle 8.3.1 2024-06-19 15:50:46 -07:00
Feodor Fitsner 6da7a3ae8f record: ^5.1.1 2024-06-19 15:47:48 -07:00
Feodor Fitsner 2eb1727362 Rollback Kotlin version 2024-06-19 15:45:08 -07:00
Feodor Fitsner e7a3ede0ee gradle:8.4.1 2024-06-19 14:54:51 -07:00
Feodor Fitsner 516518871e Kotlin 1.8.21 2024-06-19 14:46:32 -07:00
Feodor Fitsner 6e2e7eebc8 Flet 0.23.0 2024-06-19 14:39:58 -07:00
Feodor Fitsner 1f4cb54e9a Fix crash on Linux 2024-06-19 12:35:26 -07:00
Feodor Fitsner 0178bd5f23 Bump Flet 0.23.1 2024-06-19 11:04:46 -07:00
Feodor Fitsner 0eac4d4c5b
Merge pull request #11 from flet-dev/0.23.0-fix1
Fix dependencies
2024-06-19 10:07:55 -07:00
Feodor Fitsner 4447012691 Override wakelock_plus and package_info_plus deps 2024-06-19 10:04:03 -07:00
Feodor Fitsner 3c41d5cb1c kotlin_version = '1.7.22' 2024-06-19 09:48:44 -07:00
Feodor Fitsner 03d7a63609 Flet 0.23 2024-06-19 09:44:43 -07:00
Feodor Fitsner f1c45f90b4
Merge pull request #10 from flet-dev/impeller
Enable impeller on macOS and Android
2024-06-14 10:18:50 -07:00
TheEthicalBoy 1d28e0fbdb
Merge branch '0.22.1' into impeller 2024-06-14 12:18:14 +02:00
ndonkoHenri b69b87efb3 enable impeller 2024-06-14 12:14:14 +02:00
Feodor Fitsner 1cc0c49f29 minSdkVersion 23 for Android app 2024-06-13 11:52:50 -07:00
Feodor Fitsner 326209fdbf Use Flet 0.22.1 2024-04-30 12:05:58 -07:00
Feodor Fitsner a88b3b8e48 Squashed commit of the following:
commit cb9af5b9a64396835120754eb085a62fcc0b558b
Author: Feodor Fitsner <feodor@appveyor.com>
Date:   Mon Apr 29 11:32:15 2024 -0700

    Add NSMicrophoneUsageDescription to Info.plist
2024-04-29 11:36:46 -07:00
Feodor Fitsner 14a925be08 Fix for apps with numpy on macOS
https://github.com/flet-dev/serious-python/issues/85#issuecomment-2065000974
2024-04-18 12:17:32 -07:00
Feodor Fitsner 9496a9b3de Use Flet 0.22.0 2024-04-12 10:13:59 -07:00
Feodor Fitsner 7bc5081b00 Squashed commit of the following:
commit e8217a057a
Author: Feodor Fitsner <feodor@appveyor.com>
Date:   Mon Mar 11 11:11:48 2024 -0700

    Squashed commit of the following:

    commit 7660adc12c
    Author: Feodor Fitsner <feodor@appveyor.com>
    Date:   Mon Mar 11 11:11:30 2024 -0700

        minSdkVersion 21
2024-03-11 11:12:05 -07:00
Feodor Fitsner e2ab18efdd Use Flet 0.21.2 2024-03-07 08:57:54 -08:00
Feodor Fitsner 0b83309df0 Use Flet 0.21.1 2024-03-06 13:24:17 -08:00
Feodor Fitsner 27a2ec266e Use Flet 0.21.0 2024-03-06 11:04:10 -08:00
Feodor Fitsner 4ffc1adf42 android:label="{{ cookiecutter.product_name }}" 2024-02-20 14:12:50 -08:00
Feodor Fitsner 52d86b3bd3 flet: ^0.20.2 2024-02-17 14:47:05 -08:00
Feodor Fitsner 50c7144fca cupertino_icons: ^1.0.6 2024-02-17 09:47:56 -08:00
Feodor Fitsner 26b3c9a244
Merge pull request #7 from flet-dev/0.20.0-fix1
0.20.1 fixes
2024-02-16 17:39:15 -08:00
Feodor Fitsner d96ce5a571 Use Flet 0.20.1 2024-02-16 17:38:57 -08:00
Feodor Fitsner d48614191d Fix settings.gradle 2024-02-16 12:19:14 -08:00
Feodor Fitsner 5e1d40c94c Remove minSdkVersion 21 2024-02-16 12:16:41 -08:00
Feodor Fitsner a233de7547 Fix type of `createControlFactories` 2024-02-15 10:59:07 -08:00
Feodor Fitsner c25fa1db79 Fix `createControlFactories` 2024-02-14 18:51:11 -08:00
Feodor Fitsner b6b6f3426f
Merge pull request #6 from flet-dev/0.20.0-dev
Flet 0.20.0
2024-02-14 18:07:12 -08:00
Feodor Fitsner bd9285b831 Use Flet 0.20.0 2024-02-14 18:06:36 -08:00
Feodor Fitsner 6c78ea8471 Move ensureInitialized 2024-02-09 12:53:58 -08:00
Feodor Fitsner 2546c20766 {{ dep }}.ensureInitialized() 2024-02-09 12:47:09 -08:00
Feodor Fitsner 5a1fc38804 Pyodide v0.25.0 2024-02-04 09:44:50 -08:00
Feodor Fitsner 52ebf16507 var createControlFactories 2024-01-23 11:19:11 -08:00
Feodor Fitsner 4fa29e6f5d flutter_dependencies didn't work 2024-01-23 10:59:23 -08:00
Feodor Fitsner aadcfb3baa Back flutter_dependencies 2024-01-23 10:57:49 -08:00
Feodor Fitsner 31dca2b5e5 "flutter": null 2024-01-23 10:54:27 -08:00
Feodor Fitsner 417ae1c0c7 Remove from cookiecutter.json 2024-01-23 10:52:58 -08:00
Feodor Fitsner 3d3a54c486 Fix cookiecutter.flutter.dependencies 2024-01-23 10:51:54 -08:00
Feodor Fitsner 438daea208 Add flutter_dependencies 2024-01-23 10:47:34 -08:00
39 changed files with 844 additions and 350 deletions

View File

@ -2,17 +2,31 @@
"out_dir": "", "out_dir": "",
"python_module_name": "main", "python_module_name": "main",
"project_name": "", "project_name": "",
"project_name_slug": "",
"project_description": "", "project_description": "",
"product_name": "{{ cookiecutter.project_name }}", "product_name": "{{ cookiecutter.project_name }}",
"org_name": "com.flet", "org_name": "{{ cookiecutter.org_name if 'org_name' in cookiecutter else 'com.flet' }}",
"company_name": "Your Company", "company_name": "Your Company",
"copyright": "Copyright (c) 2023 Your Company", "copyright": "Copyright (c) 2023 Your Company",
"flutter": null,
"sep": "/", "sep": "/",
"kotlin_dir": "{{ cookiecutter.org_name.replace('.', cookiecutter.sep) }}{{ cookiecutter.sep }}{{ cookiecutter.project_name }}{{ cookiecutter.sep }}", "bundle_id": "{{ cookiecutter.bundle_id if 'bundle_id' in cookiecutter else cookiecutter.org_name + '.' + cookiecutter.project_name_slug }}",
"hide_loading_animation": true, "org_name_2": "{{ cookiecutter.bundle_id.rsplit('.', 1)[0] if 'bundle_id' in cookiecutter else cookiecutter.org_name if 'org_name' in cookiecutter else 'com.flet' }}",
"team_id": "", "ios_provisioning_profile": "",
"ios_export_method": "",
"ios_signing_certificate": "",
"ios_export_options": {},
"ios_team_id": "",
"package_name": "{{ cookiecutter.bundle_id.rsplit('.', 1)[-1].replace('-', '_') if 'bundle_id' in cookiecutter else cookiecutter.project_name }}",
"kotlin_dir": "{{ cookiecutter.org_name_2.replace('.', cookiecutter.sep) }}{{ cookiecutter.sep }}{{ cookiecutter.package_name }}{{ cookiecutter.sep }}",
"base_url": "/", "base_url": "/",
"route_url_strategy": "path", "route_url_strategy": "path",
"web_renderer": "canvaskit", "web_renderer": "canvaskit",
"use_color_emoji": "false" "use_color_emoji": "false",
"pwa_background_color": "#FFFFFF",
"pwa_theme_color": "#0175C2",
"split_per_abi": false,
"options": null,
"pyproject": null,
"_extensions": ["cookiecutter_extensions.FletExtension"]
} }

View File

@ -0,0 +1,22 @@
from jinja2 import pass_context
from jinja2.ext import Extension
class FletExtension(Extension):
def __init__(self, environment):
super(FletExtension, self).__init__(environment)
environment.globals["get_pyproject"] = self.get_pyproject
@pass_context
def get_pyproject(self, context, setting):
pyproject = context.get("cookiecutter", {}).get("pyproject", {})
if not setting:
return pyproject
d = pyproject
for k in setting.split("."):
d = d.get(k)
if d is None:
return None
return d

View File

@ -0,0 +1,3 @@
{% for key, value in cookiecutter.items() -%}
{{ key }}: {{ value }}
{% endfor %}

View File

@ -23,9 +23,18 @@ if (flutterVersionName == null) {
} }
android { android {
namespace "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}" namespace "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
compileSdkVersion flutter.compileSdkVersion compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
packagingOptions {
jniLibs {
useLegacyPackaging true
}
doNotStrip "*/arm64-v8a/libpython*.so"
doNotStrip "*/armeabi-v7a/libpython*.so"
doNotStrip "*/x86/libpython*.so"
doNotStrip "*/x86_64/libpython*.so"
}
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -40,26 +49,51 @@ android {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
{% set min_sdk_version = get_pyproject("tool.flet.android.min_sdk_version") %}
{% set target_sdk_version = get_pyproject("tool.flet.android.target_sdk_version") %}
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
applicationId "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}" minSdkVersion {{ min_sdk_version if min_sdk_version else "flutter.minSdkVersion" }}
// You can update the following values to match your application needs. targetSdkVersion {{ target_sdk_version if target_sdk_version else "flutter.targetSdkVersion" }}
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
println("Gradle build config:")
println(" minSdkVersion: {{ min_sdk_version if min_sdk_version else "$flutter.minSdkVersion" }}")
println(" targetSdkVersion: {{ target_sdk_version if target_sdk_version else "$flutter.targetSdkVersion" }}")
println(" versionCode: $flutter.versionCode")
println(" versionName: $flutter.versionName")
// flet: split_per_abi {% if not cookiecutter.split_per_abi %}
ndk { ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a' {% if cookiecutter.options.target_arch %}
abiFilters {% for arch in cookiecutter.options.target_arch %}'{{ arch }}'{% if not loop.last %}, {% endif %}{% endfor %}
{% else %}
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64'
{% endif %}
}
// flet: end of split_per_abi {% endif %}
}
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfigs {
release {
keyAlias System.getenv('FLET_ANDROID_SIGNING_KEY_ALIAS')
keyPassword System.getenv('FLET_ANDROID_SIGNING_KEY_PASSWORD')
storeFile System.getenv('FLET_ANDROID_SIGNING_KEY_STORE') ? file(System.getenv('FLET_ANDROID_SIGNING_KEY_STORE')) : null
storePassword System.getenv('FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD')
} }
} }
// flet: end of android_signing {% endif %}
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. // flet: android_signing {% if cookiecutter.options.android_signing %}
// Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.release
// {% else %}
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
// flet: end of android_signing {% endif %}
} }
} }
} }

View File

@ -0,0 +1,2 @@
-keep class com.flet.serious_python_android.** { *; }
-keepnames class * { *; }

View File

@ -3,5 +3,6 @@
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest> </manifest>

View File

@ -1,9 +1,24 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/> <!-- flet: permission {% for k, v in cookiecutter.options.android_permissions.items() %} {% if v == True %} -->
<uses-permission android:name="{{ k }}" />
<!-- flet: end of permission {% endif %} {% endfor %} -->
<!-- flet: feature {% for k, v in cookiecutter.options.android_features.items() %} -->
<uses-feature android:name="{{ k }}" android:required="{% if v == True %}true{% else %}false{% endif %}" />
<!-- flet: end of feature {% endfor %} -->
<!-- {% set manifest_application = cookiecutter.pyproject.get('tool', {}).get('flet', {}).get('android', {}).get('manifest_application', {}) %} -->
<application <application
android:label="{{ cookiecutter.project_name }}" android:label="{{ cookiecutter.product_name }}"
android:name="${applicationName}" android:name="${applicationName}"
android:enableOnBackInvokedCallback="true"
{% if manifest_application -%}{% for k, v in cookiecutter.pyproject.tool.flet.android.manifest_application.items() -%}
android:{{ k }}="{{ v }}"
{% endfor -%}{% endif -%}
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<!-- flet: meta-data {% for k, v in cookiecutter.options.android_meta_data.items() %} -->
<meta-data android:name="{{ k }}" android:value="{{ v }}" />
<!-- flet: end of meta-data {% endfor %} -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@ -17,13 +32,24 @@
while the Flutter UI initializes. After that, this theme continues while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"
/> />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" /> <!-- Google TV -->
</intent-filter> </intent-filter>
<!-- flet: deep linking {% if cookiecutter.options.deep_linking.scheme and cookiecutter.options.deep_linking.host %} -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="{{ cookiecutter.options.deep_linking.scheme }}"
android:host="{{ cookiecutter.options.deep_linking.host }}" />
</intent-filter>
<!-- flet: end of deep linking {% endif %} -->
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->

View File

@ -1,4 +1,4 @@
package {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }} package {{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

View File

@ -3,5 +3,6 @@
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest> </manifest>

View File

@ -1,12 +1,11 @@
buildscript { buildscript {
ext.kotlin_version = '1.7.10' ext.kotlin_version = '1.9.24'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }

View File

@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip

View File

@ -10,11 +10,20 @@ pluginManagement {
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins { plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
} }
} }
include ":app" plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.3.1" apply false
}
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" include ":app"

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
platform :ios, '12.0' platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -345,7 +345,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -360,9 +360,16 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{% if cookiecutter.team_id %} {% if cookiecutter.ios_team_id %}
DEVELOPMENT_TEAM = {{ cookiecutter.team_id }}; DEVELOPMENT_TEAM = "{{ cookiecutter.ios_team_id }}";
{% endif %}
{% if cookiecutter.ios_signing_certificate %}
CODE_SIGN_IDENTITY = "{{ cookiecutter.ios_signing_certificate }}";
{% endif %}
{% if cookiecutter.ios_provisioning_profile %}
PROVISIONING_PROFILE_SPECIFIER = "{{ cookiecutter.ios_provisioning_profile }}";
{% endif %} {% endif %}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@ -370,7 +377,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }};
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -387,7 +394,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -405,7 +412,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -421,7 +428,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -475,7 +482,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -524,7 +531,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -541,9 +548,16 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{% if cookiecutter.team_id %} {% if cookiecutter.ios_team_id %}
DEVELOPMENT_TEAM = {{ cookiecutter.team_id }}; DEVELOPMENT_TEAM = "{{ cookiecutter.ios_team_id }}";
{% endif %}
{% if cookiecutter.ios_signing_certificate %}
CODE_SIGN_IDENTITY = "{{ cookiecutter.ios_signing_certificate }}";
{% endif %}
{% if cookiecutter.ios_provisioning_profile %}
PROVISIONING_PROFILE_SPECIFIER = "{{ cookiecutter.ios_provisioning_profile }}";
{% endif %} {% endif %}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@ -551,7 +565,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }};
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -566,9 +580,16 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
{% if cookiecutter.team_id %} {% if cookiecutter.ios_team_id %}
DEVELOPMENT_TEAM = {{ cookiecutter.team_id }}; DEVELOPMENT_TEAM = "{{ cookiecutter.ios_team_id }}";
{% endif %}
{% if cookiecutter.ios_signing_certificate %}
CODE_SIGN_IDENTITY = "{{ cookiecutter.ios_signing_certificate }}";
{% endif %}
{% if cookiecutter.ios_provisioning_profile %}
PROVISIONING_PROFILE_SPECIFIER = "{{ cookiecutter.ios_provisioning_profile }}";
{% endif %} {% endif %}
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@ -576,7 +597,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }};
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

View File

@ -1,7 +1,7 @@
import UIKit import UIKit
import Flutter import Flutter
@UIApplicationMain @main
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
override func application( override func application(
_ application: UIApplication, _ application: UIApplication,

View File

@ -1,49 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>{{ cookiecutter.product_name }}</string> <string>{{ cookiecutter.product_name }}</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>{{ cookiecutter.project_name }}</string> <string>{{ cookiecutter.project_name }}</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true />
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>Main</string>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UISupportedInterfaceOrientations~ipad</key> <key>UISupportedInterfaceOrientations~ipad</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true />
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true />
</dict> <key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true />
</dict>
<!-- flet: deep linking {% if cookiecutter.options.deep_linking.scheme and cookiecutter.options.deep_linking.host%} -->
<key>FlutterDeepLinkingEnabled</key>
<true />
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>{{ cookiecutter.options.deep_linking.host }}</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{{ cookiecutter.options.deep_linking.scheme }}</string>
</array>
</dict>
</array>
<!-- flet: end of deep linking {% endif %} -->
{% macro render_dict(d) -%}
{% for key, value in d.items() -%}
<key>{{ key }}</key>
{% if value is string -%}
<string>{{ value }}</string>
{% elif value is boolean -%}
<{{ "true" if value else "false" }}/>
{% elif value is mapping -%}
<dict>
{{ render_dict(value) }}
</dict>
{% elif value is sequence -%} {# Support for lists/arrays #}
<array>
{% for item in value -%}
{% if item is string -%}
<string>{{ item }}</string>
{% elif item is boolean -%}
<{{ "true" if item else "false" }}/>
{% elif item is mapping -%}
<dict>
{{ render_dict(item) }}
</dict>
{% endif -%}
{% endfor -%}
</array>
{% endif -%}
{% endfor -%}
{% endmacro -%}
{{ render_dict(cookiecutter.options.info_plist) }}
</dict>
</plist> </plist>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>{{ cookiecutter.ios_export_method }}</string>
<key>provisioningProfiles</key>
<dict>
<key>{{ cookiecutter.bundle_id }}</key>
<string>{{ cookiecutter.ios_provisioning_profile }}</string>
</dict>
{% if cookiecutter.ios_team_id %}
<key>teamID</key>
<string>{{ cookiecutter.ios_team_id }}</string>
{% endif %}
{% if cookiecutter.ios_signing_certificate %}
<key>signingCertificate</key>
<string>{{ cookiecutter.ios_signing_certificate }}</string>
{% endif %}
{% macro render_dict(d) -%}
{% for key, value in d.items() -%}
<key>{{ key }}</key>
{% if value is string -%}
<string>{{ value }}</string>
{% elif value is boolean -%}
<{{ "true" if value else "false" }}/>
{% elif value is mapping -%}
<dict>
{{ render_dict(value) }}
</dict>
{% elif value is sequence -%} {# Support for lists/arrays #}
<array>
{% for item in value -%}
{% if item is string -%}
<string>{{ item }}</string>
{% elif item is boolean -%}
<{{ "true" if item else "false" }}/>
{% elif item is mapping -%}
<dict>
{{ render_dict(item) }}
</dict>
{% endif -%}
{% endfor -%}
</array>
{% endif -%}
{% endfor -%}
{% endmacro -%}
{{ render_dict(cookiecutter.ios_export_options) }}
</dict>
</plist>

View File

@ -5,93 +5,79 @@ import 'package:flet/flet.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as path_provider;
import 'package:serious_python/serious_python.dart'; import 'package:serious_python/serious_python.dart';
import 'package:url_strategy/url_strategy.dart'; import 'package:url_strategy/url_strategy.dart';
import 'package:window_manager/window_manager.dart';
import "python.dart";
/*
{% set show_boot_screen = get_pyproject("tool.flet." ~ cookiecutter.options.config_platform ~ ".app.boot_screen.show")
or get_pyproject("tool.flet.app.boot_screen.show")
or False %}
{% set boot_screen_message = get_pyproject("tool.flet." ~ cookiecutter.options.config_platform ~ ".app.boot_screen.message")
or get_pyproject("tool.flet.app.boot_screen.message") %}
{% set show_startup_screen = get_pyproject("tool.flet." ~ cookiecutter.options.config_platform ~ ".app.startup_screen.show")
or get_pyproject("tool.flet.app.startup_screen.show")
or False %}
{% set startup_screen_message = get_pyproject("tool.flet." ~ cookiecutter.options.config_platform ~ ".app.startup_screen.message")
or get_pyproject("tool.flet.app.startup_screen.message") %}
show_boot_screen: {{ show_boot_screen }}
boot_screen_message: {{ boot_screen_message }}
show_startup_screen: {{ show_startup_screen }}
startup_screen_message: {{ startup_screen_message }}
*/
{% for dep in cookiecutter.flutter.dependencies %}
import 'package:{{ dep }}/{{ dep }}.dart' as {{ dep }};
{% endfor %}
const bool isProduction = bool.fromEnvironment('dart.vm.product'); const bool isProduction = bool.fromEnvironment('dart.vm.product');
const assetPath = "app/app.zip"; const assetPath = "app/app.zip";
const pythonModuleName = "{{ cookiecutter.python_module_name }}"; const pythonModuleName = "{{ cookiecutter.python_module_name }}";
final hideLoadingPage = final showAppBootScreen = bool.tryParse("{{ show_boot_screen }}".toLowerCase()) ?? false;
bool.tryParse("{{ cookiecutter.hide_loading_animation }}".toLowerCase()) ?? const appBootScreenMessage = '{{ boot_screen_message | default("Preparing the app for its first launch…", true) }}';
true; final showAppStartupScreen = bool.tryParse("{{ show_startup_screen }}".toLowerCase()) ?? false;
const outLogFilename = "out.log"; const appStartupScreenMessage = '{{ startup_screen_message | default("Getting things ready…", true) }}';
const errorExitCode = 100;
const pythonScript = """ List<CreateControlFactory> createControlFactories = [
import certifi, os, runpy, socket, sys, traceback {% for dep in cookiecutter.flutter.dependencies %}
{{ dep }}.createControl,
{% endfor %}
];
os.environ["REQUESTS_CA_BUNDLE"] = certifi.where() String outLogFilename = "";
os.environ["SSL_CERT_FILE"] = certifi.where()
if os.getenv("FLET_PLATFORM") == "android":
import ssl
def create_default_context(
purpose=ssl.Purpose.SERVER_AUTH, *, cafile=None, capath=None, cadata=None
):
return ssl.create_default_context(
purpose=purpose, cafile=certifi.where(), capath=capath, cadata=cadata
)
ssl._create_default_https_context = create_default_context
out_file = open("$outLogFilename", "w+", buffering=1)
callback_socket_addr = os.environ.get("FLET_PYTHON_CALLBACK_SOCKET_ADDR")
if ":" in callback_socket_addr:
addr, port = callback_socket_addr.split(":")
callback_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
callback_socket.connect((addr, int(port)))
else:
callback_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
callback_socket.connect(callback_socket_addr)
sys.stdout = sys.stderr = out_file
def flet_exit(code=0):
callback_socket.sendall(str(code).encode())
out_file.close()
callback_socket.close()
sys.exit = flet_exit
ex = None
try:
runpy.run_module("{module_name}", run_name="__main__")
except Exception as e:
ex = e
traceback.print_exception(e)
sys.exit(0 if ex is None else $errorExitCode)
""";
// global vars // global vars
List<String> _args = [];
String pageUrl = ""; String pageUrl = "";
String assetsDir = ""; String assetsDir = "";
String appDir = ""; String appDir = "";
Map<String, String> environmentVariables = {}; Map<String, String> environmentVariables = {};
void main() async { void main(List<String> args) async {
if (isProduction) { _args = List<String>.from(args);
// ignore: avoid_returning_null_for_void
debugPrint = (String? message, {int? wrapWidth}) => null;
}
runApp(FutureBuilder( runApp(FutureBuilder(
future: prepareApp(), future: prepareApp(),
builder: (BuildContext context, AsyncSnapshot snapshot) { builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
// OK - start Python program // OK - start Python program
return kIsWeb return kIsWeb || (isDesktopPlatform() && _args.isNotEmpty)
? FletApp( ? FletApp(
pageUrl: pageUrl, pageUrl: pageUrl,
assetsDir: assetsDir, assetsDir: assetsDir,
hideLoadingPage: hideLoadingPage, showAppStartupScreen: showAppStartupScreen,
) appStartupScreenMessage: appStartupScreenMessage,
createControlFactories: createControlFactories)
: FutureBuilder( : FutureBuilder(
future: runPythonApp(), future: runPythonApp(args),
builder: builder:
(BuildContext context, AsyncSnapshot<String?> snapshot) { (BuildContext context, AsyncSnapshot<String?> snapshot) {
if (snapshot.hasData || snapshot.hasError) { if (snapshot.hasData || snapshot.hasError) {
@ -104,10 +90,11 @@ void main() async {
} else { } else {
// no result of error // no result of error
return FletApp( return FletApp(
pageUrl: pageUrl, pageUrl: pageUrl,
assetsDir: assetsDir, assetsDir: assetsDir,
hideLoadingPage: hideLoadingPage, showAppStartupScreen: showAppStartupScreen,
); appStartupScreenMessage: appStartupScreenMessage,
createControlFactories: createControlFactories);
} }
}); });
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
@ -118,12 +105,25 @@ void main() async {
text: snapshot.error.toString())); text: snapshot.error.toString()));
} else { } else {
// loading // loading
return const MaterialApp(home: BlankScreen()); return MaterialApp(home: showAppBootScreen ? const BootScreen() : const BlankScreen());
} }
})); }));
} }
Future prepareApp() async { Future prepareApp() async {
if (!_args.contains("--debug")) {
// ignore: avoid_returning_null_for_void
debugPrint = (String? message, {int? wrapWidth}) => null;
} else {
_args.remove("--debug");
}
await setupDesktop();
{% for dep in cookiecutter.flutter.dependencies %}
{{ dep }}.ensureInitialized();
{% endfor %}
if (kIsWeb) { if (kIsWeb) {
// web mode - connect via HTTP // web mode - connect via HTTP
pageUrl = Uri.base.toString(); pageUrl = Uri.base.toString();
@ -131,9 +131,22 @@ Future prepareApp() async {
if (routeUrlStrategy == "path") { if (routeUrlStrategy == "path") {
setPathUrlStrategy(); setPathUrlStrategy();
} }
} else if (_args.isNotEmpty && isDesktopPlatform()) {
// developer mode
debugPrint("Flet app is running in Developer mode");
pageUrl = _args[0];
if (_args.length > 1) {
var pidFilePath = _args[1];
debugPrint("Args contain a path to PID file: $pidFilePath}");
var pidFile = await File(pidFilePath).create();
await pidFile.writeAsString("$pid");
}
if (_args.length > 2) {
assetsDir = _args[2];
debugPrint("Args contain a path assets directory: $assetsDir}");
}
} else { } else {
await setupDesktop(); // production mode
// extract app from asset // extract app from asset
appDir = await extractAssetZip(assetPath, checkHash: true); appDir = await extractAssetZip(assetPath, checkHash: true);
@ -142,6 +155,29 @@ Future prepareApp() async {
assetsDir = path.join(appDir, "assets"); assetsDir = path.join(appDir, "assets");
// configure apps DATA and TEMP directories
WidgetsFlutterBinding.ensureInitialized();
var appTempPath = (await path_provider.getApplicationCacheDirectory()).path;
var appDataPath =
(await path_provider.getApplicationDocumentsDirectory()).path;
if (defaultTargetPlatform != TargetPlatform.iOS &&
defaultTargetPlatform != TargetPlatform.android) {
// append app name to the path and create dir
PackageInfo packageInfo = await PackageInfo.fromPlatform();
appDataPath = path.join(appDataPath, "flet", packageInfo.packageName);
if (!await Directory(appDataPath).exists()) {
await Directory(appDataPath).create(recursive: true);
}
}
environmentVariables["FLET_APP_STORAGE_DATA"] = appDataPath;
environmentVariables["FLET_APP_STORAGE_TEMP"] = appTempPath;
outLogFilename = path.join(appTempPath, "console.log");
environmentVariables["FLET_APP_CONSOLE"] = outLogFilename;
environmentVariables["FLET_PLATFORM"] = environmentVariables["FLET_PLATFORM"] =
defaultTargetPlatform.name.toLowerCase(); defaultTargetPlatform.name.toLowerCase();
@ -152,7 +188,7 @@ Future prepareApp() async {
environmentVariables["FLET_SERVER_PORT"] = tcpPort.toString(); environmentVariables["FLET_SERVER_PORT"] = tcpPort.toString();
} else { } else {
// use UDS on other platforms // use UDS on other platforms
pageUrl = "flet.sock"; pageUrl = "flet_$pid.sock";
environmentVariables["FLET_SERVER_UDS_PATH"] = pageUrl; environmentVariables["FLET_SERVER_UDS_PATH"] = pageUrl;
} }
} }
@ -160,8 +196,13 @@ Future prepareApp() async {
return ""; return "";
} }
Future<String?> runPythonApp() async { Future<String?> runPythonApp(List<String> args) async {
var script = pythonScript.replaceAll('{module_name}', pythonModuleName); var argvItems = args.map((a) => "\"${a.replaceAll('"', '\\"')}\"");
var argv = "[${argvItems.isNotEmpty ? argvItems.join(',') : '""'}]";
var script = pythonScript
.replaceAll("{outLogFilename}", outLogFilename.replaceAll("\\", "\\\\"))
.replaceAll('{module_name}', pythonModuleName)
.replaceAll('{argv}', argv);
var completer = Completer<String>(); var completer = Completer<String>();
@ -176,7 +217,7 @@ Future<String?> runPythonApp() async {
'Python output TCP Server is listening on port ${outSocketServer.port}'); 'Python output TCP Server is listening on port ${outSocketServer.port}');
socketAddr = "$tcpAddr:${outSocketServer.port}"; socketAddr = "$tcpAddr:${outSocketServer.port}";
} else { } else {
socketAddr = "stdout.sock"; socketAddr = "stdout_$pid.sock";
if (await File(socketAddr).exists()) { if (await File(socketAddr).exists()) {
await File(socketAddr).delete(); await File(socketAddr).delete();
} }
@ -275,6 +316,34 @@ class ErrorScreen extends StatelessWidget {
} }
} }
class BootScreen extends StatelessWidget {
const BootScreen({
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 30,
height: 30,
child: CircularProgressIndicator(strokeWidth: 3),
),
const SizedBox(
height: 10,
),
Text(appBootScreenMessage, style: Theme.of(context).textTheme.bodySmall,)
],
),
),
);
}
}
class BlankScreen extends StatelessWidget { class BlankScreen extends StatelessWidget {
const BlankScreen({ const BlankScreen({
super.key, super.key,
@ -295,3 +364,25 @@ Future<int> getUnusedPort() {
return port; return port;
}); });
} }
Future setupDesktop() async {
if (isDesktopPlatform()) {
WidgetsFlutterBinding.ensureInitialized();
await windowManager.ensureInitialized();
Map<String, String> env = Platform.environment;
var hideWindowOnStart = env["FLET_HIDE_WINDOW_ON_START"];
var hideAppOnStart = env["FLET_HIDE_APP_ON_START"];
debugPrint("hideWindowOnStart: $hideWindowOnStart");
debugPrint("hideAppOnStart: $hideAppOnStart");
await windowManager.waitUntilReadyToShow(null, () async {
if (hideWindowOnStart == null && hideAppOnStart == null) {
await windowManager.show();
await windowManager.focus();
} else if (hideAppOnStart != null) {
await windowManager.setSkipTaskbar(true);
}
});
}
}

View File

@ -0,0 +1,104 @@
const errorExitCode = 100;
const pythonScript = """
import os, runpy, socket, sys, traceback
# fix for cryptography package
os.environ["CRYPTOGRAPHY_OPENSSL_NO_LEGACY"] = "1"
# fix for: https://github.com/flet-dev/serious-python/issues/85#issuecomment-2065000974
os.environ["OPENBLAS_NUM_THREADS"] = "1"
def initialize_ctypes():
import ctypes.util
import os
import pathlib
import sys
android_native_lib_dir = os.getenv("ANDROID_NATIVE_LIBRARY_DIR")
def find_library_override_imp(name: str):
if name is None:
return None
if pathlib.Path(name).exists():
return name
if sys.platform == "ios":
for lf in [
f"Frameworks/{name}.framework/{name}",
f"Frameworks/lib{name}.framework/lib{name}",
]:
lib_path = pathlib.Path(sys.executable).parent.joinpath(lf)
if lib_path.exists():
return str(lib_path)
elif android_native_lib_dir:
for lf in [f"lib{name}.so", f"{name}.so", name]:
lib_path = pathlib.Path(android_native_lib_dir).joinpath(lf)
if lib_path.exists():
return str(lib_path)
return None
find_library_original = ctypes.util.find_library
def find_library_override(name):
return find_library_override_imp(name) or find_library_original(name)
ctypes.util.find_library = find_library_override
CDLL_init_original = ctypes.CDLL.__init__
def CDLL_init_override(self, name, *args, **kwargs):
CDLL_init_original(
self, find_library_override_imp(name) or name, *args, **kwargs
)
ctypes.CDLL.__init__ = CDLL_init_override
initialize_ctypes()
out_file = open("{outLogFilename}", "w+", buffering=1)
callback_socket_addr = os.getenv("FLET_PYTHON_CALLBACK_SOCKET_ADDR")
if ":" in callback_socket_addr:
addr, port = callback_socket_addr.split(":")
callback_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
callback_socket.connect((addr, int(port)))
else:
callback_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
callback_socket.connect(callback_socket_addr)
sys.stdout = sys.stderr = out_file
def flet_exit(code=0):
callback_socket.sendall(str(code).encode())
out_file.close()
callback_socket.close()
sys.exit = flet_exit
ex = None
try:
import certifi
os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
os.environ["SSL_CERT_FILE"] = certifi.where()
if os.getenv("FLET_PLATFORM") == "android":
import ssl
def create_default_context(
purpose=ssl.Purpose.SERVER_AUTH, *, cafile=None, capath=None, cadata=None
):
return ssl.create_default_context(
purpose=purpose, cafile=certifi.where(), capath=capath, cadata=cadata
)
ssl._create_default_https_context = create_default_context
sys.argv = {argv}
runpy.run_module("{module_name}", run_name="__main__")
except Exception as e:
ex = e
traceback.print_exception(e)
sys.exit(0 if ex is None else 100)
""";

View File

@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
set(BINARY_NAME "{{ cookiecutter.project_name }}") set(BINARY_NAME "{{ cookiecutter.project_name }}")
# The unique GTK application identifier for this application. See: # The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID # https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}") set(APPLICATION_ID "{{ cookiecutter.bundle_id }}")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake. # versions of CMake.
@ -41,7 +41,7 @@ endif()
# of modifying this function. # of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET) function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE -Wall -Werror -Wno-unused-variable -Wno-unused-function)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>") target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>") target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction() endfunction()
@ -73,6 +73,7 @@ apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here. # Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
target_link_libraries(${BINARY_NAME} PRIVATE ${MIMALLOC_LIB})
# Run the Flutter tool portions of the build. This must not be removed. # Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble) add_dependencies(${BINARY_NAME} flutter_assemble)
@ -138,6 +139,12 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
endif() endif()
endforeach(plugin) endforeach(plugin)
# Copy the native assets provided by the build.dart from all packages.
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
# Fully re-copy the assets directory on each build to avoid having stale files # Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install. # from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets") set(FLUTTER_ASSET_DIR_NAME "flutter_assets")

View File

@ -6,20 +6,20 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <audioplayers_linux/audioplayers_linux_plugin.h> #include <record_linux/record_linux_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <serious_python_linux/serious_python_linux_plugin.h> #include <serious_python_linux/serious_python_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
#include <window_to_front/window_to_front_plugin.h> #include <window_to_front/window_to_front_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = g_autoptr(FlPluginRegistrar) record_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin");
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); record_linux_plugin_register_with_registrar(record_linux_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_registrar = g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
g_autoptr(FlPluginRegistrar) serious_python_linux_registrar = g_autoptr(FlPluginRegistrar) serious_python_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SeriousPythonLinuxPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "SeriousPythonLinuxPlugin");
serious_python_linux_plugin_register_with_registrar(serious_python_linux_registrar); serious_python_linux_plugin_register_with_registrar(serious_python_linux_registrar);

View File

@ -3,8 +3,8 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_linux record_linux
screen_retriever screen_retriever_linux
serious_python_linux serious_python_linux
url_launcher_linux url_launcher_linux
window_manager window_manager

View File

@ -7,19 +7,17 @@
#include "flutter/generated_plugin_registrant.h" #include "flutter/generated_plugin_registrant.h"
struct _MyApplication struct _MyApplication {
{
GtkApplication parent_instance; GtkApplication parent_instance;
char **dart_entrypoint_arguments; char** dart_entrypoint_arguments;
}; };
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate. // Implements GApplication::activate.
static void my_application_activate(GApplication *application) static void my_application_activate(GApplication* application) {
{ MyApplication* self = MY_APPLICATION(application);
MyApplication *self = MY_APPLICATION(application); GtkWindow* window =
GtkWindow *window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used // Use a header bar when running in GNOME as this is the common style used
@ -31,36 +29,31 @@ static void my_application_activate(GApplication *application)
// if future cases occur). // if future cases occur).
gboolean use_header_bar = TRUE; gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
GdkScreen *screen = gtk_window_get_screen(window); GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) if (GDK_IS_X11_SCREEN(screen)) {
{ const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
const gchar *wm_name = gdk_x11_screen_get_window_manager_name(screen); if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
if (g_strcmp0(wm_name, "GNOME Shell") != 0)
{
use_header_bar = FALSE; use_header_bar = FALSE;
} }
} }
#endif #endif
if (use_header_bar) if (use_header_bar) {
{ GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar)); gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "{{ cookiecutter.product_name }}"); gtk_header_bar_set_title(header_bar, "{{ cookiecutter.product_name }}");
gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} } else {
else
{
gtk_window_set_title(window, "{{ cookiecutter.product_name }}"); gtk_window_set_title(window, "{{ cookiecutter.product_name }}");
} }
gtk_window_set_default_size(window, 1280, 720); gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window)); gtk_widget_realize(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView *view = fl_view_new(project); FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view)); gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
@ -70,18 +63,16 @@ static void my_application_activate(GApplication *application)
} }
// Implements GApplication::local_command_line. // Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication *application, gchar ***arguments, int *exit_status) static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
{ MyApplication* self = MY_APPLICATION(application);
MyApplication *self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name. // Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr; g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) if (!g_application_register(application, nullptr, &error)) {
{ g_warning("Failed to register: %s", error->message);
g_warning("Failed to register: %s", error->message); *exit_status = 1;
*exit_status = 1; return TRUE;
return TRUE;
} }
g_application_activate(application); g_application_activate(application);
@ -90,25 +81,42 @@ static gboolean my_application_local_command_line(GApplication *application, gch
return TRUE; return TRUE;
} }
// Implements GApplication::startup.
static void my_application_startup(GApplication* application) {
//MyApplication* self = MY_APPLICATION(object);
// Perform any actions required at application startup.
G_APPLICATION_CLASS(my_application_parent_class)->startup(application);
}
// Implements GApplication::shutdown.
static void my_application_shutdown(GApplication* application) {
//MyApplication* self = MY_APPLICATION(object);
// Perform any actions required at application shutdown.
G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application);
}
// Implements GObject::dispose. // Implements GObject::dispose.
static void my_application_dispose(GObject *object) static void my_application_dispose(GObject* object) {
{ MyApplication* self = MY_APPLICATION(object);
MyApplication *self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object); G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
} }
static void my_application_class_init(MyApplicationClass *klass) static void my_application_class_init(MyApplicationClass* klass) {
{
G_APPLICATION_CLASS(klass)->activate = my_application_activate; G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_APPLICATION_CLASS(klass)->startup = my_application_startup;
G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose; G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
} }
static void my_application_init(MyApplication *self) {} static void my_application_init(MyApplication* self) {}
MyApplication *my_application_new() MyApplication* my_application_new() {
{
return MY_APPLICATION(g_object_new(my_application_get_type(), return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID, "application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE, "flags", G_APPLICATION_NON_UNIQUE,

View File

@ -5,24 +5,26 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import audioplayers_darwin
import package_info_plus import package_info_plus
import path_provider_foundation import path_provider_foundation
import screen_retriever import record_darwin
import screen_retriever_macos
import serious_python_darwin import serious_python_darwin
import shared_preferences_foundation import shared_preferences_foundation
import url_launcher_macos import url_launcher_macos
import wakelock_plus
import window_manager import window_manager
import window_to_front import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) RecordPlugin.register(with: registry.registrar(forPlugin: "RecordPlugin"))
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
SeriousPythonPlugin.register(with: registry.registrar(forPlugin: "SeriousPythonPlugin")) SeriousPythonPlugin.register(with: registry.registrar(forPlugin: "SeriousPythonPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin")) WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin"))
} }

View File

@ -226,8 +226,9 @@
33CC10E52044A3C60003C045 /* Project object */ = { 33CC10E52044A3C60003C045 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0920; LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1430; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
331C80D4294CF70F00263BE5 = { 331C80D4294CF70F00263BE5 = {
@ -384,7 +385,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}";
@ -398,7 +399,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}";
@ -412,7 +413,7 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{ cookiecutter.project_name }}.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/{{ cookiecutter.project_name }}";
@ -424,6 +425,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -447,9 +449,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -497,6 +501,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -520,9 +525,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
@ -550,6 +557,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -573,9 +581,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;

View File

@ -1,9 +1,13 @@
import Cocoa import Cocoa
import FlutterMacOS import FlutterMacOS
@NSApplicationMain @main
class AppDelegate: FlutterAppDelegate { class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true return true
} }
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
} }

View File

@ -8,7 +8,7 @@
PRODUCT_NAME = {{ cookiecutter.product_name }} PRODUCT_NAME = {{ cookiecutter.product_name }}
// The application's bundle identifier // The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }} PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.bundle_id }}
// The copyright displayed in application information // The copyright displayed in application information
PRODUCT_COPYRIGHT = {{ cookiecutter.copyright }}. All rights reserved. PRODUCT_COPYRIGHT = {{ cookiecutter.copyright }}. All rights reserved.

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.app-sandbox</key> <!-- flet: entitlement {% for k, v in cookiecutter.options.macos_entitlements.items() %} -->
<false/> <key>{{ k }}</key>
<key>com.apple.security.cs.allow-jit</key> <!-- flet: True {% if v == True %} -->
<true/> <true />
<key>com.apple.security.network.server</key> <!-- flet: False {% elif v == False %} -->
<true/> <false />
</dict> <!-- flet: end of entitlement {% endif %} {% endfor %} -->
</dict>
</plist> </plist>

View File

@ -1,32 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string></string> <string></string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string> <string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>$(PRODUCT_COPYRIGHT)</string> <string>$(PRODUCT_COPYRIGHT)</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
</dict>
{% macro render_dict(d) -%}
{% for key, value in d.items() -%}
<key>{{ key }}</key>
{% if value is string -%}
<string>{{ value }}</string>
{% elif value is boolean -%}
<{{ "true" if value else "false" }}/>
{% elif value is mapping -%}
<dict>
{{ render_dict(value) }}
</dict>
{% elif value is sequence -%} {# Support for lists/arrays #}
<array>
{% for item in value -%}
{% if item is string -%}
<string>{{ item }}</string>
{% elif item is boolean -%}
<{{ "true" if item else "false" }}/>
{% elif item is mapping -%}
<dict>
{{ render_dict(item) }}
</dict>
{% endif -%}
{% endfor -%}
</array>
{% endif -%}
{% endfor -%}
{% endmacro -%}
{{ render_dict(cookiecutter.options.info_plist) }}
</dict>
</plist> </plist>

View File

@ -1,5 +1,6 @@
import Cocoa import Cocoa
import FlutterMacOS import FlutterMacOS
import window_manager
class MainFlutterWindow: NSWindow { class MainFlutterWindow: NSWindow {
override func awakeFromNib() { override func awakeFromNib() {
@ -12,4 +13,9 @@ class MainFlutterWindow: NSWindow {
super.awakeFromNib() super.awakeFromNib()
} }
override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
super.order(place, relativeTo: otherWin)
hiddenWindowAtLaunch()
}
} }

View File

@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.app-sandbox</key> <!-- flet: entitlement {% for k, v in cookiecutter.options.macos_entitlements.items() %} -->
<false/> <key>{{ k }}</key>
</dict> <!-- flet: True {% if v == True %} -->
<true />
<!-- flet: False {% elif v == False %} -->
<false />
<!-- flet: end of entitlement {% endif %} {% endfor %} -->
</dict>
</plist> </plist>

View File

@ -1,5 +1,5 @@
name: {{ cookiecutter.project_name.replace("-", "_") }} name: '{{ cookiecutter.project_name }}'
description: {{ cookiecutter.project_description }} description: '{{ cookiecutter.project_description }}'
publish_to: 'none' publish_to: 'none'
version: 1.0.0+1 version: 1.0.0+1
@ -11,30 +11,47 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
serious_python: ^0.7.0 serious_python: 0.9.8
# serious_python:
# git: path: ^1.9.0
# url: https://github.com/flet-dev/serious-python url_strategy: ^0.2.0
# path: src/serious_python cupertino_icons: ^1.0.6
# ref: 'd059aef' path_provider: ^2.1.4
package_info_plus: ^8.0.2
window_manager: ^0.4.3
dependency_overrides:
flet: 0.28.3
flet: ^0.19.0
# flet: # flet:
# git: # git:
# path: packages/flet
# ref: feodor/flet-0-27-5-fixes
# url: https://github.com/flet-dev/flet.git # url: https://github.com/flet-dev/flet.git
# path: package
# ref: '37b9581'
path: ^1.8.3 # serious_python: 0.9.6
url_strategy: ^0.2.0
cupertino_icons: ^1.0.2 serious_python:
git:
url: https://github.com/flet-dev/serious-python.git
ref: app-zip-windows-fix
path: src/serious_python
wakelock_plus: ^1.2.10
web: ^1.0.0
window_manager: ^0.4.3
# {% if 'flet_webview' in cookiecutter.flutter.dependencies %}
webview_flutter_android: 4.10.1
# {% endif %}
# {% if 'flet_audio_recorder' in cookiecutter.flutter.dependencies %}
record: ^5.1.1
# {% endif %}
dev_dependencies: dev_dependencies:
flutter_test: flutter_launcher_icons: ^0.14.1
sdk: flutter flutter_native_splash: ^2.4.1
flutter_launcher_icons: "^0.13.1"
flutter_native_splash: ^2.3.6
flutter_lints: ^2.0.0 flutter_lints: ^2.0.0
flutter: flutter:
@ -51,6 +68,8 @@ flutter_launcher_icons:
android: true android: true
image_path_android: "images/icon.png" image_path_android: "images/icon.png"
adaptive_icon_background: '#ffffff'
adaptive_icon_foreground: images/icon.png
ios: true ios: true
image_path_ios: "images/icon.png" image_path_ios: "images/icon.png"
@ -102,14 +121,10 @@ flutter_native_splash:
# 768 pixels in diameter. # 768 pixels in diameter.
image: "images/icon.png" image: "images/icon.png"
# Splash screen background color.
color: "#ffffff"
# The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that # The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
# apply when the device is in dark mode. If they are not specified, the app will use the # apply when the device is in dark mode. If they are not specified, the app will use the
# parameters from above. # parameters from above.
image_dark: "images/icon.png" image_dark: "images/icon.png"
color_dark: "#333333"
# The android, ios and web parameters can be used to disable generating a splash screen on a given # The android, ios and web parameters can be used to disable generating a splash screen on a given
# platform. # platform.

View File

@ -0,0 +1,12 @@
{{ '{{flutter_js}}' }}
{{ '{{flutter_build_config}}' }}
_flutter.loader.load({
serviceWorkerSettings: {
serviceWorkerVersion: {{ '{{flutter_service_worker_version}}' }},
},
onEntrypointLoaded: async function (engineInitializer) {
const appRunner = await engineInitializer.initializeEngine({useColorEmoji: useColorEmoji});
await appRunner.runApp();
}
});

View File

@ -2,27 +2,13 @@
<html> <html>
<head> <head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="{{ cookiecutter.base_url }}"> <base href="{{ cookiecutter.base_url }}">
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="{{ cookiecutter.project_description }}"> <meta name="description" content="{{ cookiecutter.project_description }}">
<!-- iOS meta tags & icons --> <!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="{{ cookiecutter.product_name }}"> <meta name="apple-mobile-web-app-title" content="{{ cookiecutter.product_name }}">
<link rel="apple-touch-icon" href="icons/Icon-192.png"> <link rel="apple-touch-icon" href="icons/Icon-192.png">
@ -44,34 +30,10 @@
</script> </script>
<script src="python.js"></script> <script src="python.js"></script>
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head> </head>
<body> <body>
<script> <script src="flutter_bootstrap.js" async></script>
window.addEventListener('load', function (ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: function (engineInitializer) {
engineInitializer.initializeEngine({
renderer: webRenderer,
useColorEmoji: useColorEmoji,
}).then(function (appRunner) {
appRunner.runApp();
});
}
});
});
</script>
</body> </body>
</html> </html>

View File

@ -3,8 +3,8 @@
"short_name": "{{ cookiecutter.project_name }}", "short_name": "{{ cookiecutter.project_name }}",
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"background_color": "#0175C2", "background_color": "{{ cookiecutter.pwa_background_color }}",
"theme_color": "#0175C2", "theme_color": "{{ cookiecutter.pwa_theme_color }}",
"description": "{{ cookiecutter.project_description }}", "description": "{{ cookiecutter.project_description }}",
"orientation": "portrait-primary", "orientation": "portrait-primary",
"prefer_related_applications": false, "prefer_related_applications": false,

View File

@ -1,4 +1,4 @@
importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"); importScripts("https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js");
self.pythonModuleName = null; self.pythonModuleName = null;
self.initialized = false; self.initialized = false;

View File

@ -6,18 +6,18 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <audioplayers_windows/audioplayers_windows_plugin.h> #include <record_windows/record_windows_plugin_c_api.h>
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <serious_python_windows/serious_python_windows_plugin_c_api.h> #include <serious_python_windows/serious_python_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
#include <window_to_front/window_to_front_plugin.h> #include <window_to_front/window_to_front_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AudioplayersWindowsPluginRegisterWithRegistrar( RecordWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); registry->GetRegistrarForPlugin("RecordWindowsPluginCApi"));
ScreenRetrieverPluginRegisterWithRegistrar( ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
SeriousPythonWindowsPluginCApiRegisterWithRegistrar( SeriousPythonWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SeriousPythonWindowsPluginCApi")); registry->GetRegistrarForPlugin("SeriousPythonWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@ -3,8 +3,8 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_windows record_windows
screen_retriever screen_retriever_windows
serious_python_windows serious_python_windows
url_launcher_windows url_launcher_windows
window_manager window_manager