From bb3f41a7d01ef3f13a23c1ce05eae8208fff7f65 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 7 Nov 2015 13:46:06 +0300 Subject: [PATCH] Now able to render on Gtk window using Skia and Direct2D --- src/Gtk/Perspex.Cairo/CairoPlatform.cs | 9 ++++-- src/Gtk/Perspex.Gtk/WindowImpl.cs | 43 +++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/CairoPlatform.cs b/src/Gtk/Perspex.Cairo/CairoPlatform.cs index a4bf08c4ea..75f1c45668 100644 --- a/src/Gtk/Perspex.Cairo/CairoPlatform.cs +++ b/src/Gtk/Perspex.Cairo/CairoPlatform.cs @@ -38,11 +38,14 @@ namespace Perspex.Cairo public IRenderTarget CreateRenderer(IPlatformHandle handle, double width, double height) { - if (handle.HandleDescriptor != "GtkWindow") + var window = handle as Gtk.Window; + if (window == null) throw new NotSupportedException(string.Format( - "Don't know how to create a Cairo renderer from a '{0}' handle", + "Don't know how to create a Cairo renderer from a '{0}' handle which isn't Gtk.Window", handle.HandleDescriptor)); - return new RenderTarget((Gtk.Window)handle, width, height); + + window.DoubleBuffered = true; + return new RenderTarget(window, width, height); } public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 5b1c71f8e4..64b1beb779 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -3,11 +3,13 @@ using System; using System.Reactive.Disposables; +using System.Runtime.InteropServices; using Gdk; using Perspex.Controls; using Perspex.Input.Raw; using Perspex.Platform; using Perspex.Input; +using Perspex.Threading; using Action = System.Action; namespace Perspex.Gtk @@ -46,6 +48,8 @@ namespace Perspex.Gtk EventMask.ButtonReleaseMask; _imContext = new Gtk.IMMulticontext(); _imContext.Commit += ImContext_Commit; + DoubleBuffered = false; + Realize(); } protected override void OnRealized () @@ -71,7 +75,44 @@ namespace Perspex.Gtk } IPlatformHandle ITopLevelImpl.Handle => this; - public string HandleDescriptor => "GtkWindow"; + + [DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)] + extern static IntPtr gdk_win32_drawable_get_handle(IntPtr gdkWindow); + + [DllImport("libgtk-x11-2.0.so.0", CallingConvention = CallingConvention.Cdecl)] + extern static IntPtr gdk_x11_drawable_get_xid(IntPtr gdkWindow); + + [DllImport("libgdk-quartz-2.0-0.dylib", CallingConvention = CallingConvention.Cdecl)] + extern static IntPtr gdk_quartz_window_get_nswindow(IntPtr gdkWindow); + + IntPtr _nativeWindow; + + IntPtr GetNativeWindow() + { + IntPtr h = GdkWindow.Handle; + if (_nativeWindow != IntPtr.Zero) + return _nativeWindow; + //Try whatever backend that works + try + { + return _nativeWindow = gdk_quartz_window_get_nswindow(h); + } + catch + { + } + try + { + return _nativeWindow = gdk_x11_drawable_get_xid(h); + } + catch + { + } + return _nativeWindow = gdk_win32_drawable_get_handle(h); + } + + + IntPtr IPlatformHandle.Handle => GetNativeWindow(); + public string HandleDescriptor => "HWND"; public Action Activated { get; set; }