Compare commits

...

110 Commits
main ... 0.27.2

Author SHA1 Message Date
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 778 additions and 340 deletions

View File

@ -2,17 +2,31 @@
"out_dir": "",
"python_module_name": "main",
"project_name": "",
"project_name_slug": "",
"project_description": "",
"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",
"copyright": "Copyright (c) 2023 Your Company",
"flutter": null,
"sep": "/",
"kotlin_dir": "{{ cookiecutter.org_name.replace('.', cookiecutter.sep) }}{{ cookiecutter.sep }}{{ cookiecutter.project_name }}{{ cookiecutter.sep }}",
"hide_loading_animation": true,
"team_id": "",
"bundle_id": "{{ cookiecutter.bundle_id if 'bundle_id' in cookiecutter else cookiecutter.org_name + '.' + cookiecutter.project_name_slug }}",
"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' }}",
"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": "/",
"route_url_strategy": "path",
"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
}

View File

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

View File

@ -0,0 +1,16 @@
{# _macros.jinja2 #}
{% macro get_value(dict, path) %}
{# Split the path into keys #}
{% set keys = path.split('.') %}
{% if keys and dict is mapping and keys[0] in dict %}
{% set next_value = dict[keys[0]] %}
{% if keys | length == 1 %}
{{ next_value }}
{% else %}
{{ get_value(next_value, keys[1:] | join('.')) }}
{% endif %}
{% else %}
{{ "" }}
{% endif %}
{% endmacro %}

View File

@ -1,3 +1,4 @@
{% import "_macros.jinja2" as macros %}
plugins {
id "com.android.application"
id "kotlin-android"
@ -23,9 +24,18 @@ if (flutterVersionName == null) {
}
android {
namespace "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}"
namespace "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
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 {
sourceCompatibility JavaVersion.VERSION_1_8
@ -40,26 +50,47 @@ android {
main.java.srcDirs += 'src/main/kotlin'
}
{% set min_sdk_version = macros.get_value(cookiecutter.pyproject, "tool.flet.android.min_sdk_version") | trim %}
{% set target_sdk_version = macros.get_value(cookiecutter.pyproject, "tool.flet.android.target_sdk_version") | trim %}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
applicationId "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
minSdkVersion {{ min_sdk_version if min_sdk_version else "flutter.minSdkVersion" }}
targetSdkVersion {{ target_sdk_version if target_sdk_version else "flutter.targetSdkVersion" }}
versionCode flutterVersionCode.toInteger()
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 {
abiFilters 'arm64-v8a', 'armeabi-v7a'
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64'
}
// 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 {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfig signingConfigs.release
// {% else %}
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

@ -4,4 +4,5 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>

View File

@ -1,9 +1,24 @@
<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: enf 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
android:label="{{ cookiecutter.project_name }}"
android:label="{{ cookiecutter.product_name }}"
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">
<!-- 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
android:name=".MainActivity"
android:exported="true"
@ -23,7 +38,18 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" /> <!-- Google TV -->
</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>
<!-- Don't delete the meta-data below.
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

View File

@ -4,4 +4,5 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>

View File

@ -1,12 +1,11 @@
buildscript {
ext.kotlin_version = '1.7.10'
ext.kotlin_version = '1.9.24'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
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.enableJetifier=true

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
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
platform :ios, '12.0'
platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

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

View File

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

View File

@ -45,5 +45,57 @@
<true />
<key>UIApplicationSupportsIndirectInputEvents</key>
<true />
<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>

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,9 +5,18 @@ import 'package:flet/flet.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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_provider/path_provider.dart' as path_provider;
import 'package:serious_python/serious_python.dart';
import 'package:url_strategy/url_strategy.dart';
import 'package:window_manager/window_manager.dart';
import "python.dart";
{% for dep in cookiecutter.flutter.dependencies %}
import 'package:{{ dep }}/{{ dep }}.dart' as {{ dep }};
{% endfor %}
const bool isProduction = bool.fromEnvironment('dart.vm.product');
@ -16,82 +25,38 @@ const pythonModuleName = "{{ cookiecutter.python_module_name }}";
final hideLoadingPage =
bool.tryParse("{{ cookiecutter.hide_loading_animation }}".toLowerCase()) ??
true;
const outLogFilename = "out.log";
const errorExitCode = 100;
const pythonScript = """
import certifi, os, runpy, socket, sys, traceback
List<CreateControlFactory> createControlFactories = [
{% for dep in cookiecutter.flutter.dependencies %}
{{ dep }}.createControl,
{% endfor %}
];
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
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)
""";
String outLogFilename = "";
// global vars
List<String> _args = [];
String pageUrl = "";
String assetsDir = "";
String appDir = "";
Map<String, String> environmentVariables = {};
void main() async {
if (isProduction) {
// ignore: avoid_returning_null_for_void
debugPrint = (String? message, {int? wrapWidth}) => null;
}
void main(List<String> args) async {
_args = List<String>.from(args);
runApp(FutureBuilder(
future: prepareApp(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
// OK - start Python program
return kIsWeb
return kIsWeb || (isDesktopPlatform() && _args.isNotEmpty)
? FletApp(
pageUrl: pageUrl,
assetsDir: assetsDir,
hideLoadingPage: hideLoadingPage,
)
createControlFactories: createControlFactories)
: FutureBuilder(
future: runPythonApp(),
future: runPythonApp(args),
builder:
(BuildContext context, AsyncSnapshot<String?> snapshot) {
if (snapshot.hasData || snapshot.hasError) {
@ -107,7 +72,7 @@ void main() async {
pageUrl: pageUrl,
assetsDir: assetsDir,
hideLoadingPage: hideLoadingPage,
);
createControlFactories: createControlFactories);
}
});
} else if (snapshot.hasError) {
@ -124,6 +89,19 @@ void main() 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) {
// web mode - connect via HTTP
pageUrl = Uri.base.toString();
@ -131,9 +109,22 @@ Future prepareApp() async {
if (routeUrlStrategy == "path") {
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 {
await setupDesktop();
// production mode
// extract app from asset
appDir = await extractAssetZip(assetPath, checkHash: true);
@ -142,6 +133,29 @@ Future prepareApp() async {
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"] =
defaultTargetPlatform.name.toLowerCase();
@ -152,7 +166,7 @@ Future prepareApp() async {
environmentVariables["FLET_SERVER_PORT"] = tcpPort.toString();
} else {
// use UDS on other platforms
pageUrl = "flet.sock";
pageUrl = "flet_$pid.sock";
environmentVariables["FLET_SERVER_UDS_PATH"] = pageUrl;
}
}
@ -160,8 +174,13 @@ Future prepareApp() async {
return "";
}
Future<String?> runPythonApp() async {
var script = pythonScript.replaceAll('{module_name}', pythonModuleName);
Future<String?> runPythonApp(List<String> args) async {
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>();
@ -176,7 +195,7 @@ Future<String?> runPythonApp() async {
'Python output TCP Server is listening on port ${outSocketServer.port}');
socketAddr = "$tcpAddr:${outSocketServer.port}";
} else {
socketAddr = "stdout.sock";
socketAddr = "stdout_$pid.sock";
if (await File(socketAddr).exists()) {
await File(socketAddr).delete();
}
@ -295,3 +314,25 @@ Future<int> getUnusedPort() {
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 }}")
# The unique GTK application identifier for this application. See:
# 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
# versions of CMake.
@ -41,7 +41,7 @@ endif()
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
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_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
@ -138,6 +138,12 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
endif()
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
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")

View File

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

View File

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

View File

@ -7,8 +7,7 @@
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication
{
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
@ -16,8 +15,7 @@ struct _MyApplication
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication *application)
{
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
@ -32,30 +30,25 @@ static void my_application_activate(GApplication *application)
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
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);
if (g_strcmp0(wm_name, "GNOME Shell") != 0)
{
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar)
{
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "{{ cookiecutter.product_name }}");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
}
else
{
} else {
gtk_window_set_title(window, "{{ cookiecutter.product_name }}");
}
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();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
@ -70,15 +63,13 @@ static void my_application_activate(GApplication *application)
}
// 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);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
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);
*exit_status = 1;
return TRUE;
@ -90,25 +81,42 @@ static gboolean my_application_local_command_line(GApplication *application, gch
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.
static void my_application_dispose(GObject *object)
{
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
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)->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;
}
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(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,

View File

@ -5,24 +5,26 @@
import FlutterMacOS
import Foundation
import audioplayers_darwin
import package_info_plus
import path_provider_foundation
import screen_retriever
import record_darwin
import screen_retriever_macos
import serious_python_darwin
import shared_preferences_foundation
import url_launcher_macos
import wakelock_plus
import window_manager
import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
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"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin"))
}

View File

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

View File

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

View File

@ -8,7 +8,7 @@
PRODUCT_NAME = {{ cookiecutter.product_name }}
// 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
PRODUCT_COPYRIGHT = {{ cookiecutter.copyright }}. All rights reserved.

View File

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

View File

@ -28,5 +28,35 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
{% 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>

View File

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

View File

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

View File

@ -1,5 +1,5 @@
name: {{ cookiecutter.project_name.replace("-", "_") }}
description: {{ cookiecutter.project_description }}
name: '{{ cookiecutter.project_name }}'
description: '{{ cookiecutter.project_description }}'
publish_to: 'none'
version: 1.0.0+1
@ -11,30 +11,47 @@ dependencies:
flutter:
sdk: flutter
serious_python: ^0.7.0
# serious_python:
# git:
# url: https://github.com/flet-dev/serious-python
# path: src/serious_python
# ref: 'd059aef'
serious_python: 0.9.0
path: ^1.9.0
url_strategy: ^0.2.0
cupertino_icons: ^1.0.6
path_provider: ^2.1.4
package_info_plus: ^8.0.2
window_manager: ^0.4.3
dependency_overrides:
flet: 0.27.2
flet: ^0.19.0
# flet:
# git:
# path: packages/flet
# ref: main
# url: https://github.com/flet-dev/flet.git
# path: package
# ref: '37b9581'
path: ^1.8.3
url_strategy: ^0.2.0
cupertino_icons: ^1.0.2
# serious_python:
# git:
# url: https://github.com/flet-dev/serious-python.git
# ref: main
# path: src/serious_python
wakelock_plus: ^1.2.10
web: ^1.0.0
window_manager: ^0.4.3
webview_flutter_android: ^4.0.0
# {% if 'flet_audio_recorder' in cookiecutter.flutter.dependencies %}
record: ^5.1.1
# {% endif %}
# {% if 'flet_geolocator' in cookiecutter.flutter.dependencies %}
# geolocator: ^12.0.0
# geolocator_android: ^4.6.0
# {% endif %}
dev_dependencies:
flutter_test:
sdk: flutter
flutter_launcher_icons: "^0.13.1"
flutter_native_splash: ^2.3.6
flutter_launcher_icons: ^0.14.1
flutter_native_splash: ^2.4.1
flutter_lints: ^2.0.0
flutter:
@ -51,6 +68,8 @@ flutter_launcher_icons:
android: true
image_path_android: "images/icon.png"
adaptive_icon_background: '#ffffff'
adaptive_icon_foreground: images/icon.png
ios: true
image_path_ios: "images/icon.png"

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>
<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 }}">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="{{ cookiecutter.project_description }}">
<!-- 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-title" content="{{ cookiecutter.product_name }}">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
@ -44,34 +30,10 @@
</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>
<body>
<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>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>

View File

@ -3,8 +3,8 @@
"short_name": "{{ cookiecutter.project_name }}",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"background_color": "{{ cookiecutter.pwa_background_color }}",
"theme_color": "{{ cookiecutter.pwa_theme_color }}",
"description": "{{ cookiecutter.project_description }}",
"orientation": "portrait-primary",
"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.initialized = false;

View File

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

View File

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