/// <summary> /// Matches a top-level window to the application to the window having the specified dimensions. /// </summary> /// <param name="applicationName">The name of the application as registered with the AT-SPI registry.</param> /// <param name="windowRect">A <see cref="System.Drawing.Rectangle"/> representing the window on the screen.</param> /// <param name="frameExtents">A WindowManagerFrameExtents structure containing the size (in pixels) of the /// decorations placed on the window by the window manager.</param> /// <returns>A <see cref="System.IntPtr"/> value that points to the Accessible object representing the top-level window.</returns> internal IntPtr MatchTopLevelWindowForApplication(string applicationName, Rectangle windowRect, WindowManagerFrameExtents frameExtents) { IntPtr windowPointer = IntPtr.Zero; IList<IntPtr> topLevelWindows = this.GetTopLevelWindowsForApplication(applicationName); foreach (IntPtr candidateWindow in topLevelWindows) { if (Accessible_isComponent(candidateWindow)) { // Out variables for API call int x = 0; int y = 0; int width = 0; int height = 0; int relativeX = 0; int relativeY = 0; IntPtr component = Accessible_getComponent(candidateWindow); AccessibleComponent_getExtents(component, out x, out y, out width, out height, AccessibleCoordType.Screen); AccessibleComponent_getPosition(component, out relativeX, out relativeY, AccessibleCoordType.Window); AccessibleComponentLayer layer = AccessibleComponent_getLayer(component); Rectangle componentRectangle = new Rectangle(x, y, width, height); AccessibleComponent_unref(component); // If the component layer is Window, this indicates that the window // rect as passed in by the X server does not include the window frame // as drawn by the window manager. If this is the case, adjust the rectangle // so the window can be found. if (layer == AccessibleComponentLayer.Window) { windowRect.X = windowRect.X - frameExtents.Left; windowRect.Y = windowRect.Y - frameExtents.Top; windowRect.Width = windowRect.Width + frameExtents.Left + frameExtents.Right; windowRect.Height = windowRect.Height + frameExtents.Top + frameExtents.Bottom; } // If we found the window, add its pointer to the referenced objects // cache and remove it from the list of available windows (so it // does not get unreferenced. if (windowRect.Equals(componentRectangle)) { referencedObjectCache.Add(candidateWindow); topLevelWindows.Remove(candidateWindow); windowPointer = candidateWindow; break; } } } // Unreference every window not matching as the top-level window // for the application. foreach (IntPtr referencedWindow in topLevelWindows) { Accessible_unref(referencedWindow); } return windowPointer; }
/// <summary> /// Initializes a new instance of the <see cref="AtSpiObject"/> class. /// </summary> /// <param name="processId">The ID of the process hosting this object.</param> /// <param name="windowRect">The rectangle containing this object.</param> /// <param name="frameExtents">The <see cref="WindowManagerFrameExtents"/> for the window hosting this object.</param> internal AtSpiObject(int processId, Rectangle windowRect, WindowManagerFrameExtents frameExtents) { Process applicationProcess = Process.GetProcessById(processId); string moduleName = applicationProcess.MainModule.ModuleName; this.accessibleObject = AtSpi.Instance.MatchTopLevelWindowForApplication(moduleName, windowRect, frameExtents); }
/// <summary> /// Gets the frame extents for the specified window. /// </summary> /// <param name="window">A pointer to the window.</param> /// <returns>The <see cref="WindowManagerFrameExtents"/> of the window.</returns> internal static WindowManagerFrameExtents GetFrameExtents(IntPtr window) { WindowManagerFrameExtents extents = WindowManagerFrameExtents.Empty; using (XServerConnection serverConnection = new XServerConnection()) { IntPtr prop_return = GetWindowProperty(serverConnection.Display, window, PropertyWindowFrameExtents, 0, 4 * 32); if (prop_return != IntPtr.Zero) { int[] returnedExtents = new int[4] { 0, 0, 0, 0 }; Marshal.Copy(prop_return, returnedExtents, 0, 4); extents = new WindowManagerFrameExtents(); extents.Left = returnedExtents[0]; extents.Right = returnedExtents[1]; extents.Top = returnedExtents[2]; extents.Bottom = returnedExtents[3]; XFree(prop_return); } } return extents; }