| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- # scaling.tcl --
- #
- # Contains scaling-related utility procedures.
- #
- # Copyright © 2022 Csaba Nemethi <csaba.nemethi@t-online.de>
- # ::tk::ScalingPct --
- #
- # Returns the display's "scaling percentage" (the display resolution expressed
- # as a percentage of 96dpi), rounded to the nearest multiple of 25 that is at
- # least 100.
- #
- # On X11 systems (but not on SDL systems that claim to be X11), the first call
- # of the command also sets [tk scaling] and ::tk::fontScalingFactor to values
- # extracted from the X11 configuration.
- #
- # The command is called during Tk initialization, from icons.tcl, when the
- # latter is sourced by tk.tcl.
- proc ::tk::ScalingPct {} {
- set pct [expr {[tk scaling] * 75}]
- variable doneScalingInitX11
- if {![info exists doneScalingInitX11]} {
- set pct [::tk::ScalingInitX11 $pct]
- set doneScalingInitX11 1
- }
- #
- # Save the value of pct rounded to the nearest multiple
- # of 25 that is at least 100, in the variable scalingPct.
- # See "man n tk_scalingPct" for use of ::tk::scalingPct.
- #
- variable scalingPct
- for {set scalingPct 100} {1} {incr scalingPct 25} {
- if {$pct < $scalingPct + 12.5} {
- break
- }
- }
- return $scalingPct
- }
- proc ::tk::ScalingInitX11 {pct} {
- set onX11 [expr {[tk windowingsystem] eq "x11"}]
- set usingSDL [expr {[info exists ::tk::sdltk] && $::tk::sdltk}]
- if {$onX11 && !$usingSDL} {
- set origPct $pct
- #
- # Try to get the window scaling factor (1 or 2), partly
- # based on https://wiki.archlinux.org/title/HiDPI
- #
- set winScalingFactor 1
- variable fontScalingFactor 1 ;# needed in the file ttk/fonts
- if {[catch {exec ps -e | grep xfce4-session}] == 0} { ;# Xfce
- if {[catch {exec xfconf-query -c xsettings \
- -p /Gdk/WindowScalingFactor} result] == 0} {
- set winScalingFactor $result
- if {$winScalingFactor >= 2} {
- set fontScalingFactor 2
- }
- }
- #
- # The DPI value can be set in the "Fonts" tab of the "Appearance"
- # dialog or (on Linux Lite 5+) via the "HiDPI Settings" dialog.
- #
- } elseif {[catch {exec ps -e | grep mate-session}] == 0} { ;# MATE
- if {[catch {exec gsettings get org.mate.interface \
- window-scaling-factor} result] == 0} {
- if {$result == 0} { ;# means: "Auto-detect"
- #
- # Try to get winScalingFactor from the cursor size
- #
- if {[catch {exec xrdb -query | grep Xcursor.size} result]
- == 0 &&
- [catch {exec gsettings get org.mate.peripherals-mouse \
- cursor-size} defCursorSize] == 0} {
- set cursorSize [lindex $result 1]
- set winScalingFactor \
- [expr {($cursorSize + $defCursorSize - 1) /
- $defCursorSize}]
- }
- } else {
- set winScalingFactor $result
- }
- }
- #
- # The DPI value can be set via the "Font Rendering Details"
- # dialog, which can be opened using the "Details..." button
- # in the "Fonts" tab of the "Appearance Preferences" dialog.
- #
- } elseif {[catch {exec ps -e | grep gnome-session}] == 0 &&
- [catch {exec gsettings get \
- org.gnome.settings-daemon.plugins.xsettings overrides} \
- result] == 0 &&
- [set idx \
- [string first "'Gdk/WindowScalingFactor'" $result]] >= 0} {
- scan [string range $result $idx end] "%*s <%d>" winScalingFactor
- }
- #
- # Get the scaling percentage
- #
- if {$winScalingFactor >= 2} {
- set pct 200
- } elseif {[catch {exec xrdb -query | grep Xft.dpi} result] == 0} {
- #
- # Derive the value of pct from that of the font DPI
- #
- set dpi [lindex $result 1]
- set pct [expr {100.0 * $dpi / 96}]
- } elseif {[catch {exec ps -e | grep gnome-session}] == 0 &&
- ![info exists ::env(WAYLAND_DISPLAY)] &&
- [catch {exec xrandr | grep " connected"} result] == 0 &&
- [catch {open $::env(HOME)/.config/monitors.xml} chan] == 0} {
- #
- # Update pct by scanning the file ~/.config/monitors.xml
- #
- ScanMonitorsFile $result $chan pct
- }
- if {($pct != 100) && ($pct != $origPct) && (![interp issafe])} {
- #
- # Set Tk's scaling factor according to $pct
- #
- tk scaling [expr {$pct / 75.0}]
- }
- }
- return $pct
- }
- # ::tk::ScaleNum --
- #
- # Scales an integer according to the display's current scaling percentage.
- #
- # Arguments:
- # num - An integer.
- proc ::tk::ScaleNum num {
- return [expr {round($num * [tk scaling] * 0.75)}]
- }
- # ::tk::FontScalingFactor --
- #
- # Accessor command for variable ::tk::fontScalingFactor.
- proc ::tk::FontScalingFactor {} {
- variable fontScalingFactor
- if {[info exists fontScalingFactor]} {
- return $fontScalingFactor
- } else {
- return 1
- }
- }
- # ::tk::ScanMonitorsFile --
- #
- # Updates the scaling percentage by scanning the file ~/.config/monitors.xml.
- #
- # Arguments:
- # xrandrResult - The output of 'xrandr | grep " connected"'.
- # chan - Returned from 'open ~/.config/monitors.xml'.
- # pctName - The name of a variable containing the scaling percentage.
- proc ::tk::ScanMonitorsFile {xrandrResult chan pctName} {
- upvar $pctName pct
- #
- # Get the list of connected outputs reported by xrandr
- #
- set outputList {}
- foreach line [split $xrandrResult "\n"] {
- set idx [string first " " $line]
- set output [string range $line 0 [incr idx -1]]
- lappend outputList $output
- }
- set outputList [lsort $outputList]
- #
- # Get the content of the file ~/.config/monitors.xml
- #
- set str [read $chan]
- close $chan
- #
- # Run over the file's "configuration" sections
- #
- set idx 0
- while {[set idx2 [string first "<configuration>" $str $idx]] >= 0} {
- set idx2 [string first ">" $str $idx2]
- set idx [string first "</configuration>" $str $idx2]
- set config [string range $str [incr idx2] [incr idx -1]]
- #
- # Get the list of connectors within this configuration
- #
- set connectorList {}
- foreach {dummy connector} [regexp -all -inline \
- {<connector>([^<]+)</connector>} $config] {
- lappend connectorList $connector
- }
- set connectorList [lsort $connectorList]
- #
- # If $outputList and $connectorList are identical then set the
- # variable pct to 100, 200, 300, 400, or 500, depending on the
- # max. scaling within this configuration, and exit the loop
- #
- if {$outputList eq $connectorList} {
- set maxScaling 1.0
- foreach {dummy scaling} [regexp -all -inline \
- {<scale>([^<]+)</scale>} $config] {
- if {$scaling > $maxScaling} {
- set maxScaling $scaling
- }
- }
- foreach n {4 3 2 1 0} {
- if {$maxScaling > $n} {
- set pct [expr {($n + 1) * 100}]
- break
- }
- }
- break
- }
- }
- }
|