View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0029294 | Lazarus | LCL | public | 2015-12-31 10:02 | 2021-02-26 15:53 |
Reporter | Ondrej Pokorny | Assigned To | Zeljan Rikalo | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | confirmed | Resolution | open | ||
Platform | Linux | OS | Kubuntu Linux | ||
Product Version | 1.7 (SVN) | ||||
Target Version | 2.2 | ||||
Summary | 0029294: fsStayOnTop non-modal window cannot get active in Qt | ||||
Description | fsStayOnTop non-modal window cannot get active in Qt | ||||
Steps To Reproduce | 1.) Show an fsStayOnTop non-modal window. 2.) Switch to a different application with Alt+Tab or mouse. 3.) Switch back to the fsStayOnTop non-modal window with Alt+Tab or mouse. You'll see that the form can't get active/focused. | ||||
Additional Information | See the attached screencast and test project. The code is: procedure TForm1.Button1Click(Sender: TObject); var Form2: TForm; begin Form2 := TForm.CreateNew(Self); Form2.Position := poDesigned; Form2.Left := 0; Form2.Top := 0; Form2.FormStyle := fsStayOnTop; Form2.Show; end; | ||||
Tags | No tags attached. | ||||
Fixed in Revision | |||||
LazTarget | - | ||||
Widgetset | QT | ||||
Attached Files |
|
|
|
|
|
|
Yes, it's bug. On my window manager even without Alt-Tab it is possible to reproduce bug. Just activate another application. Now try to activate fsStayOnTop form with mouse - no way. Only if you click onto main form app is activated. |
|
qtStayOnTopActivation.diff (5,629 bytes)
Index: lcl/interfaces/qt/qtobject.inc =================================================================== --- lcl/interfaces/qt/qtobject.inc (revision 51047) +++ lcl/interfaces/qt/qtobject.inc (working copy) @@ -491,7 +491,7 @@ function TQtWidgetSet.AppRestoreStayOnTopFlags(const ASystemTopAlso: Boolean = False): Boolean; begin Result := True; - QtRestoreStayOnTop(ASystemTopAlso); + QtRestoreStayOnTop(nil, ASystemTopAlso); end; procedure TQtWidgetSet.SetOverrideCursor(const AValue: TObject); @@ -547,7 +547,8 @@ end; end; -procedure TQtWidgetSet.QtRestoreStayOnTop(const ASystemTopAlso: Boolean = False); +procedure TQtWidgetSet.QtRestoreStayOnTop(ActiveWin: QWidgetH; + const ASystemTopAlso: Boolean); var i: Integer; AForm: TCustomForm; @@ -570,9 +571,23 @@ begin W.BeginUpdate; Flags := W.windowFlags; - W.setWindowFlags(Flags or QtWindowStaysOnTopHint); - W.Show; - W.setAttribute(QtWA_ShowWithoutActivating, False); + if Flags and QtWindowStaysOnTopHint <> QtWindowStaysOnTopHint then + begin + {$IF DEFINED(QTDEBUGAPPACTIVATE) OR DEFINED(VerboseQtEvents)} + DebugLn('** QtRestoreStayOnTop ! FOR ',dbgsName(W.LCLObject)); + {$ENDIF} + if ActiveWin = nil then + W.setAttribute(QtWA_ShowWithoutActivating, True) + else + W.setAttribute(QtWA_ShowWithoutActivating, False); + W.setWindowFlags(Flags or QtWindowStaysOnTopHint); + W.Show; + if ActiveWin = nil then + begin + W.setAttribute(QtWA_ShowWithoutActivating, False); + W.Activate; + end; + end; W.EndUpdate; end; end; @@ -766,6 +781,12 @@ end; QEventApplicationActivate: begin + {$IF DEFINED(QTDEBUGAPPACTIVATE) OR DEFINED(VerboseQtEvents)} + DebugLn('TQtWidgetSet.EventFilter: QEventApplicationActivate - time ',dbgs(GetTickCount)); + W := TQtMainWindow(HWNDFromWidgetH(QApplication_activeWindow())); + if W <> nil then + DebugLn('ACTIVATED WIDGET IS ',dbgsName(W)); + {$ENDIF} LCLEvent := QLCLMessageEvent_create(LCLQt_ApplicationActivate); // activate it imediatelly (high priority) QCoreApplication_postEvent(Sender, LCLEvent, 1 {high priority}); @@ -785,7 +806,10 @@ else W := nil; Application.IntfAppActivate; - QtRestoreStayOnTop; + if (W <> nil) and Assigned(StayOnTopList) and not StayOnTopList.HasId(W) then + QtRestoreStayOnTop(QApplication_activeWindow()) + else + QtRestoreStayOnTop(nil); if (W <> nil) and Assigned(StayOnTopList) and StayOnTopList.HasId(W) then W.Activate; Result := True; Index: lcl/interfaces/qt/qtwidgets.pas =================================================================== --- lcl/interfaces/qt/qtwidgets.pas (revision 51047) +++ lcl/interfaces/qt/qtwidgets.pas (working copy) @@ -6980,8 +6980,41 @@ end; QEventWindowUnblocked: Blocked := False; QEventWindowBlocked: Blocked := True; - QEventWindowActivate: if not IsMDIChild then SlotActivateWindow(True); - QEventWindowDeactivate: if not IsMDIChild then SlotActivateWindow(False); + QEventWindowActivate: + begin + if not IsMDIChild then + begin + {$IF DEFINED(QTDEBUGAPPACTIVATE) OR DEFINED(VerboseQtEvents)} + DebugLn('QEventWindowActivate: ',dbgsName(LCLObject), + ' AppActive=',dbgs(QtWidgetSet.AppActive)); + {$ENDIF} + if not QtWidgetSet.AppActive and (LCLObject.Parent = nil) then + begin + BeginUpdate; + // procedure QtRestoreStayOnTop(const ASystemTopAlso: Boolean = False); + QtWidgetSet.QtRestoreStayOnTop(Widget, True); + //if TCustomForm(LCLObject).FormStyle in fsAllStayOnTop then + Activate; + writeln('ACTIVATED !!!!'); + if TCustomForm(LCLObject).FormStyle in fsAllStayOnTop then + X11Raise(QWidget_winId(Widget)); + writeln('RAISED !!!!'); + EndUpdate; + end; + SlotActivateWindow(True); + end; + end; + QEventWindowDeactivate: + begin + if not IsMDIChild then + begin + {$IF DEFINED(QTDEBUGAPPACTIVATE) OR DEFINED(VerboseQtEvents)} + DebugLn('QEventWindowDeActivate: ',dbgsName(LCLObject), + ' AppActive=',dbgs(QtWidgetSet.AppActive)); + {$ENDIF} + SlotActivateWindow(False); + end; + end; QEventShowToParent: ; // do nothing for TQtMainWindow, but leave it unhandled QEventWindowStateChange: begin Index: lcl/interfaces/qt/qtint.pp =================================================================== --- lcl/interfaces/qt/qtint.pp (revision 51047) +++ lcl/interfaces/qt/qtint.pp (working copy) @@ -97,7 +97,6 @@ function GetStyleName: String; procedure SetOverrideCursor(const AValue: TObject); procedure QtRemoveStayOnTop(const ASystemTopAlso: Boolean = False); - procedure QtRestoreStayOnTop(const ASystemTopAlso: Boolean = False); procedure SetDefaultAppFontName; protected FStockNullBrush: HBRUSH; @@ -171,6 +170,7 @@ procedure HideAllHints; procedure RestoreAllHints; {$ENDIF} + procedure QtRestoreStayOnTop(ActiveWin: QWidgetH; const ASystemTopAlso: Boolean = False); // application global actions (mainform mainmenu mnemonics Alt+XX) procedure ClearGlobalActions; |
|
Attached patch is for my purposes only...patch fixes activation of fsStayOnTop with mouse, but Alt+Tab is still problematic since wild QEventApplicationDeactivate arrives imediatelly after QEventApplicationActivate. Uploaded here just in case if I delete it from my disk. |
Date Modified | Username | Field | Change |
---|---|---|---|
2015-12-31 10:02 | Ondrej Pokorny | New Issue | |
2015-12-31 10:02 | Ondrej Pokorny | File Added: fsStayOnTop.mp4 | |
2015-12-31 10:05 | Ondrej Pokorny | File Added: bug29294.zip | |
2015-12-31 11:46 | Zeljan Rikalo | Assigned To | => Zeljan Rikalo |
2015-12-31 11:46 | Zeljan Rikalo | Status | new => assigned |
2015-12-31 12:09 | Zeljan Rikalo | Note Added: 0088461 | |
2015-12-31 12:09 | Zeljan Rikalo | Status | assigned => confirmed |
2015-12-31 13:42 | Zeljan Rikalo | File Added: qtStayOnTopActivation.diff | |
2015-12-31 13:44 | Zeljan Rikalo | Note Added: 0088462 | |
2021-02-26 15:53 | Martin Friebe | Target Version | 1.6 => 2.2 |