29
29
* We need to wait until wl_surface of mContainer is created
30
30
* and then we create and attach our wl_subsurface to it.
31
31
*
32
- * wl_subsurface creation has these steps:
32
+ * First wl_subsurface creation has these steps:
33
33
*
34
34
* 1) moz_container_wayland_size_allocate() handler is called when
35
35
* mContainer size/position is known.
41
41
* when wl_surface owned by mozContainer is ready.
42
42
* We call initial_draw_cbs() handler and we can create our wl_subsurface
43
43
* on top of wl_surface owned by mozContainer.
44
+ *
45
+ * When MozContainer hides/show again, moz_container_wayland_size_allocate()
46
+ * handler may not be called as MozContainer size is set. So after first
47
+ * show/hide sequence use moz_container_wayland_map_event() to create
48
+ * wl_subsurface of MozContainer.
44
49
*/
45
50
46
51
#include "MozContainer.h"
@@ -76,6 +81,8 @@ static void moz_container_wayland_destroy(GtkWidget* widget);
76
81
77
82
/* widget class methods */
78
83
static void moz_container_wayland_map (GtkWidget * widget );
84
+ static gboolean moz_container_wayland_map_event (GtkWidget * widget ,
85
+ GdkEventAny * event );
79
86
static void moz_container_wayland_unmap (GtkWidget * widget );
80
87
static void moz_container_wayland_size_allocate (GtkWidget * widget ,
81
88
GtkAllocation * allocation );
@@ -94,6 +101,22 @@ static nsWindow* moz_container_get_nsWindow(MozContainer* container) {
94
101
// Imlemented in MozContainer.cpp
95
102
void moz_container_realize (GtkWidget * widget );
96
103
104
+ // Invalidate gtk wl_surface to commit changes to wl_subsurface.
105
+ // wl_subsurface changes are effective when parent surface is commited.
106
+ static void moz_container_wayland_invalidate (MozContainer * container ) {
107
+ LOGWAYLAND (("moz_container_wayland_invalidate [%p]\n" , (void * )container ));
108
+
109
+ GdkWindow * window = gtk_widget_get_window (GTK_WIDGET (container ));
110
+ if (!window ) {
111
+ LOGWAYLAND ((" Failed - missing GdkWindow!\n" ));
112
+ return ;
113
+ }
114
+
115
+ GdkRectangle rect = (GdkRectangle ){0 , 0 , gdk_window_get_width (window ),
116
+ gdk_window_get_height (window )};
117
+ gdk_window_invalidate_rect (window , & rect , true);
118
+ }
119
+
97
120
static void moz_container_wayland_move_locked (MozContainer * container , int dx ,
98
121
int dy ) {
99
122
LOGWAYLAND (
@@ -110,15 +133,6 @@ static void moz_container_wayland_move_locked(MozContainer* container, int dx,
110
133
wl_subsurface_set_position (wl_container -> subsurface ,
111
134
wl_container -> subsurface_dx ,
112
135
wl_container -> subsurface_dy );
113
-
114
- GdkWindow * window = gtk_widget_get_window (GTK_WIDGET (container ));
115
- if (window ) {
116
- GdkRectangle rect = (GdkRectangle ){0 , 0 , gdk_window_get_width (window ),
117
- gdk_window_get_height (window )};
118
- // wl_subsurface_set_position is actually property of parent surface
119
- // which is effective when parent surface is commited.
120
- gdk_window_invalidate_rect (window , & rect , true);
121
- }
122
136
}
123
137
124
138
// This is called from layout/compositor code only with
@@ -140,6 +154,7 @@ void moz_container_wayland_class_init(MozContainerClass* klass) {
140
154
GtkWidgetClass * widget_class = GTK_WIDGET_CLASS (klass );
141
155
142
156
widget_class -> map = moz_container_wayland_map ;
157
+ widget_class -> map_event = moz_container_wayland_map_event ;
143
158
widget_class -> destroy = moz_container_wayland_destroy ;
144
159
widget_class -> unmap = moz_container_wayland_unmap ;
145
160
widget_class -> realize = moz_container_realize ;
@@ -157,6 +172,7 @@ void moz_container_wayland_init(MozContainerWayland* container) {
157
172
container -> surface_needs_clear = true;
158
173
container -> subsurface_dx = 0 ;
159
174
container -> subsurface_dy = 0 ;
175
+ container -> before_first_size_alloc = true;
160
176
container -> initial_draw_cbs .clear ();
161
177
container -> container_lock = new mozilla ::Mutex ("MozContainer lock" );
162
178
}
@@ -212,6 +228,30 @@ static void moz_container_wayland_unmap_internal(MozContainer* container) {
212
228
LOGWAYLAND (("%s [%p]\n" , __FUNCTION__ , (void * )container ));
213
229
}
214
230
231
+ static gboolean moz_container_wayland_map_event (GtkWidget * widget ,
232
+ GdkEventAny * event ) {
233
+ MozContainerWayland * wl_container = & MOZ_CONTAINER (widget )-> wl_container ;
234
+ LOGWAYLAND (("%s [%p]\n" , __FUNCTION__ , (void * )MOZ_CONTAINER (widget )));
235
+
236
+ // Don't create wl_subsurface in map_event when it's already created or
237
+ // if we create it for the first time.
238
+ if (wl_container -> ready_to_draw || wl_container -> before_first_size_alloc ) {
239
+ return FALSE;
240
+ }
241
+
242
+ MutexAutoLock lock (* wl_container -> container_lock );
243
+ if (!wl_container -> surface ) {
244
+ if (!moz_container_wayland_surface_create_locked (MOZ_CONTAINER (widget ))) {
245
+ return FALSE;
246
+ }
247
+ }
248
+
249
+ moz_container_wayland_set_scale_factor_locked (MOZ_CONTAINER (widget ));
250
+ moz_container_wayland_set_opaque_region_locked (MOZ_CONTAINER (widget ));
251
+ moz_container_wayland_invalidate (MOZ_CONTAINER (widget ));
252
+ return FALSE;
253
+ }
254
+
215
255
void moz_container_wayland_map (GtkWidget * widget ) {
216
256
LOGWAYLAND (("%s [%p]\n" , __FUNCTION__ , (void * )widget ));
217
257
@@ -264,18 +304,17 @@ void moz_container_wayland_size_allocate(GtkWidget* widget,
264
304
// We need to position our subsurface according to GdkWindow
265
305
// when offset changes (GdkWindow is maximized for instance).
266
306
// see gtk-clutter-embed.c for reference.
267
- if (gfxPlatformGtk ::GetPlatform ()-> IsWaylandDisplay ()) {
268
- MutexAutoLock lock (* container -> wl_container .container_lock );
269
- if (!container -> wl_container .surface ) {
270
- if (!moz_container_wayland_surface_create_locked (container )) {
271
- return ;
272
- }
307
+ MutexAutoLock lock (* container -> wl_container .container_lock );
308
+ if (!container -> wl_container .surface ) {
309
+ if (!moz_container_wayland_surface_create_locked (container )) {
310
+ return ;
273
311
}
274
- moz_container_wayland_set_scale_factor_locked (container );
275
- moz_container_wayland_set_opaque_region_locked (container );
276
- moz_container_wayland_move_locked (container , allocation -> x ,
277
- allocation -> y );
278
312
}
313
+ moz_container_wayland_set_scale_factor_locked (container );
314
+ moz_container_wayland_set_opaque_region_locked (container );
315
+ moz_container_wayland_move_locked (container , allocation -> x , allocation -> y );
316
+ moz_container_wayland_invalidate (MOZ_CONTAINER (widget ));
317
+ container -> wl_container .before_first_size_alloc = false;
279
318
}
280
319
}
281
320
@@ -398,7 +437,7 @@ static bool moz_container_wayland_surface_create_locked(
398
437
wl_surface_commit (wl_container -> surface );
399
438
wl_display_flush (WaylandDisplayGet ()-> GetDisplay ());
400
439
401
- LOGWAYLAND ((" created surface %p ID %p \n" , (void * )wl_container -> surface ,
440
+ LOGWAYLAND ((" created surface %p ID %d \n" , (void * )wl_container -> surface ,
402
441
wl_proxy_get_id ((struct wl_proxy * )wl_container -> surface )));
403
442
return true;
404
443
}
0 commit comments