Closed georgewsinger closed 4 years ago
Inspecting the wlr_xwayland_surface
of a popup (firefox vs. chrome). In the experiments below, we put a gdb breakpoint on handle_map
and inspect the contents of its wlr_xwayland_surface
. The first surface in each experiment is the parent browser. The second surface is the popup (in Chrome the popup causes two surfaces to be mapped, for a total of three surfaces).
Experiment 1: launch google-chrome, and then right-click.
Thread 1 "godot" hit Breakpoint 1, WlrXWaylandSurface::print_xwayland_surface_properties (this=0x6f18d50) at modules/gdwlroots/wlr_xwayland.cpp:319
319 }
$1 = {
window_id = 6291457,
xwm = 0x6f20e00,
surface_id = 0,
link = {
prev = 0x6f07ae8,
next = 0x6f112b8
},
unpaired_link = {
prev = 0x0,
next = 0x0
},
surface = 0x6f2f5d0,
x = 70,
y = 27,
width = 508,
height = 101,
saved_width = 0,
saved_height = 0,
override_redirect = false,
mapped = false,
title = 0x6f129b0 "New Tab - Google Chrome",
c_class = 0x6f1cc20 "Google-chrome",
instance = 0x6f1d040 "google-chrome",
role = 0x0,
pid = 31495,
has_utf8_title = true,
children = {
prev = 0x6f18b78,
next = 0x6f18b78
},
parent = 0x0,
parent_link = {
prev = 0x6f18b90,
next = 0x6f18b90
},
window_type = 0x6f126e0,
window_type_len = 1,
protocols = 0x6f12680,
protocols_len = 2,
decorations = 3,
hints = 0x0,
hints_urgency = 0,
size_hints = 0x6f2f970,
pinging = true,
ping_timer = 0x6f01e40,
modal = false,
fullscreen = false,
maximized_vert = true,
maximized_horz = true,
has_alpha = false,
events = {
destroy = {
listener_list = {
prev = 0x6f18f98,
next = 0x6f18f98
}
},
request_configure = {
listener_list = {
prev = 0x6f18fe0,
next = 0x6f18fe0
}
},
request_move = {
listener_list = {
prev = 0x6f18f20,
next = 0x6f18f20
}
},
request_resize = {
listener_list = {
prev = 0x6f18f38,
next = 0x6f18f38
}
},
request_maximize = {
listener_list = {
prev = 0x6f18ed8,
next = 0x6f18ed8
}
},
request_fullscreen = {
listener_list = {
prev = 0x6f18ef0,
next = 0x6f18ef0
}
},
request_activate = {
listener_list = {
prev = 0x6f18c58,
next = 0x6f18c58
}
},
map = {
listener_list = {
prev = 0x7fffffffd0e0,
next = 0x6f18fb0
}
},
unmap = {
listener_list = {
prev = 0x6f18fc8,
next = 0x6f18fc8
}
},
set_title = {
listener_list = {
prev = 0x6f18c88,
next = 0x6f18c88
}
},
set_class = {
listener_list = {
prev = 0x6f18c98,
next = 0x6f18c98
}
},
set_role = {
listener_list = {
prev = 0x6f18ca8,
next = 0x6f18ca8
}
},
set_parent = {
listener_list = {
prev = 0x6f18cb8,
next = 0x6f18cb8
}
},
set_pid = {
listener_list = {
prev = 0x6f18cc8,
next = 0x6f18cc8
}
},
set_window_type = {
listener_list = {
prev = 0x6f18cd8,
next = 0x6f18cd8
}
},
set_hints = {
listener_list = {
prev = 0x6f18ce8,
next = 0x6f18ce8
}
},
set_decorations = {
listener_list = {
prev = 0x6f18cf8,
next = 0x6f18cf8
}
},
set_override_redirect = {
listener_list = {
prev = 0x6f18d08,
next = 0x6f18d08
}
},
ping_timeout = {
listener_list = {
prev = 0x6f18d18,
next = 0x6f18d18
}
}
},
surface_destroy = {
link = {
prev = 0x6f2f890,
next = 0x6f2f890
},
notify = 0x7ffff744bec5 <handle_surface_destroy>
},
data = 0x6f18d50
}
Thread 1 "godot" hit Breakpoint 1, WlrXWaylandSurface::print_xwayland_surface_properties (this=0xf173d60) at modules/gdwlroots/wlr_xwayland.cpp:319
319 }
$2 = {
window_id = 6291466,
xwm = 0x6f20e00,
surface_id = 0,
link = {
prev = 0x6f21128,
next = 0x6f07ae8
},
unpaired_link = {
prev = 0x0,
next = 0x0
},
surface = 0xf176850,
x = 308,
y = 62,
width = 48,
height = 26,
saved_width = 0,
saved_height = 0,
override_redirect = true,
mapped = false,
title = 0x0,
c_class = 0x0,
instance = 0x0,
role = 0x0,
pid = 31495,
has_utf8_title = false,
children = {
prev = 0xf173b88,
next = 0xf173b88
},
parent = 0x0,
parent_link = {
prev = 0xf173ba0,
next = 0xf173ba0
},
window_type = 0xf1587f0,
window_type_len = 1,
protocols = 0xf158030,
protocols_len = 2,
decorations = 3,
hints = 0x0,
hints_urgency = 0,
size_hints = 0xf176d80,
pinging = false,
ping_timer = 0xf16e4a0,
modal = false,
fullscreen = false,
maximized_vert = false,
maximized_horz = false,
has_alpha = false,
events = {
destroy = {
listener_list = {
prev = 0xf173fa8,
next = 0xf173fa8
}
},
request_configure = {
listener_list = {
prev = 0xf173ff0,
next = 0xf173ff0
}
},
request_move = {
listener_list = {
prev = 0xf173f30,
next = 0xf173f30
}
},
request_resize = {
listener_list = {
prev = 0xf173f48,
next = 0xf173f48
}
},
request_maximize = {
listener_list = {
prev = 0xf173ee8,
next = 0xf173ee8
}
},
request_fullscreen = {
listener_list = {
prev = 0xf173f00,
next = 0xf173f00
}
},
request_activate = {
listener_list = {
prev = 0xf173c68,
next = 0xf173c68
}
},
map = {
listener_list = {
prev = 0x7fffffffd0e0,
next = 0xf173fc0
}
},
unmap = {
listener_list = {
prev = 0xf173fd8,
next = 0xf173fd8
}
},
set_title = {
listener_list = {
prev = 0xf173c98,
next = 0xf173c98
}
},
set_class = {
listener_list = {
prev = 0xf173ca8,
next = 0xf173ca8
}
},
set_role = {
listener_list = {
prev = 0xf173cb8,
next = 0xf173cb8
}
},
set_parent = {
listener_list = {
prev = 0xf173cc8,
next = 0xf173cc8
}
},
set_pid = {
listener_list = {
prev = 0xf173cd8,
next = 0xf173cd8
}
},
set_window_type = {
listener_list = {
prev = 0xf173ce8,
next = 0xf173ce8
}
},
set_hints = {
listener_list = {
prev = 0xf173cf8,
next = 0xf173cf8
}
},
set_decorations = {
listener_list = {
prev = 0xf173d08,
next = 0xf173d08
}
},
set_override_redirect = {
listener_list = {
prev = 0xf173d18,
next = 0xf173d18
}
},
ping_timeout = {
listener_list = {
prev = 0xf173d28,
next = 0xf173d28
}
}
},
surface_destroy = {
link = {
prev = 0xf176b10,
next = 0xf176b10
},
notify = 0x7ffff744bec5 <handle_surface_destroy>
},
data = 0xf173d60
}
Thread 1 "godot" hit Breakpoint 1, WlrXWaylandSurface::print_xwayland_surface_properties (this=0xf4f87a0) at modules/gdwlroots/wlr_xwayland.cpp:319
319 }
$3 = {
window_id = 6291467,
xwm = 0x6f20e00,
surface_id = 0,
link = {
prev = 0x6f21128,
next = 0xf173b28
},
unpaired_link = {
prev = 0x0,
next = 0x0
},
surface = 0xf61a0b0,
x = 70,
y = 27,
width = 365,
height = 227,
saved_width = 0,
saved_height = 0,
override_redirect = true,
mapped = false,
title = 0x0,
c_class = 0x0,
instance = 0x0,
role = 0x0,
pid = 31495,
has_utf8_title = false,
children = {
prev = 0xf60b978,
next = 0xf60b978
},
parent = 0x0,
parent_link = {
prev = 0xf60b990,
next = 0xf60b990
},
window_type = 0xf177760,
window_type_len = 1,
protocols = 0xf15ad70,
protocols_len = 2,
decorations = 3,
hints = 0x0,
hints_urgency = 0,
size_hints = 0xf61a5e0,
pinging = false,
ping_timer = 0xf601c00,
modal = false,
fullscreen = false,
maximized_vert = false,
maximized_horz = false,
has_alpha = false,
events = {
destroy = {
listener_list = {
prev = 0xf4f89e8,
next = 0xf4f89e8
}
},
request_configure = {
listener_list = {
prev = 0xf4f8a30,
next = 0xf4f8a30
}
},
request_move = {
listener_list = {
prev = 0xf4f8970,
next = 0xf4f8970
}
},
request_resize = {
listener_list = {
prev = 0xf4f8988,
next = 0xf4f8988
}
},
request_maximize = {
listener_list = {
prev = 0xf4f8928,
next = 0xf4f8928
}
},
request_fullscreen = {
listener_list = {
prev = 0xf4f8940,
next = 0xf4f8940
}
},
request_activate = {
listener_list = {
prev = 0xf60ba58,
next = 0xf60ba58
}
},
map = {
listener_list = {
prev = 0x7fffffffd0e0,
next = 0xf4f8a00
}
},
unmap = {
listener_list = {
prev = 0xf4f8a18,
next = 0xf4f8a18
}
},
set_title = {
listener_list = {
prev = 0xf60ba88,
next = 0xf60ba88
}
},
set_class = {
listener_list = {
prev = 0xf60ba98,
next = 0xf60ba98
}
},
set_role = {
listener_list = {
prev = 0xf60baa8,
next = 0xf60baa8
}
},
set_parent = {
listener_list = {
prev = 0xf60bab8,
next = 0xf60bab8
}
},
set_pid = {
listener_list = {
prev = 0xf60bac8,
next = 0xf60bac8
}
},
set_window_type = {
listener_list = {
prev = 0xf60bad8,
next = 0xf60bad8
}
},
set_hints = {
listener_list = {
prev = 0xf60bae8,
next = 0xf60bae8
}
},
set_decorations = {
listener_list = {
prev = 0xf60baf8,
next = 0xf60baf8
}
},
set_override_redirect = {
listener_list = {
prev = 0xf60bb08,
next = 0xf60bb08
}
},
ping_timeout = {
listener_list = {
prev = 0xf60bb18,
next = 0xf60bb18
}
}
},
surface_destroy = {
link = {
prev = 0xf61a370,
next = 0xf61a370
},
notify = 0x7ffff744bec5 <handle_surface_destroy>
},
data = 0xf4f87a0
}
Experiment 2: Firefox Right-Click.
Thread 1 "godot" hit Breakpoint 1, WlrXWaylandSurface::print_xwayland_surface_properties (this=0x6f0aab0) at modules/gdwlroots/wlr_xwayland.cpp:319
319 }
$1 = {
window_id = 6291472,
xwm = 0x6f21c50,
surface_id = 0,
link = {
prev = 0x6f0c808,
next = 0x6f05678
},
unpaired_link = {
prev = 0x0,
next = 0x0
},
surface = 0x6f17d50,
x = 0,
y = 0,
width = 1152,
height = 648,
saved_width = 0,
saved_height = 0,
override_redirect = false,
mapped = false,
title = 0x6f00ff0 "Mozilla Firefox",
c_class = 0x6f11170 "Firefox",
instance = 0x6f11150 "Navigator",
role = 0x6f11130 "browser",
pid = 5003,
has_utf8_title = true,
children = {
prev = 0x6f0a8d8,
next = 0x6f0a8d8
},
parent = 0x0,
parent_link = {
prev = 0x6f0a8f0,
next = 0x6f0a8f0
},
window_type = 0x6f29830,
window_type_len = 1,
protocols = 0x6f29810,
protocols_len = 4,
decorations = 0,
hints = 0x6bc5cd0,
hints_urgency = 0,
size_hints = 0x6f18070,
pinging = false,
ping_timer = 0x6f09ba0,
modal = false,
fullscreen = false,
maximized_vert = true,
maximized_horz = true,
has_alpha = false,
events = {
destroy = {
listener_list = {
prev = 0x6f0acf8,
next = 0x6f0acf8
}
},
request_configure = {
listener_list = {
prev = 0x6f0ad40,
next = 0x6f0ad40
}
},
request_move = {
listener_list = {
prev = 0x6f0ac80,
next = 0x6f0ac80
}
},
request_resize = {
listener_list = {
prev = 0x6f0ac98,
next = 0x6f0ac98
}
},
request_maximize = {
listener_list = {
prev = 0x6f0ac38,
next = 0x6f0ac38
}
},
request_fullscreen = {
listener_list = {
prev = 0x6f0ac50,
next = 0x6f0ac50
}
},
request_activate = {
listener_list = {
prev = 0x6f0a9b8,
next = 0x6f0a9b8
}
},
map = {
listener_list = {
prev = 0x7fffffffd0e0,
next = 0x6f0ad10
}
},
unmap = {
listener_list = {
prev = 0x6f0ad28,
next = 0x6f0ad28
}
},
set_title = {
listener_list = {
prev = 0x6f0a9e8,
next = 0x6f0a9e8
}
},
set_class = {
listener_list = {
prev = 0x6f0a9f8,
next = 0x6f0a9f8
}
},
set_role = {
listener_list = {
prev = 0x6f0aa08,
next = 0x6f0aa08
}
},
set_parent = {
listener_list = {
prev = 0x6f0aa18,
next = 0x6f0aa18
}
},
set_pid = {
listener_list = {
prev = 0x6f0aa28,
next = 0x6f0aa28
}
},
set_window_type = {
listener_list = {
prev = 0x6f0aa38,
next = 0x6f0aa38
}
},
set_hints = {
listener_list = {
prev = 0x6f0aa48,
next = 0x6f0aa48
}
},
set_decorations = {
listener_list = {
prev = 0x6f0aa58,
next = 0x6f0aa58
}
},
set_override_redirect = {
listener_list = {
prev = 0x6f0aa68,
next = 0x6f0aa68
}
},
ping_timeout = {
listener_list = {
prev = 0x6f0aa78,
next = 0x6f0aa78
}
}
},
surface_destroy = {
link = {
prev = 0x6f18010,
next = 0x6f18010
},
notify = 0x7ffff744bec5 <handle_surface_destroy>
},
data = 0x6f0aab0
}
Video of the bug. The bug is demonstrated in the following video:
https://www.youtube.com/watch?v=mIDMb_fDuxw
The video first shows Firefox subsurfaces working properly, and then follows it with a demonstration of the chrome bug.
How our code is failing. Every time a new surface xwayland surface is mapped, the
handle_map
gdwlroots function is fired:Notice that we don't emit the Godot "map" signal unless
xwayland_surface->wlr_xwayland_surface->parent == NULL
. Apparently, this test isn't sufficient for chrome popups: every chrome popup haswlr_xwayland_surface->parent == NULL
, and so Simula thinks they should spawn their own \~GodotSimulaViewSprite\~s.On the other hand, when we draw subsurfaces onto the parent chrome window, the popups aren't drawn either. That is, the chrome popups aren't retrieved by
WlrXWaylandSurface::get_children()
function:So they don't draw properly onto chrome.