TCanvas has wrong pixel dimension

Hi,

I stumbled about a strange behaviour when creating a new TCanvas, in my case in a Linux Mint Virtual Box in a Windows 11 host. When I e.g. create the TCanvas with

root -l -n
root [0] TCanvas c1("c1","c1",20,20,500,500)

it actually has pixel dimensions of 720x738 pixels (according to interactive inspect). When I resize it with

gPad->GetCanvas()->SetWindowSize(500,500);

it afterwards has the correct size of 500x500. I never observed something like this before. Does anybody have an idea what’s going on?

Best,
Klaus

ROOT Version: 6.28/04
Platform: Linux Mint 21.1 Vera (VBox guest on Win11 host)
Compiler: Not Provided


Hi Klaus,

It is desired behavior of TCanvas class. See class reference how pixel-correct size can be set.

Regards,
Sergey

Hi Sergey,

thanks for the hint. As far as I understand the possible pixel differences described in the reference are just due to the windows decoration. However, it is not the case that my margins are 100px wide, but the graphics area itself is scaled incorrectly.

When creating the windows as described above I get from ‘inspect’ the following numbers:

fWindowWidth     720    Width of window (including borders, etc.)
fWindowHeight    738    Height of window (including menubar, borders, etc.)
fCw              718    Width of the canvas along X (pixels)
fCh              696    Height of the canvas along Y (pixels)

After I called gPad->GetCanvas()->SetWindowSize(500,500); I see

fWindowWidth     500    Width of window (including borders, etc.)
fWindowHeight    500    Height of window (including menubar, borders, etc.)
fCw              498    Width of the canvas along X (pixels)
fCh              458    Height of the canvas along Y (pixels)

which are the expected dimensions right from the beginning.

Or did I miss the point?

Best,
Klaus

Hi Klaus,

In principle, you are right.
On my Linux desktop I have from the beginning 500x500 window sizes.
Probably it has something to do with your VBox.

May be Olivier @couet has some idea.

Regards,
Sergey

See also TCanvas size is inconsistent in batch vs non-batch mode · Issue #11004 · root-project/root · GitHub

Try:

{
   Double_t w = 500;
   Double_t h = 500;
   auto c = new TCanvas("c", "c", w, h);
   c->SetWindowSize(w + (w - c->GetWw()), h + (h - c->GetWh()));
}

and in batch mode simply do:

c->SetCanvasSize(w,h);

I meanwhile found the problem. In my .rootrc I have a line

Canvas.UseScreenFactor: true

When I set this switch to false, I get the canvas size as requested in the constructor.

Hi,

I tried your SetWindowSize and made also a funny observation.

When I create a canvas with

TCanvas c1("c1","c1",500,500)

it has dimensions of 500 x 518 and 498 x 476 (window and canvas size, respectively) according to inspect/dump. Using the resize command

c1.SetWindowSize(500 + (500 - c1.GetWw()), 500 + (500 - c1.GetWh())),

it has 502 x 524 and 500 x 482 (the latter not being 500 x 500!) afterwards. Now the funny thing: If I execute the resize over and over again, it wiggles between to the original 500 x 518 / 498 x 476 and the reset 502 x 524 and 500 x 482 forth and back.

Using the function c1.SetCanvasSize(500,500) led to scroll bars on both windows axis. Finally I got these to vanish with ‘c1.SetWindowSize(502,558)’. Using the ‘inspect’ tool gives me for this setting dimensions of 500 x 518 / 500 x 500.

I’m actually totally puzzled by this behaviour.

Best,
Klaus

Yeah… canvas size, together with zooming a TGraph, is one of those things where you say… how can ROOT make it so difficult to define such standard things, and so easy to process 10 TB of data in 5 seconds.

Hi Klaus,

I will investigate the problem with canvas/window size.
Hope that some solution can be found.

Regards,
Sergey

Thanks a lot!

For the time being I’m fine with switching off the Canvas.UseScreenFactor in .rootrc. But it nevertheless might be worth to take a look to the code to make it more predictable.

Maybe the new TWebCanvas will facilitate things: [webcanvas] implement `TWebCanvas::SetCanvasSize` by linev · Pull Request #13268 · root-project/root · GitHub

Hi,

With TWebCanvas it will be more tricky.

Not all operations can be performed synchronous with web canvas - therefore its real dimensions (window and canvas size) will be set only after next TCanvas::Update() call.

I want to fix implementation for normal canvas that real canvas sizes are returned by TCanvas::GetWw() and TCanvas::GetWh() methods.

Regards,
Sergey

Thanks! I guess that in that case, the function SetRealAspectRatio will need to be cross-checked too, as it relies on GetWw if I remember correctly.

Hi Klaus,

I create test macro to check canvas sizes at different stages.

realsize.C (1.1 KB)

Both master and v6-28-00-patches branches give me expected results:

root [0] 
Processing realsize.C...

Create canvas
Window size 700 x 700
Window pos 0 x 0
Canvas size 698 x 675
Canvas imp size 698 x 675

c1->SetWindowSize(700, 700)
Window size 700 x 700
Window pos 3490 x 358
Canvas size 698 x 675
Canvas imp size 698 x 675

c1->SetWindowSize(700 + (700 - c1->GetWw()), 700 + (700 - c1->GetWh()))
Window size 702 x 725
Window pos 3490 x 358
Canvas size 700 x 700
Canvas imp size 700 x 700

c1->Update()
Window size 702 x 725
Window pos 3490 x 358
Canvas size 700 x 700
Canvas imp size 700 x 700

Can you run macro and put here printout?

Regards,
Sergey

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.