Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_binary_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_clipping_view.cc
FILE: ../../../flutter/shell/platform/linux/fl_clipping_view.h
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_private.h
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc
Expand All @@ -1452,6 +1454,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
FILE: ../../../flutter/shell/platform/linux/fl_engine_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_event_channel.cc
FILE: ../../../flutter/shell/platform/linux/fl_event_channel_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_gesture_helper.cc
FILE: ../../../flutter/shell/platform/linux/fl_gesture_helper.h
FILE: ../../../flutter/shell/platform/linux/fl_gl_area.cc
FILE: ../../../flutter/shell/platform/linux/fl_gl_area.h
FILE: ../../../flutter/shell/platform/linux/fl_json_message_codec.cc
Expand All @@ -1478,6 +1482,11 @@ FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_platform_views.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_views_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_views_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_platform_views_plugin_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_views_private.h
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registrar.cc
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registrar_private.h
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registry.cc
Expand Down Expand Up @@ -1519,6 +1528,7 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_call.
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_response.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_platform_views.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h
Expand Down
7 changes: 7 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ _public_headers = [
"public/flutter_linux/fl_method_channel.h",
"public/flutter_linux/fl_method_codec.h",
"public/flutter_linux/fl_method_response.h",
"public/flutter_linux/fl_platform_views.h",
"public/flutter_linux/fl_plugin_registrar.h",
"public/flutter_linux/fl_plugin_registry.h",
"public/flutter_linux/fl_standard_message_codec.h",
Expand Down Expand Up @@ -91,9 +92,11 @@ source_set("flutter_linux_sources") {
"fl_basic_message_channel.cc",
"fl_binary_codec.cc",
"fl_binary_messenger.cc",
"fl_clipping_view.cc",
"fl_dart_project.cc",
"fl_engine.cc",
"fl_event_channel.cc",
"fl_gesture_helper.cc",
"fl_gl_area.cc",
"fl_json_message_codec.cc",
"fl_json_method_codec.cc",
Expand All @@ -105,6 +108,8 @@ source_set("flutter_linux_sources") {
"fl_method_response.cc",
"fl_mouse_cursor_plugin.cc",
"fl_platform_plugin.cc",
"fl_platform_views.cc",
"fl_platform_views_plugin.cc",
"fl_plugin_registrar.cc",
"fl_plugin_registry.cc",
"fl_renderer.cc",
Expand Down Expand Up @@ -171,13 +176,15 @@ executable("flutter_linux_unittests") {
"fl_method_channel_test.cc",
"fl_method_codec_test.cc",
"fl_method_response_test.cc",
"fl_platform_views_plugin_test.cc",
"fl_standard_message_codec_test.cc",
"fl_standard_method_codec_test.cc",
"fl_string_codec_test.cc",
"fl_value_test.cc",
"testing/fl_test.cc",
"testing/mock_engine.cc",
"testing/mock_epoxy.cc",
"testing/mock_platform_views.cc",
"testing/mock_renderer.cc",
"testing/mock_text_input_plugin.cc",
]
Expand Down
180 changes: 180 additions & 0 deletions shell/platform/linux/fl_clipping_view.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright 2013 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 "flutter/shell/platform/linux/fl_clipping_view.h"

#include "flutter/shell/platform/embedder/embedder.h"

struct _FlClippingView {
GtkEventBox parent_instance;

GdkRectangle geometry;
GPtrArray* mutations;
};

G_DEFINE_TYPE(FlClippingView, fl_clipping_view, GTK_TYPE_EVENT_BOX)

static void fl_clipping_view_dispose(GObject* gobject) {
FlClippingView* self = FL_CLIPPING_VIEW(gobject);

g_clear_pointer(&self->mutations, g_ptr_array_unref);

G_OBJECT_CLASS(fl_clipping_view_parent_class)->dispose(gobject);
}

// Implements GtkWidget::size-allocate.
static void fl_clipping_view_size_allocate(GtkWidget* widget,
GtkAllocation* allocation) {
FlClippingView* self = FL_CLIPPING_VIEW(widget);

gtk_widget_set_allocation(widget, allocation);

if (gtk_widget_get_has_window(widget)) {
if (gtk_widget_get_realized(widget))
gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
allocation->y, allocation->width,
allocation->height);
}

GtkWidget* child = gtk_bin_get_child(GTK_BIN(self));
if (!child || !gtk_widget_get_visible(child))
return;

GtkAllocation child_allocation = self->geometry;
if (!gtk_widget_get_has_window(widget)) {
child_allocation.x += allocation->x;
child_allocation.y += allocation->y;
}
gtk_widget_size_allocate(child, &child_allocation);
}

// Implements GtkWidget::draw.
static gboolean fl_clipping_view_draw(GtkWidget* widget, cairo_t* cr) {
FlClippingView* self = FL_CLIPPING_VIEW(widget);

// We currently can only clip widgets that have no GdkWindow.

cairo_save(cr);
if (self->mutations) {
for (guint i = 0; i < self->mutations->len; i++) {
FlutterPlatformViewMutation* mutation =
reinterpret_cast<FlutterPlatformViewMutation*>(
self->mutations->pdata[i]);
switch (mutation->type) {
case kFlutterPlatformViewMutationTypeOpacity: {
// opacitiy is applied in fl_clipping_view_reset ().
} break;
case kFlutterPlatformViewMutationTypeClipRect: {
cairo_rectangle(cr, mutation->clip_rect.left, mutation->clip_rect.top,
mutation->clip_rect.right - mutation->clip_rect.left,
mutation->clip_rect.bottom - mutation->clip_rect.top);
cairo_clip(cr);
} break;
case kFlutterPlatformViewMutationTypeClipRoundedRect: {
FlutterSize* top_left_radii =
&mutation->clip_rounded_rect.upper_left_corner_radius;
FlutterSize* top_right_radii =
&mutation->clip_rounded_rect.upper_right_corner_radius;
FlutterSize* bottom_left_radii =
&mutation->clip_rounded_rect.lower_left_corner_radius;
FlutterSize* bottom_right_radii =
&mutation->clip_rounded_rect.lower_right_corner_radius;
FlutterRect* rect = &mutation->clip_rounded_rect.rect;
cairo_move_to(cr, rect->left + top_left_radii->width, rect->top);

cairo_line_to(cr, rect->right - top_right_radii->width, rect->top);
cairo_curve_to(cr, rect->right, rect->top, //
rect->right, rect->top + top_right_radii->height,
rect->right, rect->top + top_right_radii->height);

cairo_line_to(cr, rect->right,
rect->bottom - bottom_right_radii->height);
cairo_curve_to(cr, rect->right, rect->bottom,
rect->right - bottom_right_radii->width, rect->bottom,
rect->right - bottom_right_radii->width, rect->bottom);

cairo_line_to(cr, rect->left + bottom_left_radii->width,
rect->bottom);
cairo_curve_to(cr, rect->left, rect->bottom, //
rect->left, rect->bottom - bottom_left_radii->height,
rect->left, rect->bottom - bottom_left_radii->height);

cairo_line_to(cr, rect->left, rect->top + top_left_radii->height);
cairo_curve_to(cr, rect->left, rect->top,
rect->left + top_left_radii->width, rect->top,
rect->left + top_left_radii->width, rect->top);

cairo_close_path(cr);
cairo_clip(cr);
} break;
case kFlutterPlatformViewMutationTypeTransformation: {
cairo_matrix_t matrix = {
.xx = mutation->transformation.scaleX,
.yx = mutation->transformation.skewY,
.xy = mutation->transformation.skewX,
.yy = mutation->transformation.scaleY,
.x0 = mutation->transformation.transX,
.y0 = mutation->transformation.transY,
};
cairo_transform(cr, &matrix);
} break;
}
}
}
cairo_translate(cr, -self->geometry.x, -self->geometry.y);
gboolean result =
GTK_WIDGET_CLASS(fl_clipping_view_parent_class)->draw(widget, cr);
cairo_restore(cr);
return result;
}

static void fl_clipping_view_constructed(GObject* object) {
gtk_event_box_set_visible_window(GTK_EVENT_BOX(object), TRUE);
}

static void fl_clipping_view_class_init(FlClippingViewClass* klass) {
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
gobject_class->constructed = fl_clipping_view_constructed;
gobject_class->dispose = fl_clipping_view_dispose;

GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
widget_class->draw = fl_clipping_view_draw;
widget_class->size_allocate = fl_clipping_view_size_allocate;
}

static void fl_clipping_view_init(FlClippingView* self) {}

GtkWidget* fl_clipping_view_new() {
return GTK_WIDGET(g_object_new(fl_clipping_view_get_type(), nullptr));
}

void fl_clipping_view_reset(FlClippingView* self,
GtkWidget* child,
GdkRectangle* geometry,
GPtrArray* mutations) {
g_return_if_fail(FL_IS_CLIPPING_VIEW(self));
g_return_if_fail(mutations != nullptr);

GtkWidget* old_child = gtk_bin_get_child(GTK_BIN(self));
if (old_child != child) {
if (old_child) {
gtk_container_remove(GTK_CONTAINER(self), old_child);
}

g_object_ref(child);
gtk_container_add(GTK_CONTAINER(self), child);
}
self->geometry = *geometry;
g_clear_pointer(&self->mutations, g_ptr_array_unref);
self->mutations = g_ptr_array_ref(mutations);

for (guint i = 0; i < mutations->len; i++) {
FlutterPlatformViewMutation* mutation =
reinterpret_cast<FlutterPlatformViewMutation*>(
self->mutations->pdata[i]);
if (mutation->type == kFlutterPlatformViewMutationTypeOpacity) {
gtk_widget_set_opacity(child, mutation->opacity);
}
}
}
52 changes: 52 additions & 0 deletions shell/platform/linux/fl_clipping_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2013 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_SHELL_PLATFORM_LINUX_FL_CLIPPING_VIEW_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_CLIPPING_VIEW_H_

#include <gtk/gtk.h>

#include <glib-object.h>

G_BEGIN_DECLS

G_DECLARE_FINAL_TYPE(FlClippingView,
fl_clipping_view,
FL,
CLIPPING_VIEW,
GtkEventBox)

/**
* FlClippingView:
*
* #FlClippingView is a GTK widget that applies clipping mutations set by
* Framework side to child platform view.
*/

/**
* fl_clipping_view_new:
*
* Creates a new #FlClippingView widget.
*
* Returns: the newly created #FlClippingView widget.
*/
GtkWidget* fl_clipping_view_new();

/**
* fl_clipping_view_reset:
* @clipping_view: an #FlClippingView.
* @child: widget to apply mutators.
* @geometry: geometry of widget.
* @mutations: the clipping mutations to be applied.
*
* Reset child widget and its mutations.
*/
void fl_clipping_view_reset(FlClippingView* clipping_view,
GtkWidget* child,
GdkRectangle* geometry,
GPtrArray* mutations);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_CLIPPING_VIEW_H_
Loading