dotnet 在 UNO 裡獲取 X11 視窗指標的方法

lindexi發表於2024-05-23

在 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 視窗指標

但是必須說明的是,使用反射獲取,也許在後續版本將會失效

本文程式碼放在 githubgitee 上,可以使用如下命令列拉取程式碼

先建立一個空資料夾,接著使用命令列 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 資料夾,即可獲取到原始碼

相關文章