Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / gtk / MozContainer.cpp
blob446dc97a66f6ee1ee7d2d999f8791192ddbafb07
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "MozContainer.h"
10 #include <glib.h>
11 #include <gtk/gtk.h>
12 #include <stdio.h>
13 #include "mozilla/WidgetUtilsGtk.h"
14 #include "nsWindow.h"
16 #ifdef MOZ_LOGGING
17 # include "mozilla/Logging.h"
18 # include "nsTArray.h"
19 # include "Units.h"
20 extern mozilla::LazyLogModule gWidgetLog;
21 # define LOGCONTAINER(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args)
22 #else
23 # define LOGCONTAINER(args)
24 #endif /* MOZ_LOGGING */
26 /* init methods */
27 void moz_container_class_init(MozContainerClass* klass);
28 static void moz_container_init(MozContainer* container);
30 /* widget class methods */
31 static void moz_container_map(GtkWidget* widget);
32 void moz_container_unmap(GtkWidget* widget);
33 static void moz_container_size_allocate(GtkWidget* widget,
34 GtkAllocation* allocation);
35 static void moz_container_realize(GtkWidget* widget);
36 static void moz_container_unrealize(GtkWidget* widget);
38 /* public methods */
40 GType moz_container_get_type(void) {
41 static GType moz_container_type = 0;
43 if (!moz_container_type) {
44 static GTypeInfo moz_container_info = {
45 sizeof(MozContainerClass), /* class_size */
46 NULL, /* base_init */
47 NULL, /* base_finalize */
48 (GClassInitFunc)moz_container_class_init, /* class_init */
49 NULL, /* class_destroy */
50 NULL, /* class_data */
51 sizeof(MozContainer), /* instance_size */
52 0, /* n_preallocs */
53 (GInstanceInitFunc)moz_container_init, /* instance_init */
54 NULL, /* value_table */
57 moz_container_type =
58 g_type_register_static(GTK_TYPE_CONTAINER, "MozContainer",
59 &moz_container_info, static_cast<GTypeFlags>(0));
62 return moz_container_type;
65 GtkWidget* moz_container_new(void) {
66 MozContainer* container;
68 container =
69 static_cast<MozContainer*>(g_object_new(MOZ_CONTAINER_TYPE, nullptr));
71 return GTK_WIDGET(container);
74 static void moz_container_destroy(GtkWidget* widget) {
75 auto* container = MOZ_CONTAINER(widget);
76 if (container->destroyed) {
77 return; // The destroy signal may run multiple times.
79 LOGCONTAINER(("moz_container_destroy() [%p]\n",
80 (void*)moz_container_get_nsWindow(MOZ_CONTAINER(widget))));
81 container->destroyed = TRUE;
82 container->data.~Data();
85 void moz_container_class_init(MozContainerClass* klass) {
86 /*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
87 GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); */
88 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
90 widget_class->map = moz_container_map;
91 widget_class->realize = moz_container_realize;
92 widget_class->unrealize = moz_container_unrealize;
93 widget_class->destroy = moz_container_destroy;
95 #ifdef MOZ_WAYLAND
96 if (mozilla::widget::GdkIsWaylandDisplay()) {
97 widget_class->size_allocate = moz_container_wayland_size_allocate;
98 widget_class->map_event = moz_container_wayland_map_event;
99 widget_class->unmap = moz_container_wayland_unmap;
100 } else {
101 #endif
102 widget_class->size_allocate = moz_container_size_allocate;
103 widget_class->unmap = moz_container_unmap;
104 #ifdef MOZ_WAYLAND
106 #endif
109 void moz_container_init(MozContainer* container) {
110 container->destroyed = FALSE;
111 new (&container->data) MozContainer::Data();
112 gtk_widget_set_can_focus(GTK_WIDGET(container), TRUE);
113 gtk_widget_set_redraw_on_allocate(GTK_WIDGET(container), FALSE);
114 LOGCONTAINER(("%s [%p]\n", __FUNCTION__,
115 (void*)moz_container_get_nsWindow(container)));
118 void moz_container_map(GtkWidget* widget) {
119 MozContainer* container;
121 g_return_if_fail(IS_MOZ_CONTAINER(widget));
122 container = MOZ_CONTAINER(widget);
124 LOGCONTAINER(("moz_container_map() [%p]",
125 (void*)moz_container_get_nsWindow(container)));
127 gtk_widget_set_mapped(widget, TRUE);
129 if (gtk_widget_get_has_window(widget)) {
130 gdk_window_show(gtk_widget_get_window(widget));
133 // Enable rendering to nsWindow/MozContainer
134 nsWindow* window = moz_container_get_nsWindow(MOZ_CONTAINER(widget));
135 window->OnMap();
138 void moz_container_unmap(GtkWidget* widget) {
139 g_return_if_fail(IS_MOZ_CONTAINER(widget));
141 LOGCONTAINER(("moz_container_unmap() [%p]",
142 (void*)moz_container_get_nsWindow(MOZ_CONTAINER(widget))));
144 // Disable rendering to nsWindow/MozContainer before we really unmap it.
145 nsWindow* window = moz_container_get_nsWindow(MOZ_CONTAINER(widget));
146 window->OnUnmap();
148 gtk_widget_set_mapped(widget, FALSE);
150 if (gtk_widget_get_has_window(widget)) {
151 gdk_window_hide(gtk_widget_get_window(widget));
155 void moz_container_realize(GtkWidget* widget) {
156 GdkWindow* parent = gtk_widget_get_parent_window(widget);
157 GdkWindow* window;
159 gtk_widget_set_realized(widget, TRUE);
161 GdkWindowAttr attributes;
162 gint attributes_mask = GDK_WA_VISUAL | GDK_WA_X | GDK_WA_Y;
163 GtkAllocation allocation;
165 gtk_widget_get_allocation(widget, &allocation);
166 attributes.event_mask = gtk_widget_get_events(widget);
167 attributes.x = allocation.x;
168 attributes.y = allocation.y;
169 attributes.width = allocation.width;
170 attributes.height = allocation.height;
171 attributes.wclass = GDK_INPUT_OUTPUT;
172 attributes.window_type = GDK_WINDOW_CHILD;
173 MozContainer* container = MOZ_CONTAINER(widget);
174 attributes.visual =
175 container->data.force_default_visual
176 ? gdk_screen_get_system_visual(gtk_widget_get_screen(widget))
177 : gtk_widget_get_visual(widget);
179 window = gdk_window_new(parent, &attributes, attributes_mask);
181 LOGCONTAINER(("moz_container_realize() [%p] GdkWindow %p\n",
182 (void*)moz_container_get_nsWindow(container), (void*)window));
184 gtk_widget_register_window(widget, window);
185 gtk_widget_set_window(widget, window);
188 void moz_container_unrealize(GtkWidget* widget) {
189 GdkWindow* window = gtk_widget_get_window(widget);
190 LOGCONTAINER(("moz_container_unrealize() [%p] GdkWindow %p\n",
191 (void*)moz_container_get_nsWindow(MOZ_CONTAINER(widget)),
192 (void*)window));
194 if (gtk_widget_get_mapped(widget)) {
195 gtk_widget_unmap(widget);
198 gtk_widget_unregister_window(widget, window);
199 gtk_widget_set_window(widget, nullptr);
200 gdk_window_destroy(window);
201 gtk_widget_set_realized(widget, false);
204 void moz_container_size_allocate(GtkWidget* widget, GtkAllocation* allocation) {
205 GtkAllocation tmp_allocation;
207 g_return_if_fail(IS_MOZ_CONTAINER(widget));
209 LOGCONTAINER(("moz_container_size_allocate [%p] %d,%d -> %d x %d\n",
210 (void*)moz_container_get_nsWindow(MOZ_CONTAINER(widget)),
211 allocation->x, allocation->y, allocation->width,
212 allocation->height));
214 /* short circuit if you can */
215 gtk_widget_get_allocation(widget, &tmp_allocation);
216 if (tmp_allocation.x == allocation->x && tmp_allocation.y == allocation->y &&
217 tmp_allocation.width == allocation->width &&
218 tmp_allocation.height == allocation->height) {
219 return;
222 gtk_widget_set_allocation(widget, allocation);
224 if (gtk_widget_get_has_window(widget) && gtk_widget_get_realized(widget)) {
225 gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
226 allocation->y, allocation->width,
227 allocation->height);
231 void moz_container_force_default_visual(MozContainer* container) {
232 container->data.force_default_visual = true;
235 nsWindow* moz_container_get_nsWindow(MozContainer* container) {
236 gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow");
237 return static_cast<nsWindow*>(user_data);
240 #undef LOGCONTAINER