mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 10:19:36 +02:00
gtk2: fixed application deactivate on switch using alt-tab
This commit is contained in:
parent
8e72df6b62
commit
b66a32c36b
@ -971,7 +971,6 @@ begin
|
||||
{$ENDIF}
|
||||
//DebugLn('GTKKillFocusCB ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget));
|
||||
{$IFDEF VerboseFocus}
|
||||
NeedShiftUpdateAfternFocus := True; // <- JRA: this doesn't look like simply log !!!
|
||||
LCLObject:=TObject(data);
|
||||
DebugLn(['GTKillFocusCB Widget=',DbgS(Widget),' Event^.theIn=',Event^._in,
|
||||
' LCLObject=',dbgsName(LCLobject)]);
|
||||
@ -1002,7 +1001,6 @@ begin
|
||||
{$ENDIF}
|
||||
//DebugLn('GTKKillFocusCBAfter ',DbgSName(TObject(Data)),' ',GetWidgetDebugReport(Widget));
|
||||
{$IFDEF VerboseFocus}
|
||||
NeedShiftUpdateAfternFocus := True; // <- JRA: this doesn't look like simply log !!!
|
||||
LCLObject:=TObject(data);
|
||||
DebugLnEnter(['GTKillFocusCBAfter INIT Widget=',DbgS(Widget),' Event^.theIn=',Event^._in,
|
||||
' LCLObject=',dbgsName(LCLObject)]);
|
||||
|
@ -325,7 +325,8 @@ type
|
||||
procedure HideAllHints;
|
||||
procedure RestoreAllHints;
|
||||
{$ENDIF}
|
||||
procedure StartFocusTimer;
|
||||
procedure StartAppFocusTimer;
|
||||
procedure StopAppFocusTimer;
|
||||
property AppActive: Boolean read GetAppActive write SetAppActive;
|
||||
property IsLibraryInstance: Boolean read FIsLibraryInstance;
|
||||
property GtkIsTerminated: Boolean read FGtkTerminated;
|
||||
|
@ -2776,13 +2776,12 @@ function gtkAppFocusTimer({%H-}Data: gPointer):gBoolean; cdecl;
|
||||
// needed by app activate/deactivate
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
TGtk2WidgetSet(WidgetSet).StopAppFocusTimer;
|
||||
if TGtk2WidgetSet(WidgetSet).LastFocusIn = nil then
|
||||
TGtk2WidgetSet(WidgetSet).AppActive := False;
|
||||
gtk_timeout_remove(TGtk2WidgetSet(WidgetSet).FocusTimer);
|
||||
TGtk2WidgetSet(WidgetSet).FocusTimer := 0;
|
||||
end;
|
||||
|
||||
procedure TGtk2WidgetSet.StartFocusTimer;
|
||||
procedure TGtk2WidgetSet.StartAppFocusTimer;
|
||||
begin
|
||||
FLastFocusIn := nil;
|
||||
if FocusTimer <> 0 then
|
||||
@ -2790,6 +2789,13 @@ begin
|
||||
FocusTimer := gtk_timeout_add(50, TGtkFunction(@gtkAppFocusTimer), nil);
|
||||
end;
|
||||
|
||||
procedure TGtk2WidgetSet.StopAppFocusTimer;
|
||||
begin
|
||||
if FocusTimer = 0 then exit;
|
||||
gtk_timeout_remove(FocusTimer);
|
||||
FocusTimer := 0;
|
||||
end;
|
||||
|
||||
procedure TGtk2WidgetSet.InitStockItems;
|
||||
var
|
||||
LogBrush: TLogBrush;
|
||||
|
@ -269,31 +269,52 @@ begin
|
||||
GDK_FOCUS_CHANGE:
|
||||
begin
|
||||
ACtl := TWinControl(Data);
|
||||
|
||||
// Application.Activate/Deactivate is done via a timer
|
||||
// Every time a form looses the focus a timer is started
|
||||
// and every time focus is gained the timer is stopped.
|
||||
// Note: It seems gtk2 itself does not always detect focus lost
|
||||
// For example in LinuxMint switching from a TEdit using Alt-Tab to another
|
||||
// app generates a focus out, but gtk2 still shows the TEdit focused
|
||||
// with blinking cursor.
|
||||
// Switching focus using the mouse to another app, also generates
|
||||
// a focus out, and gtk2 hides the blinking cursor and focus coloring.
|
||||
// Switching to another workspace does not generate a focus out event <sigh>.
|
||||
if PGdkEventFocus(event)^._in = 0 then
|
||||
begin
|
||||
{$IFDEF HASX}
|
||||
XDisplay := gdk_display;
|
||||
XGetInputFocus(XDisplay, @Window, @RevertStatus);
|
||||
// Window - 1 is our frame !
|
||||
if (RevertStatus = RevertToParent) and
|
||||
(GDK_WINDOW_XID(Widget^.Window) = Window - 1) then
|
||||
exit(True);
|
||||
if ACtl.Parent<>nil then
|
||||
begin
|
||||
XDisplay := gdk_display;
|
||||
XGetInputFocus(XDisplay, @Window, @RevertStatus);
|
||||
// Window - 1 is our frame !
|
||||
if (RevertStatus = RevertToParent) and
|
||||
(GDK_WINDOW_XID(Widget^.Window) = Window - 1) then
|
||||
begin
|
||||
// Note: on LinuxMint switching via Alt-Tab to another window
|
||||
// generates RevertToParent. The above
|
||||
//
|
||||
exit(True);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
with Gtk2WidgetSet do
|
||||
begin
|
||||
LastFocusOut := {%H-}PGtkWidget(ACtl.Handle);
|
||||
if LastFocusOut = LastFocusIn then
|
||||
StartFocusTimer;
|
||||
StartAppFocusTimer;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
with Gtk2WidgetSet do
|
||||
begin
|
||||
StopAppFocusTimer;
|
||||
LastFocusIn := {%H-}PGtkWidget(ACtl.Handle);
|
||||
if not AppActive then
|
||||
AppActive := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
if GTK_IS_WINDOW(Widget) and
|
||||
(g_object_get_data({%H-}PGObject(ACtl.Handle),'lcl_nonmodal_over_modal') <> nil) then
|
||||
begin
|
||||
@ -308,9 +329,14 @@ end;
|
||||
|
||||
class procedure TGtk2WSCustomForm.SetCallbacks(const AWidget: PGtkWidget;
|
||||
const AWidgetInfo: PWidgetInfo);
|
||||
var
|
||||
aLCLObj: TObject;
|
||||
aLCLControl: TWinControl;
|
||||
begin
|
||||
TGtk2WSWinControl.SetCallbacks(PGtkObject(AWidget), TComponent(AWidgetInfo^.LCLObject));
|
||||
if (TWinControl(AWidgetInfo^.LCLObject).Parent = nil) and (TWinControl(AWidgetInfo^.LCLObject).ParentWindow = 0) then
|
||||
aLCLObj:=AWidgetInfo^.LCLObject;
|
||||
aLCLControl:=TWinControl(aLCLObj);
|
||||
TGtk2WSWinControl.SetCallbacks(PGtkObject(AWidget), aLCLControl);
|
||||
if (aLCLControl.Parent = nil) and (aLCLControl.ParentWindow = 0) then
|
||||
with TGTK2WidgetSet(Widgetset) do
|
||||
begin
|
||||
{$IFDEF HASX}
|
||||
@ -318,18 +344,18 @@ begin
|
||||
// see http://bugs.freepascal.org/view.php?id=17523
|
||||
if not compositeManagerRunning then
|
||||
{$ENDIF}
|
||||
SetCallback(LM_CONFIGUREEVENT, PGtkObject(AWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_CLOSEQUERY, PGtkObject(AWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallBack(LM_ACTIVATE, PGtkObject(AWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_CONFIGUREEVENT, PGtkObject(AWidget), aLCLObj);
|
||||
SetCallback(LM_CLOSEQUERY, PGtkObject(AWidget), aLCLObj);
|
||||
SetCallBack(LM_ACTIVATE, PGtkObject(AWidget), aLCLObj);
|
||||
if (gtk_major_version = 2) and (gtk_minor_version <= 8) then
|
||||
begin
|
||||
SetCallback(LM_HSCROLL, PGtkObject(AWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_VSCROLL, PGtkObject(AWidget), AWidgetInfo^.LCLObject);
|
||||
SetCallback(LM_HSCROLL, PGtkObject(AWidget), aLCLObj);
|
||||
SetCallback(LM_VSCROLL, PGtkObject(AWidget), aLCLObj);
|
||||
end;
|
||||
end;
|
||||
|
||||
g_signal_connect(PGtkObject(AWidgetInfo^.CoreWidget), 'event',
|
||||
gtk_signal_func(@Gtk2FormEvent), AWidgetInfo^.LCLObject);
|
||||
gtk_signal_func(@Gtk2FormEvent), aLCLObj);
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomForm.CanFocus(const AWinControl: TWinControl
|
||||
|
Loading…
Reference in New Issue
Block a user