No announcement yet.

NSIS on HiDPI displays

  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    New version.

    SetClassic: Classic flat look
    SetFlat: Same as classic for now
    SetThemed: Themed on XP+, same as SetFlat on <= 2000
    GetSysDpi: System DPI in $0
    Attached Files
    IntOp $PostCount $PostCount + 1


    • #17
      Awesome! The checkboxes now really look consistent with the rest of the GUI


      • #18
        New version, added Unicode and 64-bit builds.

        Support for custom bitmaps:

        Function OnCompShow
        ${If} $0 > 144
        File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\big.bmp" ; 192
        ${ElseIf} $0 > 120
        File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\red-round.bmp" ; 144
        ${ElseIf} $0 > 96
        File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\grey.bmp" ; 120
        File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\simple.bmp" ; 96
        SysCompImg::SetCustom "$PluginsDir\check.bmp"
        Attached Files
        IntOp $PostCount $PostCount + 1


        • #19
          Really cool Will this be merged into NSIS?


          • #20
            Yes, thanks for this, @Anders !

            I've experimented with this a bit, and another issue is the scrollbars (for, e.g., the License Agreement) are very small.


            • #21
              Windows is drawing the scrollbars, not us. There is EnableNonClientDpiScaling but I don't think we can use it. I will investigate PerMonitorAwareV2, we might be able to support that.
              IntOp $PostCount $PostCount + 1


              • #22
                I've tried using both a normal-size and an over-sized banner bmp (2x) using the modern_headerbmp.exe UI, but unlike mgrand I'm not seeing it scale properly at HiDPI (ie. at 200% I would have expected to work with the 2x sized banner). It appears to maintain the exact pixel counts regardless of scale or the image being used, instead of percentage coverage, as if the size was pixel-fixed (possibly in the modern_headerbmp.exe resource?). I used ResourceHacker to check the control sizes in the exe, but I couldn't determine which control affects the banner (a full-width banner, unlike 1046 which appears to be a 100x35 image).

                ManifestDPIAware and ManifestSupportedOS have been set (true and all, respectively), which fixes the text scaling, but not the image. I've tried all the different settings with MUI_HEADERIMAGE_BITMAP_STRETCH to no avail. I've also attempted to use SetBrandingImage (as per, along with using AddBrandingImage before calling SetBrandingImage to see if that changes the behaviour when using the oversized image, but I'm getting "no branding image found in chosen UI!" and I'm not sure that's the right way of solving this issue.

                Any ideas?


                • #23
                  Resources use dialog units, not pixels. The final pixel size is calculated by Windows at run-time and it is based on the font size (dialog unit) and DPI.

                  More information would be nice. Windows version? Is the primary monitor 200% DPI? Logged out and back in after changing DPI?
                  IntOp $PostCount $PostCount + 1


                  • #24
                    After some further investigation, it looks like we're manually setting image sizes via SetWindowPos(), which would explain the issues, so this has been resolved.

                    However, I noticed that the window size is slightly narrower in 120dpi mode (125%), while all other modes (100%, 150%, 200%) show the correct window width. This shows up because it will cut off part of the banner on the right side, as well as wrap text that doesn't wrap in any other dpi mode.

                    I'm also seeing something similar happening with jp/ko languages as well, regardless of DPI, but not to en-us or zh-cn. In the language case, the window is much wider than the normal window. I'm not sure it's necessarily related to the 125% mode issue, but it may be due to a similar mechanism.


                    • #25
                      Again, you are not telling me your Windows version.

                      The pixel size depends on the font because dialog units are based on the font. On Windows 10, some far east fonts are no longer installed by default and that might mess things up so make sure the font listed in the .nlf language file is actually installed. (Installing the keyboard layout and/or UI language should fix it IIRC)
                      IntOp $PostCount $PostCount + 1


                      • #26
                        For the 125% DPI problem, the Windows versions I have seen this on are Windows 7, 8.1, 10, and Server 2008 R2 non-exhaustive.

                        For the language issues, I've been testing with localized Windows 7 installations, but I believe I have seen them across a similar range at some point or another. So the takeaway here is to ensure that the font specified in the .nlf language files exist on the system first for localized installations...I will check on that, thanks.


                        • #27
                          The font issue only exists on Windows 10 (and 95/NT4 if you care about those).

                          I believe 120 dpi used to be known as Large Fonts in Windows and might have some weird compatibility hacks, not sure.
                          IntOp $PostCount $PostCount + 1


                          • #28
                            Sorry to revive an ancient thread, but I was struggling with getting the SysCompImg DLL to work, and hopefully this might help others. I'm using NSIS v3.06.1, MUI (and not MUI2, if it matters), and to get the DLL to work I had to call it using a custom function before the components page on dialog show via MUI_PAGE_CUSTOMFUNCTION_SHOW, eg:

                            !define MUI_PAGE_CUSTOMFUNCTION_SHOW ShowHiDpiComponents
                            !define MUI_PAGE_CUSTOMFUNCTION_PRE SetupComponents
                            !insertmacro MUI_PAGE_COMPONENTS

                            Function ShowHiDpiComponents

                            Function SetupComponents
                            # Do my other pre-page code here

                            I'd been trying to call the DLL from the MUI_PAGE_CUSTOMFUNCTION_PRE function, and that just doesn't work.

                            I'd feel slightly happier if the source for SysCompImg was available somewhere too, but for now I'm happy to finally have HiDPI checkboxes in my installer!


                            • #29

                              A problem exists in uninstallers.

                              SysCompImg.dll detects 144 dpi, if you set the DPI-aware declaration in ManifestDPIAware to 'true', correctly.

                              This is on a 4K monitor (with a 150% scale-factor for fonts and such).

                              It works for the installer but not for the uninstaller.

                              Maybe it's my mistake. I tried also "ManifestDPIAware true" in the uninstaller script, but the default (that can't be changed?) is false.

                              I can tell that Windows system does the scaling. And it should not.

                              The installer spawns the uninstaller. It looks hacky when the installer is 144 dpi 'not blurred' and the uninstaller is 96 dpi 'blurred'.

                              Note, I assume that 96 dpi is what happens when "ManifestDPIAware false" is set. Just I don't set it to that.


                              • #30
                                Originally Posted by rgreen View Post

                                It works for the installer but not for the uninstaller.

                                Maybe it's my mistake. I tried also "ManifestDPIAware true" in the uninstaller script, but the default (that can't be changed?) is false.
                                ManifestDPIAware is supposed to apply to both. What do you mean by "uninstaller script"?

                                Are you using !uninstfinalize to sign the uninstaller?

                                There might be some Windows caching going on if you previously had an older version without ManifestDPIAware?

                                You can download Resource Hacker (or Manifestview) and inspect the manifest of the uninstaller, it should have <dpiAware xmlns="...">true</dpiAware> in there somewhere.

                                It works correctly for me on Windows 10.
                                IntOp $PostCount $PostCount + 1