Coder Social home page Coder Social logo

Handle DPI settings about autorandr HOT 19 OPEN

phillipberndt avatar phillipberndt commented on May 24, 2024 4
Handle DPI settings

from autorandr.

Comments (19)

Vladimir-csp avatar Vladimir-csp commented on May 24, 2024 6

I've ported the example DPI hook from my rerandr3 to autorandr scripts:

postsave:
saves current DPI value to "${AUTORANDR_PROFILE_FOLDER}/dpi"

#!/bin/sh
DPI="$(xdpyinfo | grep 'resolution:' | grep -o '[0-9]\+x[0-9]\+' | head -n 1 | cut -d 'x' -f 1)"
[ -n "$DPI" ] && echo "$DPI" > "${AUTORANDR_PROFILE_FOLDER}/dpi"

postswitch:
expects DPI value in "${AUTORANDR_PROFILE_FOLDER}/dpi", falls back to calculated DPI of primary monitor, then falls back to default 96.

#!/bin/sh

DEFAULT_DPI=96

## try DPI from profile
printf "%s\n" "Trying to get DPI from \"${AUTORANDR_PROFILE_FOLDER}/dpi\""
DPI="$(cat "${AUTORANDR_PROFILE_FOLDER}/dpi" 2>/dev/null | head -n 1 | grep -o '[0-9]\+')"

## try dpi from primary monitor
if [ -z "$DPI" ]
then
     printf "%s\n%s\n" "No DPI value in profile \"$AUTORANDR_CURRENT_PROFILE\"" "Trying to calculate from primary monitor"
     DPX="$(xrandr -q | grep ' primary ' | grep -o ' [0-9]\+x' | grep -o '[0-9]\+')"
     DMM="$(xrandr -q | grep ' primary ' | grep -o ') [0-9]\+mm' | grep -o '[0-9]\+')"

     if [ -n "$DPX" -a -n "$DMM" ]
     then
          DPI="$(python -c "print( int( $DPX / ( $DMM * 0.039370079 ) ) )" )"
     fi
fi

if [ -z "$DPI" ]
then
     printf "%s\n%s\n" "Could not calculate DPI of primary monitor" "Using default"
     DPI=$DEFAULT_DPI
fi

printf "%s\n" "Resulting DPI: $DPI"

## apply DPI to xrandr
xrandr --dpi "$DPI"


## sync dpi to xrdb
printf "%s\n" "Xft.dpi: $DPI" | xrdb -merge

## sync dpi to fontconfig
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/fontconfig/conf.d"
cat > "${XDG_CONFIG_HOME:-$HOME/.config}/fontconfig/conf.d/90-xrandr-sync-dpi.conf" << EOF
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- Generated by autorandr postswitch script, do not edit. -->
<fontconfig>
  <match target="pattern">
    <edit name="dpi" mode="assign"><double>$DPI</double></edit>
  </match>
</fontconfig>
EOF

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

This does not appear to be reflected in the output of xrandr -q --verbose.

Couldn't we extract this from the first line (it states effective resolution and physical device size in mm) of each output?

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

I just tried. No, that doesn't work, and that it doesn't makes a lot of sense, too, now that I've come to think about it.. What xrandr displays is per-output DPI only, which can be different from the screen's DPI and also isn't alterable (the physical screen size is hard-coded in the EDID, bytes 21 & 22). What --dpi alters, on the other hand, is the screen's DPI, which corresponds to the FB resolution (first line in xrandr's output)

I don't think that including a call to xdpyinfo in autorandr is a good idea. For one, that would be an external dependency. For the other, it currently doesn't fiddle with the FB size at all (but lets xrandr decide how to set it), but once we'd set --dpi, we'd need to set --fb as well, and I don't know what sorts of regression that might create.

What we could do, if you need this, is to integrate a plugin structure that would enable you to do this without maintaining your own fork - I'm thinking of something simple like importing all modules from a plugin directory and calling well-named hooks from those plugins at detection and application time, probably with a mechanism to store custom settings?!

from autorandr.

blueyed avatar blueyed commented on May 24, 2024

A plugin structure would be nice, but a more simple approach is probably just looking at autorandr's output, and then call by xsettings-setup manually.

I can use just autorandr and look for "(detected)", right? (It would not change the current setup)

But then again (and for other use cases), it would be useful to have information about if the detected setup is already applied, without calling "autorandr -c", which would apply the changes.

In the end, I think two lines should be added to the output: "detected: X" and "current: X" (or something similar).

Currently I could just use -c and then grep for the (detected) line, especially since I will likely move calling autorandr to a custom script anyway. "Config already loaded" could then be used there to not apply any changes (again).

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

If you're fine with configuring this manually, then you can also place a script called postswitch in your profile's directory. It is executed after applying a profile, and only then.

Changing autorandr's default output is a good idea. The current output comes from the legacy bash version (not quite, it exits after it has found the "detected" configuration), and I always thought that it is quite useless in its current form, too. For increased backwards compatibility, we could keep it in its current form, but just replace "(detected)" with "(current)" for the currently loaded configuration?!

from autorandr.

blueyed avatar blueyed commented on May 24, 2024

Oh yeah, postswitch is useful in this case - had forgotten about it.

Re backwards compatibility: a change from "(detected)" to "(current)" would then also be not backwards compatible.

I think this issue can be closed for now - there's no need to change anything currently.

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

Re backwards compatibility: a change from "(detected)" to "(current)" would then also be not
backwards compatible.

Right. But it'd require less changes in existing scripts. (Maybe I'll change this.. if anyone complains this could always be reverted.)

I think this issue can be closed for now - there's no need to change anything currently.

Ok

from autorandr.

blueyed avatar blueyed commented on May 24, 2024

But it'd require less changes in existing scripts. (Maybe I'll change this.. if anyone complains this could always be reverted.)

👍

from autorandr.

rriemann avatar rriemann commented on May 24, 2024

@blueyed Would you please share your final solutions? I have an internal and external display that differ a lot in dpi.

from autorandr.

Vladimir-csp avatar Vladimir-csp commented on May 24, 2024

A couple of thoughts on DPI from my experience
First, in X there is no such thing as per-display DPI from practical standpoint. You have to choose some global value that suits you.
Second, xdpyinfo is a sufficiently reliable source of the current DPI. It is directly affected by xrandr's --dpi parameter and can be used as the base for further manipulations.
Said manipulations would include exporting that value to xrdb and fontconfig. With DPI value correctly set in these three places, majority of applications are affected.

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

Turns out that adding --fb to autorandr is a brilliant idea, I hadn't considered the side effect @Vladimir-csp mentioned in #88. Gives a much smoother user experience on my notebook at least. So let's reconsider adding native DPI support: Anyone willing to implement this?

from autorandr.

Mange avatar Mange commented on May 24, 2024

What would it entail to implement it?

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

Using Vladimir's script as a template extract the DPI while storing a profile (using xdpyinfo and the falllback if it's not installed), store it in config files a dpi xyz, (probably extend autorandr to be able to handle such non-output related options at all, IIRC it currently matches everything to an output), and finally extend apply_configuration to set it.

It might actually be a good idea to just store the --fb value to the configuration in general, and only use the calculation function if the key is not present in the configuration.

from autorandr.

Mange avatar Mange commented on May 24, 2024

I had a look, but I'm not up to the task. 😞

I'm not a Python developer, but I thought I could find a test and adjust it and then just figure out the code as I went. I wasn't aware that all the code is in a single file without no tests, so I'm just too scared to try it.
I also cannot tell where in the code the config file is parsed either.

(Not saying it's bad or anything, just that I personally don't want to go in there and muck around without better understanding of Python. 🙇‍♂️)

I think that if someone could add support for non-output specific options (like dpi and fb), then a lot of setups could be supported even if detection cannot happen automatically. Maybe that's a simpler goal for someone to take a look at?

from autorandr.

phillipberndt avatar phillipberndt commented on May 24, 2024

Pushed a work in progress version with an early attempt to toy around with this to the dpi branch. I don't bother much with obtaining dpi information from the external tool yet, it's mainly an attempt to play around with piggy-backing the options onto the first output. Feedback appreciated.

from autorandr.

Vladimir-csp avatar Vladimir-csp commented on May 24, 2024

I've tested dpi branch. It seems to get primary output native dpi correctly, save it and apply on restore to xrandr.

from autorandr.

RidaAyed avatar RidaAyed commented on May 24, 2024

Pushed a work in progress version with an early attempt to toy around with this to the dpi branch. I don't bother much with obtaining dpi information from the external tool yet, it's mainly an attempt to play around with piggy-backing the options onto the first output. Feedback appreciated.

Very nice project, thank you.
How is DPI handled in the current release (AUR)?

from autorandr.

MikaelElkiaer avatar MikaelElkiaer commented on May 24, 2024

How does all of this relate to multihead (multiple monitors) with different resolutions/DPIs?

I have a laptop (3840x2160) and an ultrawide (3440x1440).
I've had to settle with running my laptop at 2560x1440 and ultrawide at 3440x1440, with a DPI of 96. This keeps my laptop at reasonable size, but my ultrawide is actually a bit too big. However, I'd prefer to run both at full resolution, but a DPI of 144 for the laptop and 72 for the ultrawide..

from autorandr.

Mange avatar Mange commented on May 24, 2024

Sadly X11 only supports a single global DPI. You'll need Wayland for Display-specific DPI settings.

from autorandr.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.