Gtk2: fixed restoring form position after form is hidden, and then shown.

Fixes #15069,#15417,#16507

git-svn-id: trunk@25519 -
This commit is contained in:
zeljko 2010-05-19 17:33:54 +00:00
parent 0d8b6c26e0
commit d7de33e1aa
4 changed files with 84 additions and 4 deletions

View File

@ -1976,6 +1976,7 @@ function gtksize_allocateCB(widget: PGtkWidget; size: pGtkAllocation;
var
w, h: Gint;
{$ENDIF}
begin
Result := CallBackDefaultReturn;
@ -1992,6 +1993,18 @@ begin
RaiseGDBException('');
exit;
end;
{$IFDEF Gtk2}
// do not send msg to LCL if we are shown after hide, setVisible will
// do that.
if TObject(Data) is TForm then
begin
with GetWidgetInfo(Widget)^.FormSavedPos do
begin
if (X <> -10000) and (Y <> -10000) then
exit;
end;
end;
{$ENDIF}
{$IFDEF VerboseSizeMsg}
w:=0; h:=0;
@ -2037,7 +2050,8 @@ begin
Result := CallBackDefaultReturn;
if (Widget=nil) or (Size=nil) then ;
if (TObject(Data) is TWinControl) then begin
if (TObject(Data) is TWinControl) then
begin
{$IFDEF VerboseSizeMsg}
DebugLn('gtksize_allocate_client: ',
TControl(Data).Name,':',TControl(Data).ClassName,

View File

@ -481,6 +481,8 @@ type
UserData: Pointer;
FormBorderStyle: Integer; // used only by forms
FormWindowState: TGdkEventWindowState; // used only by forms to stop infinite loops eg. issue #16505
FormSavedPos: TPoint; // used only by forms - saved LCL Left & Top if form hidden eg. issue #15417
// so later when we call show, it's restored to it's original position
end;
//TODO: remove

View File

@ -3699,7 +3699,8 @@ begin
LM_WINDOWPOSCHANGED: //LM_SIZEALLOCATE, LM_RESIZE :
begin
ConnectSenderSignal(gObject, 'size-allocate', @gtksize_allocateCB);
if gObject<>gFixed then begin
if gObject<>gFixed then
begin
ConnectSenderSignal(gFixed, 'size-allocate', @gtksize_allocate_client);
end;
end;
@ -4350,6 +4351,10 @@ var
AWindow: PGdkWindow;
ACustomForm: TCustomForm;
{$IFDEF GTK2}
{$IFDEF VerboseFormPositioning}
X1, Y1: gint; // current gdk_window_root_origin
{$ENDIF}
SavedOrigin: TPoint;
CurWindowState: TWindowState;
{$ENDIF}
begin
@ -4431,7 +4436,41 @@ begin
if gtk_widget_visible(SenderWidget) then
exit;
{$IFDEF GTK2}
// we must restore Left & Top coords here to prevent flickering
if (ACustomForm <> nil) and
(ACustomForm.Parent = nil) and
(ACustomForm.ParentWindow = 0) and
(ACustomForm is TForm) and // be sure that we are not THintWindow !
(ACustomForm.BorderStyle <> bsNone) and
not (ACustomForm.FormStyle in [fsMDIChild, fsSplash]) then
begin
if (ACustomForm.WindowState <> wsMinimized) then
begin
SavedOrigin := GetWidgetInfo(SenderWidget)^.FormSavedPos;
if (SavedOrigin.X <> -10000) and (SavedOrigin.Y <> -10000) then
begin
{$IFDEF VerboseFormPositioning}
gdk_window_get_root_origin(SenderWidget^.window, @X1, @Y1);
DebugLn('VFP [TGtkWidgetSet.ShowHide] B ',
LCLControl.Name,':',LCLControl.ClassName,
' Window=',dbgs(GetControlWindow(SenderWidget)<>nil),
' RESTORE FORMSAVEDPOS CURRENT X=',dbgs(X1),' Y=',dbgs(Y1),
' SAVED X=',dbgs(SavedOrigin.X),' Y=',dbgs(SavedOrigin.Y));
{$ENDIF}
with SavedOrigin do
gtk_window_move(PGtkWindow(SenderWidget), X, Y);
SavedOrigin.X := -10000;
SavedOrigin.Y := -10000;
GetWidgetInfo(SenderWidget)^.FormSavedPos := SavedOrigin;
end;
end;
end;
{$ENDIF}
gtk_widget_show(SenderWidget);
{$IFDEF GTK2}
if (ACustomForm <> nil) and
(ACustomForm.Parent = nil) and
@ -4453,13 +4492,30 @@ begin
{$ENDIF}
end
else begin
if (ACustomForm<>nil) then begin
if (ACustomForm<>nil) then
UnshareWindowAccelGroups(SenderWidget);
end;
if not gtk_widget_visible(SenderWidget) then
exit;
{$IFDEF GTK2}
// save previous position
if ACustomForm <> nil then
begin
if (ACustomForm is TForm) and
not (ACustomForm.FormStyle in [fsMDIChild, fsSplash])
and (ACustomForm.BorderStyle <> bsNone) then
begin
with GetWidgetInfo(SenderWidget)^.FormSavedPos do
begin
X := ACustomForm.Left;
Y := ACustomForm.Top;
end;
end;
end;
{$ENDIF}
gtk_widget_hide(SenderWidget);
if GtkWidgetIsA(SenderWidget,GTK_TYPE_WINDOW) then begin

View File

@ -317,6 +317,14 @@ begin
FillChar(WidgetInfo^.FormWindowState, SizeOf(WidgetInfo^.FormWindowState), #0);
WidgetInfo^.FormWindowState.new_window_state := GDK_WINDOW_STATE_WITHDRAWN;
// FormRootOrigin is used only to save and restore LCL's Left & Top
// in case when form is hidden and then shown again !
with WidgetInfo^.FormSavedPos do
begin
X := -10000;
Y := -10000;
end;
Box := CreateFormContents(ACustomForm, P, WidgetInfo);
gtk_container_add(PGtkContainer(P), Box);