O driver de vídeo no WSL (17/08/2024) não está enviando as informações do tamanho real do monitor para o Xrandr.
Isso é um problema para qualquer aplicação que possua uma GUI.
Você pode conferir uma ferramenta que fiz usando o conteúdo desse post no github: https://github.com/A-Ribeiro/wsl-hidpi-suggestion .
Contexto
Por esses dias estava programando uma ferramenta que utiliza o Xrandr para fazer uma query do tamanho do display para renderizar os componentes gráficos com a resolução correta.
O código nativo no windows e no linux funcionam corretamente.
No WSL tem essa questão.
Parece que o driver de vídeo no WSL não transfere a informação correta do tamanho dos monitores do sistema para as aplicações.
Por isso criei esses scripts que configuram a escala de DPI nas variáveis de ambiente do WSL no '~/.bashrc'.
Configuração
1) Entre no wsl e crie um arquivo com o nome '~/powershell_get_dim.ps1' e preencha com o conteúdo abaixo:
Add-Type @" using System; using System.Runtime.InteropServices; public class DCOps { [DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr hwnd); [DllImport("user32.dll")] public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); [DllImport("gdi32.dll")] public static extern int GetDeviceCaps(IntPtr hdc, int nIndex); public static int HORZSIZE = 4; public static int VERTSIZE = 6; public static int DESKTOPVERTRES = 117; public static int DESKTOPHORZRES = 118; } "@ $hdc = [DCOps]::GetDC([IntPtr]::Zero) if ($hdc -eq [IntPtr]::Zero){ echo "1,1,1,1" exit } $w=[DCOps]::GetDeviceCaps($hdc, [DCOps]::DESKTOPHORZRES) $h=[DCOps]::GetDeviceCaps($hdc, [DCOps]::DESKTOPVERTRES) $wm=[DCOps]::GetDeviceCaps($hdc, [DCOps]::HORZSIZE) $hm=[DCOps]::GetDeviceCaps($hdc, [DCOps]::VERTSIZE) $rc=[DCOps]::ReleaseDC([IntPtr]::Zero, $hdc) echo "$w,$h,$wm,$hm"
Esse script pega o monitor padrão do windows e retorna a resolução atual em pixels e em milímetros.
2) Agora crie um arquivo '~/_new_set_dpi_scale_from_win32.sh' com o conteúdo abaixo:
#!/bin/sh f_dpi_scale() { local dpi_scale powershell_script MainDisplayInfo dpi_100_percent # the notation ${<item1>:-<item2>} # is similar to <item1> or <item2>, if <item1> is not defined dpi_scale="${GDK_DPI_SCALE:-${QT_SCALE_FACTOR:-${GTK_SCALE:-${GDK_SCALE:-}}}}" if [[ -z "${dpi_scale:-}" ]] ; then powershell_script=`cat ~/powershell_get_dim.ps1` MainDisplayInfo=$("/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" "$powershell_script") # set -f # avoid globbing (expansion of *). # array=(${MainDisplayInfo//,/ }) # array=(`echo $MainDisplayInfo | sed 's/,/\n/g'`) array=(`echo $MainDisplayInfo | tr ',' '\n'`) w=${array[0]} # width in px h=${array[1]} # height in px wm=${array[2]} # width in mm hm=${array[3]} # height in mm dpi_100_percent=$(bc <<<"scale=6; $w / ($wm / 25.4)") dpi_scale=$(bc <<<"scale=6; ($w * 25.4) / ($wm * 96) ") export GDK_SCALE=${GDK_SCALE:-$dpi_scale} export GDK_DPI_SCALE=${GDK_DPI_SCALE:-$dpi_scale} export GTK_SCALE=${GTK_SCALE:-$dpi_scale} # https://doc.qt.io/qt-5/highdpi.html # export QT_AUTO_SCREEN_SCALE_FACTOR=${QT_AUTO_SCREEN_SCALE_FACTOR:-1} # export QT_ENABLE_HIGHDPI_SCALING=${QT_ENABLE_HIGHDPI_SCALING:-1} export QT_SCALE_FACTOR=${QT_SCALE_FACTOR:-$dpi_scale} echo "DPI scale info:" echo " - Main size" echo " (px): ${w}x${h}" echo " (mm): ${wm}x${hm}" echo " (DPI-100%): ${dpi_100_percent} DPI" echo " - Scale set to: $dpi_scale" fi } # if dir runtime-dir exists, then ... [ -d /mnt/wslg/runtime-dir ] && f_dpi_scale
Esse script basicamente executa nosso script em powershell e no final configura as variáveis no sistema: GDK_SCALE, GDK_DPI_SCALE, GTK_SCALE e QT_SCALE_FACTOR.
3) Por fim, abra o seu arquivo '~/.bashrc' e acrescente a seguinte linha de código:
# ... . ~/_new_set_dpi_scale_from_win32.sh
Pronto
Agora é só entrar no WSL e testar as aplicações de GUI.
Obs.: Essa configuração só tem efeito nas aplicações que utilizam alguma dessas variáveis de ambiente que acabamos de configurar.
Espero que tenham gostado do conteúdo.
abraços,
Alessandro Ribeiro