fix(engine/linux): guard GTK3-only embedder paths

This commit is contained in:
Rich Young 2026-02-04 05:49:42 -05:00
parent c4e4f26067
commit 2e062a89a9
6 changed files with 40 additions and 5 deletions

View File

@ -222,7 +222,8 @@ copy("flutter_linux_gschemas") {
outputs = [ "$target_gen_dir/assets/{{source_name_part}}/gschemas.compiled" ]
}
executable("flutter_linux_unittests") {
if (!use_gtk4) {
executable("flutter_linux_unittests") {
testonly = true
sources = [
@ -311,6 +312,7 @@ executable("flutter_linux_unittests") {
"//flutter/shell/platform/embedder:embedder_test_utils",
"//flutter/testing",
]
}
}
shared_library("flutter_linux_gtk") {

View File

@ -5,9 +5,11 @@
#include "flutter/shell/platform/linux/public/flutter_linux/fl_application.h"
#include <gtk/gtk.h>
#if !FLUTTER_LINUX_GTK4
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#endif
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
@ -34,7 +36,11 @@ G_DEFINE_TYPE_WITH_CODE(FlApplication,
// Called when the first frame is received.
static void first_frame_cb(FlApplication* self, FlView* view) {
#if FLUTTER_LINUX_GTK4
GtkWidget* window = gtk_widget_get_root(GTK_WIDGET(view));
#else
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(view));
#endif
// Show the main window.
if (window != nullptr && GTK_IS_WINDOW(window)) {
@ -61,6 +67,7 @@ static GtkWindow* fl_application_create_window(FlApplication* self,
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
#if !FLUTTER_LINUX_GTK4
GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
@ -68,6 +75,7 @@ static GtkWindow* fl_application_create_window(FlApplication* self,
use_header_bar = FALSE;
}
}
#endif
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());

View File

@ -3,8 +3,13 @@
// found in the LICENSE file.
#include <epoxy/egl.h>
#if FLUTTER_LINUX_GTK4
#include <gdk/wayland/gdkwayland.h>
#include <gdk/x11/gdkx.h>
#else
#include <gdk/gdkwayland.h>
#include <gdk/gdkx.h>
#endif
#include "flutter/shell/platform/linux/fl_opengl_manager.h"

View File

@ -347,8 +347,12 @@ static void update_im_cursor_position(FlTextInputHandler* self) {
// Transform from Flutter view coordinates to GTK window coordinates.
GdkRectangle preedit_rect = {};
gtk_widget_translate_coordinates(self->widget,
gtk_widget_get_toplevel(self->widget), x, y,
#if FLUTTER_LINUX_GTK4
GtkWidget* toplevel = GTK_WIDGET(gtk_widget_get_root(self->widget));
#else
GtkWidget* toplevel = gtk_widget_get_toplevel(self->widget);
#endif
gtk_widget_translate_coordinates(self->widget, toplevel, x, y,
&preedit_rect.x, &preedit_rect.y);
// Set the cursor location in window coordinates so that GTK can position
@ -480,8 +484,12 @@ void fl_text_input_handler_set_widget(FlTextInputHandler* self,
GtkWidget* widget) {
g_return_if_fail(FL_IS_TEXT_INPUT_HANDLER(self));
self->widget = widget;
#if FLUTTER_LINUX_GTK4
gtk_im_context_set_client_widget(self->im_context, widget);
#else
gtk_im_context_set_client_window(self->im_context,
gtk_widget_get_window(self->widget));
#endif
}
GtkWidget* fl_text_input_handler_get_widget(FlTextInputHandler* self) {

View File

@ -27,7 +27,9 @@ struct _FlWindowStateMonitor {
GtkWindow* window;
// Current state information.
#if !FLUTTER_LINUX_GTK4
GdkWindowState window_state;
#endif
// Signal connection ID for window-state-changed
gulong window_state_event_cb_id;
@ -51,11 +53,13 @@ static void send_lifecycle_state(FlWindowStateMonitor* self,
message, nullptr, nullptr, nullptr);
}
#if !FLUTTER_LINUX_GTK4
static gboolean is_hidden(GdkWindowState state) {
return (state & GDK_WINDOW_STATE_WITHDRAWN) ||
(state & GDK_WINDOW_STATE_ICONIFIED);
}
#endif // !FLUTTER_LINUX_GTK4
#if !FLUTTER_LINUX_GTK4
// Signal handler for GtkWindow::window-state-event
static gboolean window_state_event_cb(FlWindowStateMonitor* self,
GdkEvent* event) {
@ -81,6 +85,7 @@ static gboolean window_state_event_cb(FlWindowStateMonitor* self,
return FALSE;
}
#endif // !FLUTTER_LINUX_GTK4
static void fl_window_state_monitor_dispose(GObject* object) {
FlWindowStateMonitor* self = FL_WINDOW_STATE_MONITOR(object);
@ -109,11 +114,16 @@ FlWindowStateMonitor* fl_window_state_monitor_new(FlBinaryMessenger* messenger,
self->window = window;
// Listen to window state changes.
#if !FLUTTER_LINUX_GTK4
self->window_state_event_cb_id =
g_signal_connect_swapped(self->window, "window-state-event",
G_CALLBACK(window_state_event_cb), self);
self->window_state =
gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(self->window)));
#else
self->window_state_event_cb_id = 0;
// TODO(gtk4): Reconnect lifecycle updates using GdkToplevel state.
#endif
return self;
}

View File

@ -10,6 +10,7 @@
#include "gtest/gtest.h"
#if !FLUTTER_LINUX_GTK4
TEST(FlWindowStateMonitorTest, GainFocus) {
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
@ -44,7 +45,6 @@ TEST(FlWindowStateMonitorTest, GainFocus) {
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
}
TEST(FlWindowStateMonitorTest, LoseFocus) {
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
@ -287,3 +287,5 @@ TEST(FlWindowStateMonitorTest, LeaveWithdrawnFocused) {
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
}
#endif // !FLUTTER_LINUX_GTK4