我正在开发一个管理远程连接的个人使用的WinForms mono应用程序。我一直试图找出一种方法来将某些X11窗口重新父化到我的WinForms应用程序中。我在Windows上完美地运行了此功能,但Linux中的X11 API给了我问题。
我明白这可能是浪费时间,因为有更好的解决方案,但我现在深入研究,至少想知道为什么这不起作用,也许如果有一个解决方案。
我想将Putty SSH终端窗口重新父化到WinForms面板(WinForms程序在mono中运行)。我可以使用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);
}
我已经尝试过这与其他程序以及并已发现,一些将家长只是发现(calculator,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);
}
1条答案
按热度按时间af7jpaap1#
好吧,我找到了我的问题的解决方案。很可能是Cinnamon和它的窗口管理器在我重新父化窗口时导致了问题。为了阻止Cinnamon取消父化,我必须在我想要重新父化的窗口上将覆盖重定向标志设置为True。奇怪的是,在设置标志之后,我需要执行XReparentWindow两次,以便使窗口正确地重新父化。不知道为什么,但它的工作原理。然而,在窗口reparents它不再更新图形。我仍然在这个问题上的工作。
我已经用修改后的代码更新了原始文章。