View Issue Details

IDProjectCategoryView StatusLast Update
0037227Lazarus CCRLCLpublic2020-06-30 11:05
ReporterEmil Totev Assigned Towp  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformWindowsOSWindows 10 x64 
Summary0037227: Properties DesignPPI and ParenFont changed without warning when opening project
DescriptionThe documentation at https://wiki.lazarus.freepascal.org/Autosize_/_Layout#DPI_auto-adjustment_and_absolute_layout_auto-adjustment says:
 TCustomForm.DesignTimeDPI should store the DPI value of the system where the form was designed.

However when I open a form, designed at 96ppi on a display with 120ppi, this is automatically and without warning changed to 120, causing other changes to the form and controls properties. One of the changed properties is ParentFont, which is set to False for the form and the child controls.

Furthermore, it is not possible to change the DesignTimePPI back to the correct value.

As a result of this, the same project looks and behaves differently when opened built at different display PPIs.

This is on Lazarus 2.0.8 x64.
Steps To ReproduceSet the scaling in Windows settings to 100%. Start lazarus, create a form with a group box on it and set on both ParentFont = True. The DesignPPI will be 96.
Save the form, close lazarus, set the scaling to 125%.
Start lazarus and open the form. ParentFont will be false for the form and the group box. DesignTimePPi will be 120, and not possible to change. Some other properties will be changed as well.
Additional InformationNote that only opening the project does not change the LFM file, so if the project is built, all will be OK. But if you make any change in the object inspector, e.g. to the caption, that will trigger saving the modified form and the next build will be wrong.

Working on the same project at different screen PPIs becomes virtually impossible.
TagsNo tags attached.
WidgetsetWin32/Win64
Attached Files

Activities

Emil Totev

2020-06-20 14:29

reporter   ~0123484

OK, I found the Environment option "Form Editor -> Force DPI scaling in design time" and unchecked it. Now things look better, ParentFont is not changed and not all positions and sizes are changed.
But still DesignTimePPI is changed, and so are some of the positions and sizes of components.

Basically, the IDE is changing our form behind our backs, and any version control system will record this. Furthermore, I'm not sure if these changes are reversible, i.e. if the form is saved at 96 ppi, then changed at 120 ppi, and then again changed at 96 ppi - will the numbers be the same (rounding errors etc.)

I think the DesignTimePPI should reflect the PPI at which the form was created, and not the PPI at the time it was opened. Changing it should be a conscious act of the developer, especially if it leads to other changes in control sizes and positions.

wp

2020-06-20 18:28

developer   ~0123486

Last edited: 2020-06-20 18:30

View 4 revisions

DesigntimePPI is an essential part of LCL scaling. Since you obviously do not want this feature you must turn it off: "Project options" > "Application": uncheck "Use LCL scaling (Hi-DPI)".

Could somebody move this report to project "Lazarus" (instead of "Lazarus CCR")

Emil Totev

2020-06-20 19:04

reporter   ~0123487

I'm not against scaling, I fought with it a couple of years ago and I managed to get satisfactory results.
What I'm against here is the obtrusiveness of the IDE. Imagine a team of developers working on the same project, and each using a PC with different font scaling. Every time one developer changes something on a form (even a caption), the controls' sizes and positions in the LFM will change for all the other developers.

At the moment, the DesignTimePPI holds no information about the PPI at the time the form was designed, instead it shows the PPI at the moment the form was opened in the IDE. So it is not really a property of the form, but a property of the IDE instance...

Sorry for posting this in the wrong category. At the time I started to write it I was thinking it was an LCL issue...

wp

2020-06-20 19:56

developer   ~0123488

Last edited: 2020-06-20 23:06

View 2 revisions

Ondrej, may I assign this report to you since you are the best person to answer?

wp

2020-06-21 13:19

developer   ~0123494

Last edited: 2020-06-21 13:20

View 2 revisions

I am not the inventor of LCL scaling, so my following notes can be wrong or incomplete. Maybe Ondrej can correct me:

I have the feeling that you are not using LCL scaling correctly. Normally it runs smoothly.

Please understand the DesignTimePPI as the units in which the numbers in the lfm file and displayed by the object inspector are given. When a project is created at 96ppi, the DesignTimePPI is 96, and all dimensions correspond to this resolution. When the file is save the DesignTimePPI is written to the lfm file as a "measurement unit". When this project is opened on a system at, say, 144ppi (150%) the LCL detects that the dimensions were saved in different units as used now and rescales the numbers accordingly, i.e. multiplies all dimensions by the factor 1.5.

Although it is in the ObjectInspector the DesignTimePPI is not a parameter to be changed by the user.

Here are the steps of an experiment trying the verify your observations, the resulting files are in the attachment:

STEP 1: Win 10, 96 ppi
- Project options: "Use LCL scaling", "DPI awareness" "on"
- Create a form 320x240 (default), Font default, Size 0
- Add a panel (170x50) (default), left 10, top 10, Font default, Size 0, ParentFont true
- Add a button to the panel (75x25, default), left 8, top 8, Font default, Size 0, ParentFont true
- Copy and paste the panel (including button) to position left 10, top 100, set Font to Arial Size 12, the Font of the button adjusts to the same parameters, its ParentFont is true
- Save

STEP 2: Open a VM with Win7 / 144ppi (150%) which has access to the saved files
- Copy project saved in previous step and rename to indicate that it will contain 144ppi dimensions
- Open the copied project
- Form size: 480 x 360, 1.5x the created size, Font default, size 0 ===> as expected
- Panel1: size 255 x 75, left = 15, top = 15. = 1.5 x created values. ===> as expected
  Font default, size 0, PARENTFONT = FALSE ===> Parentfont change NOT expected
- Button on Panel1: size 112 x 38, left 12, top 12 --> 1.5x original values. ===> as expected
  Font default, size 0, PARENTFONT = FALSE ===> ParentFont change NOT expected
- Panel2: size 255 x 75, left = 15, top = 150. ===> 1.5x created values ===> as expected
  Font 'Arial', Size 12, ParentFont = false ===> as expected
- Button on Panel2: size 112 x 38, left 12, top 12 ===> 1.5x original values ===> as expected
  Font 'Arial', Size 12, ParentFont = false ===> ParentFont change NOT expected
- Move form to a slightly different position and save (moveing required so that the form is written with DesignTimePPI 144, otherwise it will stay at 96ppi)
- Save

STEP 3: Return to Win10/96 ppi
- Copy project saved in previous step and rename to indicate that it will contain 96ppi dimensions
- Open copied project
- Form size 320x240 ==> as expected
  Font default, size 0 ===> as expected
- Panel1: size 170x 50, left 10, top 10 ===> as expected
  Font default, size 0, ParentFont = false ====> PARENT FONT expected from step 2, but not expected from step 1
- Button on Panel1: size 75x25, left 8, top 8 ===> as expected
  Font default, size 0, ParentFont = false ====> PARENT FONT expected from step 2, but not expected from step 1
- Panel2: size 170x50, left 10, top 100 ===> as expected
  Font 'Arial', size 12, ParentFont = false ===> as expected
- Button on Panel2: size 75x25, left 8, top 9 ===> as expected
  Font 'Arial', size 12, ParentFont = false ===> as expected
  
As you can see the sizes and positions of the controls scale correctly. There is a problem, though, with ParentFont which changes in cases where it shouldn't.

wp

2020-06-21 13:19

developer   ~0123495

lcl_scaling TEST.zip (6,858 bytes)

Emil Totev

2020-06-21 17:57

reporter   ~0123499

Yes, I understand how changing the DesignTimePPI is supposed to work and I am more or less fine with it (except for the ParentFont side effect, which is obviously wrong and probably deserves a separate BUG, regardless of the outcome of this discussion)

What I don't agree with is that DesignTimePPI is changed automatically and unconditionally, which causes unwanted changes to the form file. The fact that I am opening the project in my IDE does not necessarily mean that I want to change the design of the form, and even if I change the design, it might not be related to positioning and sizing - the simple example with changing captions or colors. Yet the form file will be changed, and the source control system will pick up the change and distribute it among other developers, and I don't want that. If I want to change the size and positioning, I might do it even without changing the DesignTimePPI, keeping in mind that all sizes are valid at the original DesignTimePPi. Or I may want to change the DesignTimePPI to the correct one for my display and then the form will be re-scaled and I will be sure that this is how it will look at this scaling.

And the other thing is that even without the "Force DPI scaling at design time" SOME sizes and positions do change in the LFM. I can only guess that this is related to the size of the title bar and other OS-dependent parts of the window, but again this doesn't feel right. In my view, nothing should be changed automatically, and only a huge warning may be displayed that "the DesignTimePPI of this form is different from the PPI of your current display", until you decide to change the DesignTimePPI yourself.

wp

2020-06-21 19:57

developer   ~0123503

When you only open the lfm no changes will be written back, you must at least modify something. But yes, changing a text or a color will write the new dimensions to the file. But what is the problem of distributing the changed file with the new dimensions to other team members? Suppose another team member has a screen with a different resolution: when he opens the form, the LCL detects that he has a different PPI and thus recalculates the dimensions. When he changes something and stores the file again, the lfm will have the new dimensions but also his DesignTimePPI. Now when you open the file, your system will detect the change in PPI and adjust the dimensions again.

It is like traveling between countries in different time zones. When you enter a country in a different time zone you will have to adjust your clock so that the time displayed is consistent with this country. When you return to your country you will have to readjust the clock again, and the time displayed is correct for your country

To me the system is perfectly logical (exept for the ParentFont, agreed). I still think that there is something wrong in the way you work with LCL scaling. For example, you should not turn off "Force DPI scaling at design time". As far as I understand this should be unchecked only when LCL scaling in the project is off.

> nothing should be changed automatically
In this case you must turn off LCL scaling and take care of scaling yourself (and I promise: you will have a hard life...)

Emil Totev

2020-06-21 21:45

reporter   ~0123505

Actually, I have turned off the "Use LCL scaling (HighDPI)" on the project and I am handling the scaling myself, based on the selected font size (in points!). That is not the point.

Your time zone analogy is nice, but a) you don't get get a stamp in the passport whenever you change time zones, but each change to the LFM file is recorded in the source control system and pollutes it with meaningless changes; and b) sizes are integer, with scaling comes rounding, and it is possible that at some point numbers will change.

The problem for me currently is that even when "Force DPI scaling" is OFF, the DesignTimePPI changes and some scaling (I think font-dependent) is performed. I would expect the form to be displayed at design time with the exact pixel sizes from design time, including pixel (and not point) size of fonts. Anyway it is the FontHeight in pixels that is written in the LFM.

wp

2020-06-21 22:29

developer   ~0123506

Last edited: 2020-06-21 22:35

View 2 revisions

Just to make sure I repeated my experiment of note 0123494 with LCL scaling turned off. The attached screenshot shows, from left to right:
- the original project at 96ppi,
- the project loaded by a 144ppi Windows,
- the project saved at 144ppi and loaded by the 96ppi system.
The imagse are taken at runtime. The forms look the same at designtime when "Force DPI scaling in designtime" is off (otherwise the center image would be enlarged by 50%).

As you can see:
- The control sizes and positions are not scaled, as expected.
- The user-defined fonts (font size <> 0) in the lower panel and button is not scaled, as expected.
- The automatic font size (fontSize = 0) in the upper panel and button is scaled in the center image. Maybe you disagree, but to me this is expected, too, because this scaling has always been like that even before LCL scaling was introduced.

So, in order to do your own scaling method you must
- prepare the IDE by setting "Force DPI scaling in designtime" to true
- prepare the project by turning LCL scaling off
- not use automatic font size detection, use Form.Font.Size > 0 instead
no_lcl_scaling.png (15,583 bytes)   
no_lcl_scaling.png (15,583 bytes)   

Emil Totev

2020-06-22 09:31

reporter   ~0123511

Yes! It is the last thing you said that did it - not to use default font size! I think I achieved my main objective, which was to avoid changing the LFM when saving it at different display PPI. Here are the main points:
* Project option "Use LCL scaling (HighDPI)" is OFF
* Environment option "Force DPI scaling" is OFF
* A small patch to the IDE that changes form's DesignTimePPI ONLY IF scaling is actually performed (and with the above options it is NOT). And I think this is the logically correct behavior.
* All fonts are specified explicitly, no FontSize=0.

In this way at design time the form is displayed at exactly the PPI it was designed and not at the PPI it will have at runtime. All changes to the design should be made with this in mind, but after all I think this is the reason DesignTimePPI exists in the first place. I might experiment with allowing the property to be changed at design time, which is supposed to perform the scaling then - if really wanted.
There may be still some unwanted changes to the form, but I'll try to deal with them when they bite.

Thanks a lot for your help!!!

wp

2020-06-22 11:21

developer   ~0123512

> A small patch to the IDE that changes form's DesignTimePPI ONLY IF scaling is actually performed (and with the above options it is NOT). And I think this is the logically correct behavior.

Can you provide this patch? Is it harmful when LCL scaling is active?

Emil Totev

2020-06-22 13:32

reporter   ~0123515

It is basically moving one line up into the IF block, around line 6055 of ide\sourcefilemanager.pas, like this:

          DsgControl := TCustomDesignControl(NewComponent);
          if (Project1.Scaled or EnvironmentOptions.ForceDPIScalingInDesignTime)
          and DsgControl.Scaled and (DsgControl.DesignTimePPI<>Screen.PixelsPerInch) then
          begin
            DsgControl.AutoAdjustLayout(lapAutoAdjustForDPI, DsgControl.DesignTimePPI, Screen.PixelsPerInch, 0, 0);
            DesignerProcs.ScaleNonVisual(DsgControl, DsgControl.DesignTimePPI, Screen.PixelsPerInch);
+ DsgControl.DesignTimePPI := Screen.PixelsPerInch;
          end;
- DsgControl.DesignTimePPI := Screen.PixelsPerInch;
          DsgControl.PixelsPerInch := Screen.PixelsPerInch;
        end;

I am not 100% sure it's OK and I haven't tested it with scaling on either on project or environment level, but seems to work for me now.

Rafael Castro

2020-06-25 03:46

reporter   ~0123588

Last edited: 2020-06-25 03:49

View 3 revisions

Example:
Do not modify the code, please.
If you compile this code in windows without scaling the screen (100% scale) the software works perfectly.
If you compile this code in windows scaling the screen (125%) it does not work.

ParentFont ??

Sorry about my English. Thank you.
font.zip (129,334 bytes)

Emil Totev

2020-06-30 08:04

reporter   ~0123673

The patch above is to the IDE and has no effect on code compilation.
The idea of the patch is that if the "Force DPI scaling in design time" is unchecked, the DesignTimePPI should not be changed - as no DPI scaling at design time happens.

I think the best would be if this bug with its overlong discussion is closed, and then I will probably create two new ones:

1. Change of ParentFont when "Force DPI scaling in design time" is checked - which we all agreed is strange, and even though it might be explainable as a side effect of the scaling, is worth noting;

2. Change of DesignTimePPI when "Force DPI scaling in design time" is NOT checked and NO scaling is done.

wp

2020-06-30 11:05

developer   ~0123675

Sorry to keep you waiting, but I thought that Ondrej would pick this up because LCL scaling is his work, but he seems to be busy with other things.

Anyway, I committed the patch for the DesignTimePPI changing when "Force DPI Scaling in Designtime" is off (r63482), thanks for the patch. Test again and close if ok. Please put the related issue with ParentFont being changed by LCL scaling into a separate report.

@Rafael Castro: Your demo shows that ParentFont is broken by LCL scaling. This is not affected by the current commit.

Issue History

Date Modified Username Field Change
2020-06-20 09:46 Emil Totev New Issue
2020-06-20 14:29 Emil Totev Note Added: 0123484
2020-06-20 18:28 wp Note Added: 0123486
2020-06-20 18:30 wp Note Edited: 0123486 View Revisions
2020-06-20 18:30 wp Note Edited: 0123486 View Revisions
2020-06-20 18:30 wp Note Edited: 0123486 View Revisions
2020-06-20 19:04 Emil Totev Note Added: 0123487
2020-06-20 19:55 wp Assigned To => Ondrej Pokorny
2020-06-20 19:55 wp Status new => assigned
2020-06-20 19:56 wp Note Added: 0123488
2020-06-20 23:06 wp Note Edited: 0123488 View Revisions
2020-06-21 13:19 wp Note Added: 0123494
2020-06-21 13:19 wp Note Added: 0123495
2020-06-21 13:19 wp File Added: lcl_scaling TEST.zip
2020-06-21 13:20 wp Note Edited: 0123494 View Revisions
2020-06-21 17:57 Emil Totev Note Added: 0123499
2020-06-21 19:57 wp Note Added: 0123503
2020-06-21 21:45 Emil Totev Note Added: 0123505
2020-06-21 22:29 wp Note Added: 0123506
2020-06-21 22:29 wp File Added: no_lcl_scaling.png
2020-06-21 22:35 wp Note Edited: 0123506 View Revisions
2020-06-22 09:31 Emil Totev Note Added: 0123511
2020-06-22 11:21 wp Note Added: 0123512
2020-06-22 11:21 wp Status assigned => feedback
2020-06-22 13:32 Emil Totev Note Added: 0123515
2020-06-22 13:32 Emil Totev Status feedback => assigned
2020-06-25 03:46 Rafael Castro Note Added: 0123588
2020-06-25 03:46 Rafael Castro File Added: font.zip
2020-06-25 03:48 Rafael Castro Note Edited: 0123588 View Revisions
2020-06-25 03:49 Rafael Castro Note Edited: 0123588 View Revisions
2020-06-30 08:04 Emil Totev Note Added: 0123673
2020-06-30 11:05 wp Assigned To Ondrej Pokorny => wp
2020-06-30 11:05 wp Status assigned => resolved
2020-06-30 11:05 wp Resolution open => fixed
2020-06-30 11:05 wp Widgetset Win32/Win64 => Win32/Win64
2020-06-30 11:05 wp Note Added: 0123675