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

news/2024/9/21 12:36:54

本文将告诉大家如何在 dotnet 里面的后台线程向自己进程内的窗口发送消息

核心是通过 XSendEvent 发送消息,发送消息想要有反应需要另开 XOpenDisplay 获取 display 对象,最后再将其关闭才能发送出去

核心代码如下

_ = Task.Run(async () =>
{while (true){await Task.Delay(TimeSpan.FromSeconds(1));var display1 = XOpenDisplay(IntPtr.Zero);try{var @event = new XEvent{ClientMessageEvent ={type = XEventName.ClientMessage,send_event = true,window = handle,message_type = 0,format = 32,ptr1 = 0,ptr2 = 0,ptr3 = 0,ptr4 = 0,}};XSendEvent(display1, handle, false, 0, ref @event);}finally{XCloseDisplay(display1);}}
});

以上的 handle 是一个 X11 窗口指针,代码如下

var display = XOpenDisplay(IntPtr.Zero);
var screen = XDefaultScreen(display);var handle = XCreateWindow(display, rootWindow, 0, 0, xDisplayWidth, xDisplayHeight, 5,32,(int)CreateWindowArgs.InputOutput,visual,(nuint)valueMask, ref xSetWindowAttributes);

如果在 Task.Run 后台线程里面,使用的是外面的 display 对象,则发送失败

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

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

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

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

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

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

更多 X11 开发请参阅 博客导航

再经过更多的测试和阅读大佬们的示例代码,发现只需带上 XFlush 即可,更改之后的代码如下

_ = Task.Run(async () =>
{while (true){await Task.Delay(TimeSpan.FromSeconds(1));var @event = new XEvent{ClientMessageEvent ={type = XEventName.ClientMessage,send_event = true,window = handle,message_type = 0,format = 32,ptr1 = 0,ptr2 = 0,ptr3 = 0,ptr4 = 0,}};XSendEvent(display, handle, false, 0, ref @event);XFlush(display);}
});

这里由于需要进行多线程共用一个 display 对象,根据 X11 文档,需要添加 XInitThreads 方法才能确保安全

完全的代码如下

// See https://aka.ms/new-console-template for more informationusing CPF.Linux;
using System;
using System.Diagnostics;
using System.Runtime;
using static CPF.Linux.XLib;XInitThreads();
var display = XOpenDisplay(IntPtr.Zero);
var screen = XDefaultScreen(display);var rootWindow = XDefaultRootWindow(display);XMatchVisualInfo(display, screen, 32, 4, out var info);
var visual = info.visual;var valueMask =//SetWindowValuemask.BackPixmap0| SetWindowValuemask.BackPixel| SetWindowValuemask.BorderPixel| SetWindowValuemask.BitGravity| SetWindowValuemask.WinGravity| SetWindowValuemask.BackingStore| SetWindowValuemask.ColorMap//| SetWindowValuemask.OverrideRedirect;
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 = 0,
};var xDisplayWidth = XDisplayWidth(display, screen) / 2;
var xDisplayHeight = XDisplayHeight(display, screen) / 2;
var handle = XCreateWindow(display, rootWindow, 0, 0, xDisplayWidth, xDisplayHeight, 5,32,(int)CreateWindowArgs.InputOutput,visual,(nuint)valueMask, ref xSetWindowAttributes);XEventMask ignoredMask = XEventMask.SubstructureRedirectMask | XEventMask.ResizeRedirectMask |XEventMask.PointerMotionHintMask;
var mask = new IntPtr(0xffffff ^ (int)ignoredMask);
XSelectInput(display, handle, mask);XMapWindow(display, handle);
XFlush(display);var white = XWhitePixel(display, screen);
var black = XBlackPixel(display, screen);var gc = XCreateGC(display, handle, 0, 0);
XSetForeground(display, gc, white);
XSync(display, false);_ = Task.Run(async () =>
{while (true){await Task.Delay(TimeSpan.FromSeconds(1));var @event = new XEvent{ClientMessageEvent ={type = XEventName.ClientMessage,send_event = true,window = handle,message_type = 0,format = 32,ptr1 = 0,ptr2 = 0,ptr3 = 0,ptr4 = 0,}};XSendEvent(display, handle, false, 0, ref @event);XFlush(display);}
});while (true)
{var xNextEvent = XNextEvent(display, out var @event);if (xNextEvent != 0){Console.WriteLine($"xNextEvent {xNextEvent}");break;}if (@event.type == XEventName.Expose){XDrawLine(display, handle, gc, 0, 0, 100, 100);}Console.WriteLine(@event.type);
}Console.WriteLine("Hello, World!");

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

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

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

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

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

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

更多 X11 开发请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/31681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

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

本文记录我阅读 Avalonia 代码过程中所学习到的在 X11 的窗口之间发送鼠标消息,可以跨进程给其他进程的窗口发送鼠标消息,通过此方式可以实现模拟鼠标输入直接使用 XSendEvent 给指定窗口发送消息即可,如以下示例代码var xEvent = new XEvent{MotionEvent ={type = XEventNa…

28-SpringMVC源码解析

Quiz:Spring和SpringMVC整合使用时,会创建一个容器还是两个容器(父子容器?) DispatcherServlet初始化过程中做了什么? 请求的执行流程是怎么样的?SpringMVC 是基于 Servlet 和 Spring 容器设计的 Web 框架。1. Servlet 回顾 Servlet 接口及其实现类结构:public interfa…

读人工智能时代与人类未来笔记03_演变

读人工智能时代与人类未来笔记03_演变1. 演变 1.1. 每个社会都找到了属于自己的一套适应世界的方法 1.1.1. 适应的核心,是有关人类心智与现实之间关系的概念 1.1.2. 人类认识周围环境的能力 1.1.2.1. 这种能力通过知识获得,同时…

爱芯通元产品与关键技术

爱芯通元产品与关键技术 混合精度NPU 以算子为原子指令集的AI计算处理器爱芯通元NPU采用多线程异构多核设计,实现算子、网络微结构、数据流和内存访问优化,高效支持混合精度算法设计,natively支持Transformer网络结构,为大模型在边缘侧、端侧的应用提供良好的基础。 经过多…

ffmpeg 去除音频中的静音

去除音频中的静音 //去除所有超过0.3秒的静音部分 ffmpeg -i input.mp3 -af silenceremove=stop_periods=-1:stop_duration=0.3:stop_threshold=-30dB -y output.mp3ffmpeg音频处理常用命令:调节音量大小ffmpeg -y -i input.mp3 -af volume=-10dB output.mp3 \n 主要是volume参…

基于异步协程的增量式微博网页版爬虫(一)思路篇

项目介绍 本项目旨在利用高级搜索功能,爬取微博网页版的详细数据。而大多数爬虫以单线程为主,但单线程存在资源利用率低的不足,针对这以问题,本项目主要使用如下技术: (1)多线程+协程技术+Redis实现增量式爬虫。实现过程中存在两个技术难点:一是使用redis数据传输时开销…

(9)FIFO ip核

一、FIFO简介 二、FIFO ip使用 使用方案: 操作: 在IP Catalog中找到这个 配置fifo: 生成ip:

imx6ull Linux内核构建

IMX6ULL的Linux内核编译步骤用户文档下载 在NXP官网的文档搜索界面,搜索Linux和User两个关键字就能查询到相关的文档 官网文档搜索地址:https://www.nxp.com.cn/design/documentation:DOCUMENTATION#/内核下载 在上面文档的第七章有交怎么下载以及编译内核#git安装 sudo apt-…