Flutter Engine
 
Loading...
Searching...
No Matches
fl_window_state_monitor.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <gtk/gtk.h>
8
10
11static constexpr const char* kFlutterLifecycleChannel = "flutter/lifecycle";
12
13static constexpr const char* kAppLifecycleStateResumed =
14 "AppLifecycleState.resumed";
15static constexpr const char* kAppLifecycleStateInactive =
16 "AppLifecycleState.inactive";
17static constexpr const char* kAppLifecycleStateHidden =
18 "AppLifecycleState.hidden";
19
22
23 // Messenger to communicate with engine.
24 FlBinaryMessenger* messenger;
25
26 // Window being monitored.
27 GtkWindow* window;
28
29 // Current state information.
30 GdkWindowState window_state;
31
32 // Signal connection ID for window-state-changed
34};
35
36G_DEFINE_TYPE(FlWindowStateMonitor, fl_window_state_monitor, G_TYPE_OBJECT);
37
38static void send_lifecycle_state(FlWindowStateMonitor* self,
39 const gchar* lifecycle_state) {
40 g_autoptr(FlValue) value = fl_value_new_string(lifecycle_state);
41 g_autoptr(FlStringCodec) codec = fl_string_codec_new();
42 g_autoptr(GError) error = nullptr;
43 g_autoptr(GBytes) message =
44 fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), value, &error);
45 if (message == nullptr) {
46 g_warning("Failed to encoding lifecycle state message: %s", error->message);
47 return;
48 }
49
51 message, nullptr, nullptr, nullptr);
52}
53
54static gboolean is_hidden(GdkWindowState state) {
55 return (state & GDK_WINDOW_STATE_WITHDRAWN) ||
56 (state & GDK_WINDOW_STATE_ICONIFIED);
57}
58
59// Signal handler for GtkWindow::window-state-event
60static gboolean window_state_event_cb(FlWindowStateMonitor* self,
61 GdkEvent* event) {
62 GdkWindowState state = event->window_state.new_window_state;
63 GdkWindowState previous_state = self->window_state;
64 self->window_state = state;
65 bool was_visible = !is_hidden(previous_state);
66 bool is_visible = !is_hidden(state);
67 bool was_focused = (previous_state & GDK_WINDOW_STATE_FOCUSED);
68 bool is_focused = (state & GDK_WINDOW_STATE_FOCUSED);
69
70 if (was_visible != is_visible || was_focused != is_focused) {
71 const gchar* lifecycle_state;
72 if (is_visible) {
73 lifecycle_state =
75 } else {
76 lifecycle_state = kAppLifecycleStateHidden;
77 }
78
79 send_lifecycle_state(self, lifecycle_state);
80 }
81
82 return FALSE;
83}
84
85static void fl_window_state_monitor_dispose(GObject* object) {
86 FlWindowStateMonitor* self = FL_WINDOW_STATE_MONITOR(object);
87
88 g_clear_object(&self->messenger);
89 if (self->window_state_event_cb_id != 0) {
90 g_signal_handler_disconnect(self->window, self->window_state_event_cb_id);
91 self->window_state_event_cb_id = 0;
92 }
93
94 G_OBJECT_CLASS(fl_window_state_monitor_parent_class)->dispose(object);
95}
96
98 FlWindowStateMonitorClass* klass) {
99 G_OBJECT_CLASS(klass)->dispose = fl_window_state_monitor_dispose;
100}
101
102static void fl_window_state_monitor_init(FlWindowStateMonitor* self) {}
103
104FlWindowStateMonitor* fl_window_state_monitor_new(FlBinaryMessenger* messenger,
105 GtkWindow* window) {
106 FlWindowStateMonitor* self = FL_WINDOW_STATE_MONITOR(
107 g_object_new(fl_window_state_monitor_get_type(), nullptr));
108 self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
109 self->window = window;
110
111 // Listen to window state changes.
112 self->window_state_event_cb_id =
113 g_signal_connect_swapped(self->window, "window-state-event",
114 G_CALLBACK(window_state_event_cb), self);
115 self->window_state =
116 gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(self->window)));
117
118 return self;
119}
int32_t value
GLFWwindow * window
Definition main.cc:60
static gboolean is_focused(FlutterSemanticsFlags flags)
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
g_autoptr(GMutexLocker) locker
G_MODULE_EXPORT GBytes * fl_message_codec_encode_message(FlMessageCodec *self, FlValue *message, GError **error)
G_BEGIN_DECLS GBytes * message
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT FlStringCodec * fl_string_codec_new()
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition fl_value.cc:276
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition fl_value.h:42
static constexpr const char * kAppLifecycleStateHidden
static void fl_window_state_monitor_dispose(GObject *object)
static gboolean is_hidden(GdkWindowState state)
G_DEFINE_TYPE(FlWindowStateMonitor, fl_window_state_monitor, G_TYPE_OBJECT)
FlWindowStateMonitor * fl_window_state_monitor_new(FlBinaryMessenger *messenger, GtkWindow *window)
static constexpr const char * kAppLifecycleStateResumed
static constexpr const char * kFlutterLifecycleChannel
static gboolean window_state_event_cb(FlWindowStateMonitor *self, GdkEvent *event)
static void fl_window_state_monitor_init(FlWindowStateMonitor *self)
static void fl_window_state_monitor_class_init(FlWindowStateMonitorClass *klass)
static void send_lifecycle_state(FlWindowStateMonitor *self, const gchar *lifecycle_state)
static constexpr const char * kAppLifecycleStateInactive
GdkWindow * gtk_widget_get_window(GtkWidget *widget)
Definition mock_gtk.cc:298
GdkWindowState gdk_window_get_state(GdkWindow *window)
Definition mock_gtk.cc:89