本文將告訴大家如何在 dotnet 裡面的後臺執行緒設定 X11 視窗的最小化
核心設定 X11 視窗最小化的方法是 XIconifyWindow 方法,核心問題是在後臺執行緒需要自己使用 XOpenDisplay 獲取 Display 物件,且必須呼叫 XCloseDisplay 時才能生效
核心程式碼如下
_ = Task.Run(async () =>
{
while (true)
{
var display1 = XOpenDisplay(IntPtr.Zero);
var screen1 = XDefaultScreen(display1);
try
{
await Task.Delay(TimeSpan.FromSeconds(1));
var result = XIconifyWindow(display1, windowHandle, screen1);
Console.WriteLine($"XIconifyWindow {result}");
}
finally
{
XCloseDisplay(display1);
}
}
});
以上程式碼的 windowHandle 的建立程式碼如下
var display = XOpenDisplay(IntPtr.Zero);
var screen = XDefaultScreen(display);
... // 忽略其他程式碼
var windowHandle = XCreateWindow(display, rootWindow, 0, 0, xDisplayWidth, xDisplayHeight, 5,
32,
(int)CreateWindowArgs.InputOutput,
visual,
(nuint)valueMask, ref xSetWindowAttributes);
在 Task.Run 裡面,不能使用外面 display 物件,否則在 XIconifyWindow 方法將不會返回
如果沒有呼叫 XCloseDisplay 則 XIconifyWindow 的設定是無效的
本文程式碼放在 github 和 gitee 上,可以使用如下命令列拉取程式碼
先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 33dbc36c47d6f1e68265c0f0f389a566823425fd
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 33dbc36c47d6f1e68265c0f0f389a566823425fd
獲取程式碼之後,進入 DikalehebeekaJaqunicobo 資料夾,即可獲取到原始碼
後續進行更多測試,找到了 XFlush 和 XSync 方法,即不需要建立和關閉 display 物件。但實際測試發現透過如下程式碼方式,將需要在一定的時機下才能生效,比如滑鼠在視窗內晃動,或者重新啟用視窗才能生效
_ = Task.Run(async () =>
{
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var result = XIconifyWindow(display, handle, screen);
XFlush(display);
}
});
完全的程式碼如下
// See https://aka.ms/new-console-template for more information
using 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.BackPixmap
0
| 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 result = XIconifyWindow(display, handle, screen);
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 cf6f4749e4f90e44b671482e289dfaf1b24f5896
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin cf6f4749e4f90e44b671482e289dfaf1b24f5896
獲取程式碼之後,進入 DikalehebeekaJaqunicobo 資料夾,即可獲取到原始碼
更多 X11 開發請參閱 部落格導航