LCL-Gtk2: fixed window move/resize issues with Fly/Openbox window managers, patch by Artem Izmaylov, issue #40752

This commit is contained in:
Maxim Ganetsky 2024-02-09 17:05:23 +03:00
parent d6b7ffd24c
commit d538fbd4f7
4 changed files with 61 additions and 11 deletions

View File

@ -2506,7 +2506,6 @@ function gtksize_allocateCB(widget: PGtkWidget; size: pGtkAllocation;
var
w, h: Gint;
{$ENDIF}
begin
Result := CallBackDefaultReturn;
@ -2543,7 +2542,15 @@ begin
if TControl(Data) is TCustomForm then
DebugLn('VFP gtksize_allocateCB: ',TControl(Data).ClassName,' ',dbgs(Size^.X),',',dbgs(Size^.Y));
{$ENDIF}
SendSizeNotificationToLCL(Widget);
if GTK_WIDGET_REALIZED(widget) and LockTopLevelWindowResizeOnNativeCall then
begin
Inc(TopLevelWindowResizeLocked);
SendSizeNotificationToLCL(Widget);
Dec(TopLevelWindowResizeLocked);
end
else
SendSizeNotificationToLCL(Widget);
end;
function gtksize_allocate_client({%H-}widget: PGtkWidget; {%H-}size: pGtkAllocation;

View File

@ -6736,9 +6736,13 @@ begin
clientRectFix^.Height:= MainWidget^.Allocation.Height - GtkHeight;
WidthHeightChanged:= true;
end;
if WidthHeightChanged then begin
SetWindowSizeAndPosition(PGtkWindow(MainWidget), LCLControl);
SetResizeRequest(MainWidget);
if WidthHeightChanged then
begin
if TopLevelWindowResizeLocked = 0 then
begin
SetWindowSizeAndPosition(PGtkWindow(MainWidget), LCLControl);
SetResizeRequest(MainWidget);
end;
SetWidgetConstraints(LCLControl);
end;
end else begin
@ -6856,6 +6860,8 @@ begin
YPos := SmallInt(GtkTop);
end;
MessageDelivered := (DeliverMessage(LCLControl, MoveMsg) = 0);
if TopLevelWindowResizeLocked > 0 then
FWidgetsWithResizeRequest.Remove(MainWidget);
if not MessageDelivered then exit;
end;
@ -7135,6 +7141,7 @@ var
Width, Height: integer;
allocation: TGtkAllocation;
clientRectFix: TRect;
x, y: gint;
//Info: PGtkWindowGeometryInfo;
begin
clientRectFix:= GetWidgetInfo(Window)^.FormClientRectFix;
@ -7155,7 +7162,9 @@ begin
// resize
gtk_window_resize(Window, Width, Height);
// reposition
gtk_window_move(Window, AWinControl.Left, AWinControl.Top);
gtk_window_get_position(Window, @x, @y);
if (x <> AWinControl.Left) or (y <> AWinControl.Top) then // for fly-wm + openbox
gtk_window_move(Window, AWinControl.Left, AWinControl.Top);
// force early resize
allocation := PGtkWidget(Window)^.allocation;
allocation.width := Width;
@ -7166,8 +7175,10 @@ begin
if (PGtkWidget(Window)^.Window <> nil) then
begin
// resize gdkwindow directly (sometimes the gtk forgets this)
gdk_window_move_resize(PGtkWidget(Window)^.Window,AWinControl.Left,
AWinControl.Top,Width,Height)
if (x <> AWinControl.Left) or (y <> AWinControl.Top) then // for fly-wm + openbox
gdk_window_move_resize(PGtkWidget(Window)^.Window,AWinControl.Left,AWinControl.Top,Width,Height)
else
gdk_window_resize(PGtkWidget(Window)^.Window,Width,Height);
end;
{$IFDEF VerboseSizeMsg}

View File

@ -801,6 +801,11 @@ function GTKWindowStateEventCB(widget: PGtkWidget;
function gtkMouseWheelCB({%H-}widget: PGtkWidget; event: PGdkEventScroll;
data: gPointer): GBoolean; cdecl;
{$Region 'Workaround for Fly (Astra Linux) + openbox'}
var
TopLevelWindowResizeLocked: Integer = 0;
function LockTopLevelWindowResizeOnNativeCall: Boolean;
{$EndRegion}
implementation
uses
@ -871,6 +876,27 @@ type
TWinControlAccess = class(TWinControl)
end;
{$Region 'Workaround for Fly (Astra Linux) + openbox'}
var
fLockTopLevelWindowResizeOnNativeCall: Integer = -1;
// Ref.to https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/40752
function LockTopLevelWindowResizeOnNativeCall: Boolean;
var
AWindowManager: string;
begin
if fLockTopLevelWindowResizeOnNativeCall < 0 then
begin
AWindowManager := GTK2WidgetSet.GetWindowManager;
if (AWindowManager = 'fly-wm') or (AWindowManager = 'openbox') then
fLockTopLevelWindowResizeOnNativeCall := 1
else
fLockTopLevelWindowResizeOnNativeCall := 0;
end;
Result := fLockTopLevelWindowResizeOnNativeCall <> 0;
end;
{$EndRegion}
{ TLCLHandledKeyEvent }
constructor TLCLHandledKeyEvent.Create(Event: PGdkEventKey);

View File

@ -721,9 +721,15 @@ begin
gtk_window_set_geometry_hints({%H-}PGtkWindow(AForm.Handle), nil, @Geometry,
AHints);
end;
gtk_window_resize( {%H-}PGtkWindow(AForm.Handle),
AForm.Width+clientRectFix.Width,
AForm.Height+clientRectFix.Height);
if LockTopLevelWindowResizeOnNativeCall then
begin
if TopLevelWindowResizeLocked = 0 then
SetWindowSizeAndPosition({%H-}PGtkWindow(AForm.Handle), AForm);
end
else
gtk_window_resize({%H-}PGtkWindow(AForm.Handle),
AForm.Width + clientRectFix.Width,
AForm.Height + clientRectFix.Height);
end;
end;
end;