Windows Text Scaling seems unrelated to MediaQuery.of(context).TextScaler;

I would appreciate any thoughts on the following issue.
Windows has a display option for scaling text and Apps on the screen. I have not been able to pick up this scale value in Media Query. When the scaler is set to 100% and a graphic window and texture box are set to the same width and height, then the texture box is correctly sized and the image is centered in that box. When the Windows Display Setting scale is set > 100% then the texture box is correctly sized but the image is scaled to match the Windows Display Setting and the image is off-centered in the Texture box. That would not be an issue if I could detect the scaling factor. Media Query has a TextScaler, but it does not appear to report the Windows setting value. Without that value I cannot correct for a change in this desktop setting.
As a test if I build the App at 100% then change the desktop setting, the image remains centered in the texture and the texture is zoomed to the new size. If instead I set scale to 150% then build the App the image is 150% larger in the same sized window and is off center. This setting is in Windows 10 and 11.
I tried to force the MediaData TextScaler to 100%, but that had no effect (See below).
Here is some code

  @override
  Widget build(BuildContext context) {
    TextScaler scale = MediaQuery.of(context).textScaler;
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    double dpr = MediaQuery.of(context).devicePixelRatio;
    print ('scale = ${MediaQuery.of(context).textScaler}');
    return RepaintBoundary(
      child: GraphicArea(width, height, dpr),
    );
  }

or this change

    return MediaQuery(
      data: MediaQuery.of(context).copyWith(
        textScaler: const TextScaler.linear(1.0),
      ),
      child: RepaintBoundary(
        child: GraphicArea(width, height, dpr),
      ),
    );

The GraphicArea Widget paints to a texture as follows.

  @override
  Widget build(BuildContext context) {
    if (!initialized) {
      return const Center(child: CircularProgressIndicator());
    }
    final int? textureId = graphic3D.three3dRender.textureId;
    if (textureId == null || textureId == 0) {
      return Container();
    }
    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: Texture(textureId: textureId),
    );
  }
Thanks for any help on this!
1 Like

My first thought would be to use the win32 package (which allows you to call any windows API function) and then call GetScaleFactorForMonitor to get the scale factor from Windows directly. Or any other win32 api function that provides the info you need to work around the issue (GetDeviceCaps, etc)

1 Like

At least from a distance, this looks like a bug in MediaQuery (at least its implementation on Windows), no? If so, consider filing a bug and sharing its link here.

2 Likes

Thanks, I will check this out!

filip, thanks, I needed some reinforcement that this was indeed a bug and not just my imagination. I’ll see if I can file a bug. The odd part on this is that the app itself sizes correctly regardless of the setting. The issue is only that I apparently can’t pick up the setting. The fact that my images offset Is likely an issue with the 3D package I was using, three_dart, which hasn’t been updated for a couple of years. I filed an issue with the package, but have no responses.

Notice that for Win32 to work, you need to alter (or create) your .exe manifest, otherwise Windows will not inform the correct values (there are 7 UI libraries in Windows that deal with HDPI differently, 3 of them do not support the concept at all (GDI, GDI+ and MFC)).

I’m not sure, but I think Windows Flutter is a Win32 app (not a UWP one), so, in order to get the correct values, you should create a your_app.exe.manifest file with the correct settings so the calls are redirected to the correct ones.

1 Like

Hm Flutter reports system-wide text scaling (see textScaleFactor property - PlatformDispatcher class - dart:ui library - Dart API) but not display-specific text scaling (see Display class - dart:ui library - Dart API). This is likely something we’ll need to plumb through.

3 Likes

Good info. Thanks for the response