diff --git a/lcl/interfaces/qt/qtint.pp b/lcl/interfaces/qt/qtint.pp index 0bf852e13e..cafc61c677 100644 --- a/lcl/interfaces/qt/qtint.pp +++ b/lcl/interfaces/qt/qtint.pp @@ -241,6 +241,8 @@ type function X11GetActiveWindow: QWidgetH; function GetWindowManager: String; procedure SetSkipX11Taskbar(Widget: QWidgetH; const ASkipTaskBar: Boolean); + {check if XWindow have _NET_WM_STATE_ABOVE and our form doesn''t know anything about it} + function GetAlwaysOnTopX11(Widget: QWidgetH): boolean; {check if we are running under kde3 installation} function IsOldKDEInstallation: Boolean; {$ENDIF} diff --git a/lcl/interfaces/qt/qtwsforms.pp b/lcl/interfaces/qt/qtwsforms.pp index 724b36fef9..2667e87cfd 100644 --- a/lcl/interfaces/qt/qtwsforms.pp +++ b/lcl/interfaces/qt/qtwsforms.pp @@ -524,7 +524,6 @@ begin Widget.BeginUpdate; if not (csDesigning in AWinControl.ComponentState) then begin - if ShowNonModalOverModal then // issue #12459 else @@ -545,13 +544,37 @@ begin QApplication_activeModalWidget()); end else begin - if (TCustomForm(AWinControl).FormStyle in fsAllStayOnTop) - and not (csDestroying in AWinControl.ComponentState) then + if (TCustomForm(AWinControl).FormStyle in fsAllStayOnTop) then begin - Flags := Widget.windowFlags; - Flags := Flags and not QtWindowStaysOnTopHint; - Widget.setWindowFlags(Flags); + if not (csDestroying in AWinControl.ComponentState) then + begin + Flags := Widget.windowFlags; + Flags := Flags and not QtWindowStaysOnTopHint; + Widget.setWindowFlags(Flags); + end; end; + {$IFDEF HASX11} + // issue #26018 + if AWinControl.HandleObjectShouldBeVisible and + not (TCustomForm(AWinControl).FormStyle in fsAllStayOnTop) and + not (fsModal in TCustomForm(AWinControl).FormState) and + (TCustomForm(AWinControl).PopupMode = pmAuto) and + (TCustomForm(AWinControl).BorderStyle = bsNone) and + (TCustomForm(AWinControl).PopupParent = nil) then + begin + W := QApplication_activeWindow; + if W <> nil then + begin + Flags := QWidget_windowFlags(W); + if (Flags and QtWindowStaysOnTopHint <> QtWindowStaysOnTopHint) and + GetAlwaysOnTopX11(W) then + begin + Flags := Widget.windowFlags; + Widget.setWindowFlags(Flags or QtWindowStaysOnTopHint); + end; + end; + end; + {$ENDIF} end; end; diff --git a/lcl/interfaces/qt/qtx11.inc b/lcl/interfaces/qt/qtx11.inc index 479f0de4e6..6bdaff4d22 100644 --- a/lcl/interfaces/qt/qtx11.inc +++ b/lcl/interfaces/qt/qtx11.inc @@ -256,6 +256,58 @@ begin @Xclient); end; +function GetAlwaysOnTopX11(Widget: QWidgetH): boolean; +var + Display: PDisplay; + X11Window: TWindow; + WMAtom: TAtom; + typeReturned: TAtom; + formatReturned: Integer; + nitemsReturned: PtrInt; + unused: PtrInt; + data: Pointer; +begin + Result := False; + Display := QX11Info_display(); + + if Display = nil then + exit; + + X11Window := TWindow(QWidget_winId(Widget)); + if X11Window = 0 then + exit; + + WMAtom := XInternAtom(Display,'_NET_WM_STATE', False); + if WMAtom > 0 then + begin + data := nil; + if XGetWindowProperty(Display, X11Window, WMAtom, 0, 1024, False, XA_ATOM, + @typeReturned, @formatReturned, @nitemsReturned, + @unused, @data) = Success then + begin + if (typeReturned = XA_ATOM) and (formatReturned = 32) and + (Data <> nil) then + begin + while nitemsReturned > 0 do + begin + // make happy ancient x11 or old kde ? + if XInternAtom(Display,'_NET_WM_STATE_STAYS_ON_TOP', False) = TAtom(Data^) then + Result := True + else + if XInternAtom(Display,'_NET_WM_STATE_ABOVE', False) = TAtom(Data^) then + Result := True; + dec(nItemsReturned); + if Result or (nItemsReturned = 0) then + break; + inc(Data); + end; + XFree(Data); + Data := nil; + end; + end; + end; +end; + function GetKeyLockState(const AKey: Byte): Boolean; var Display: PDisplay;