diff --git a/lcl/interfaces/gtk/gtkcallback.inc b/lcl/interfaces/gtk/gtkcallback.inc index b8531f100e..6e8222e122 100644 --- a/lcl/interfaces/gtk/gtkcallback.inc +++ b/lcl/interfaces/gtk/gtkcallback.inc @@ -632,7 +632,8 @@ end; function gtkfrmactivateAfter(widget: PGtkWidget; Event : PgdkEventFocus; data: gPointer) : GBoolean; cdecl; var - Mess : TLMActivate; + Mess: TLMActivate; + Info: PWidgetInfo; {$IFDEF VerboseFocus} LCLObject: TObject; CurFocusWidget: PGtkWidget; @@ -677,14 +678,22 @@ begin DebugLn(''); {$ENDIF} - Mess.Msg := LM_ACTIVATE; - Mess.Active:=true; - Mess.Minimized:=false; - Mess.ActiveWindow:=0; - if GtkWidgetIsA(Widget, gtk_window_get_type) then - Mess.ActiveWindow:=HWnd(PtrUInt(PGTKWindow(Widget)^.focus_widget)); - Mess.Result := 0; - DeliverMessage(Data, Mess); // send message directly (not Post) + Info := GetWidgetInfo(Widget, false); + try + if (Info <> nil) then + Include(Info^.Flags, wwiActivating); + Mess.Msg := LM_ACTIVATE; + Mess.Active := True; + Mess.Minimized := False; + Mess.ActiveWindow := 0; + if GtkWidgetIsA(Widget, gtk_window_get_type) then + Mess.ActiveWindow := HWnd(PtrUInt(PGTKWindow(Widget)^.focus_widget)); + Mess.Result := 0; + DeliverMessage(Data, Mess); // send message directly (not Post) + finally + if Info <> nil then + Exclude(Info^.Flags, wwiActivating); + end; Result := CallBackDefaultReturn; end; @@ -692,7 +701,7 @@ end; function gtkfrmdeactivateAfter( widget: PGtkWidget; Event : PgdkEventFocus; data: gPointer) : GBoolean; cdecl; var - Mess : TLMActivate; + Mess: TLMActivate; Info: PWidgetInfo; {$IFDEF VerboseFocus} LCLObject: TControl; diff --git a/lcl/interfaces/gtk/gtkdef.pp b/lcl/interfaces/gtk/gtkdef.pp index 6a82b03dad..b5a28642a9 100644 --- a/lcl/interfaces/gtk/gtkdef.pp +++ b/lcl/interfaces/gtk/gtkdef.pp @@ -412,7 +412,8 @@ type wwiNotOnParentsClientArea, wwiValidQueuedEvent, // Mark this widgetinfo as valid queued proc // see gtkwsmenus.pp: gtkWSPopupMenuDeactivate - wwiDeactivating // during gtk deactivate + wwiDeactivating, // during gtk deactivate + wwiActivating // during gtk activate ); TWidgetInfoFlags = set of TWidgetInfoFlag; tGtkStateEnumRange = 0..31; diff --git a/lcl/interfaces/gtk/gtkwinapi.inc b/lcl/interfaces/gtk/gtkwinapi.inc index bb45eadb6a..54e2f74b11 100644 --- a/lcl/interfaces/gtk/gtkwinapi.inc +++ b/lcl/interfaces/gtk/gtkwinapi.inc @@ -8603,6 +8603,7 @@ function TGtkWidgetSet.SetFocus(hWnd: HWND): HWND; {off $DEFINE VerboseFocus} var Widget, TopLevel, NewFocusWidget: PGtkWidget; + Info: PWidgetInfo; {$IfDef VerboseFocus} AWinControl: TWinControl; {$EndIf} @@ -8623,7 +8624,7 @@ begin // return the old focus handle Result := GetFocus; - NewFocusWidget:=nil; + NewFocusWidget := nil; TopLevel := gtk_widget_get_toplevel(Widget); {$IfDef VerboseFocus} @@ -8662,9 +8663,7 @@ begin DebugLn(' there is a modal form above -> focus forbidden'); {$EndIf} exit; - end{ - else - SetForegroundWindow(NewForm.Handle)}; + end; end; NewFocusWidget := FindFocusWidget(Widget); @@ -8678,14 +8677,15 @@ begin write(' TopLvlVisible=',GTK_WIDGET_VISIBLE(PGtkWidget(TopLevel))); DebugLn(''); {$EndIf} - if (NewFocusWidget<>nil) and GTK_WIDGET_CAN_FOCUS(NewFocusWidget) then begin - if (PGtkWindow(TopLevel)^.Focus_Widget<>NewFocusWidget) - then begin + if (NewFocusWidget<>nil) and GTK_WIDGET_CAN_FOCUS(NewFocusWidget) then + begin + if (PGtkWindow(TopLevel)^.Focus_Widget<>NewFocusWidget) then + begin {$IfDef VerboseFocus} DebugLn(' H SETTING NewFocusWidget=',dbgs(NewFocusWidget),' ',DbgSName(GetNearestLCLObject(NewFocusWidget))); {$EndIf} //DebugLn('TGtkWidgetSet.SetFocus TopLevel[',DebugGtkWidgets.GetInfo(TopLevel,false),'] NewFocusWidget=[',DebugGtkWidgets.GetInfo(NewFocusWidget,false),']'); - gtk_window_set_focus(PGtkWindow(TopLevel),NewFocusWidget); + gtk_window_set_focus(PGtkWindow(TopLevel), NewFocusWidget); {$IfDef VerboseFocus} DebugLn(' I NewTopLevel FocusWidget=',DbgS(PGtkWindow(TopLevel)^.Focus_Widget),' Success=',dbgs(PGtkWindow(TopLevel)^.Focus_Widget=NewFocusWidget)); {$EndIf} @@ -8700,9 +8700,10 @@ begin begin // grab the focus to the parent window NewTopLevelWidget := gtk_widget_get_toplevel(NewFocusWidget); + NewTopLevelObject := GetNearestLCLObject(NewTopLevelWidget); if (Screen<>nil) and (Screen.GetCurrentModalForm<>nil) - and (GetNearestLCLObject(NewTopLevelWidget)<>Screen.GetCurrentModalForm) + and (NewTopLevelObject <>Screen.GetCurrentModalForm) then begin {$IFDEF VerboseFocus} DebugLn('[TGtkWidgetSet.SetFocus] there is a modal form -> not grabbing'); @@ -8711,6 +8712,12 @@ begin {$IfDef VerboseFocus} DebugLn(' J Grabbing focus ',GetWidgetDebugReport(NewFocusWidget)); {$EndIf} + if NewTopLevelObject is TCustomForm then + begin + Info := GetWidgetInfo(NewTopLevelWidget, False); + if (Info <> nil) and not (wwiActivating in Info^.Flags) then + SetForegroundWindow(TCustomForm(NewTopLevelObject).Handle); + end; gtk_widget_grab_focus(NewFocusWidget); end; end;