@@ -663,7 +663,14 @@ function TSimbaNativeInterface_Linux.GetTopWindows: TWindowHandleArray;
663663
664664function TSimbaNativeInterface_Linux.GetWindowAtCursor (Exclude: TWindowHandleArray): TWindowHandle;
665665
666- function ShouldReturnWindow (Window: TWindow): Boolean;
666+ function NormalizeWindow (Window: TWindow): TWindow;
667+ begin
668+ Result := GetRootWindow(Window);
669+ if (Result = 0 ) then
670+ Result := Window;
671+ end ;
672+
673+ function IsUsableWindow (Window: TWindow): Boolean;
667674 var
668675 B: TBox;
669676 begin
@@ -675,31 +682,61 @@ function TSimbaNativeInterface_Linux.GetWindowAtCursor(Exclude: TWindowHandleArr
675682 end ;
676683
677684var
678- Root, Child: TWindow;
685+ Root, Child, Current : TWindow;
679686 x_root, y_root, x, y: Integer;
680687 mask: UInt32;
681688 I: Integer;
682689 Windows: array [UInt8] of TWindow;
683690 WindowCount: Integer;
691+ RawCandidate, NormalizedCandidate: TWindow;
684692begin
685693 Result := 0 ;
686694 WindowCount := 0 ;
687695
688- SimbaXLib.XQueryPointer(GetDesktopWindow(), @Root, @Child, @x_root, @y_root, @x, @y, @mask);
689- while SimbaXLib.XQueryPointer(Child, @Root, @Child, @x_root, @y_root, @x, @y, @mask) do
696+ if not SimbaXLib.XQueryPointer(GetDesktopWindow(), @Root, @Child, @x_root, @y_root, @x, @y, @mask) then
697+ begin
698+ Exit(0 );
699+ end ;
700+
701+ if (Child = 0 ) then
702+ begin
703+ Exit(0 );
704+ end ;
705+
706+ Current := Child;
707+
708+ // IMPORTANT: include the first child returned from the root query
709+ Windows[WindowCount] := Current;
710+ Inc(WindowCount);
711+
712+ while SimbaXLib.XQueryPointer(Current, @Root, @Child, @x_root, @y_root, @x, @y, @mask) do
690713 begin
691714 if (Child = 0 ) then
692715 Break;
693- Windows[WindowCount] := Child;
716+
717+ Current := Child;
718+ Windows[WindowCount] := Current;
694719 Inc(WindowCount);
720+
695721 if (WindowCount > High(Windows)) then
696- Exit ;
722+ Break ;
697723 end ;
698724
699- // now go back until we find something worthwhile
700725 for I := WindowCount - 1 downto 0 do
701- if ShouldReturnWindow(Windows[I]) then
702- Exit(Windows[I])
726+ begin
727+ RawCandidate := Windows[I];
728+
729+ if IsUsableWindow(RawCandidate) then
730+ begin
731+ Exit(RawCandidate);
732+ end ;
733+
734+ NormalizedCandidate := NormalizeWindow(RawCandidate);
735+ if IsUsableWindow(NormalizedCandidate) then
736+ begin
737+ Exit(NormalizedCandidate);
738+ end ;
739+ end ;
703740end ;
704741
705742function TSimbaNativeInterface_Linux.GetDesktopWindow : TWindowHandle;
@@ -725,8 +762,14 @@ function TSimbaNativeInterface_Linux.IsWindowValid(Window: TWindowHandle): Boole
725762end ;
726763
727764function TSimbaNativeInterface_Linux.IsWindowVisible (Window: TWindowHandle): Boolean;
765+ var
766+ Attr: TXWindowAttributes;
728767begin
729- Result := HasWindowProperty(GetRootWindow(Window), SimbaXLib.WM_STATE);
768+ if (Window = 0 ) then
769+ Exit;
770+
771+ if SimbaXLib.XGetWindowAttributes(Window, @Attr) then
772+ Result := Attr.map_state = IsViewable;
730773end ;
731774
732775function TSimbaNativeInterface_Linux.GetWindowPID (Window: TWindowHandle): Integer;
0 commit comments