ROOT GUI scaling

Hello,

Is there any way or any workaround to make ROOT accept a custom GUI scaling? I know I can change font sizes (and be left with unchanged controls sizes), however when I am switching from monitor to monitor, one with scaling 2 and other without, changing font sizes manually each time is quite difficult.

You can change the font size in $(ROOTSYS)/etc/system.rootrc or in you custom $(HOME)/.rootrc:

Gui.DefaultFont:            -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1
Gui.MenuFont:               -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1
Gui.MenuHiFont:             -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
Gui.DocFixedFont:           -*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1
Gui.DocPropFont:            -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1
Gui.IconFont:               -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-1
Gui.StatusFont:             -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-1

I am afraid that does not answer the question. This requires manual change of fonts each time I switch monitor to a one with a different scaling.

Maybe it will help if you can post images of what you are getting and explain what you want to change from that. Anyway, it looks like you mean that, in one monitor, root (say, the TBrowser) looks ok but then in another it looks too big (or too small). In this case, and if this is on Windows 10, you might be able to do something using manifest files; read here, for example (a random page I found just now; you can google this yourself and make sure you don’t download harmful stuff :slight_smile: ):
https://appuals.com/disable-display-scaling-on-high-dpi-devices-in-windows-10/

Yes, this is the case that you described - ROOT GUI windows look OK on one monitor, bad on another monitor. One monitor has 1920x1080 resolution, the other 3840x2160 resolution, but with scaling to 200%, which makes all the windows look on it like it was 1920x1080 resolution, except ROOT, which does not do anything with scaling factor.

Unfortunately I am working on Linux, GNOME.

You could try something like this:

#include <iostream>
#include "TEnv.h"

void setFontSize()
{
   UInt_t ww = 0;
   TString res;
#ifdef WIN32
   res = gSystem->GetFromPipe("wmic desktopmonitor get screenwidth");
   res.ReplaceAll("ScreenWidth", "");
#else
   TString ret = gSystem->GetFromPipe("xrandr -q");
   std::string rs(ret.Data());
   unsigned first = rs.find(", current ") + 10;
   unsigned last = rs.find(" x ", first);
   std::string sw = rs.substr(first, last-first);
   res = sw.c_str();
#endif
   ww = res.Atoi();
   if (ww > 2048) {
      gEnv->SetValue("GUI.DefaultFont", "-*-helvetica-medium-r-*-*-16-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.MenuFont", "-*-helvetica-medium-r-*-*-16-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.MenuHiFont", "-*-helvetica-bold-r-*-*-16-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.DocFixedFont", "-*-courier-medium-r-*-*-16-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.DocPropFont", "-*-helvetica-medium-r-*-*-16-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.IconFont", "-*-helvetica-medium-r-*-*-13-*-*-*-*-*-iso8859-1");
      gEnv->SetValue("Gui.StatusFont", "-*-helvetica-medium-r-*-*-13-*-*-*-*-*-iso8859-1");
   }
}

Thanks, I’ve put this into .rootlogon.C and it works. The issues are:

  1. The font sized that you’ve specified are not available in my system. ROOT does not give any error because of this, so it took me a while to understand, why the script does not have any effect. Perhaps ROOT could give an error, or maybe some TTF could be used?
  2. This script detect the X resolution, which, in case of multiple monitors, if othen combined resolution of the monitors and not the real resolution. Thus it would result in rescaling in multimonitor setup of FHD monitors, which shouldn’t be the case. I’ve modified it to get the real resolution of the first monitor. .rootlogon.C (1.1 KB)

Now, the real problem. I can’t get it working in pyROOT. I’ve converted to a python function that properly sets gEnv (tested with gEnv.Print()), but TCanvas called from pyROOT still has old font sizes. Why is that?

This is a X11 issue, ROOT doesn’t know if the font is available or not…And TTF should be enabled by default. If it’s not the case, you can change the X11.UseXft value from no to yes in your .rootrc file

Maybe @etejedor has an idea…

But can TTF fonts be used for controls in ROOT? I am not sure how, because the type1 font already includes the size, etc., while for TTF it would have to be specified somehow differently

As I said, simply change the X11.UseXft value from no to yes in your .rootrc file, nothing else is needed. And this option is for the GUI only

But I don’t get how to specify MenuFont, StatusFont, etc., with TTF. I understand that the default like:
“--helvetica-medium-r---12------iso8859-1” specifies type1.

Oh, OK, I see. Sorry, but I’m afraid you’ll have to Google for it. Here is what I set on Windows: -adobe-segoe UI-medium-r-*-*-12-*-*-*-*-*-iso8859-1. I think the most relevant parts are the name, the type (r for regular) and the size

Great, it seems to work. The point is, that for TTF all sizes are there “out of the box”. I chose some gnu-free font because it is likely to be common on many linux distribution. I attach my .rootlogon.C .rootlogon.C (1.1 KB) if anyone wants to use.

I still hope that we can make it running also in pyROOT…

2 Likes

Hi @LeWhoo
So if you create a Python function that is a literal translation of what you have in your rootlogon.C file, the result is different?
Enric

Yes. I used the function below, after which I’ve checked the gEnv values with Print and they are as set by the function. Still, the menu font in canvas is as specified in system.rootrc

def setFontSize():
	ret = str(ROOT.gSystem.GetFromPipe("xrandr | grep \\* | awk \'{print $1}\'"))
	res = ret.split("x")[0]

	ww = int(res)
	if ww > 2048:
		ROOT.gEnv.SetValue("GUI.DefaultFont", "-*-helvetica-medium-r-*-*-20-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.MenuFont", "-*-helvetica-medium-r-*-*-20-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.MenuHiFont", "-*-helvetica-bold-r-*-*-20-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.DocFixedFont", "-*-courier-medium-r-*-*-20-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.DocPropFont", "-*-helvetica-medium-r-*-*-20-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.IconFont", "-*-helvetica-medium-r-*-*-17-*-*-*-*-*-iso8859-1")
		ROOT.gEnv.SetValue("Gui.StatusFont", "-*-helvetica-medium-r-*-*-17-*-*-*-*-*-iso8859-1")

In general, it seems that it is taking the value from system.rootrc instead of gEnv. If the gEnv is altered by rootlogon.C (so not by a python function), gEnv changes but the fonts sizes are still as specified in system.rootrc, when I am cheking from ipython.

The problem might be that the Python code you run is executed too late.

If you want to do it in Python, you need to define a ~/.rootlogon.py file. So the code you posted should go into that file. If you define rootlogon.py then rootlogon.C is ignored, but you can also load the .C from the .py, is you want to.

1 Like

Still the same effect. I’ve created .rootlogon.py (780 Bytes)
which Is run when I call, for exaple, ROOT.gEnv.Print(), as I can see from the printout from inside the .rootlogon.py. Still, if I later do c = ROOT.TCanvas(), the canvas has a small menu.

I checked and the rootlogon.py does run before any initialization of the graphics, so I don’t have an explanation why it should not work. I would suggest then to either have the rootlogon in C or have different rootrc.

I have rootlogon in C. But it also does not have any effect in pyROOT. It is like pyROOT is ignoring gEnv settings…

@etejedor Is it only my case, that pyROOT does not respect settings in gEnv, or is it a general bug?