FIX: Wrong scaling (Gtk3)

(cherry picked from commit 7c0b46c0e7)
This commit is contained in:
Alexander Koblov 2026-05-30 16:51:30 +03:00
commit 18e48bc8b6
4 changed files with 156 additions and 2 deletions

View file

@ -171,14 +171,14 @@ begin
UnitPath += 'platform/$(SrcOS)/qt6;platform/$(SrcOS)/wayland;';
end;
if (LCLWidgetType = 'gtk2') and (SrcOS = 'unix') and (TargetOS <> 'darwin') then
if ((LCLWidgetType = 'gtk2') or (LCLWidgetType = 'gtk3')) and (SrcOS = 'unix') then
begin
UnitPath += 'platform/$(SrcOS)/$(LCLWidgetType);';
end;
if (SrcOS = 'unix') and (TargetOS <> 'darwin') and (TargetOS <> 'haiku') then
begin
CustomOptions += '-dXDG -dRabbitVCS';
CustomOptions += ' -dXDG -dRabbitVCS';
end;"/>
<Parsing>
<SyntaxOptions>
@ -2211,6 +2211,11 @@ begin
UnitPath += &apos;platform/$(SrcOS)/qt6;platform/$(SrcOS)/wayland;&apos;;
end;
if ((LCLWidgetType = &apos;gtk2&apos;) or (LCLWidgetType = &apos;gtk3&apos;)) and (SrcOS = &apos;unix&apos;) then
begin
UnitPath += &apos;platform/$(SrcOS)/$(LCLWidgetType);&apos;;
end;
if (SrcOS = &apos;unix&apos;) and (TargetOS &lt;> &apos;darwin&apos;) and (TargetOS &lt;> &apos;haiku&apos;) then
begin
CustomOptions += &apos;-dXDG -dRabbitVCS&apos;;

View file

@ -56,6 +56,9 @@ uses
{$IFDEF LCLGTK2}
uGtk2FixCursorPos,
{$ENDIF}
{$IFDEF LCLGTK3}
uGtk3WSControls,
{$ENDIF}
{$IFDEF darwin}
uDarwinApplication,
uiCloudDriveConfig,

View file

@ -0,0 +1,95 @@
unit Interfaces;
{$mode objfpc}{$H+}
interface
uses
InterfaceBase, LCLType, Gtk3Int;
type
{ TGtk3WidgetSetEx }
TGtk3WidgetSetEx = class(TGtk3WidgetSet)
public
function GetDpiForMonitor(hMonitor: HMONITOR; dpiType: TMonitorDpiType; out dpiX: UINT; out dpiY: UINT): HRESULT; override;
end;
implementation
uses
Forms, LazGLib2, LazGdk3;
{ TGtk3WidgetSetEx }
function TGtk3WidgetSetEx.GetDpiForMonitor(hMonitor: HMONITOR;
dpiType: TMonitorDpiType; out dpiX: UINT; out dpiY: UINT): HRESULT;
var
ADisplay: PGdkDisplay;
AMonitor: PGdkMonitor;
AMonitorRect: TGdkRectangle;
AWmm, AHmm, AMonitorIdx, ANMon: gint;
AScreenDpi: gdouble;
AFallback: UINT;
begin
Result := S_OK;
AScreenDpi := gdk_screen_get_resolution(gdk_screen_get_default);
if AScreenDpi > 0 then
AFallback := Round(AScreenDpi)
else
AFallback := 96;
dpiX := AFallback;
dpiY := AFallback;
if hMonitor = 0 then
Exit;
AMonitorIdx := Integer(hMonitor) - 1;
ADisplay := gdk_display_get_default;
if ADisplay = nil then
Exit;
ANMon := gdk_display_get_n_monitors(ADisplay);
if (AMonitorIdx < 0) or (AMonitorIdx >= ANMon) then
begin
Result := S_FALSE;
Exit;
end;
AMonitor := gdk_display_get_monitor(ADisplay, AMonitorIdx);
if AMonitor = nil then
begin
Result := S_FALSE;
Exit;
end;
case dpiType of
MDT_RAW_DPI:
begin
gdk_monitor_get_geometry(AMonitor, @AMonitorRect);
AWmm := gdk_monitor_get_width_mm(AMonitor);
AHmm := gdk_monitor_get_height_mm(AMonitor);
if AWmm > 0 then
dpiX := Round(AMonitorRect.width * 25.4 / AWmm)
else
dpiX := 96;
if AHmm > 0 then
dpiY := Round(AMonitorRect.height * 25.4 / AHmm)
else
dpiY := 96;
end;
end;
end;
initialization
CreateWidgetset(TGtk3WidgetSetEx);
finalization
FreeWidgetSet;
end.

View file

@ -0,0 +1,51 @@
unit uGtk3WSControls;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, Controls, Gtk3WSControls;
type
{ TGtk3WSWinControlEx }
TGtk3WSWinControlEx = class(TGtk3WSWinControl)
published
class function GetCanvasScaleFactor(const AControl: TControl): Double; override;
end;
implementation
uses
WSLCLClasses, WSControls, Gtk3Widgets, Gtk3Procs, LazGdk3;
procedure Initialize;
begin
WSControls.RegisterControl;
WSControls.RegisterWinControl;
RegisterWSComponent(TWinControl, TGtk3WSWinControlEx);
end;
{ TGtk3WSWinControlEx }
class function TGtk3WSWinControlEx.GetCanvasScaleFactor(const AControl: TControl): Double;
var
W: TGtk3Widget;
begin
Result := 1;
if TWinControl(AControl).HandleAllocated then
begin
W := TGtk3Widget(TWinControl(AControl).Handle);
if Gtk3IsGdkWindow(W.GetWindow) then
Result := gdk_window_get_scale_factor(W.GetWindow);
end;
end;
initialization
Initialize;
end.