无法使用 XReparentWindow 使窗口永久重定位

问题描述 投票:0回答:1

我正在开发一个 WinForms mono 应用程序供个人使用,用于管理远程连接。我一直在尝试找出一种方法将某些 X11 窗口重新设置为我的 WinForms 应用程序。我有这个功能在 Windows 上完美运行,但是 Linux 中的 X11 API 给我带来了问题。

我知道这可能是浪费时间,因为有更好的解决方案,但是我现在已经深入了解它,并且至少想知道为什么这不起作用,也许是否有解决方案。

我想将 Putty SSH 终端窗口重新设置为 WinForms 面板(WinForms 程序以单声道运行)。我可以使用 XReparentWindow 完成此操作,但是一秒钟后 Putty 窗口将取消父级返回到根窗口。它不会停留在 WinForms 面板上。

这些是我用来重新设置 Putty 窗口父级的 API 调用:

private static void ReparentWindow()
{
    IntPtr display = XOpenDisplay(Environment.GetEnvironmentVariable("DISPLAY"));
    IntPtr puttyWindowHandle = [handle_of_putty_window]; //I have a function here that finds a window by title and returns the handle
    IntPtr panelHandle = panTestPanel.Handle;

    XReparentWindow(display, puttyWindowHandle, panelHandle, 0, 0);
    XMapWindow(display, puttyWindowHandle);
    XFlush(display);
    XSync(display, false);
}

我也用其他程序尝试过这个,发现有些程序只会找到(计算器,gedit)而其他程序,特别是终端应用程序,根本不会保持父级。我对 X11 的了解不够,无法理解这是为什么以及是否有解决方案。我怀疑它与等待输入的终端应用程序有关,尽管我也尝试重新设置 gxlgears 作为测试,它有同样的问题,所以我不确定。

如有任何帮助或建议,我们将不胜感激。

更新的解决方案:

private static void ReparentWindow()
{
    IntPtr display = XOpenDisplay(Environment.GetEnvironmentVariable("DISPLAY"));
    IntPtr puttyWindowHandle = [handle_of_putty_window]; //I have a function here that finds a window by title and returns the handle
    IntPtr panelHandle = panTestPanel.Handle;

    //Set the override redirect flag on the window we want to reparent
    XSetWindowAttributes xSetWindowAttributes = new XSetWindowAttributes();
    xSetWindowAttributes.override_redirect = true;

    IntPtr attr = Marshal.AllocHGlobal (Marshal.SizeOf (xSetWindowAttributes));
    Marshal.StructureToPtr (xSetWindowAttributes, attr, false);

    XChangeWindowAttributes (display, puttyWindowHandle, XWindowAttributeFlags.CWOverrideRedirect, attr);

    Marshal.FreeHGlobal (attr);

    //Reparent the window
    XReparentWindow(display, puttyWindowHandle, panelHandle, 0, 0);
    XReparentWindow(display, puttyWindowHandle, panelHandle, 0, 0);
    XMapWindow(display, puttyWindowHandle);
    XFlush(display);
    XSync(display, false);
}
c# linux mono x11
1个回答
0
投票

好吧,我找到了问题的解决方案。很可能是 Cinnamon 和它的窗口管理器在我重新设置窗口时引起了问题。为了阻止 Cinnamon 取消父级设置,我必须在我想要重新设置父级的窗口上将覆盖重定向标志设置为 True。奇怪的是,我需要在设置标志后执行两次 XReparentWindow 以使窗口正确重新设置父级。不知道为什么会这样,但它有效。但是,在窗口重新设置父级后,它不再以图形方式更新。我还在研究这个问题。

我已经用修改后的代码更新了原始帖子。

© www.soinside.com 2019 - 2024. All rights reserved.