mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
fix(engine/linux): add GTK4 close-request and monitor updates
This commit is contained in:
parent
d012f1e1a9
commit
33235f42ae
@ -84,6 +84,49 @@ static void monitor_removed_cb(FlDisplayMonitor* self, GdkMonitor* monitor) {
|
||||
notify_display_update(self);
|
||||
}
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
static void prune_display_ids_for_current_monitors(FlDisplayMonitor* self) {
|
||||
GListModel* monitors = gdk_display_get_monitors(self->display);
|
||||
guint n_monitors = g_list_model_get_n_items(monitors);
|
||||
|
||||
GHashTable* current = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
for (guint i = 0; i < n_monitors; i++) {
|
||||
GdkMonitor* monitor = GDK_MONITOR(g_list_model_get_item(monitors, i));
|
||||
g_hash_table_add(current, monitor);
|
||||
}
|
||||
|
||||
GHashTableIter iter;
|
||||
gpointer key = nullptr;
|
||||
g_hash_table_iter_init(&iter, self->display_ids_by_monitor);
|
||||
while (g_hash_table_iter_next(&iter, &key, nullptr)) {
|
||||
if (!g_hash_table_contains(current, key)) {
|
||||
g_hash_table_iter_remove(&iter);
|
||||
}
|
||||
}
|
||||
|
||||
GHashTableIter current_iter;
|
||||
g_hash_table_iter_init(¤t_iter, current);
|
||||
while (g_hash_table_iter_next(¤t_iter, &key, nullptr)) {
|
||||
g_object_unref(G_OBJECT(key));
|
||||
}
|
||||
g_hash_table_unref(current);
|
||||
}
|
||||
|
||||
static void monitors_changed_cb(GListModel* list,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer user_data) {
|
||||
(void)list;
|
||||
(void)position;
|
||||
(void)removed;
|
||||
(void)added;
|
||||
FlDisplayMonitor* self = FL_DISPLAY_MONITOR(user_data);
|
||||
prune_display_ids_for_current_monitors(self);
|
||||
notify_display_update(self);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void fl_display_monitor_dispose(GObject* object) {
|
||||
FlDisplayMonitor* self = FL_DISPLAY_MONITOR(object);
|
||||
|
||||
@ -117,12 +160,19 @@ FlDisplayMonitor* fl_display_monitor_new(FlEngine* engine,
|
||||
void fl_display_monitor_start(FlDisplayMonitor* self) {
|
||||
g_return_if_fail(FL_IS_DISPLAY_MONITOR(self));
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
GListModel* monitors = gdk_display_get_monitors(self->display);
|
||||
g_signal_connect_object(monitors, "items-changed",
|
||||
G_CALLBACK(monitors_changed_cb), self,
|
||||
static_cast<GConnectFlags>(0));
|
||||
#else
|
||||
g_signal_connect_object(self->display, "monitor-added",
|
||||
G_CALLBACK(monitor_added_cb), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object(self->display, "monitor-removed",
|
||||
G_CALLBACK(monitor_removed_cb), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
#endif
|
||||
notify_display_update(self);
|
||||
}
|
||||
|
||||
|
||||
@ -153,13 +153,23 @@ static FlGdkSurface* fl_view_get_toplevel_surface(FlView* self) {
|
||||
return toplevel != nullptr ? fl_gtk_widget_get_surface(toplevel) : nullptr;
|
||||
}
|
||||
|
||||
// Signal handler for GtkWidget::delete-event
|
||||
// Signal handler for GtkWidget::delete-event (GTK3 only)
|
||||
static gboolean window_delete_event_cb(FlView* self) {
|
||||
fl_engine_request_app_exit(self->engine);
|
||||
// Stop the event from propagating.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
// Signal handler for GtkWindow::close-request.
|
||||
static gboolean window_close_request_cb(GtkWindow* window, FlView* self) {
|
||||
(void)window;
|
||||
fl_engine_request_app_exit(self->engine);
|
||||
// Stop the event from propagating.
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_scrolling(FlView* self) {
|
||||
g_clear_object(&self->scrolling_manager);
|
||||
self->scrolling_manager =
|
||||
@ -754,8 +764,13 @@ static void realize_cb(FlView* self) {
|
||||
GTK_WINDOW(toplevel_window));
|
||||
|
||||
// Handle requests by the user to close the application.
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
g_signal_connect(toplevel_window, "close-request",
|
||||
G_CALLBACK(window_close_request_cb), self);
|
||||
#else
|
||||
g_signal_connect_swapped(toplevel_window, "delete-event",
|
||||
G_CALLBACK(window_delete_event_cb), self);
|
||||
#endif
|
||||
|
||||
// Flutter engine will need to make the context current from raster thread
|
||||
// during initialization.
|
||||
@ -767,6 +782,11 @@ static void realize_cb(FlView* self) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
fl_text_input_handler_set_widget(
|
||||
fl_engine_get_text_input_handler(self->engine), GTK_WIDGET(self));
|
||||
#endif
|
||||
|
||||
setup_cursor(self);
|
||||
|
||||
handle_geometry_changed(self);
|
||||
@ -1014,11 +1034,6 @@ static void setup_engine(FlView* self) {
|
||||
|
||||
init_scrolling(self);
|
||||
init_touch(self);
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
fl_text_input_handler_set_widget(
|
||||
fl_engine_get_text_input_handler(self->engine),
|
||||
GTK_WIDGET(self));
|
||||
#endif
|
||||
|
||||
self->on_pre_engine_restart_cb_id =
|
||||
g_signal_connect_swapped(self->engine, "on-pre-engine-restart",
|
||||
|
||||
@ -55,6 +55,13 @@ static void title_notify_cb(FlWindowMonitor* self) {
|
||||
self->on_title_notify();
|
||||
}
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
static gboolean close_request_cb(FlWindowMonitor* self) {
|
||||
flutter::IsolateScope scope(self->isolate);
|
||||
self->on_close();
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
static gboolean delete_event_cb(FlWindowMonitor* self, GdkEvent* event) {
|
||||
flutter::IsolateScope scope(self->isolate);
|
||||
self->on_close();
|
||||
@ -62,6 +69,18 @@ static gboolean delete_event_cb(FlWindowMonitor* self, GdkEvent* event) {
|
||||
// Stop default behaviour of destroying the window.
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
static gboolean close_request_cb(GtkWindow* window, FlWindowMonitor* self) {
|
||||
(void)window;
|
||||
flutter::IsolateScope scope(self->isolate);
|
||||
self->on_close();
|
||||
|
||||
// Stop default behaviour of destroying the window.
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void destroy_cb(FlWindowMonitor* self) {
|
||||
flutter::IsolateScope scope(self->isolate);
|
||||
@ -114,8 +133,17 @@ G_MODULE_EXPORT FlWindowMonitor* fl_window_monitor_new(
|
||||
G_CALLBACK(is_active_notify_cb), self);
|
||||
g_signal_connect_swapped(window, "notify::title", G_CALLBACK(title_notify_cb),
|
||||
self);
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
g_signal_connect(window, "close-request", G_CALLBACK(close_request_cb), self);
|
||||
#else
|
||||
#if FLUTTER_LINUX_GTK4
|
||||
g_signal_connect_swapped(window, "close-request",
|
||||
G_CALLBACK(close_request_cb), self);
|
||||
#else
|
||||
g_signal_connect_swapped(window, "delete-event", G_CALLBACK(delete_event_cb),
|
||||
self);
|
||||
#endif
|
||||
#endif
|
||||
g_signal_connect_swapped(window, "destroy", G_CALLBACK(destroy_cb), self);
|
||||
|
||||
return self;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user