mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-01 21:01:14 +02:00
Gtk2: fixed clientRect of TCustomForm with main menu. Patch by rich2014. issue #40071
This commit is contained in:
parent
3990e8a080
commit
d195570688
@ -1105,6 +1105,7 @@ var
|
||||
SizeMsg: TLMSize;
|
||||
GtkWidth: LongInt;
|
||||
GtkHeight: LongInt;
|
||||
clientRectFix: TRect;
|
||||
{$IFDEF HasX}
|
||||
NetAtom: TGdkAtom;
|
||||
AtomType: TGdkAtom;
|
||||
@ -1138,6 +1139,11 @@ begin
|
||||
if GtkWidth<0 then GtkWidth:=0;
|
||||
GtkHeight:=Widget^.Allocation.Height;
|
||||
if GtkHeight<0 then GtkHeight:=0;
|
||||
|
||||
clientRectFix:= GetWidgetInfo(Widget)^.FormClientRectFix;
|
||||
inc( GtkWidth, clientRectFix.Width );
|
||||
inc( GtkHeight, clientRectFix.Height );
|
||||
|
||||
//debugln('GTKWindowStateEventCB ',DbgSName(TObject(Data)),' ',dbgs(state^.new_window_state),' ',WidgetFlagsToString(Widget));
|
||||
if ((GDK_WINDOW_STATE_ICONIFIED and state^.new_window_state)>0) then
|
||||
begin
|
||||
|
@ -484,6 +484,8 @@ type
|
||||
PaintDepth: integer; // increased/decreased by Begin/EndPaint
|
||||
DataOwner: Boolean; // Set if the UserData should be freed when the info is freed
|
||||
UserData: Pointer;
|
||||
|
||||
FormClientRectFix: TRect; // used only by forms, eg. MainMenu occupy client rect
|
||||
FormBorderStyle: Integer; // used only by forms
|
||||
FormWindowState: TGdkEventWindowState; // used only by forms to stop infinite loops eg. issue #16505
|
||||
FirstPaint: boolean; // for accurate frame - forms only
|
||||
|
@ -6571,11 +6571,62 @@ begin
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
// move from gtk2wscontrls.pp
|
||||
// to avoid unit circular references
|
||||
procedure SetWidgetConstraints(const AWinControl: TWinControl);
|
||||
var
|
||||
Widget: PGtkWidget;
|
||||
Geometry: TGdkGeometry;
|
||||
clientRectFix: TRect;
|
||||
begin
|
||||
Widget := {%H-}PGtkWidget(AWinControl.Handle);
|
||||
if (Widget <> nil) and (GtkWidgetIsA(Widget, gtk_window_get_type)) then
|
||||
begin
|
||||
clientRectFix:= GetWidgetInfo(Widget)^.FormClientRectFix;
|
||||
with Geometry do
|
||||
begin
|
||||
if AWinControl.Constraints.MinWidth > 0 then
|
||||
min_width := AWinControl.Constraints.MinWidth
|
||||
else
|
||||
min_width := 1;
|
||||
if AWinControl.Constraints.MaxWidth > 0 then
|
||||
max_width := AWinControl.Constraints.MaxWidth
|
||||
else
|
||||
max_width := 32767;
|
||||
if AWinControl.Constraints.MinHeight > 0 then
|
||||
min_height := AWinControl.Constraints.MinHeight
|
||||
else
|
||||
min_height := 1;
|
||||
if AWinControl.Constraints.MaxHeight > 0 then
|
||||
max_height := AWinControl.Constraints.MaxHeight
|
||||
else
|
||||
max_height := 32767;
|
||||
|
||||
if min_width>0 then inc(min_width, clientRectFix.Width);
|
||||
if max_width>0 then inc(max_width, clientRectFix.Width);
|
||||
if min_height>0 then inc(min_height, clientRectFix.Height);
|
||||
if max_height>0 then inc(max_height, clientRectFix.Height);
|
||||
|
||||
base_width := AWinControl.Width + clientRectFix.Width;
|
||||
base_height := AWinControl.Height + clientRectFix.Height;
|
||||
width_inc := 1;
|
||||
height_inc := 1;
|
||||
min_aspect := 0;
|
||||
max_aspect := 1;
|
||||
win_gravity := gtk_window_get_gravity(PGtkWindow(Widget));
|
||||
end;
|
||||
//debugln('TGtk2WSWinControl.ConstraintsChange A ',GetWidgetDebugReport(Widget),' max=',dbgs(Geometry.max_width),'x',dbgs(Geometry.max_height));
|
||||
gtk_window_set_geometry_hints(PGtkWindow(Widget), nil, @Geometry,
|
||||
GDK_HINT_POS or GDK_HINT_MIN_SIZE or GDK_HINT_MAX_SIZE);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SendSizeNotificationToLCL(aWidget: PGtkWidget);
|
||||
var
|
||||
LCLControl: TWinControl;
|
||||
LCLLeft, LCLTop, LCLWidth, LCLHeight: integer;
|
||||
GtkLeft, GtkTop, GtkWidth, GtkHeight: integer;
|
||||
clientRectFix: PRect;
|
||||
TopLeftChanged, WidthHeightChanged, IsTopLevelWidget: boolean;
|
||||
MessageDelivered: boolean;
|
||||
SizeMsg: TLMSize;
|
||||
@ -6617,17 +6668,43 @@ begin
|
||||
|
||||
GetWidgetRelativePosition(MainWidget,GtkLeft,GtkTop);
|
||||
|
||||
gtk_widget_get_size_request(MainWidget, @GtkWidth, @GtkHeight);
|
||||
if LCLControl is TCustomForm then begin
|
||||
gtk_widget_get_size_request(FixedWidget, @GtkWidth, @GtkHeight);
|
||||
if GtkWidth < 0 then
|
||||
GtkWidth:=FixedWidget^.Allocation.Width;
|
||||
if GtkHeight <0 then
|
||||
GtkHeight:=FixedWidget^.Allocation.Height;
|
||||
|
||||
if GtkWidth < 0 then
|
||||
GtkWidth:=MainWidget^.Allocation.Width
|
||||
else
|
||||
MainWidget^.Allocation.Width:=GtkWidth;
|
||||
if GtkHeight < 0 then
|
||||
GtkHeight:=MainWidget^.Allocation.Height
|
||||
else
|
||||
MainWidget^.Allocation.Height:=GtkHeight;
|
||||
//DebugLn(['SendSizeNotificationToLCL ',DbgSName(LCLControl),' gtk=',GtkLeft,',',GtkTop,',',GtkWidth,'x',GtkHeight,' Allocation=',MainWidget^.Allocation.Width,'x',MainWidget^.Allocation.Height]);
|
||||
// if ClientRect of the Form is occupied,
|
||||
// record the occupied size into FormClientRectFix,
|
||||
// it will be used when setting the Real Gtk Window elsewhere
|
||||
WidthHeightChanged:= false;
|
||||
clientRectFix:= @(GetWidgetInfo(aWidget)^.FormClientRectFix);
|
||||
if (GtkWidth+clientRectFix^.Width) <> MainWidget^.Allocation.Width then begin
|
||||
clientRectFix^.Width:= MainWidget^.Allocation.Width - GtkWidth;
|
||||
WidthHeightChanged:= true;
|
||||
end;
|
||||
if (GtkHeight+clientRectFix^.Height) <> MainWidget^.Allocation.Height then begin
|
||||
clientRectFix^.Height:= MainWidget^.Allocation.Height - GtkHeight;
|
||||
WidthHeightChanged:= true;
|
||||
end;
|
||||
if WidthHeightChanged then begin
|
||||
SetResizeRequest(MainWidget);
|
||||
SetWidgetConstraints(LCLControl);
|
||||
end;
|
||||
end else begin
|
||||
gtk_widget_get_size_request(MainWidget, @GtkWidth, @GtkHeight);
|
||||
|
||||
if GtkWidth < 0 then
|
||||
GtkWidth:=MainWidget^.Allocation.Width
|
||||
else
|
||||
MainWidget^.Allocation.Width:=GtkWidth;
|
||||
if GtkHeight < 0 then
|
||||
GtkHeight:=MainWidget^.Allocation.Height
|
||||
else
|
||||
MainWidget^.Allocation.Height:=GtkHeight;
|
||||
//DebugLn(['SendSizeNotificationToLCL ',DbgSName(LCLControl),' gtk=',GtkLeft,',',GtkTop,',',GtkWidth,'x',GtkHeight,' Allocation=',MainWidget^.Allocation.Width,'x',MainWidget^.Allocation.Height]);
|
||||
end;
|
||||
|
||||
if GtkWidth<0 then GtkWidth:=0;
|
||||
if GtkHeight<0 then GtkHeight:=0;
|
||||
@ -7008,12 +7085,14 @@ procedure SetWindowSizeAndPosition(Window: PGtkWindow;
|
||||
var
|
||||
Width, Height: integer;
|
||||
allocation: TGtkAllocation;
|
||||
clientRectFix: TRect;
|
||||
//Info: PGtkWindowGeometryInfo;
|
||||
begin
|
||||
Width:=AWinControl.Width;
|
||||
clientRectFix:= GetWidgetInfo(Window)^.FormClientRectFix;
|
||||
Width:=AWinControl.Width+clientRectFix.Width;
|
||||
// 0 and negative values have a special meaning, so don't use them
|
||||
if Width<=0 then Width:=1;
|
||||
Height:=AWinControl.Height;
|
||||
Height:=AWinControl.Height+clientRectFix.Height;
|
||||
if Height<=0 then Height:=1;
|
||||
|
||||
{$IFDEF VerboseSizeMsg}
|
||||
|
@ -657,6 +657,7 @@ function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode;cdecl;
|
||||
procedure SaveSizeNotification(Widget: PGtkWidget);
|
||||
procedure SaveClientSizeNotification(FixWidget: PGtkWidget);
|
||||
procedure SendSizeNotificationToLCL(aWidget: PGtkWidget);
|
||||
procedure SetWidgetConstraints(const AWinControl: TWinControl);
|
||||
function CreateTopologicalSortedWidgets(HashArray: TDynHashArray): TFPList;
|
||||
procedure GetGTKDefaultWidgetSize(AWinControl: TWinControl;
|
||||
var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean);
|
||||
|
@ -555,44 +555,8 @@ begin
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSWinControl.ConstraintsChange(const AWinControl: TWinControl);
|
||||
var
|
||||
Widget: PGtkWidget;
|
||||
Geometry: TGdkGeometry;
|
||||
begin
|
||||
Widget := {%H-}PGtkWidget(AWinControl.Handle);
|
||||
if (Widget <> nil) and (GtkWidgetIsA(Widget, gtk_window_get_type)) then
|
||||
begin
|
||||
with Geometry do
|
||||
begin
|
||||
if AWinControl.Constraints.MinWidth > 0 then
|
||||
min_width := AWinControl.Constraints.MinWidth
|
||||
else
|
||||
min_width := 1;
|
||||
if AWinControl.Constraints.MaxWidth > 0 then
|
||||
max_width := AWinControl.Constraints.MaxWidth
|
||||
else
|
||||
max_width := 32767;
|
||||
if AWinControl.Constraints.MinHeight > 0 then
|
||||
min_height := AWinControl.Constraints.MinHeight
|
||||
else
|
||||
min_height := 1;
|
||||
if AWinControl.Constraints.MaxHeight > 0 then
|
||||
max_height := AWinControl.Constraints.MaxHeight
|
||||
else
|
||||
max_height := 32767;
|
||||
|
||||
base_width := AWinControl.Width;
|
||||
base_height := AWinControl.Height;
|
||||
width_inc := 1;
|
||||
height_inc := 1;
|
||||
min_aspect := 0;
|
||||
max_aspect := 1;
|
||||
win_gravity := gtk_window_get_gravity(PGtkWindow(Widget));
|
||||
end;
|
||||
//debugln('TGtk2WSWinControl.ConstraintsChange A ',GetWidgetDebugReport(Widget),' max=',dbgs(Geometry.max_width),'x',dbgs(Geometry.max_height));
|
||||
gtk_window_set_geometry_hints(PGtkWindow(Widget), nil, @Geometry,
|
||||
GDK_HINT_POS or GDK_HINT_MIN_SIZE or GDK_HINT_MAX_SIZE);
|
||||
end;
|
||||
SetWidgetConstraints(AWinControl);
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSWinControl.DestroyHandle(const AWinControl: TWinControl);
|
||||
@ -657,6 +621,7 @@ var
|
||||
Geometry: TGdkGeometry;
|
||||
AHints: TGdkWindowHints;
|
||||
AFixedWidthHeight: Boolean;
|
||||
clientRectFix: TRect;
|
||||
begin
|
||||
if not WSCheckHandleAllocated(AWinControl, 'SetBounds')
|
||||
then Exit;
|
||||
@ -667,10 +632,12 @@ begin
|
||||
if (not (AWinControl is TCustomForm)) or (AWinControl.Parent<>nil)
|
||||
or (AWinControl.ParentWindow<>0) then
|
||||
exit;
|
||||
|
||||
AForm := TCustomForm(AWinControl);
|
||||
if not (csDesigning in AForm.ComponentState) and
|
||||
AForm.HandleObjectShouldBeVisible then
|
||||
begin
|
||||
clientRectFix:= GetWidgetInfo(PGtkWidget(AForm.Handle))^.FormClientRectFix;
|
||||
// we must set fixed size, gtk_window_set_resizable does not work
|
||||
// as expected for some reason.issue #20741.
|
||||
// Constraints fix issue #29563
|
||||
@ -704,8 +671,13 @@ begin
|
||||
if not AFixedWidthHeight and (AForm.Constraints.MaxWidth = 0) then
|
||||
max_width := 32767;
|
||||
|
||||
base_width := AForm.Width;
|
||||
base_height := AForm.Height;
|
||||
if min_width>0 then inc(min_width, clientRectFix.Width);
|
||||
if max_width>0 then inc(max_width, clientRectFix.Width);
|
||||
if min_height>0 then inc(min_height, clientRectFix.Height);
|
||||
if max_height>0 then inc(max_height, clientRectFix.Height);
|
||||
|
||||
base_width := AForm.Width + clientRectFix.Width;
|
||||
base_height := AForm.Height + clientRectFix.Height;
|
||||
width_inc := 1;
|
||||
height_inc := 1;
|
||||
min_aspect := 0;
|
||||
@ -740,7 +712,9 @@ begin
|
||||
gtk_window_set_geometry_hints({%H-}PGtkWindow(AForm.Handle), nil, @Geometry,
|
||||
AHints);
|
||||
end;
|
||||
gtk_window_resize({%H-}PGtkWindow(AForm.Handle), AForm.Width, AForm.Height);
|
||||
gtk_window_resize( {%H-}PGtkWindow(AForm.Handle),
|
||||
AForm.Width+clientRectFix.Width,
|
||||
AForm.Height+clientRectFix.Height);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -705,6 +705,7 @@ var
|
||||
AForm, APopupParent: TCustomForm;
|
||||
GtkWindow: PGtkWindow;
|
||||
Geometry: TGdkGeometry;
|
||||
clientRectFix: TRect;
|
||||
|
||||
function ShowNonModalOverModal: Boolean;
|
||||
var
|
||||
@ -820,17 +821,18 @@ begin
|
||||
AForm.HandleObjectShouldBeVisible and
|
||||
(AForm.BorderStyle in [bsDialog, bsSingle]) then
|
||||
begin
|
||||
clientRectFix:= GetWidgetInfo(PGtkWidget(AForm.Handle))^.FormClientRectFix;
|
||||
// we must set fixed size, gtk_window_set_resizable does not work
|
||||
// as expected for some reason.issue #20741
|
||||
with Geometry do
|
||||
begin
|
||||
min_width := AForm.Width;
|
||||
max_width := AForm.Width;
|
||||
min_height := AForm.Height;
|
||||
max_height := AForm.Height;
|
||||
min_width := AForm.Width + clientRectFix.Width;
|
||||
max_width := AForm.Width + clientRectFix.Width;
|
||||
min_height := AForm.Height + clientRectFix.Height;
|
||||
max_height := AForm.Height + clientRectFix.Height;
|
||||
|
||||
base_width := AForm.Width;
|
||||
base_height := AForm.Height;
|
||||
base_width := AForm.Width + clientRectFix.Width;
|
||||
base_height := AForm.Height + clientRectFix.Height;
|
||||
width_inc := 1;
|
||||
height_inc := 1;
|
||||
min_aspect := 0;
|
||||
|
Loading…
Reference in New Issue
Block a user