diff --git a/CHANGELOG.md b/CHANGELOG.md index ee45422..577d2dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,32 @@ All notable changes to ConfigurO are recorded here. The updater reads the heading for the running version to decide what to show, so keep the `## [x.y]` format. +## [3.3] + +### Fixes +- **The whole interface has been rendering at 1.0 scale since 1.0.** The + Per-Monitor-V2 switches Windows Forms needs live in `App.config`, and the + release ships a single executable with no `ConfigurO.exe.config` beside it. + Run that way -- which is how everyone runs it -- `Control.DeviceDpi` answers + 96 on every machine, so the layout was computed at 100% and drawn two-thirds + size on a 150% display. Not blurry: the manifest still makes the process + Per-Monitor-V2 aware, so the window was measured at exactly the size it asked + for. Just small and dense, which reads as an older build rather than as a + fault. Scale now comes from `GetDpiForWindow`, falling back to + `GetDpiForMonitor` on 8.1 and `GetDeviceCaps` before that. Win32 always knew; + nothing was asking it. Verified against the bare executable with no config + file present: 96/1.00 before, 144/1.50 after. +- **80 of the 139 app icons were drawn as logos in a black box.** They had been + flattened onto an opaque black background with no alpha channel, which is + invisible against a black page and a hard black square against the app's + `#232532` cards. Alpha is restored by flooding inward from the border, so + only black actually connected to the outside is removed and a dark detail + inside a mark survives -- Opera keeps its counter, 7-Zip keeps its grey + field, Vivaldi keeps its red tile. The one-pixel fringe where each logo was + antialiased against the black is un-premultiplied so the edges stay smooth + instead of leaving a halo. No black-matted icon remains; the five still + without an alpha channel are square by design. + ## [3.2] ### Fixes diff --git a/feed/icons.zip b/feed/icons.zip index e2c57b6..ae12dc2 100644 Binary files a/feed/icons.zip and b/feed/icons.zip differ diff --git a/feed/icons/7zip.png b/feed/icons/7zip.png index 2843b65..ac8d043 100644 Binary files a/feed/icons/7zip.png and b/feed/icons/7zip.png differ diff --git a/feed/icons/adobereader.png b/feed/icons/adobereader.png index 5194572..878f12d 100644 Binary files a/feed/icons/adobereader.png and b/feed/icons/adobereader.png differ diff --git a/feed/icons/androidstudio.png b/feed/icons/androidstudio.png index 63621ca..86d2ed4 100644 Binary files a/feed/icons/androidstudio.png and b/feed/icons/androidstudio.png differ diff --git a/feed/icons/antiexploit.png b/feed/icons/antiexploit.png index 50e18ef..439ad1e 100644 Binary files a/feed/icons/antiexploit.png and b/feed/icons/antiexploit.png differ diff --git a/feed/icons/anydesk.png b/feed/icons/anydesk.png index b9ee773..76d9108 100644 Binary files a/feed/icons/anydesk.png and b/feed/icons/anydesk.png differ diff --git a/feed/icons/atom.png b/feed/icons/atom.png index 52f93ef..1090cf4 100644 Binary files a/feed/icons/atom.png and b/feed/icons/atom.png differ diff --git a/feed/icons/audacity.png b/feed/icons/audacity.png index 17b5c3f..177cc02 100644 Binary files a/feed/icons/audacity.png and b/feed/icons/audacity.png differ diff --git a/feed/icons/balena.png b/feed/icons/balena.png index b37195c..9134d28 100644 Binary files a/feed/icons/balena.png and b/feed/icons/balena.png differ diff --git a/feed/icons/bittorrent.png b/feed/icons/bittorrent.png index 7a6e73d..6726f0f 100644 Binary files a/feed/icons/bittorrent.png and b/feed/icons/bittorrent.png differ diff --git a/feed/icons/blender.png b/feed/icons/blender.png index cb4a50f..cd49672 100644 Binary files a/feed/icons/blender.png and b/feed/icons/blender.png differ diff --git a/feed/icons/bsplayer.png b/feed/icons/bsplayer.png index 69de023..adc1792 100644 Binary files a/feed/icons/bsplayer.png and b/feed/icons/bsplayer.png differ diff --git a/feed/icons/chrome.png b/feed/icons/chrome.png index 1e9a598..047bdf6 100644 Binary files a/feed/icons/chrome.png and b/feed/icons/chrome.png differ diff --git a/feed/icons/chromium.png b/feed/icons/chromium.png index 8d6799e..7c01a06 100644 Binary files a/feed/icons/chromium.png and b/feed/icons/chromium.png differ diff --git a/feed/icons/deluge.png b/feed/icons/deluge.png index c65ca6f..68a5bc1 100644 Binary files a/feed/icons/deluge.png and b/feed/icons/deluge.png differ diff --git a/feed/icons/discord.png b/feed/icons/discord.png index a2704f0..f12f924 100644 Binary files a/feed/icons/discord.png and b/feed/icons/discord.png differ diff --git a/feed/icons/dropbox.png b/feed/icons/dropbox.png index 9d99bfe..344d169 100644 Binary files a/feed/icons/dropbox.png and b/feed/icons/dropbox.png differ diff --git a/feed/icons/eclipse.png b/feed/icons/eclipse.png index 400b3ae..ba9e513 100644 Binary files a/feed/icons/eclipse.png and b/feed/icons/eclipse.png differ diff --git a/feed/icons/epic.png b/feed/icons/epic.png index dbc62e0..e1e9863 100644 Binary files a/feed/icons/epic.png and b/feed/icons/epic.png differ diff --git a/feed/icons/evernote.png b/feed/icons/evernote.png index 66c93b1..13418ca 100644 Binary files a/feed/icons/evernote.png and b/feed/icons/evernote.png differ diff --git a/feed/icons/filezilla.png b/feed/icons/filezilla.png index fe2f92d..83a70a5 100644 Binary files a/feed/icons/filezilla.png and b/feed/icons/filezilla.png differ diff --git a/feed/icons/firefox.png b/feed/icons/firefox.png index 43c35ad..981a9ce 100644 Binary files a/feed/icons/firefox.png and b/feed/icons/firefox.png differ diff --git a/feed/icons/flux.png b/feed/icons/flux.png index b3c3d55..3b77afa 100644 Binary files a/feed/icons/flux.png and b/feed/icons/flux.png differ diff --git a/feed/icons/foobar.png b/feed/icons/foobar.png index 1a2550b..1060c3a 100644 Binary files a/feed/icons/foobar.png and b/feed/icons/foobar.png differ diff --git a/feed/icons/foxit.png b/feed/icons/foxit.png index 48901a6..5671102 100644 Binary files a/feed/icons/foxit.png and b/feed/icons/foxit.png differ diff --git a/feed/icons/gimp.png b/feed/icons/gimp.png index 4e09c94..18d1f8b 100644 Binary files a/feed/icons/gimp.png and b/feed/icons/gimp.png differ diff --git a/feed/icons/github.png b/feed/icons/github.png index 9082c8c..cba145b 100644 Binary files a/feed/icons/github.png and b/feed/icons/github.png differ diff --git a/feed/icons/gyazo.png b/feed/icons/gyazo.png index 42f4944..d309696 100644 Binary files a/feed/icons/gyazo.png and b/feed/icons/gyazo.png differ diff --git a/feed/icons/iobitdefrag.png b/feed/icons/iobitdefrag.png index b190056..3c5049d 100644 Binary files a/feed/icons/iobitdefrag.png and b/feed/icons/iobitdefrag.png differ diff --git a/feed/icons/iobitdrivers.png b/feed/icons/iobitdrivers.png index 4edf47d..be0f785 100644 Binary files a/feed/icons/iobitdrivers.png and b/feed/icons/iobitdrivers.png differ diff --git a/feed/icons/iobituninstall.png b/feed/icons/iobituninstall.png index 68ae310..052010d 100644 Binary files a/feed/icons/iobituninstall.png and b/feed/icons/iobituninstall.png differ diff --git a/feed/icons/iobitupdater.png b/feed/icons/iobitupdater.png index 348e77a..0043e25 100644 Binary files a/feed/icons/iobitupdater.png and b/feed/icons/iobitupdater.png differ diff --git a/feed/icons/irfanview.png b/feed/icons/irfanview.png index 0a29c6b..c0b4d69 100644 Binary files a/feed/icons/irfanview.png and b/feed/icons/irfanview.png differ diff --git a/feed/icons/itunes.png b/feed/icons/itunes.png index 148a944..d92a7f0 100644 Binary files a/feed/icons/itunes.png and b/feed/icons/itunes.png differ diff --git a/feed/icons/java.png b/feed/icons/java.png index 0ec7c2d..ceb6b5e 100644 Binary files a/feed/icons/java.png and b/feed/icons/java.png differ diff --git a/feed/icons/klite.png b/feed/icons/klite.png index 3ecd3d0..2a0c070 100644 Binary files a/feed/icons/klite.png and b/feed/icons/klite.png differ diff --git a/feed/icons/libreoffice.png b/feed/icons/libreoffice.png index 07b1283..341a660 100644 Binary files a/feed/icons/libreoffice.png and b/feed/icons/libreoffice.png differ diff --git a/feed/icons/lightshot.png b/feed/icons/lightshot.png index 3e344c1..dfa9a58 100644 Binary files a/feed/icons/lightshot.png and b/feed/icons/lightshot.png differ diff --git a/feed/icons/malwarebytes.png b/feed/icons/malwarebytes.png index ca04da3..ab186f1 100644 Binary files a/feed/icons/malwarebytes.png and b/feed/icons/malwarebytes.png differ diff --git a/feed/icons/maxthon.png b/feed/icons/maxthon.png index 9e65580..7a6131d 100644 Binary files a/feed/icons/maxthon.png and b/feed/icons/maxthon.png differ diff --git a/feed/icons/mega.png b/feed/icons/mega.png index d00027e..95ba6d2 100644 Binary files a/feed/icons/mega.png and b/feed/icons/mega.png differ diff --git a/feed/icons/mp3tag.png b/feed/icons/mp3tag.png index 0c6f182..e27f836 100644 Binary files a/feed/icons/mp3tag.png and b/feed/icons/mp3tag.png differ diff --git a/feed/icons/nodejs.png b/feed/icons/nodejs.png index 0b2a88f..41cf0e3 100644 Binary files a/feed/icons/nodejs.png and b/feed/icons/nodejs.png differ diff --git a/feed/icons/notepadpp.png b/feed/icons/notepadpp.png index 5a69094..80acb55 100644 Binary files a/feed/icons/notepadpp.png and b/feed/icons/notepadpp.png differ diff --git a/feed/icons/onedrive.png b/feed/icons/onedrive.png index c940ff2..7ab5fe6 100644 Binary files a/feed/icons/onedrive.png and b/feed/icons/onedrive.png differ diff --git a/feed/icons/opera.png b/feed/icons/opera.png index f4b616a..11bb2b5 100644 Binary files a/feed/icons/opera.png and b/feed/icons/opera.png differ diff --git a/feed/icons/origin.png b/feed/icons/origin.png index 74f3cb7..e326e2c 100644 Binary files a/feed/icons/origin.png and b/feed/icons/origin.png differ diff --git a/feed/icons/peazip.png b/feed/icons/peazip.png index 28f6292..105bf3c 100644 Binary files a/feed/icons/peazip.png and b/feed/icons/peazip.png differ diff --git a/feed/icons/photofiltre.png b/feed/icons/photofiltre.png index 41fd405..e9fb493 100644 Binary files a/feed/icons/photofiltre.png and b/feed/icons/photofiltre.png differ diff --git a/feed/icons/postman.png b/feed/icons/postman.png index 8bc2196..8f5d0a4 100644 Binary files a/feed/icons/postman.png and b/feed/icons/postman.png differ diff --git a/feed/icons/potplayer.png b/feed/icons/potplayer.png index f6c5d43..f1e11ed 100644 Binary files a/feed/icons/potplayer.png and b/feed/icons/potplayer.png differ diff --git a/feed/icons/putty.png b/feed/icons/putty.png index 85d24f3..5455a55 100644 Binary files a/feed/icons/putty.png and b/feed/icons/putty.png differ diff --git a/feed/icons/python.png b/feed/icons/python.png index 516d3ab..6819009 100644 Binary files a/feed/icons/python.png and b/feed/icons/python.png differ diff --git a/feed/icons/qbittorrent.png b/feed/icons/qbittorrent.png index deced52..ca47f44 100644 Binary files a/feed/icons/qbittorrent.png and b/feed/icons/qbittorrent.png differ diff --git a/feed/icons/revo.png b/feed/icons/revo.png index c0fe123..c899bb3 100644 Binary files a/feed/icons/revo.png and b/feed/icons/revo.png differ diff --git a/feed/icons/rufus.png b/feed/icons/rufus.png index 16eac8f..c307e51 100644 Binary files a/feed/icons/rufus.png and b/feed/icons/rufus.png differ diff --git a/feed/icons/skype.png b/feed/icons/skype.png index 5ebabf9..676a31d 100644 Binary files a/feed/icons/skype.png and b/feed/icons/skype.png differ diff --git a/feed/icons/spotify.png b/feed/icons/spotify.png index 9633d6c..7f0d2e7 100644 Binary files a/feed/icons/spotify.png and b/feed/icons/spotify.png differ diff --git a/feed/icons/steam.png b/feed/icons/steam.png index 24b47e3..0b0eb70 100644 Binary files a/feed/icons/steam.png and b/feed/icons/steam.png differ diff --git a/feed/icons/sublimemerge.png b/feed/icons/sublimemerge.png index 3d35eff..9b6243c 100644 Binary files a/feed/icons/sublimemerge.png and b/feed/icons/sublimemerge.png differ diff --git a/feed/icons/sublimetext.png b/feed/icons/sublimetext.png index 83484e1..2ebdb1a 100644 Binary files a/feed/icons/sublimetext.png and b/feed/icons/sublimetext.png differ diff --git a/feed/icons/sumatrapdf.png b/feed/icons/sumatrapdf.png index dffaf76..2fcdcba 100644 Binary files a/feed/icons/sumatrapdf.png and b/feed/icons/sumatrapdf.png differ diff --git a/feed/icons/teams.png b/feed/icons/teams.png index 8f3d160..af603ca 100644 Binary files a/feed/icons/teams.png and b/feed/icons/teams.png differ diff --git a/feed/icons/teamviewer.png b/feed/icons/teamviewer.png index 2534e26..ea8b606 100644 Binary files a/feed/icons/teamviewer.png and b/feed/icons/teamviewer.png differ diff --git a/feed/icons/thunderbird.png b/feed/icons/thunderbird.png index 7182ad1..90bbcc8 100644 Binary files a/feed/icons/thunderbird.png and b/feed/icons/thunderbird.png differ diff --git a/feed/icons/tor.png b/feed/icons/tor.png index bd4a402..51f0908 100644 Binary files a/feed/icons/tor.png and b/feed/icons/tor.png differ diff --git a/feed/icons/uplay.png b/feed/icons/uplay.png index d5884e0..cbcbe28 100644 Binary files a/feed/icons/uplay.png and b/feed/icons/uplay.png differ diff --git a/feed/icons/utorrent.png b/feed/icons/utorrent.png index 1ce8af9..e232a3b 100644 Binary files a/feed/icons/utorrent.png and b/feed/icons/utorrent.png differ diff --git a/feed/icons/uui.png b/feed/icons/uui.png index 504de0c..ace9d05 100644 Binary files a/feed/icons/uui.png and b/feed/icons/uui.png differ diff --git a/feed/icons/viber.png b/feed/icons/viber.png index 2317b79..ea9f770 100644 Binary files a/feed/icons/viber.png and b/feed/icons/viber.png differ diff --git a/feed/icons/viper.png b/feed/icons/viper.png index e50d597..290542c 100644 Binary files a/feed/icons/viper.png and b/feed/icons/viper.png differ diff --git a/feed/icons/visualstudio.png b/feed/icons/visualstudio.png index db8bab3..999ab35 100644 Binary files a/feed/icons/visualstudio.png and b/feed/icons/visualstudio.png differ diff --git a/feed/icons/vivaldi.png b/feed/icons/vivaldi.png index e5c245b..38cab0d 100644 Binary files a/feed/icons/vivaldi.png and b/feed/icons/vivaldi.png differ diff --git a/feed/icons/vlc.png b/feed/icons/vlc.png index 1ddf0af..8ee990e 100644 Binary files a/feed/icons/vlc.png and b/feed/icons/vlc.png differ diff --git a/feed/icons/vscode.png b/feed/icons/vscode.png index 5038ba2..8aaac8e 100644 Binary files a/feed/icons/vscode.png and b/feed/icons/vscode.png differ diff --git a/feed/icons/vscodium.png b/feed/icons/vscodium.png index fc85e46..65d3c7e 100644 Binary files a/feed/icons/vscodium.png and b/feed/icons/vscodium.png differ diff --git a/feed/icons/winamp.png b/feed/icons/winamp.png index 4604f9a..b87cc06 100644 Binary files a/feed/icons/winamp.png and b/feed/icons/winamp.png differ diff --git a/feed/icons/winrar.png b/feed/icons/winrar.png index 89dbd9d..9f9564b 100644 Binary files a/feed/icons/winrar.png and b/feed/icons/winrar.png differ diff --git a/feed/icons/winscp.png b/feed/icons/winscp.png index 4ad7492..215c140 100644 Binary files a/feed/icons/winscp.png and b/feed/icons/winscp.png differ diff --git a/feed/icons/xampp.png b/feed/icons/xampp.png index 3d16946..52788ee 100644 Binary files a/feed/icons/xampp.png and b/feed/icons/xampp.png differ diff --git a/feed/icons/zoom.png b/feed/icons/zoom.png index a148da2..fbeabab 100644 Binary files a/feed/icons/zoom.png and b/feed/icons/zoom.png differ diff --git a/src/ConfigurO/Forms/MainForm.cs b/src/ConfigurO/Forms/MainForm.cs index 151c90b..55893a9 100644 --- a/src/ConfigurO/Forms/MainForm.cs +++ b/src/ConfigurO/Forms/MainForm.cs @@ -242,7 +242,7 @@ void OnLoaded(object sender, EventArgs e) TitleBar == null ? "absent" : "present", TitleBar == null ? "-" : TitleBar.Bounds.ToString(), TitleBar == null ? 0 : TitleBar.Height, - DeviceDpi, + NocturneScale.DpiOf(Handle), NocturneScale.Factor.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture), NocturneFonts.Bundled)); diff --git a/src/ConfigurO/Nocturne/NocturneScale.cs b/src/ConfigurO/Nocturne/NocturneScale.cs index 9e9b626..e01f96c 100644 --- a/src/ConfigurO/Nocturne/NocturneScale.cs +++ b/src/ConfigurO/Nocturne/NocturneScale.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Runtime.InteropServices; using System.Windows.Forms; namespace ConfigurO @@ -39,6 +40,79 @@ internal static void SetDpi(int dpi) Factor = dpi / Base; } + // ── Asking the system, not the framework ──────────────────────── + const int LOGPIXELSX = 88; + const int MDT_EFFECTIVE_DPI = 0; + const int MONITOR_DEFAULTTONEAREST = 2; + + [DllImport("user32.dll")] static extern uint GetDpiForWindow(IntPtr hwnd); + [DllImport("user32.dll")] static extern IntPtr MonitorFromWindow(IntPtr hwnd, int flags); + [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hwnd); + [DllImport("user32.dll")] static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); + [DllImport("gdi32.dll")] static extern int GetDeviceCaps(IntPtr hdc, int index); + [DllImport("shcore.dll")] static extern int GetDpiForMonitor(IntPtr monitor, int type, out uint x, out uint y); + + /// + /// The DPI of the display is on, straight from + /// Win32. + /// + /// Deliberately not Control.DeviceDpi. WinForms on .NET Framework only + /// reports a real DPI when the DpiAwareness switches in App.config are + /// present, and those live in ConfigurO.exe.config -- a file the + /// release does not ship, because the app is distributed as one + /// executable. Run that way, DeviceDpi answers 96 on every machine, + /// the whole interface lays out at 1.0, and on a 150% display it comes + /// out two-thirds of the size it was drawn at. It is crisp, because + /// the manifest still makes the process Per-Monitor-V2 aware at the + /// Win32 level -- it is simply small, which reads as an older, denser + /// build of the app rather than as a bug. + /// + /// Win32 has always known the right answer; nothing was asking it. + /// Every version since 1.0 shipped this way. + /// + /// Falls back the way the API history goes: GetDpiForWindow is + /// Windows 10 1607, GetDpiForMonitor is 8.1, and GetDeviceCaps is the + /// system-wide value that works everywhere else. + /// + internal static int DpiOf(IntPtr hwnd) + { + if (hwnd != IntPtr.Zero) + { + try + { + uint d = GetDpiForWindow(hwnd); + if (d > 0) return (int)d; + } + catch (EntryPointNotFoundException) { } // pre-1607 + catch (DllNotFoundException) { } + + try + { + IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + uint x, y; + if (monitor != IntPtr.Zero && + GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, out x, out y) == 0 && x > 0) + return (int)x; + } + catch (EntryPointNotFoundException) { } // pre-8.1 + catch (DllNotFoundException) { } + } + + try + { + IntPtr dc = GetDC(IntPtr.Zero); + if (dc != IntPtr.Zero) + { + int d = GetDeviceCaps(dc, LOGPIXELSX); + ReleaseDC(IntPtr.Zero, dc); + if (d > 0) return d; + } + } + catch (DllNotFoundException) { } + + return 96; + } + /// Scales a design-token pixel value to the current display. internal static int S(int v) { diff --git a/src/ConfigurO/Nocturne/NocturneShell.cs b/src/ConfigurO/Nocturne/NocturneShell.cs index 7a49dc1..def625b 100644 --- a/src/ConfigurO/Nocturne/NocturneShell.cs +++ b/src/ConfigurO/Nocturne/NocturneShell.cs @@ -195,8 +195,9 @@ protected override void OnHandleCreated(EventArgs e) // was computed at 96 DPI. Now that the target display is known, // rescale before the first paint. int previous = (int)Math.Round(NocturneScale.Factor * 96f); - NocturneScale.SetDpi(DeviceDpi); - if (DeviceDpi != previous) + int dpi = NocturneScale.DpiOf(Handle); + NocturneScale.SetDpi(dpi); + if (dpi != previous) { MinimumSize = NocturneScale.S(NocturneTheme.WindowMinimumSize); if (WindowState == FormWindowState.Normal)