学习 Avalonia 框架笔记 如何创建一个全屏置顶的 X11 应用窗口
本文记录我从 Avalonia 框架里面学到如何创建一个全屏置顶的 X11 应用窗口的方法
开始之前,先从 Avalonia 或 CPF 里面拷贝足够的代码,这部分代码可以从本文末尾找到下载方法
设置全屏的核心代码是以下三行
ChangeWMAtoms(false, XLib.XInternAtom(display, "_NET_WM_STATE_HIDDEN", true));
ChangeWMAtoms(true, XLib.XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true));
ChangeWMAtoms(false, XLib.XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", true),
XLib.XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", true));
设置置顶的代码如下
// 最顶层 类似 WPF 的 Topmost 功能
ChangeWMAtoms(true, XLib.XInternAtom(display, "_NET_WM_STATE_ABOVE", true));
以上代码的 ChangeWMAtoms 是一个内部方法,实现如下
var wmState = XLib.XInternAtom(display, "_NET_WM_STATE", true);
void ChangeWMAtoms(bool enable, params IntPtr[] atoms)
{
var xev = new XEvent
{
ClientMessageEvent =
{
type = XEventName.ClientMessage,
send_event = true,
window = window,
message_type = wmState,
format = 32,
ptr1 = new IntPtr(enable ? 1 : 0),
ptr2 = (IntPtr?)atoms[0] ?? IntPtr.Zero,
ptr3 = (IntPtr?)(atoms.Length > 1 ? atoms[1] : IntPtr.Zero) ?? IntPtr.Zero,
ptr4 = (IntPtr?)(atoms.Length > 2 ? atoms[2] : IntPtr.Zero) ?? IntPtr.Zero
}
};
XLib.XSendEvent(display, rootWindow, false,
new IntPtr((int)(EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
}
如此即可获取一个全屏且在所有窗口,包括任务栏的上层的最顶层 X11 窗口
分别是 WindowState 属性的 set 方法以及 SetTopmost 方法
为了让大家能够看到窗口在最顶层的效果,接下来绘制两条线段,用来作为界面,代码如下
var white = XLib.XWhitePixel(display, screen);
var black = XLib.XBlackPixel(display, screen);
XLib.XSetForeground(display, gc, white);
var xDisplayWidth = XLib.XDisplayWidth(display, screen);
var xDisplayHeight = XLib.XDisplayHeight(display, screen);
while (XLib.XNextEvent(display, out var xEvent) == default)
{
if (xEvent.type == XEventName.Expose)
{
XLib.XDrawLine(display, window, gc, 0, 0, xDisplayWidth, xDisplayHeight);
XLib.XDrawLine(display, window, gc, 0, xDisplayHeight, xDisplayWidth, 0);
}
}
完成之后运行代码,以下是我在 Hyperv 虚拟机的运行效果,可以看到绘制的两条线段在所有应用上方,也在任务栏上方
完全的 Program.cs 文件的代码如下
using CeaherecelallLemlalnohuce;
XLib.XInitThreads();
var display = XLib.XOpenDisplay(0);
var screen = XLib.XDefaultScreen(display);
var defaultScreen = XLib.XDefaultScreen(display);
var rootWindow = XLib.XRootWindow(display, defaultScreen);
XLib.XMatchVisualInfo(display, screen, 32, 4, out var info);
var visual = info.visual;
var valueMask = SetWindowValuemask.BackPixmap
| SetWindowValuemask.BackPixel
| SetWindowValuemask.BorderPixel
| SetWindowValuemask.BitGravity
| SetWindowValuemask.WinGravity
| SetWindowValuemask.BackingStore
| SetWindowValuemask.ColorMap;
var attr = new XSetWindowAttributes
{
backing_store = 1,
bit_gravity = Gravity.NorthWestGravity,
win_gravity = Gravity.NorthWestGravity,
override_redirect = false, // 参数:_overrideRedirect
colormap = XLib.XCreateColormap(display, rootWindow, visual, 0),
};
var window = XLib.XCreateWindow(display, rootWindow, 100, 100, 320, 240, 0,
32,
(int)CreateWindowArgs.InputOutput,
visual,
(nuint)valueMask, ref attr);
XEventMask ignoredMask = XEventMask.SubstructureRedirectMask | XEventMask.ResizeRedirectMask |
XEventMask.PointerMotionHintMask;
var mask = new IntPtr(0xffffff ^ (int)ignoredMask);
XLib.XSelectInput(display, window, mask);
var gc = XLib.XCreateGC(display, window, 0, 0);
XLib.XMapWindow(display, window);
XLib.XFlush(display);
#region 全屏 最顶层
var wmState = XLib.XInternAtom(display, "_NET_WM_STATE", true);
ChangeWMAtoms(false, XLib.XInternAtom(display, "_NET_WM_STATE_HIDDEN", true));
ChangeWMAtoms(true, XLib.XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true));
ChangeWMAtoms(false, XLib.XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", true),
XLib.XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", true));
// 最顶层 类似 WPF 的 Topmost 功能
ChangeWMAtoms(true, XLib.XInternAtom(display, "_NET_WM_STATE_ABOVE", true));
void ChangeWMAtoms(bool enable, params IntPtr[] atoms)
{
var xev = new XEvent
{
ClientMessageEvent =
{
type = XEventName.ClientMessage,
send_event = true,
window = window,
message_type = wmState,
format = 32,
ptr1 = new IntPtr(enable ? 1 : 0),
ptr2 = (IntPtr?)atoms[0] ?? IntPtr.Zero,
ptr3 = (IntPtr?)(atoms.Length > 1 ? atoms[1] : IntPtr.Zero) ?? IntPtr.Zero,
ptr4 = (IntPtr?)(atoms.Length > 2 ? atoms[2] : IntPtr.Zero) ?? IntPtr.Zero
}
};
XLib.XSendEvent(display, rootWindow, false,
new IntPtr((int)(EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
}
#endregion
var white = XLib.XWhitePixel(display, screen);
var black = XLib.XBlackPixel(display, screen);
XLib.XSetForeground(display, gc, white);
var xDisplayWidth = XLib.XDisplayWidth(display, screen);
var xDisplayHeight = XLib.XDisplayHeight(display, screen);
while (XLib.XNextEvent(display, out var xEvent) == default)
{
if (xEvent.type == XEventName.Expose)
{
XLib.XDrawLine(display, window, gc, 0, 0, xDisplayWidth, xDisplayHeight);
XLib.XDrawLine(display, window, gc, 0, xDisplayHeight, xDisplayWidth, 0);
}
}
XLib.XUnmapWindow(display, window);
XLib.XDestroyWindow(display, window);
本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 693a137d9349bc65b5e2ed3a7c5d2480775e621a
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 693a137d9349bc65b5e2ed3a7c5d2480775e621a
获取代码之后,进入 CeaherecelallLemlalnohuce 文件夹,即可获取到源代码
更多 Avalonia 以及 X11 等相关技术,请参阅 博客导航
学习 Avalonia 框架笔记 如何创建一个全屏置顶的 X11 应用窗口的更多相关文章
- mfc实现对话框全屏置顶显示
一.MFC让对话框窗口始终在最前 方法一:在对话框的属性中,把SystemModal设置为True. 二.全屏显示 在CDialog7::OnInitDialog()中加入: 先取得分辨率, int ...
- 深度学习Keras框架笔记之Dense类(标准的一维全连接层)
深度学习Keras框架笔记之Dense类(标准的一维全连接层) 例: keras.layers.core.Dense(output_dim,init='glorot_uniform', activat ...
- 深度学习Keras框架笔记之TimeDistributedDense类
深度学习Keras框架笔记之TimeDistributedDense类使用方法笔记 例: keras.layers.core.TimeDistributedDense(output_dim,init= ...
- 深度学习Keras框架笔记之AutoEncoder类
深度学习Keras框架笔记之AutoEncoder类使用笔记 keras.layers.core.AutoEncoder(encoder, decoder,output_reconstruction= ...
- yii学习笔记--快速创建一个项目
下载yii框架 下载地址:http://www.yiiframework.com/ 中文网站:http://www.yiichina.com/ 解压文件
- django examples 学习笔记(1)创建一个独立的python环境
pip install virtualenv 创建一个虚拟环境 virtualenv my_env 创建一个独立的环境 source my_env/bin/activate 激活 ...
- 一个先进的App框架:使用Ionic创建一个简单的APP
原文 http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...
- ROS学习记录(三)————创建一个简单的发布节点和订阅节点
暑假在家有些懈怠,不,非常懈怠- -||!良心已经发痛了,想快些补回原来的进度,但忽然发现,中断了一段时间再重新去学习,有的地方连最基本的符号都忘记了 ,这次特意弄个最最基础的,恢复一下,以前的进度. ...
- 我的Go语言学习之旅七:创建一个GUI窗口
在上次中,刚刚学过了 弹窗效果.这里再接着学习一下怎样创建一个窗口. 还是老路子,先上代码: package main import ( "github.com/lxn/go-winapi ...
- Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程
陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 登陆实验楼 ...
随机推荐
- 面试官:volatile如何保证可见性的,具体如何实现?
写在开头 在之前的几篇博文中,我们都提到了 volatile 关键字,这个单词中文释义为:不稳定的,易挥发的,在Java中代表变量修饰符,用来修饰会被不同线程访问和修改的变量,对于方法,代码块,方法参 ...
- 记录--H5页面对接微信支付踩坑杂记
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 背景 应用背景:vite搭建的vue3项目 需求背景:功能都涉及了支付业务,故需要和外部支付系统对接 外部支付系统:聚合支付.微信小程序支 ...
- PyQt5报错:This application failed to start because no Qt platform plugin could be initialized
问题背景: 想使用PyQt5来创建一个可视化窗口,先在pycharm里面安装PyQt5,版本为5.14.0.之后在代码中调用此包:from PyQt5 import QtCore, QtGui, Qt ...
- CentOS 安装webmin
下载地址 http://download.webmin.com/download/yum/ 安装依赖 sudo yum -y install openssl perl perl-Net-SSLeay ...
- 算法学习笔记【5】| ST表
ST表 Part 1:ST表解决的问题是什么 ST 表可以用来解决RMQ(区间最值问题)等可重复贡献的问题. ST表基于倍增的思想来实现. Part 2:ST表的实现 ST表通过 O(nlogn)& ...
- C++ 线程安全的队列
无界队列 #include<queue> #include<mutex> #include<condition_variable> #include<opti ...
- SQL 查询优化指南:SELECT、SELECT DISTINCT、WHERE 和 ORDER BY 详解
SELECT 关键字 SQL的SELECT语句用于从数据库中选择数据.SELECT语句的基本语法如下: SELECT column1, column2, ... FROM table_name; 其中 ...
- C# 报错 Lc.exe已退出 代码为-1 如何解决
完美解决方案:把项目文件夹下Properties文件夹下的licenses.licx文件删除,重新编译即可:
- Qt 实现涂鸦板三:实现鼠标绘制矩形
.h 文件 #pragma once #include <QtWidgets/QWidget> #include "ui_xuexi.h" #include " ...
- django admin后台自定义数据保存方式
故事背景是这样的: 为了方便工作中数据的整理,需要开发一个 管理系统,用于记录一些事情. 该系统不需要精美的前端的页面,只需要使用django的admin后台管理就可以了. 我需要在添加数据的时候,把 ...