From 16060bde0961143d6dd9d3d4ccd78782f0ca9018 Mon Sep 17 00:00:00 2001 From: zeljko Date: Mon, 5 May 2014 11:30:39 +0000 Subject: [PATCH] Qt: fixed order of kill/set focus messages sent to LCL. issue #26106 git-svn-id: trunk@44923 - --- lcl/interfaces/qt/qtobject.inc | 75 ++++++++++++++++++++------------- lcl/interfaces/qt/qtwidgets.pas | 16 ++++--- lcl/interfaces/qt/qtwinapi.inc | 9 +++- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/lcl/interfaces/qt/qtobject.inc b/lcl/interfaces/qt/qtobject.inc index ffe2c87fac..dda9c4f6ca 100644 --- a/lcl/interfaces/qt/qtobject.inc +++ b/lcl/interfaces/qt/qtobject.inc @@ -558,7 +558,6 @@ var begin Result := False; case QEvent_type(Event) of - QEventShortcutOverride: // issue #22827 begin QKeyEvent_text(QKeyEventH(Event), @AKey); @@ -792,9 +791,40 @@ var ((NewWin = nil) or (NewWin = NewWidget.LCLObject)); end; + procedure LostFocus; + begin + FillChar(Msg, SizeOf(Msg), 0); + if IsValidHandle(HWND(OldWidget)) then + begin + {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} + WriteLn('TQtWidgetSet.FocusChanged: KILL ', dbgsName(OldWidget.LCLObject),' W.Visible ',OldWidget.getVisible, + ' destroying ? ',csDestroying in OldWidget.LCLObject.ComponentState, + ' handle ?!? ',OldWidget.LCLObject.HandleAllocated); + {$ENDIF} + Msg.msg := LM_KILLFOCUS; + Msg.wParam := PtrInt(NewWidget); + if ((OldWidget is TQtMainWindow) and TQtMainWindow(OldWidget).IsMdiChild and + Assigned(TQtMainWindow(OldWidget).LCLObject) and + not (csDesigning in TQtMainWindow(OldWidget).LCLObject.ComponentState)) + or MDIFocusFixNeeded then + // DO NOT TRIGGER ANYTHING, THIS IS SPURIOUS EVENT FROM MDIAREA + {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} + Writeln('TQtWidgetSet.FocusChanged: *** DO NOT KILL FOCUS ***') + {$ENDIF} + else + if CheckIfActiveForm(OldWidget) then + OldWidget.DeliverMessage(Msg) + {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} + else + Writeln('TQtWidgetSet.FocusChanged: ***** Cannot kill focus of ',dbgsName(OldWidget.LCLObject)) + {$ENDIF} + ; + end; + end; + begin {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} - WriteLn('TQtWidgetSet.FocusChanged: old: ', dbgHex(PtrUInt(aold)), ' new: ', dbgHex(PtrUInt(anew))); + WriteLn('> ** TQtWidgetSet.FocusChanged: old: ', dbgHex(PtrUInt(aold)), ' new: ', dbgHex(PtrUInt(anew))); {$ENDIF} OldWidget := GetFirstQtObjectFromWidgetH(aold); NewWidget := GetFirstQtObjectFromWidgetH(anew); @@ -820,7 +850,16 @@ begin exit; end; + if IsValidHandle(HWND(NewWidget)) and (NewWidget.getOwner <> nil) then + NewWidget := NewWidget.getOwner; + if IsValidHandle(HWND(OldWidget)) and (OldWidget.getOwner <> nil) then + OldWidget := OldWidget.getOwner; + Msg.Msg := 0; // shutup compiler + + // issue #26106 + LostFocus; + FillChar(Msg, SizeOf(Msg), 0); if IsValidHandle(HWND(NewWidget)) then @@ -844,6 +883,8 @@ begin FocusedTQtWidget := TQtWidget(HwndFromWidgetH(FocusedQtWidget)); if FocusedTQtWidget <> nil then begin + if (FocusedTQtWidget.getOwner <> nil) then + FocusedTQtWidget := FocusedTQtWidget.getOwner; if FocusedTQtWidget = NewWidget then begin {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} @@ -861,6 +902,8 @@ begin FocusedTQtWidget := TQtWidget(TCustomForm(NewWidget.LCLObject).ActiveControl.Handle); if FocusedTQtWidget <> nil then begin + if (FocusedTQtWidget.getOwner <> nil) then + FocusedTQtWidget := FocusedTQtWidget.getOwner; // first check if we are active subwin, if not then we'll trigger qt do // do correct thing if TQtMainWindow(NewWidget).MDIChildArea.ActiveSubWindow <> NewWidget.Widget then @@ -905,34 +948,6 @@ begin end else NewWidget.DeliverMessage(Msg); end; - - FillChar(Msg, SizeOf(Msg), 0); - if IsValidHandle(HWND(OldWidget)) then - begin - {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} - WriteLn('TQtWidgetSet.FocusChanged: KILL ', dbgsName(OldWidget.LCLObject),' W.Visible ',OldWidget.getVisible, - ' destroying ? ',csDestroying in OldWidget.LCLObject.ComponentState, - ' handle ?!? ',OldWidget.LCLObject.HandleAllocated); - {$ENDIF} - Msg.msg := LM_KILLFOCUS; - Msg.wParam := PtrInt(NewWidget); - if ((OldWidget is TQtMainWindow) and (TQtMainWindow(OldWidget).IsMdiChild) and - Assigned(TQtMainWindow(OldWidget).LCLObject) and - not (csDesigning in TQtMainWindow(OldWidget).LCLObject.ComponentState)) - or MDIFocusFixNeeded then - // DO NOT TRIGGER ANYTHING, THIS IS SPURIOUS EVENT FROM MDIAREA - {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} - Writeln('TQtWidgetSet.FocusChanged: *** DO NOT KILL FOCUS ***') - {$ENDIF} - else - if CheckIfActiveForm(OldWidget) then - OldWidget.DeliverMessage(Msg) - {$IF DEFINED(VerboseFocus) OR DEFINED(DebugQtFocus)} - else - Writeln('TQtWidgetSet.FocusChanged: Cannot kill focus of ',dbgsName(OldWidget.LCLObject)) - {$ENDIF} - ; - end; end; procedure TQtWidgetSet.OnWakeMainThread(Sender: TObject); diff --git a/lcl/interfaces/qt/qtwidgets.pas b/lcl/interfaces/qt/qtwidgets.pas index fd5ae34bcb..55d9abf9f7 100644 --- a/lcl/interfaces/qt/qtwidgets.pas +++ b/lcl/interfaces/qt/qtwidgets.pas @@ -1997,12 +1997,18 @@ begin if (LCLObject <> nil) then begin if (Self is TQtMainWindow) and - (csNoFocus in LCLObject.ControlStyle) then + (TQtMainWindow(Self).IsMDIChild or (csNoFocus in LCLObject.ControlStyle)) then begin - if LCLObject.TabStop then - setFocusPolicy(QtWheelFocus) - else - setFocusPolicy(QtNoFocus); + if TQtMainWindow(Self).IsMDIChild then + begin + QWidget_setFocusPolicy(FCentralWidget, QtNoFocus); + end else + begin + if LCLObject.TabStop then + setFocusPolicy(QtWheelFocus) + else + setFocusPolicy(QtNoFocus); + end; end else begin if (csNoFocus in LCLObject.ControlStyle) then diff --git a/lcl/interfaces/qt/qtwinapi.inc b/lcl/interfaces/qt/qtwinapi.inc index 13de0d9dfb..4cca13b557 100644 --- a/lcl/interfaces/qt/qtwinapi.inc +++ b/lcl/interfaces/qt/qtwinapi.inc @@ -2952,9 +2952,14 @@ begin if W <> nil then begin Result := HwndFromWidgetH(W); + if IsValidHandle(Result) then + begin + if TQtWidget(Result).getOwner <> nil then + Result := HWND(TQtWidget(Result).getOwner); + end; {$ifdef VerboseFocus} Obj := TQtWidget(Result); - Write('TQtWidgetSet.GetFocus: WidgetH=',dbghex(ptruint(W)), ' QtWidget=', dbgsname(Obj)); + WriteLn('TQtWidgetSet.GetFocus: WidgetH=',dbghex(ptruint(W)), ' QtWidget=', dbgsname(Obj)); if Obj<>nil then WriteLn(' LclObject=', dbgsname(Obj.LCLObject)) else @@ -5740,7 +5745,7 @@ begin W.Activate; TQtWidget(hWnd).setFocus; {$ifdef VerboseFocus} - DebugLn('********* TQtWidgetSet.SetFocus END was %x now is %x',[result,hwnd]); + DebugLn('********* TQtWidgetSet.SetFocus END was %x now is %x %s %d',[result,hwnd,dbgsName(TQtWidget(hWnd).LCLObject), GetTickCount]); {$endif} end; end;