Qt5, Qt6: do not use FocusChangedHook by default, use EventFilter since events are in correct order with qt5 and qt6

This commit is contained in:
Željan Rikalo 2024-10-03 11:42:36 +02:00
parent cbc3f3751c
commit bf3bf9d897
4 changed files with 156 additions and 4 deletions

View File

@ -75,7 +75,9 @@ type
SysTrayIconsList: TFPList;
// global hooks
FAppEvenFilterHook: QObject_hookH;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook: QApplication_hookH;
{$ENDIF}
FAppSessionQuit: QGUIApplication_hookH;
FAppSaveSessionRequest: QGUIApplication_hookH;
@ -127,7 +129,9 @@ type
function CreateThemeServices: TThemeServices; override;
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
procedure FocusChanged(aold: QWidgetH; anew: QWidgetH); cdecl;
{$ENDIF}
procedure OnWakeMainThread(Sender: TObject);
{$ifndef QT_NO_SESSIONMANAGER}
procedure SlotCommitDataRequest(sessionManager: QSessionManagerH); cdecl;

View File

@ -51,7 +51,9 @@ begin
{$J-}
FCachedMenuBarHeight := -1;
FAppEvenFilterHook := nil;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook := nil;
{$ENDIF}
FPenForSetPixel := nil;
FInGetPixel := False;
@ -211,9 +213,10 @@ begin
QObject_hook_hook_events(FAppEvenFilterHook, @EventFilter);
// install focus change slot
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook := QApplication_hook_create(App);
QApplication_hook_hook_focusChanged(FAppFocusChangedHook, @FocusChanged);
{$ENDIF}
if not FIsLibraryInstance then
begin
@ -346,10 +349,12 @@ begin
// free hooks
if Assigned(FAppEvenFilterHook) then
QObject_hook_destroy(FAppEvenFilterHook);
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
if Assigned(FAppFocusChangedHook) then
QApplication_hook_destroy(FAppFocusChangedHook);
FAppEvenFilterHook := nil;
FAppFocusChangedHook := nil;
{$ENDIF}
FAppEvenFilterHook := nil;
// do not quit application if we are library
if not FIsLibraryInstance then
begin
@ -658,6 +663,12 @@ var
AParent: QWidgetH;
R: TRect;
AQtPoint: TQtPoint;
{$IFNDEF QTUSEFOCUSCHANGEDHOOK}
OldWidget, NewWidget: TQtWidget;
Msg: TLMessage;
FocusedQtWidget: QWidgetH;
FocusedTQtWidget: TQtWidget;
{$ENDIF}
function IsAnyWindowActive: Boolean;
begin
@ -914,6 +925,65 @@ begin
FreeSysColorBrushes(True);
end;
end;
{$IFNDEF QTUSEFOCUSCHANGEDHOOK}
QEventFocusIn:
begin
if not QObject_isWidgetType(Sender) then
exit;
FocusedQtWidget := QApplication_focusWidget();
// writeln('FocusedWidget ? ',Assigned(FocusedQtWidget),' Sender ? ',QObject_isWidgetType(Sender));
if Assigned(FocusedQtWidget) and (QWidgetH(Sender) <> FocusedQtWidget) then
begin
OldWidget := TQtWidget(HwndFromWidgetH(FocusedQtWidget));
if OldWidget <> nil then
begin
NewWidget := TQtWidget(HwndFromWidgetH(QWidgetH(Sender)));
Msg := Default(TLMessage);
Msg.msg := LM_KILLFOCUS;
Msg.wParam := PtrInt(NewWidget);
OldWidget.DeliverMessage(Msg);
{$IFDEF DebugQtFocus}
writeln('OldWidget(1) deliver focus out =',DbgSName(OldWidget));
{$ENDIF}
end;
end;
NewWidget := TQtWidget(HwndFromWidgetH(QWidgetH(Sender)));
// writeln('NewWidget=',DbgSName(NewWidget),' Ptr=',PtrUInt(NewWidget));
Msg := Default(TLMessage);
Msg.msg := LM_SETFOCUS;
if Assigned(FocusedQtWidget) and (FocusedQtWidget <> QWidgetH(Sender)) then
OldWidget := TQtWidget(HWndFromWidgetH(FocusedQtWidget))
else
OldWidget := nil;
// writeln('OldWidget=',DbgSName(OldWidget),' Ptr=',PtrUInt(OldWidget));
Msg.WParam := PtrInt(OldWidget);
if Assigned(NewWidget) then
begin
{$IFDEF DebugQtFocus}
writeln('Deliver focus IN for ',dbgsName(NewWidget));
{$ENDIF}
NewWidget.DeliverMessage(Msg);
end;
end;
QEventFocusOut:
begin
if not QObject_isWidgetType(Sender) then
exit;
FocusedQtWidget := QWidgetH(Sender);
OldWidget := TQtWidget(HwndFromWidgetH(FocusedQtWidget));
if Assigned(OldWidget) then
begin
Msg := Default(TLMessage);
Msg.msg := LM_KILLFOCUS;
Msg.wParam := 0; // PtrInt(NewWidget);
OldWidget.DeliverMessage(Msg);
{$IFDEF DebugQtFocus}
writeln('DELIVER focus OUT for ',dbgsName(OldWidget));
{$ENDIF}
end;
end;
{$ENDIF}
QEventShow,
QEventHide:
begin
@ -937,6 +1007,7 @@ begin
end;
end;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
procedure TQtWidgetSet.FocusChanged(aold: QWidgetH; anew: QWidgetH); cdecl;
var
OldWidget, NewWidget: TQtWidget;
@ -1213,6 +1284,7 @@ begin
NewWidget.DeliverMessage(Msg);
end;
end;
{$ENDIF}
procedure TQtWidgetSet.OnWakeMainThread(Sender: TObject);
var

View File

@ -77,7 +77,9 @@ type
// global hooks
FAppEventApplicationStateHook: QGuiApplication_hookH;
FAppEvenFilterHook: QObject_hookH;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook: QApplication_hookH;
{$ENDIF}
FAppSessionQuit: QGUIApplication_hookH;
FAppSaveSessionRequest: QGUIApplication_hookH;
@ -130,7 +132,9 @@ type
function CreateThemeServices: TThemeServices; override;
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
procedure FocusChanged(aold: QWidgetH; anew: QWidgetH); cdecl;
{$ENDIF}
procedure AppStateChanged(AState: QtApplicationState); cdecl;
procedure OnWakeMainThread(Sender: TObject);
{$ifndef QT_NO_SESSIONMANAGER}

View File

@ -54,7 +54,9 @@ begin
{$J-}
FCachedMenuBarHeight := -1;
FAppEvenFilterHook := nil;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook := nil;
{$ENDIF}
FAppEventApplicationStateHook := nil;
FPenForSetPixel := nil;
FInGetPixel := False;
@ -215,9 +217,10 @@ begin
QObject_hook_hook_events(FAppEvenFilterHook, @EventFilter);
// install focus change slot
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
FAppFocusChangedHook := QApplication_hook_create(App);
QApplication_hook_hook_focusChanged(FAppFocusChangedHook, @FocusChanged);
{$ENDIF}
FAppEventApplicationStateHook := QGuiApplication_hook_Create(App);
QGuiApplication_hook_hook_applicationStateChanged(FAppEventApplicationStateHook, @AppStateChanged);
@ -347,12 +350,14 @@ begin
// free hooks
if Assigned(FAppEvenFilterHook) then
QObject_hook_destroy(FAppEvenFilterHook);
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
if Assigned(FAppFocusChangedHook) then
QApplication_hook_destroy(FAppFocusChangedHook);
FAppFocusChangedHook := nil;
{$ENDIF}
if Assigned(FAppEventApplicationStateHook) then
QGuiApplication_hook_Destroy(FAppEventApplicationStateHook);
FAppEvenFilterHook := nil;
FAppFocusChangedHook := nil;
FAppEventApplicationStateHook := nil;
// do not quit application if we are library
if not FIsLibraryInstance then
@ -669,6 +674,12 @@ var
AParent: QWidgetH;
R: TRect;
AQtPoint: TQtPoint;
{$IFNDEF QTUSEFOCUSCHANGEDHOOK}
OldWidget, NewWidget: TQtWidget;
Msg: TLMessage;
FocusedQtWidget: QWidgetH;
FocusedTQtWidget: TQtWidget;
{$ENDIF}
function IsAnyWindowActive: Boolean;
begin
@ -847,6 +858,65 @@ begin
FreeSysColorBrushes(True);
end;
end;
{$IFNDEF QTUSEFOCUSCHANGEDHOOK}
QEventFocusIn:
begin
if not QObject_isWidgetType(Sender) then
exit;
FocusedQtWidget := QApplication_focusWidget();
// writeln('FocusedWidget ? ',Assigned(FocusedQtWidget),' Sender ? ',QObject_isWidgetType(Sender));
if Assigned(FocusedQtWidget) and (QWidgetH(Sender) <> FocusedQtWidget) then
begin
OldWidget := TQtWidget(HwndFromWidgetH(FocusedQtWidget));
if OldWidget <> nil then
begin
NewWidget := TQtWidget(HwndFromWidgetH(QWidgetH(Sender)));
Msg := Default(TLMessage);
Msg.msg := LM_KILLFOCUS;
Msg.wParam := PtrInt(NewWidget);
OldWidget.DeliverMessage(Msg);
{$IFDEF DebugQtFocus}
writeln('OldWidget(1) deliver focus out =',DbgSName(OldWidget));
{$ENDIF}
end;
end;
NewWidget := TQtWidget(HwndFromWidgetH(QWidgetH(Sender)));
// writeln('NewWidget=',DbgSName(NewWidget),' Ptr=',PtrUInt(NewWidget));
Msg := Default(TLMessage);
Msg.msg := LM_SETFOCUS;
if Assigned(FocusedQtWidget) and (FocusedQtWidget <> QWidgetH(Sender)) then
OldWidget := TQtWidget(HWndFromWidgetH(FocusedQtWidget))
else
OldWidget := nil;
// writeln('OldWidget=',DbgSName(OldWidget),' Ptr=',PtrUInt(OldWidget));
Msg.WParam := PtrInt(OldWidget);
if Assigned(NewWidget) then
begin
{$IFDEF DebugQtFocus}
writeln('Deliver focus IN for ',dbgsName(NewWidget));
{$ENDIF}
NewWidget.DeliverMessage(Msg);
end;
end;
QEventFocusOut:
begin
if not QObject_isWidgetType(Sender) then
exit;
FocusedQtWidget := QWidgetH(Sender);
OldWidget := TQtWidget(HwndFromWidgetH(FocusedQtWidget));
if Assigned(OldWidget) then
begin
Msg := Default(TLMessage);
Msg.msg := LM_KILLFOCUS;
Msg.wParam := 0; // PtrInt(NewWidget);
OldWidget.DeliverMessage(Msg);
{$IFDEF DebugQtFocus}
writeln('DELIVER focus OUT for ',dbgsName(OldWidget));
{$ENDIF}
end;
end;
{$ENDIF}
QEventShow,
QEventHide:
begin
@ -870,6 +940,7 @@ begin
end;
end;
{$IFDEF QTUSEFOCUSCHANGEDHOOK}
procedure TQtWidgetSet.FocusChanged(aold: QWidgetH; anew: QWidgetH); cdecl;
var
OldWidget, NewWidget: TQtWidget;
@ -1146,6 +1217,7 @@ begin
NewWidget.DeliverMessage(Msg);
end;
end;
{$ENDIF}
procedure TQtWidgetSet.AppStateChanged(AState: QtApplicationState); cdecl;
begin