Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
8ee019d5
Unverified
Commit
8ee019d5
authored
Jul 11, 2023
by
Robert Ancell
Committed by
GitHub
Jul 11, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Linux implementation of the platform view example (#123731)
parent
3163306d
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
429 additions
and
1 deletion
+429
-1
main.dart
examples/platform_view/lib/main.dart
+2
-1
CMakeLists.txt
examples/platform_view/linux/CMakeLists.txt
+140
-0
CMakeLists.txt
examples/platform_view/linux/flutter/CMakeLists.txt
+88
-0
main.cc
examples/platform_view/linux/main.cc
+10
-0
my_application.cc
examples/platform_view/linux/my_application.cc
+167
-0
my_application.h
examples/platform_view/linux/my_application.h
+22
-0
No files found.
examples/platform_view/lib/main.dart
View file @
8ee019d5
...
@@ -57,8 +57,9 @@ class _MyHomePageState extends State<MyHomePage> {
...
@@ -57,8 +57,9 @@ class _MyHomePageState extends State<MyHomePage> {
return
const
Text
(
'Continue in Windows view'
);
return
const
Text
(
'Continue in Windows view'
);
case
TargetPlatform
.
macOS
:
case
TargetPlatform
.
macOS
:
return
const
Text
(
'Continue in macOS view'
);
return
const
Text
(
'Continue in macOS view'
);
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
linux
:
case
TargetPlatform
.
linux
:
return
const
Text
(
'Continue in Linux view'
);
case
TargetPlatform
.
fuchsia
:
throw
UnimplementedError
(
'Platform not yet implemented'
);
throw
UnimplementedError
(
'Platform not yet implemented'
);
}
}
}
}
...
...
examples/platform_view/linux/CMakeLists.txt
0 → 100644
View file @
8ee019d5
# Project-level configuration.
cmake_minimum_required
(
VERSION 3.10
)
project
(
runner LANGUAGES CXX
)
set
(
CMAKE_CXX_STANDARD 17
)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set
(
BINARY_NAME
"platform_view"
)
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set
(
APPLICATION_ID
"io.flutter.examples.platform_view"
)
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy
(
SET CMP0063 NEW
)
# Load bundled libraries from the lib/ directory relative to the binary.
set
(
CMAKE_INSTALL_RPATH
"$ORIGIN/lib"
)
# Root filesystem for cross-building.
if
(
FLUTTER_TARGET_PLATFORM_SYSROOT
)
set
(
CMAKE_SYSROOT
${
FLUTTER_TARGET_PLATFORM_SYSROOT
}
)
set
(
CMAKE_FIND_ROOT_PATH
${
CMAKE_SYSROOT
}
)
set
(
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER
)
set
(
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY
)
set
(
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY
)
set
(
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY
)
endif
()
# Define build configuration options.
if
(
NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES
)
set
(
CMAKE_BUILD_TYPE
"Debug"
CACHE
STRING
"Flutter build mode"
FORCE
)
set_property
(
CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug"
"Profile"
"Release"
)
endif
()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# 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
"$<$<NOT:$<CONFIG:Debug>>:-O3>"
)
target_compile_definitions
(
${
TARGET
}
PRIVATE
"$<$<NOT:$<CONFIG:Debug>>:NDEBUG>"
)
endfunction
()
# Flutter library and tool build rules.
set
(
FLUTTER_MANAGED_DIR
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/flutter"
)
add_subdirectory
(
${
FLUTTER_MANAGED_DIR
}
)
# System-level dependencies.
find_package
(
PkgConfig REQUIRED
)
pkg_check_modules
(
GTK REQUIRED IMPORTED_TARGET gtk+-3.0
)
add_definitions
(
-DAPPLICATION_ID=
"
${
APPLICATION_ID
}
"
)
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable
(
${
BINARY_NAME
}
"main.cc"
"my_application.cc"
"
${
FLUTTER_MANAGED_DIR
}
/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings
(
${
BINARY_NAME
}
)
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries
(
${
BINARY_NAME
}
PRIVATE flutter
)
target_link_libraries
(
${
BINARY_NAME
}
PRIVATE PkgConfig::GTK
)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies
(
${
BINARY_NAME
}
flutter_assemble
)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties
(
${
BINARY_NAME
}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY
"
${
CMAKE_BINARY_DIR
}
/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include
(
flutter/generated_plugins.cmake
)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set
(
BUILD_BUNDLE_DIR
"
${
PROJECT_BINARY_DIR
}
/bundle"
)
if
(
CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
)
set
(
CMAKE_INSTALL_PREFIX
"
${
BUILD_BUNDLE_DIR
}
"
CACHE PATH
"..."
FORCE
)
endif
()
# Start with a clean build bundle directory every time.
install
(
CODE
"
file(REMOVE_RECURSE
\"
${
BUILD_BUNDLE_DIR
}
/
\"
)
"
COMPONENT Runtime
)
set
(
INSTALL_BUNDLE_DATA_DIR
"
${
CMAKE_INSTALL_PREFIX
}
/data"
)
set
(
INSTALL_BUNDLE_LIB_DIR
"
${
CMAKE_INSTALL_PREFIX
}
/lib"
)
install
(
TARGETS
${
BINARY_NAME
}
RUNTIME DESTINATION
"
${
CMAKE_INSTALL_PREFIX
}
"
COMPONENT Runtime
)
install
(
FILES
"
${
FLUTTER_ICU_DATA_FILE
}
"
DESTINATION
"
${
INSTALL_BUNDLE_DATA_DIR
}
"
COMPONENT Runtime
)
install
(
FILES
"
${
FLUTTER_LIBRARY
}
"
DESTINATION
"
${
INSTALL_BUNDLE_LIB_DIR
}
"
COMPONENT Runtime
)
foreach
(
bundled_library
${
PLUGIN_BUNDLED_LIBRARIES
}
)
install
(
FILES
"
${
bundled_library
}
"
DESTINATION
"
${
INSTALL_BUNDLE_LIB_DIR
}
"
COMPONENT Runtime
)
endforeach
(
bundled_library
)
# 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"
)
install
(
CODE
"
file(REMOVE_RECURSE
\"
${
INSTALL_BUNDLE_DATA_DIR
}
/
${
FLUTTER_ASSET_DIR_NAME
}
\"
)
"
COMPONENT Runtime
)
install
(
DIRECTORY
"
${
PROJECT_BUILD_DIR
}
/
${
FLUTTER_ASSET_DIR_NAME
}
"
DESTINATION
"
${
INSTALL_BUNDLE_DATA_DIR
}
"
COMPONENT Runtime
)
# Install the AOT library on non-Debug builds only.
if
(
NOT CMAKE_BUILD_TYPE MATCHES
"Debug"
)
install
(
FILES
"
${
AOT_LIBRARY
}
"
DESTINATION
"
${
INSTALL_BUNDLE_LIB_DIR
}
"
COMPONENT Runtime
)
endif
()
examples/platform_view/linux/flutter/CMakeLists.txt
0 → 100644
View file @
8ee019d5
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required
(
VERSION 3.10
)
set
(
EPHEMERAL_DIR
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/ephemeral"
)
# Configuration provided via flutter tool.
include
(
${
EPHEMERAL_DIR
}
/generated_config.cmake
)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function
(
list_prepend LIST_NAME PREFIX
)
set
(
NEW_LIST
""
)
foreach
(
element
${${
LIST_NAME
}}
)
list
(
APPEND NEW_LIST
"
${
PREFIX
}${
element
}
"
)
endforeach
(
element
)
set
(
${
LIST_NAME
}
"
${
NEW_LIST
}
"
PARENT_SCOPE
)
endfunction
()
# === Flutter Library ===
# System-level dependencies.
find_package
(
PkgConfig REQUIRED
)
pkg_check_modules
(
GTK REQUIRED IMPORTED_TARGET gtk+-3.0
)
pkg_check_modules
(
GLIB REQUIRED IMPORTED_TARGET glib-2.0
)
pkg_check_modules
(
GIO REQUIRED IMPORTED_TARGET gio-2.0
)
set
(
FLUTTER_LIBRARY
"
${
EPHEMERAL_DIR
}
/libflutter_linux_gtk.so"
)
# Published to parent scope for install step.
set
(
FLUTTER_LIBRARY
${
FLUTTER_LIBRARY
}
PARENT_SCOPE
)
set
(
FLUTTER_ICU_DATA_FILE
"
${
EPHEMERAL_DIR
}
/icudtl.dat"
PARENT_SCOPE
)
set
(
PROJECT_BUILD_DIR
"
${
PROJECT_DIR
}
/build/"
PARENT_SCOPE
)
set
(
AOT_LIBRARY
"
${
PROJECT_DIR
}
/build/lib/libapp.so"
PARENT_SCOPE
)
list
(
APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend
(
FLUTTER_LIBRARY_HEADERS
"
${
EPHEMERAL_DIR
}
/flutter_linux/"
)
add_library
(
flutter INTERFACE
)
target_include_directories
(
flutter INTERFACE
"
${
EPHEMERAL_DIR
}
"
)
target_link_libraries
(
flutter INTERFACE
"
${
FLUTTER_LIBRARY
}
"
)
target_link_libraries
(
flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies
(
flutter flutter_assemble
)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command
(
OUTPUT
${
FLUTTER_LIBRARY
}
${
FLUTTER_LIBRARY_HEADERS
}
${
CMAKE_CURRENT_BINARY_DIR
}
/_phony_
COMMAND
${
CMAKE_COMMAND
}
-E env
${
FLUTTER_TOOL_ENVIRONMENT
}
"
${
FLUTTER_ROOT
}
/packages/flutter_tools/bin/tool_backend.sh"
${
FLUTTER_TARGET_PLATFORM
}
${
CMAKE_BUILD_TYPE
}
VERBATIM
)
add_custom_target
(
flutter_assemble DEPENDS
"
${
FLUTTER_LIBRARY
}
"
${
FLUTTER_LIBRARY_HEADERS
}
)
examples/platform_view/linux/main.cc
0 → 100644
View file @
8ee019d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "my_application.h"
int
main
(
int
argc
,
char
**
argv
)
{
g_autoptr
(
MyApplication
)
app
=
my_application_new
();
return
g_application_run
(
G_APPLICATION
(
app
),
argc
,
argv
);
}
examples/platform_view/linux/my_application.cc
0 → 100644
View file @
8ee019d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct
_MyApplication
{
GtkApplication
parent_instance
;
// Channel to receive platform view requests from Flutter.
FlMethodChannel
*
platform_view_channel
;
// Main window.
GtkWindow
*
window
;
// Current counter.
int64_t
counter
;
// Request in progress.
FlMethodCall
*
method_call
;
// Native window requested by Flutter.
GtkWindow
*
native_window
;
// Label to show count.
GtkLabel
*
counter_label
;
};
G_DEFINE_TYPE
(
MyApplication
,
my_application
,
GTK_TYPE_APPLICATION
)
static
void
update_counter_label
(
MyApplication
*
self
)
{
g_autofree
gchar
*
text
=
g_strdup_printf
(
"Button tapped %"
G_GINT64_FORMAT
" %s."
,
self
->
counter
,
self
->
counter
==
1
?
"time"
:
"times"
);
gtk_label_set_text
(
self
->
counter_label
,
text
);
}
static
void
button_clicked_cb
(
MyApplication
*
self
)
{
self
->
counter
++
;
update_counter_label
(
self
);
}
static
void
native_window_delete_event_cb
(
MyApplication
*
self
,
gint
response_id
)
{
g_autoptr
(
FlValue
)
counter_value
=
fl_value_new_int
(
self
->
counter
);
fl_method_call_respond_success
(
self
->
method_call
,
counter_value
,
nullptr
);
g_clear_object
(
&
self
->
method_call
);
}
// Handle request to switch the view.
static
void
handle_switch_view
(
MyApplication
*
self
,
FlMethodCall
*
method_call
)
{
FlValue
*
counter_value
=
fl_method_call_get_args
(
method_call
);
if
(
fl_value_get_type
(
counter_value
)
!=
FL_VALUE_TYPE_INT
)
{
fl_method_call_respond_error
(
self
->
method_call
,
"Invalid args"
,
"Invalid switchView args"
,
nullptr
,
nullptr
);
return
;
}
self
->
counter
=
fl_value_get_int
(
counter_value
);
self
->
method_call
=
FL_METHOD_CALL
(
g_object_ref
(
method_call
));
// Show the same UI in a native window.
self
->
native_window
=
GTK_WINDOW
(
gtk_window_new
(
GTK_WINDOW_TOPLEVEL
));
gtk_window_set_transient_for
(
self
->
native_window
,
self
->
window
);
gtk_window_set_modal
(
self
->
native_window
,
TRUE
);
gtk_window_set_destroy_with_parent
(
self
->
native_window
,
TRUE
);
g_signal_connect_swapped
(
self
->
native_window
,
"delete-event"
,
G_CALLBACK
(
native_window_delete_event_cb
),
self
);
GtkWidget
*
box
=
gtk_box_new
(
GTK_ORIENTATION_VERTICAL
,
12
);
gtk_widget_set_margin_start
(
box
,
24
);
gtk_widget_set_margin_end
(
box
,
24
);
gtk_widget_set_margin_top
(
box
,
24
);
gtk_widget_set_margin_bottom
(
box
,
24
);
gtk_widget_show
(
box
);
gtk_container_add
(
GTK_CONTAINER
(
self
->
native_window
),
box
);
self
->
counter_label
=
GTK_LABEL
(
gtk_label_new
(
""
));
gtk_widget_show
(
GTK_WIDGET
(
self
->
counter_label
));
gtk_container_add
(
GTK_CONTAINER
(
box
),
GTK_WIDGET
(
self
->
counter_label
));
GtkWidget
*
button
=
gtk_button_new_with_label
(
"+"
);
gtk_style_context_add_class
(
gtk_widget_get_style_context
(
GTK_WIDGET
(
button
)),
"circular"
);
gtk_widget_set_halign
(
button
,
GTK_ALIGN_CENTER
);
gtk_widget_show
(
button
);
gtk_container_add
(
GTK_CONTAINER
(
box
),
button
);
g_signal_connect_swapped
(
button
,
"clicked"
,
G_CALLBACK
(
button_clicked_cb
),
self
);
update_counter_label
(
self
);
gtk_window_present
(
self
->
native_window
);
}
// Handle platform view requests from Flutter.
static
void
platform_view_channel_method_cb
(
FlMethodChannel
*
channel
,
FlMethodCall
*
method_call
,
gpointer
user_data
)
{
MyApplication
*
self
=
MY_APPLICATION
(
user_data
);
const
char
*
name
=
fl_method_call_get_name
(
method_call
);
if
(
g_str_equal
(
name
,
"switchView"
))
{
handle_switch_view
(
self
,
method_call
);
}
else
{
fl_method_call_respond_not_implemented
(
method_call
,
nullptr
);
}
}
// Implements GObject::dispose.
static
void
my_application_dispose
(
GObject
*
object
)
{
MyApplication
*
self
=
MY_APPLICATION
(
object
);
g_clear_object
(
&
self
->
platform_view_channel
);
G_OBJECT_CLASS
(
my_application_parent_class
)
->
dispose
(
object
);
}
// Implements GApplication::activate.
static
void
my_application_activate
(
GApplication
*
application
)
{
MyApplication
*
self
=
MY_APPLICATION
(
application
);
self
->
window
=
GTK_WINDOW
(
gtk_application_window_new
(
GTK_APPLICATION
(
application
)));
gtk_window_set_default_size
(
self
->
window
,
1280
,
720
);
gtk_widget_show
(
GTK_WIDGET
(
self
->
window
));
g_autoptr
(
FlDartProject
)
project
=
fl_dart_project_new
();
FlView
*
view
=
fl_view_new
(
project
);
gtk_widget_show
(
GTK_WIDGET
(
view
));
gtk_container_add
(
GTK_CONTAINER
(
self
->
window
),
GTK_WIDGET
(
view
));
// Create channel to handle platform view requests from Flutter.
FlEngine
*
engine
=
fl_view_get_engine
(
view
);
g_autoptr
(
FlStandardMethodCodec
)
codec
=
fl_standard_method_codec_new
();
self
->
platform_view_channel
=
fl_method_channel_new
(
fl_engine_get_binary_messenger
(
engine
),
"samples.flutter.io/platform_view"
,
FL_METHOD_CODEC
(
codec
));
fl_method_channel_set_method_call_handler
(
self
->
platform_view_channel
,
platform_view_channel_method_cb
,
self
,
nullptr
);
fl_register_plugins
(
FL_PLUGIN_REGISTRY
(
view
));
gtk_widget_grab_focus
(
GTK_WIDGET
(
view
));
}
static
void
my_application_class_init
(
MyApplicationClass
*
klass
)
{
G_OBJECT_CLASS
(
klass
)
->
dispose
=
my_application_dispose
;
G_APPLICATION_CLASS
(
klass
)
->
activate
=
my_application_activate
;
}
static
void
my_application_init
(
MyApplication
*
self
)
{}
MyApplication
*
my_application_new
()
{
return
MY_APPLICATION
(
g_object_new
(
my_application_get_type
(),
"application-id"
,
APPLICATION_ID
,
"flags"
,
G_APPLICATION_NON_UNIQUE
,
nullptr
));
}
examples/platform_view/linux/my_application.h
0 → 100644
View file @
8ee019d5
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE
(
MyApplication
,
my_application
,
MY
,
APPLICATION
,
GtkApplication
)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication
*
my_application_new
();
#endif // FLUTTER_MY_APPLICATION_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment