首页 > 其他分享 >学习 Avalonia 框架笔记 如何创建一个全屏置顶的 X11 应用窗口

学习 Avalonia 框架笔记 如何创建一个全屏置顶的 X11 应用窗口

时间:2024-04-25 09:25:18浏览次数:15  
标签:IntPtr XLib window 全屏 var X11 true display 置顶

本文记录我从 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 窗口

以上代码是从 https://github.com/AvaloniaUI/Avalonia/blob/b5db6bb0f6c19070e2a09a23231bcc1e01c40610/src/Avalonia.X11/X11Window.cs 里面抄的

分别是 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);

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

先创建一个空文件夹,接着使用命令行 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 等相关技术,请参阅 博客导航

标签:IntPtr,XLib,window,全屏,var,X11,true,display,置顶
From: https://www.cnblogs.com/lindexi/p/18127919

相关文章

  • vscode remote-x11 ssh 连接时Another All configured authentication methods failed
    错误remote-x11-ssh插件使用ssh2扩展出现以下错误https://github.com/joelspadin/vscode-remote-x11/issues/75Error:Allconfiguredauthenticationmethodsfailed原因https://github.com/mscdex/ssh2/issues/989解决换成ed25519并修改配置......
  • HarmonyOS NEXT应用开发案例——全屏登录页面
    全屏登录页面介绍本例介绍各种应用登录页面。全屏登录页面:在主页面点击跳转到全屏登录页后,显示全屏模态页面,全屏模态页面从下方滑出并覆盖整个屏幕,模态页面内容自定义,此处分为默认一键登录方式和其他登录方式。效果图预览使用说明点击主页面按钮"点击跳转到全屏登录页",......
  • x11 转 wayland 后 qBittorrent 启动闪退
    qBittorrent启动闪退date:2024-04-12在启动中心(菜单栏)点击qBittorrent无法启动,没有错误信息,没有启动画面,就像什么都没有发生。从终端启动也是什么都没有发生。最近系统进行了升级,可能是x11升级到了wayland解决办法:删除配置文件夹~/.config/qBittorrent/即可$print......
  • js设置浏览器全屏,无地址栏
    html:<p><buttonid="view-fullscreen">全屏</button><buttonid="cancel-fullscreen">退出</button></p>js://JavaScriptDocument(function(){varviewFullScreen=document.getEleme......
  • 火狐浏览器看视频全屏时会黑一下屏幕
    火狐浏览器看视频全屏时会黑一下屏幕在浏览器地址栏输入:“about:config”(不包含引号,下同)并回车,然后点击“我知道了”,可以进入高级设置界面。在地址栏下方的搜索栏中输入:“full-screen-api.transition-duration”,首选项中出现两项设置,分别双击并把数值修改为“00”(注意中......
  • .NET MAUI设置windows下自动全屏显示
    来源:https://www.saoniuhuo.com/question/detail-2593977.html方式1MainPage.xaml对应的cs文件中namespaceXCGMauiApp{publicpartialclassMainPage:ContentPage{publicMainPage(){InitializeComponent();}......
  • Ubuntu22.04修改默认窗口系统为X11
    Ubuntu22.04安装默认窗口系统为Wayland(通过设置->关于可以看到)。一、用UbuntuonXorg会话登录用户登录时,点“未列出”,输入用户名后,在登录界面底部的齿轮图标中,选择"UbuntuonXorg"作为会话类型登录,系统将为当前会话使用Xorg。如果每次手动选择Xorg登录,系统应该记住选......
  • 第三个OpenGL程序,shaders _ 后续 之 moreAttribute (设置顶点位置属性 颜色位置属性),从
    效果: 代码main.cpp#include<iostream>#include<glad/glad.h>#include<glfw3.h>#include<math.h>usingnamespacestd;//回调函数,每当窗口改变大小,视口大小也跟随改变voidframebuffer_size_callback(GLFWwindow*window,intwidth,intheight){glV......
  • AHK v2实例:任意置顶窗口透明
    我使用WinSetTransColor而不是WinSetTransparent,这样透明更柔和^\::{active:=WinGetTitle("A")Transparent:=WinGetTransparent("A")If(Transparent=""){WinSetTransColor"800050240",active}ElseIf(......
  • js数组置顶元素(将某一项移到首位)
    方法1letarr=[1,2,3]//假设选中的元素为第二个arr.forEach((item,index)=>{ if(item===2){ arr.unshift(arr.splice(index,1)[0])}})console.log(arr)//[2,1,3]方法2letarr=[1,2,3,4]letkey=3//假设选中的元素为第二个for(leti=1;i<arr.length;i++){if(arr[i]==......