本文记录我学习开发 X11 应用的笔记

如何设置X11里面两个窗口之间的层级关系

如何类似 WPF 的 Owner 之类的关系?可使用 XSetTransientForHint 方法。比如有 a 和 b 两个窗口,使用下面代码即可设置 a 窗口一定在 b 窗口上方

        // 我们使用XSetTransientForHint函数将窗口a设置为窗口b的子窗口。这将确保窗口a始终在窗口b的上方
        XSetTransientForHint(Display, a, b);

以上代码放在 githubgitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 0331c5dd6057106df5cb179e45d34966a3eafd1b

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 0331c5dd6057106df5cb179e45d34966a3eafd1b

获取代码之后,进入 GececurbaiduhaldiFokeejukolu 文件夹,即可获取到源代码

以上为 Owner-Owned 关系方法,还有 Parent-Child 关系方法,详细请看 dotnet 设置 X11 建立窗口之间的父子关系

设置窗口无边框

设置窗口的override_redirect属性为True,以避免窗口管理器的干预,如此即可实现无边框

        var valueMask =
            0
            | SetWindowValuemask.OverrideRedirect;
        var xSetWindowAttributes = new XSetWindowAttributes
        {
            override_redirect = true, // 设置窗口的override_redirect属性为True,以避免窗口管理器的干预
        };

        var handle = XCreateWindow(Display, rootWindow, 100, 100, 1000, 500, 5,
            32,
            (int) CreateWindowArgs.InputOutput,
            visual,
            (nuint) valueMask, ref xSetWindowAttributes);

以上代码的 SetWindowValuemask.OverrideRedirect 十分重要,如果没有加上将会导致 override_redirect 设置无效

以上代码放在 githubgitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin dc1b79521e00300dfaef49d54226b6f687b25b3e

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin dc1b79521e00300dfaef49d54226b6f687b25b3e

获取代码之后,进入 GececurbaiduhaldiFokeejukolu 文件夹,即可获取到源代码

移动窗口

核心 C# 代码如下,即可移动 X11 窗口

XMoveWindow(display, handle, Random.Shared.Next(500), Random.Shared.Next(200));

完全的代码放在 githubgitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 8b5f024b002b2dbc2bd630c2ffcd24ece9b5a9c5

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 8b5f024b002b2dbc2bd630c2ffcd24ece9b5a9c5

获取代码之后,进入 DikalehebeekaJaqunicobo 文件夹,即可获取到源代码

设置窗口坐标过程中,是不会存在窗口移动动画的

配置 XCompositeRedirectSubwindows 将会导致窗口背景透明

如使用以下代码即可创建不透明背景窗口

var xSetWindowAttributes = new XSetWindowAttributes
{
    backing_store = 1,
    bit_gravity = Gravity.NorthWestGravity,
    win_gravity = Gravity.NorthWestGravity,
    //override_redirect = true, // 设置窗口的override_redirect属性为True,以避免窗口管理器的干预
    colormap = XCreateColormap(display, rootWindow, visual, 0),
    border_pixel = 0,
    background_pixel = new IntPtr(0xF5565656),
};

var childWindowHandle = XCreateWindow(display, rootWindow, 0, 0, xDisplayWidth, xDisplayHeight, 5,
    32,
    (int) CreateWindowArgs.InputOutput,
    visual,
    (nuint) valueMask, ref xSetWindowAttributes);

但是如果在此窗口加上 XCompositeRedirectSubwindows 将会导致窗口背景依然是透明的

var overlayWindow = childWindowHandle;
XCompositeRedirectSubwindows(display, overlayWindow, 1/*CompositeRedirectAutomatic*/);

以上代码放在 githubgitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 4fb78fdd2e18de5d2f7b5461c4f1ec662db50b77

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 4fb78fdd2e18de5d2f7b5461c4f1ec662db50b77

获取代码之后,进入 DikalehebeekaJaqunicobo 文件夹,即可获取到源代码

设置窗口透明

参阅: dotnet C# 设置 X11 应用窗口背景透明

和 Avalonia 相互调用

设置工具栏与 X11 窗口绘制的笔迹关联,要求 X11 笔迹窗口在下方,配合设置X11里面两个窗口之间的层级关系的方法即可实现

获取 Avalonia 的 X11 窗口,代码如下

    if (TryGetPlatformHandle()?.Handle is { } handle)
    {
    }

以上代码拿到的 handle 就是可以用来作为 X11 窗口的指针,类似于 Windows 下的窗口句柄概念

以上代码放在 githubgitee

和 UNO Gtk 相互调用

参阅 dotnet 如何从 Gtk 3 的窗口到对应的 X11 窗口

更多博客

dotnet X11 窗口之间发送鼠标消息 模拟鼠标输入

dotnet 后台线程发送 X11 窗口消息

dotnet 后台线程设置 X11 窗口最小化


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/dotnet-C-X11-%E5%BC%80%E5%8F%91%E7%AC%94%E8%AE%B0.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

微软最具价值专家


无盈利,不卖课,做纯粹的技术博客

以下是广告时间

推荐关注 Edi.Wang 的公众号

欢迎进入 Eleven 老师组建的 .NET 社区

以上广告全是友情推广,无盈利