Compare commits
95 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c99bd8f120 | |
|
|
08844c6e1d | |
|
|
a80ff08a9b | |
|
|
29c074847e | |
|
|
6a773c37f7 | |
|
|
a090ff82dc | |
|
|
d4bb8781d9 | |
|
|
810cedd458 | |
|
|
7f2e57aa9a | |
|
|
0d7f36b47c | |
|
|
8bcd4e1ee7 | |
|
|
cc5df08f38 | |
|
|
a6f8ef257e | |
|
|
222dc57a6f | |
|
|
fecd2df8c2 | |
|
|
893e7d9fd5 | |
|
|
287ee5350f | |
|
|
1a557571ff | |
|
|
879bc4e2cd | |
|
|
38c001dd2e | |
|
|
8cf6a6a777 | |
|
|
2c08be510e | |
|
|
5b00ffb439 | |
|
|
4d4420a369 | |
|
|
a334ffce32 | |
|
|
2ef869dcb6 | |
|
|
751dd24874 | |
|
|
34c35a5b01 | |
|
|
a471e02725 | |
|
|
f8d79be167 | |
|
|
c3415d600e | |
|
|
dd93c8ae6d | |
|
|
b63cdfe089 | |
|
|
73cae4ec99 | |
|
|
ceaf31531e | |
|
|
fc515f77c5 | |
|
|
dc8a457647 | |
|
|
b5b455d0de | |
|
|
3d0975eb2b | |
|
|
c467094581 | |
|
|
b1c6b15da5 | |
|
|
652bbfa243 | |
|
|
6067841b81 | |
|
|
24d1a7056e | |
|
|
a58c6ffa92 | |
|
|
0ca26dd6b5 | |
|
|
9c399dfaae | |
|
|
f42393a5ae | |
|
|
6377f131b8 | |
|
|
5b39497d20 | |
|
|
e7ecd3baff | |
|
|
6da7a3ae8f | |
|
|
2eb1727362 | |
|
|
e7a3ede0ee | |
|
|
516518871e | |
|
|
6e2e7eebc8 | |
|
|
1f4cb54e9a | |
|
|
0178bd5f23 | |
|
|
0eac4d4c5b | |
|
|
4447012691 | |
|
|
3c41d5cb1c | |
|
|
03d7a63609 | |
|
|
f1c45f90b4 | |
|
|
1d28e0fbdb | |
|
|
b69b87efb3 | |
|
|
1cc0c49f29 | |
|
|
326209fdbf | |
|
|
a88b3b8e48 | |
|
|
14a925be08 | |
|
|
9496a9b3de | |
|
|
7bc5081b00 | |
|
|
e2ab18efdd | |
|
|
0b83309df0 | |
|
|
27a2ec266e | |
|
|
4ffc1adf42 | |
|
|
52d86b3bd3 | |
|
|
50c7144fca | |
|
|
26b3c9a244 | |
|
|
d96ce5a571 | |
|
|
d48614191d | |
|
|
5e1d40c94c | |
|
|
a233de7547 | |
|
|
c25fa1db79 | |
|
|
b6b6f3426f | |
|
|
bd9285b831 | |
|
|
6c78ea8471 | |
|
|
2546c20766 | |
|
|
5a1fc38804 | |
|
|
52ebf16507 | |
|
|
4fa29e6f5d | |
|
|
aadcfb3baa | |
|
|
31dca2b5e5 | |
|
|
417ae1c0c7 | |
|
|
3d3a54c486 | |
|
|
438daea208 |
|
|
@ -2,11 +2,13 @@
|
||||||
"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": "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 }}",
|
"kotlin_dir": "{{ cookiecutter.org_name.replace('.', cookiecutter.sep) }}{{ cookiecutter.sep }}{{ cookiecutter.project_name }}{{ cookiecutter.sep }}",
|
||||||
"hide_loading_animation": true,
|
"hide_loading_animation": true,
|
||||||
|
|
@ -14,5 +16,9 @@
|
||||||
"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
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,16 @@ if (flutterVersionName == null) {
|
||||||
android {
|
android {
|
||||||
namespace "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}"
|
namespace "{{ cookiecutter.org_name }}.{{ cookiecutter.project_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
|
||||||
|
|
@ -41,25 +50,37 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "{{ cookiecutter.org_name }}.{{ cookiecutter.project_name }}"
|
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
|
minSdkVersion flutter.minSdkVersion
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
|
||||||
|
// flet: split_per_abi {% if not cookiecutter.split_per_abi %}
|
||||||
ndk {
|
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 {
|
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 %}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -1,9 +1,20 @@
|
||||||
<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: 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 %} -->
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="{{ cookiecutter.project_name }}"
|
android:label="{{ cookiecutter.product_name }}"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
android:enableOnBackInvokedCallback="true"
|
||||||
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"
|
||||||
|
|
@ -21,9 +32,20 @@
|
||||||
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 -->
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -370,7 +370,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }};
|
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name_slug }};
|
||||||
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 +387,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.org_name }}.{{ cookiecutter.project_name_slug }}.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 +405,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.org_name }}.{{ cookiecutter.project_name_slug }}.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 +421,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.org_name }}.{{ cookiecutter.project_name_slug }}.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 +475,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 +524,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;
|
||||||
|
|
@ -551,7 +551,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }};
|
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name_slug }};
|
||||||
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";
|
||||||
|
|
@ -576,7 +576,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name }};
|
PRODUCT_BUNDLE_IDENTIFIER = {{ cookiecutter.org_name }}.{{ cookiecutter.project_name_slug }};
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?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>
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<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>
|
||||||
|
|
@ -42,8 +42,39 @@
|
||||||
<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 %} -->
|
||||||
|
<!-- flet: prop {% for k, v in cookiecutter.options.info_plist.items() %} -->
|
||||||
|
<key>{{ k }}</key>
|
||||||
|
<!-- flet: True {% if v == True %} -->
|
||||||
|
<true />
|
||||||
|
<!-- flet: False {% elif v == False %} -->
|
||||||
|
<false />
|
||||||
|
<!-- flet: string value {% else %} -->
|
||||||
|
<string>{{ v }}</string>
|
||||||
|
<!-- flet: end of prop {% endif %} {% endfor %} -->
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
@ -5,9 +5,18 @@ 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";
|
||||||
|
|
||||||
|
{% 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');
|
||||||
|
|
||||||
|
|
@ -16,82 +25,38 @@ const pythonModuleName = "{{ cookiecutter.python_module_name }}";
|
||||||
final hideLoadingPage =
|
final hideLoadingPage =
|
||||||
bool.tryParse("{{ cookiecutter.hide_loading_animation }}".toLowerCase()) ??
|
bool.tryParse("{{ cookiecutter.hide_loading_animation }}".toLowerCase()) ??
|
||||||
true;
|
true;
|
||||||
const outLogFilename = "out.log";
|
|
||||||
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,
|
hideLoadingPage: hideLoadingPage,
|
||||||
)
|
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) {
|
||||||
|
|
@ -107,7 +72,7 @@ void main() async {
|
||||||
pageUrl: pageUrl,
|
pageUrl: pageUrl,
|
||||||
assetsDir: assetsDir,
|
assetsDir: assetsDir,
|
||||||
hideLoadingPage: hideLoadingPage,
|
hideLoadingPage: hideLoadingPage,
|
||||||
);
|
createControlFactories: createControlFactories);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
|
|
@ -124,6 +89,19 @@ void main() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +109,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 +133,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 +166,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 +174,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 +195,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();
|
||||||
}
|
}
|
||||||
|
|
@ -295,3 +314,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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
""";
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -138,6 +138,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")
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,15 +63,13 @@ 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;
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,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.org_name }}.{{ cookiecutter.project_name_slug }}.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 +398,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.org_name }}.{{ cookiecutter.project_name_slug }}.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 +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.org_name }}.{{ cookiecutter.project_name_slug }}.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 }}";
|
||||||
|
|
|
||||||
|
|
@ -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.org_name }}.{{ cookiecutter.project_name_slug }}
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?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>
|
||||||
|
|
@ -28,5 +28,14 @@
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
</dict>
|
<!-- flet: prop {% for k, v in cookiecutter.options.info_plist.items() %} -->
|
||||||
|
<key>{{ k }}</key>
|
||||||
|
<!-- flet: True {% if v == True %} -->
|
||||||
|
<true />
|
||||||
|
<!-- flet: False {% elif v == False %} -->
|
||||||
|
<false />
|
||||||
|
<!-- flet: string value {% else %} -->
|
||||||
|
<string>{{ v }}</string>
|
||||||
|
<!-- flet: end of prop {% endif %} {% endfor %} -->
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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,40 @@ dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
serious_python: ^0.7.0
|
serious_python: 0.8.7
|
||||||
# serious_python:
|
|
||||||
# git:
|
|
||||||
# url: https://github.com/flet-dev/serious-python
|
|
||||||
# path: src/serious_python
|
|
||||||
# ref: 'd059aef'
|
|
||||||
|
|
||||||
flet: ^0.19.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.26.0
|
||||||
# flet:
|
# flet:
|
||||||
# git:
|
# git:
|
||||||
|
# path: packages/flet
|
||||||
|
# ref: main
|
||||||
# url: https://github.com/flet-dev/flet.git
|
# url: https://github.com/flet-dev/flet.git
|
||||||
# path: package
|
|
||||||
# ref: '37b9581'
|
|
||||||
|
|
||||||
path: ^1.8.3
|
wakelock_plus: ^1.2.10
|
||||||
url_strategy: ^0.2.0
|
web: ^1.0.0
|
||||||
cupertino_icons: ^1.0.2
|
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:
|
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 +61,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"
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js");
|
importScripts("https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js");
|
||||||
|
|
||||||
self.pythonModuleName = null;
|
self.pythonModuleName = null;
|
||||||
self.initialized = false;
|
self.initialized = false;
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue