Skip to content

Commit c937424

Browse files
Further fixes
1 parent a983495 commit c937424

16 files changed

Lines changed: 2843 additions & 202451 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ uWindowCapture.log
7979

8080
# External native libraries - build them by yourself
8181
Assets/MATE\ ENGINE\ -\ Packages/StandaloneFileBrowser/Plugins/Linux/x86_64/
82+
Assets/MATE\ ENGINE\ -\ Packages/StandaloneFileBrowser/Plugins/Linux/x86_64.meta
Binary file not shown.

Assets/ChineseCharacters.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
动画变化时间转场开始舞蹈音量角色置顶会跳头部望向鼠标指针大小保存重总计面数骨骼上限设宠物效果菜单质极致非常高中低花圈添加移除语言载模组实验性功能坐在窗口和任务栏此可导带有反作弊的游戏被封号简体繁體文欢迎使用这是一个仍处发阶段应程序如何快速手只要右键点击打选项你以更改或关闭特将让入白名块与自定义型件接下来我介绍若需从等网站得到后并按钮资源管理器择候失败通不问题而因为出了错误着架遇种情况请查看官方说明档些试图修复损坏但未也确確正户责过完成嘿主人样子爱吗嗎放公抱啦啊呀好喂求轻别那把举起尴尬新灯光颜饱度强全局启氛围环境闹钟测制进行垃圾回收于调知道其际屏幕护经桌闲直蔽多逆运学脚适合获取女风格目跟踪灵敏传缺缩略随脊椎步返停心嘻现台偶像哦对决才输呢休息终歇儿就嗯地舒服工喵里安静待约忙碌油很辛苦陪嘘充电扰马卡龙午睡吧枕股甜味做梦软绵感觉掉太去樱古基事提示信渡系统词删聊天历史级級~!…()—{}【】「」[];:‘’“”《》,。?
Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/MATE ENGINE - Fonts/Asia Fonts/ChineseSimplified.asset

Lines changed: 2514 additions & 2526 deletions
Large diffs are not rendered by default.
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
#if !UNITY_EDITOR
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Runtime.InteropServices;
6+
using Gtk;
7+
using Unity.Collections;
8+
using UnityEngine;
9+
using X11;
10+
using Debug = UnityEngine.Debug;
11+
12+
public static class EarlyEnvSet
13+
{
14+
[DllImport("libc")]
15+
private static extern IntPtr setenv(string name, string value, int overwrite);
16+
17+
[DllImport(X11Manager.LibX11)]
18+
private static extern int XGetWindowAttributes(IntPtr display, IntPtr window, out X11Manager.XWindowAttributes attributes);
19+
20+
[DllImport(X11Manager.LibXRender)]
21+
private static extern IntPtr XRenderFindVisualFormat(IntPtr display, IntPtr visual);
22+
23+
[DllImport(X11Manager.LibX11)]
24+
private static extern IntPtr XOpenDisplay(string displayName);
25+
26+
[DllImport(X11Manager.LibX11)]
27+
private static extern IntPtr XInternAtom(IntPtr display, string atomName, bool onlyIfExists);
28+
29+
[DllImport(X11Manager.LibX11)]
30+
private static extern IntPtr XDefaultRootWindow(IntPtr display);
31+
32+
[DllImport(X11Manager.LibX11)]
33+
private static extern bool XTranslateCoordinates(IntPtr display, IntPtr srcW, IntPtr destW,
34+
int srcX, int srcY, out int destX, out int destY, out IntPtr child);
35+
36+
[DllImport(X11Manager.LibX11)]
37+
private static extern int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr property,
38+
long longOffset, long longLength, bool delete, IntPtr reqType,
39+
out IntPtr actualTypeReturn, out int actualFormatReturn,
40+
out ulong nItemsReturn, out ulong bytesAfterReturn, out IntPtr propReturn);
41+
42+
[DllImport(X11Manager.LibX11)]
43+
private static extern int XGetSelectionOwner(IntPtr display, IntPtr atom);
44+
45+
[DllImport(X11Manager.LibX11)]
46+
private static extern int XScreenCount(IntPtr display);
47+
48+
[DllImport(X11Manager.LibX11)]
49+
private static extern int XFree(IntPtr data);
50+
51+
52+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
53+
private static void InitBeforeAnything()
54+
{
55+
setenv("GDK_BACKEND", "x11", 0);
56+
setenv("NO_AT_BRIDGE", "1", 0);
57+
string[] argc = { };
58+
if (!Init.Check(ref argc))
59+
{
60+
throw new Exception("Gtk initialization failed.");
61+
}
62+
var display = XOpenDisplay(null);
63+
if (display == IntPtr.Zero)
64+
{
65+
throw new Exception("Cannot open X11 display");
66+
}
67+
CheckVisual(display, out IntPtr window);
68+
if (!IsCompositionSupported(display))
69+
{
70+
Gdk.Window unityWindow = GdkX11Helper.ForeignNewForDisplay(window);
71+
var dummyParent = new Window("");
72+
dummyParent.Realize();
73+
dummyParent.SkipTaskbarHint = true;
74+
dummyParent.SkipPagerHint = true;
75+
dummyParent.Decorated = false;
76+
dummyParent.Window.Reparent(unityWindow, 0, 0);
77+
var dialog = new MessageDialog(dummyParent, DialogFlags.DestroyWithParent, MessageType.Warning, ButtonsType.Ok, false, "Composition is unavailable for this window manager.");
78+
dialog.SecondaryText = "A compositor is required for MateEngine to show a transparent background.\n\nIf you are running MateEngine on WMs that don't compose (like Openbox), try installing a compositing manager (such as picom) and configure it correctly, or simply switch to Mutter (GNOME), Xfwm4 (Xfce4) and other WMs which natively supports composition.\n\nIf you are running KWin (KDE), please make sure \"Allow applications to block compositing\" is turned off in KDE System Settings (It's in the compositor section of Display and Monitor).";
79+
dialog.MessageType = MessageType.Warning;
80+
var image = new Image(new Gdk.Pixbuf(Resources.Load<Texture2D>("KWinHint").EncodeToPNG()));
81+
image.Halign = Align.Center;
82+
image.Show();
83+
dialog.ContentArea?.PackStart(image, false, false, 0);
84+
dialog.ShowAll();
85+
dialog.Run();
86+
}
87+
}
88+
89+
private static bool IsCompositionSupported(IntPtr display)
90+
{
91+
for (int screen = 0; screen < XScreenCount(display); screen++)
92+
{
93+
IntPtr selectionAtom = XInternAtom(display, "_NET_WM_CM_S" + screen, false);
94+
if (selectionAtom == IntPtr.Zero)
95+
continue;
96+
return XGetSelectionOwner(display, selectionAtom) != 0;
97+
}
98+
return false;
99+
}
100+
101+
static void CheckVisual(IntPtr display, out IntPtr window)
102+
{
103+
int pid = Process.GetCurrentProcess().Id;
104+
List<IntPtr> windows = FindWindowsByPid(display, pid);
105+
106+
IntPtr unityWindow = IntPtr.Zero;
107+
108+
if (windows.Count > 0)
109+
{
110+
unityWindow = windows[0]; // Typically the first is the main window
111+
}
112+
window = unityWindow;
113+
if (XGetWindowAttributes(display, unityWindow, out X11Manager.XWindowAttributes attrs) == 0)
114+
{
115+
Debug.LogError("Failed to get window attributes");
116+
return;
117+
}
118+
119+
if (attrs.depth != 32 || !IsArgbVisual(display, attrs.visual))
120+
{
121+
Gdk.Window gdkWindow = GdkX11Helper.ForeignNewForDisplay(unityWindow);
122+
var dummyParent = new Window("");
123+
dummyParent.Realize();
124+
dummyParent.SkipTaskbarHint = true;
125+
dummyParent.SkipPagerHint = true;
126+
dummyParent.Decorated = false;
127+
dummyParent.Window.Reparent(gdkWindow, 0, 0);
128+
var dialog = new MessageDialog(dummyParent, DialogFlags.DestroyWithParent, MessageType.Warning, ButtonsType.Ok, false, "It looks like MateEngine is not running under an ARGB visual.");
129+
dialog.SecondaryText = "MateEngine must rely on a true transparent canvas (aka ARGB visual) to show a transparent background. Without it, your avatar will display on a big black background.\n\nTo acquire an ARGB visual, try launching MateEngine using the launch script (usually called launch.sh) provided in MateEngine executable path.";
130+
dialog.MessageType = MessageType.Warning;
131+
dialog.Run();
132+
}
133+
}
134+
135+
private static bool IsArgbVisual(IntPtr display, IntPtr visual)
136+
{
137+
IntPtr formatPtr = XRenderFindVisualFormat(display, visual);
138+
if (formatPtr == IntPtr.Zero) return false;
139+
140+
X11Manager.XRenderPictFormat format = Marshal.PtrToStructure<X11Manager.XRenderPictFormat>(formatPtr);
141+
return format.type == 1 && format.direct.alphaMask != 0;
142+
}
143+
144+
private static List<IntPtr> FindWindowsByPid(IntPtr display, int targetPid)
145+
{
146+
var result = new List<IntPtr>();
147+
var atom = XInternAtom(display, "_NET_WM_PID", false);
148+
149+
if (atom == IntPtr.Zero)
150+
{
151+
Debug.Log("_NET_WM_PID atom not found");
152+
return result;
153+
}
154+
155+
var windows = GetAllVisibleWindows(display, XDefaultRootWindow(display));
156+
157+
foreach (var window in windows)
158+
{
159+
int pid = GetWindowPid(display, window, atom);
160+
if (pid == targetPid)
161+
{
162+
result.Add(window);
163+
}
164+
}
165+
166+
return result;
167+
}
168+
169+
private static int GetWindowPid(IntPtr display, IntPtr window, IntPtr pidAtom)
170+
{
171+
int status = XGetWindowProperty(display, window, pidAtom,
172+
0, 1, false, (IntPtr)6,
173+
out _, out _,
174+
out var nItems, out _, out var prop);
175+
176+
if (status == 0 && prop != IntPtr.Zero && nItems > 0)
177+
{
178+
int pid = Marshal.ReadInt32(prop);
179+
XFree(prop);
180+
return pid;
181+
}
182+
183+
return -1;
184+
}
185+
186+
private static bool IsWindowVisible(IntPtr display, IntPtr rootWindow, IntPtr window)
187+
{
188+
if (display == IntPtr.Zero) return false;
189+
190+
int result = XGetWindowAttributes(display, window, out X11Manager.XWindowAttributes attr);
191+
if (result == 0 || attr.map_state != 2) return false;
192+
193+
if (!XTranslateCoordinates(display, window, rootWindow, 0, 0, out int absX, out int absY, out _))
194+
return false;
195+
196+
float targetX1 = absX;
197+
float targetY1 = absY;
198+
float targetX2 = absX + attr.width;
199+
float targetY2 = absY + attr.height;
200+
float targetArea = (float)attr.width * attr.height;
201+
202+
List<IntPtr> stacking = GetClientStackingList(display, rootWindow);
203+
int index = stacking.IndexOf(window);
204+
if (index < 0) return false;
205+
206+
List<(float x1, float y1, float x2, float y2)> coversList = new();
207+
for (int i = index + 1; i < stacking.Count; i++)
208+
{
209+
IntPtr ow = stacking[i];
210+
XGetWindowAttributes(display, ow, out X11Manager.XWindowAttributes oattr);
211+
if (oattr.map_state != 2) continue;
212+
213+
if (!XTranslateCoordinates(display, ow, rootWindow, 0, 0, out int oabsX, out int oabsY, out _))
214+
continue;
215+
216+
float ox1 = oabsX;
217+
float oy1 = oabsY;
218+
float ox2 = oabsX + oattr.width;
219+
float oy2 = oabsY + oattr.height;
220+
221+
float ix1 = Math.Max(targetX1, ox1);
222+
float iy1 = Math.Max(targetY1, oy1);
223+
float ix2 = Math.Min(targetX2, ox2);
224+
float iy2 = Math.Min(targetY2, oy2);
225+
if (ix1 < ix2 && iy1 < iy2)
226+
{
227+
coversList.Add((ix1, iy1, ix2, iy2));
228+
}
229+
}
230+
231+
if (coversList.Count == 0) return true;
232+
233+
// Burst-optimized union area computation
234+
NativeArray<X11Manager.RectF> covers = new NativeArray<X11Manager.RectF>(coversList.Count, Allocator.Temp);
235+
for (int i = 0; i < coversList.Count; i++)
236+
{
237+
var t = coversList[i];
238+
covers[i] = new X11Manager.RectF { x1 = t.x1, y1 = t.y1, x2 = t.x2, y2 = t.y2 };
239+
}
240+
float coveredArea = X11Manager.UnionAreaCalculator.Compute(covers);
241+
covers.Dispose();
242+
243+
return coveredArea < targetArea - 1e-4f;
244+
}
245+
246+
private static List<IntPtr> GetClientStackingList(IntPtr display, IntPtr rootWindow)
247+
{
248+
IntPtr atom = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", false);
249+
if (atom == IntPtr.Zero) return new List<IntPtr>();
250+
251+
int status = XGetWindowProperty(display, rootWindow, atom, 0, 1024, false, (IntPtr)33,
252+
out _, out int actualFormat, out ulong nItems, out _, out IntPtr prop);
253+
254+
if (status != 0 || prop == IntPtr.Zero || nItems == 0 || actualFormat != 32)
255+
{
256+
if (prop != IntPtr.Zero) XFree(prop);
257+
return new List<IntPtr>();
258+
}
259+
260+
List<IntPtr> windows = new List<IntPtr>((int)nItems);
261+
for (int i = 0; i < (int)nItems; i++)
262+
{
263+
IntPtr w = Marshal.ReadIntPtr(prop, (i * IntPtr.Size));
264+
windows.Add(w);
265+
}
266+
XFree(prop);
267+
return windows;
268+
}
269+
270+
private static List<IntPtr> GetAllVisibleWindows(IntPtr display, IntPtr rootWindow)
271+
{
272+
var result = new List<IntPtr>();
273+
274+
IntPtr clientListAtom = XInternAtom(display, "_NET_CLIENT_LIST", true);
275+
if (clientListAtom != IntPtr.Zero)
276+
{
277+
int status = XGetWindowProperty(display, rootWindow, clientListAtom, 0, 1024, false, (IntPtr)33,
278+
out IntPtr actualType, out int actualFormat, out ulong nItems, out _, out IntPtr prop);
279+
280+
if (status == 0 && actualType == (IntPtr)33 && actualFormat == 32 && prop != IntPtr.Zero)
281+
{
282+
for (ulong i = 0; i < nItems; i++)
283+
{
284+
IntPtr win = Marshal.ReadIntPtr(prop, (int)(i * (ulong)IntPtr.Size));
285+
if (IsWindowVisible(display, rootWindow, win))
286+
{
287+
result.Add(win);
288+
}
289+
}
290+
XFree(prop);
291+
return result;
292+
}
293+
if (prop != IntPtr.Zero) XFree(prop);
294+
}
295+
return result;
296+
}
297+
}
298+
#endif

Assets/MATE ENGINE - Scripts/APIs/EarlyEnvSet.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/MATE ENGINE - Scripts/APIs/TrayIndicator.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ private static extern ulong g_signal_connect_data(IntPtr instance,
8787
private void OnEnable()
8888
{
8989
Instance = this;
90-
string[] argc = { };
91-
initialized = Gtk.Init.Check(ref argc);
9290
}
9391

9492
private void Update()

0 commit comments

Comments
 (0)