Skip to content

Commit 3b19575

Browse files
Copilotphilstopford
andcommitted
Fix DrawingArea widget embedding by implementing deferred native window creation to prevent separate window appearance
Co-authored-by: philstopford <1983851+philstopford@users.noreply.github.com>
1 parent 7b215fb commit 3b19575

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

Eto/Eto.Veldrid.Gtk/GtkVeldridSurfaceHandler.cs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,22 +136,35 @@ private SwapchainSource CreateWaylandSwapchainSource(IntPtr gdkDisplay)
136136

137137
Console.WriteLine($"[DEBUG] DrawingArea state - Visible: {drawingArea.Visible}, Realized: {drawingArea.IsRealized}, Mapped: {drawingArea.IsMapped}, Window.IsVisible: {drawingArea.Window.IsVisible}");
138138

139-
// Ensure native window only if Wayland handles can't be obtained without it
139+
// First attempt to get Wayland handles without forcing native window creation
140140
var waylandDisplay = X11Interop.gdk_wayland_display_get_wl_display(gdkDisplay);
141141
var waylandSurface = X11Interop.gdk_wayland_window_get_wl_surface(drawingArea.Window.Handle);
142142

143+
// Only create native window if handles are not available and we're in a proper widget hierarchy context
143144
if (waylandDisplay == IntPtr.Zero || waylandSurface == IntPtr.Zero)
144145
{
145-
Console.WriteLine("[DEBUG] Wayland handles not available, ensuring native window as last resort");
146-
X11Interop.gdk_window_ensure_native(drawingArea.Window.Handle);
146+
Console.WriteLine("[DEBUG] Wayland handles not available, ensuring native window for Vulkan operations");
147147

148-
// Retry getting handles after ensuring native window
149-
waylandDisplay = X11Interop.gdk_wayland_display_get_wl_display(gdkDisplay);
150-
waylandSurface = X11Interop.gdk_wayland_window_get_wl_surface(drawingArea.Window.Handle);
148+
// Ensure the widget is properly embedded in its parent before creating native window
149+
if (drawingArea.Parent != null && drawingArea.IsMapped)
150+
{
151+
// Create native window only when widget is properly embedded and mapped
152+
X11Interop.gdk_window_ensure_native(drawingArea.Window.Handle);
153+
154+
// Process events to ensure native window creation is complete
155+
while (global::Gtk.Application.EventsPending())
156+
{
157+
global::Gtk.Application.RunIteration();
158+
}
159+
160+
// Retry getting handles after native window creation
161+
waylandDisplay = X11Interop.gdk_wayland_display_get_wl_display(gdkDisplay);
162+
waylandSurface = X11Interop.gdk_wayland_window_get_wl_surface(drawingArea.Window.Handle);
163+
}
151164

152165
if (waylandDisplay == IntPtr.Zero || waylandSurface == IntPtr.Zero)
153166
{
154-
throw new InvalidOperationException($"Failed to get Wayland handles even after ensuring native window - Display: {waylandDisplay}, Surface: {waylandSurface}");
167+
throw new InvalidOperationException($"Failed to get Wayland handles even with native window - Display: {waylandDisplay}, Surface: {waylandSurface}");
155168
}
156169
}
157170

@@ -194,9 +207,11 @@ private void DrawingArea_InitializeGraphicsBackend(object? sender, EventArgs e)
194207
{
195208
Console.WriteLine("[DEBUG] DrawingArea mapped and ready for graphics initialization");
196209

197-
// Note: Removed gdk_window_ensure_native call as it was causing the DrawingArea
198-
// to appear as a separate window instead of being embedded in the parent container.
199-
// Native window creation is handled automatically by GTK when needed for Vulkan operations.
210+
// For Vulkan operations, we need a native window, but creating it immediately
211+
// during initialization can cause the DrawingArea to appear as a separate window.
212+
// Instead, we defer native window creation until it's actually needed for Vulkan surface operations.
213+
// This ensures proper widget hierarchy is maintained.
214+
Console.WriteLine("[DEBUG] Deferring native window creation to maintain proper widget embedding");
200215

201216
// Get display info for debugging
202217
var gdkDisplay = drawingArea!.Display.Handle;

0 commit comments

Comments
 (0)