在 UNO 的 5.2 版本,可以使用 X11 平臺承載 UNO 應用。此時我需要獲取到 UNO 應用的視窗的 X11 視窗指標,如此即可呼叫 X11 平臺相關邏輯對 UNO 視窗執行一些互動
本文以下的方法需要用到反射
透過閱讀 UNO 的原始碼,可以看到 Window 型別裡面放入了不公開的 NativeWindow 屬性,這個屬性是平臺相關的。在 X11 平臺下是 Uno.WinUI.Runtime.Skia.X11.X11Window 型別。對應的 X11Window 型別的定義如下
internal record struct X11Window(IntPtr Display, IntPtr Window, (int stencilBits, int sampleCount, IntPtr context)? glXInfo)
{
public X11Window(IntPtr Display, IntPtr Window) : this(Display, Window, null)
{
}
public readonly void Deconstruct(out IntPtr Display, out IntPtr Window, out (int stencilBits, int sampleCount, IntPtr context)? GLXInfo)
{
Display = this.Display;
Window = this.Window;
GLXInfo = this.glXInfo;
}
}
獲取 X11Window 裡面的 Window 屬性即可獲取到 X11 視窗指標
反射的程式碼如下
var type = MainWindow.GetType();
var nativeWindowPropertyInfo = type.GetProperty("NativeWindow", BindingFlags.Instance | BindingFlags.NonPublic);
var x11Window = nativeWindowPropertyInfo!.GetMethod!.Invoke(MainWindow, null)!;
// Uno.WinUI.Runtime.Skia.X11.X11Window
var x11WindowType = x11Window.GetType();
var x11WindowIntPtr = (IntPtr) x11WindowType.GetProperty("Window", BindingFlags.Instance | BindingFlags.Public)!.GetMethod!.Invoke(x11Window, null)!;
Console.WriteLine($"Uno 視窗控制代碼 {x11WindowIntPtr}");
透過以上方式即可獲取到 X11 視窗指標
但是必須說明的是,使用反射獲取,也許在後續版本將會失效
本文程式碼放在 github 和 gitee 上,可以使用如下命令列拉取程式碼
先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 0f1d39d4f2bde2e60d790cb14302b5397ca0ae9c
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 0f1d39d4f2bde2e60d790cb14302b5397ca0ae9c
獲取程式碼之後,進入 UnoDemo/ChuchejairqaibalNallnowequyalgaw 資料夾,即可獲取到原始碼