Skip to content

Auto detection of monitor scale for Hyprland, GTK, QT, Electron #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

ryanyogan
Copy link
Contributor

@ryanyogan ryanyogan commented Jul 18, 2025

🧠 Concept Summary

This pull request introduces automatic HiDPI scale detection and configuration for Hyprland setups within Omarchy. It includes:

  • Automatic detection of monitor resolution and appropriate scaling (e.g., 1x or 2x).

  • Backup script to preserve existing user configurations before any changes are applied.

  • Generation of environment configuration for GTK, Qt, and Electron applications to reflect the selected scale.

  • Automatic Hyprland reload to apply changes immediately.

  • Convenient helper script to manually re-run scale detection.

  • Font & Cursor Scaling applies sane defaults for fonts on different resolutions

    • I am currently investigating with different font sizes @ resolutions to determine sane defaults based on the original terminal font size 9 on a SCALE=2 setting.
  • Pending Concept should we resize the layout and padding based on DPI? I tested it, it looks nice, but it's more of a personal preference I think?

  • Can this be better?! you will not hurt my feelings, is there a smarter way to knock-out this challenge?


📦 Changes Introduced

  1. Backup Script (omarchy-backup-scale.sh)

    • Saves copies of monitors.conf, autostart.conf, and any existing scale environment files to a timestamped backup directory.
    • Ensures users can safely revert to a known-good state.
  2. Scale Detection Script (omarchy-scale-detect)

    • Uses hyprctl monitors to determine primary display resolution.
    • Automatically sets scale=2 for displays with width ≥ 3000px, otherwise sets scale=1.
    • Updates monitors.conf with the appropriate monitor=,preferred,auto,<scale> setting.
    • Generates a corresponding ~/.config/environment.d/50-hypr-scale.conf file for toolkit compatibility (GTK, Qt, Electron).
    • Reloads Hyprland via hyprctl reload if available.
  3. Manual Refresh Script (omarchy-scale-refresh.sh)

    • A simple wrapper that re-invokes the detection script and reports the operation.
  4. Autostart Hook

    • Adds exec-once = ~/.local/share/omarchy/bin/omarchy-scale-detect to automatically run the detection at Hyprland launch.

📁 File Structure

~/.local/share/omarchy/bin/
├── omarchy-backup-scale.sh         # One-time safe backup
├── omarchy-scale-detect            # Core logic
└── omarchy-scale-refresh.sh        # Convenience rerun command

✅ Benefits

  • Improves out-of-the-box experience for users on HiDPI displays.
  • Reduces manual configuration burden across toolkits (GTK, Qt, Electron).
  • Safe and reversible, thanks to the backup script.
  • Compliant with Hyprland best practices, using systemd-style env overrides and native reload.

🧪 Testing Performed

  • Tested on:

    • 4K display (3840x2160): correctly applied scale=2
    • 1080p display (1920x1080): correctly applied scale=1
  • Confirmed proper generation of environment file

  • Verified Hyprland reload occurs without issue

  • Tested backup script preserves config files in expected location


📎 Notes

  • This PR assumes hyprctl is available in PATH and Hyprland is actively running.
  • Edge cases (e.g., multiple displays with mixed resolutions) are not yet handled—future improvements could involve per-monitor scale settings.
  • Background fallback and error detection are kept minimal to maintain script simplicity.

@ryanyogan ryanyogan marked this pull request as ready for review July 18, 2025 19:47
@ryanyogan ryanyogan marked this pull request as draft July 18, 2025 20:26
@ryanyogan
Copy link
Contributor Author

@dhh should we adjust Hyprland layout & padding settings based upon the monitor DPI & resolution, or leave that be?

@@ -1,5 +1,6 @@
exec-once = uwsm app -- hypridle
exec-once = uwsm app -- mako
exec-once = ~/.local/share/omarchy/bin/omarchy-scale-detect
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There must be a more efficient way to perform this...

Comment on lines +41 to +52
cat > "$HOME/.config/environment.d/50-hypr-scale.conf" <<EOF
# auto‑generated by omarchy-scale-detect
GDK_SCALE=${SCALE}
GDK_DPI_SCALE=$(awk "BEGIN {printf \"%.2f\", 1/${SCALE}}")
QT_SCALE_FACTOR=${SCALE}
QT_AUTO_SCREEN_SCALE_FACTOR=0
# Electron (Spotify, VSCode, etc.)
ELECTRON_ENABLE_HIGH_DPI_SUPPORT=1
ELECTRON_FORCE_DEVICE_SCALE_FACTOR=${SCALE}
# Cursor scaling (more sensible sizes)
XCURSOR_SIZE=${CURSOR_SIZE}
HYPRCURSOR_SIZE=${CURSOR_SIZE}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With all the hardcoded configuration for the scale factors here, what will happen if I move, for example, an Electron-based app from my primary, high DPI display to the secondary, at a normal scale?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess Hyprland itself might be able to handle some things like cursor size, but not sure about the apps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good question! I do not like this either, these are here as more of expose it all to test phase. I had to keep a few things easy to modify as I explore fonts.

Do you have any nudges in a direction you'd like to see? I should denote much of the constants right now are arbitrary as I am trying to find that perfect balance for a wide array of monitors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the dual monitors, this is something I put in the notes. I need help figuring that one out. I would like to get the basics working on one monitor first. That is the north star however :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the direction here is good, I got nothing to say about your suggested constants. My concern is mostly regarding what is actually possible in terms of moving a window between monitors with different scaling. I hope some magic will happen and nothing breaks. I experience different issues with scaling depending on the OS and app. 😄

I will see if I can setup some simple tests with these env vars to see how the apps behave.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome thank you! I just moved and I still need to unpack some monitors, thus I am limited to augmenting my display. I put that backup script in as I thought I would remember my default config, nope!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a quick test with the Electron settings and I didn't notice any difference in app behavior when switching displays with and without the environment variables.

Potentially setting up the Electron apps to use Wayland and a good configuration of the scaling of the monitors in Hyprland is enough to cover this part.

Not sure about the QT/GTK stuff, I didn't test it.

@trmcnvn
Copy link

trmcnvn commented Jul 19, 2025

For another note, this would cause some non-4K Ultrawide monitors to be scaled to 2 due to their width.

@dhh
Copy link
Member

dhh commented Jul 19, 2025

I think maybe a simpler way here is to encapsulate everything needed for a 1x display to look good in something like omarchy-setup-screen, and then people can just try it themselves.

Instead of scaling, we should also look at text scaling. That's what made the original Framework display tolerable to me. I used gsettings set org.gnome.desktop.interface text-scaling-factor 0.8, corrected the font sizes, and it looked great.

@dhh
Copy link
Member

dhh commented Jul 19, 2025

Here's what we did for the Framework scaling fix: https://github.com/basecamp/omakub/blob/master/install/desktop/set-framework-text-scaling.sh

I think there might be something similar that could be done, which would fix most people's setups. I bet 90% of all the screens are either 1080p, 1440p, or 4K, so just have to nail what the right text scaling would be for those compared to the size of the monitor. Not sure if we can reliably get the size of a monitor programmatically, but we could even just ask the user.

@ryanyogan
Copy link
Contributor Author

ryanyogan commented Jul 19, 2025

For another note, this would cause some non-4K Ultrawide monitors to be scaled to 2 due to their width.

Yeah I am running into that as I slowly move into my new home and tinker with different monitors heh.

I think maybe a simpler way here is to encapsulate everything needed for a 1x display to look good in something like omarchy-setup-screen, and then people can just try it themselves.

Instead of scaling, we should also look at text scaling. That's what made the original Framework display tolerable to me. I used gsettings set org.gnome.desktop.interface text-scaling-factor 0.8, corrected the font sizes, and it looked great.

I believe you are correct, potentially a TUI would be nice to make changes from sane defaults. I'll pivot in the direction of getting 1x scale nice, followed by text scaling.

Edit:

Here's what we did for the Framework scaling fix: https://github.com/basecamp/omakub/blob/master/install/desktop/set-framework-text-scaling.sh

I think there might be something similar that could be done, which would fix most people's setups. I bet 90% of all the screens are either 1080p, 1440p, or 4K, so just have to nail what the right text scaling would be for those compared to the size of the monitor. Not sure if we can reliably get the size of a monitor programmatically, but we could even just ask the user.

Thanks for that!

My framework shows up in 2 days, I need to crank this!

@ryanyogan
Copy link
Contributor Author

I was thinking something like this, is this more along the lines?

screenshot-2025-07-20_11-01-53 screenshot-2025-07-20_11-02-16 screenshot-2025-07-20_11-02-35

@ryanyogan ryanyogan closed this Jul 20, 2025
@ryanyogan ryanyogan deleted the auto-scale branch July 20, 2025 20:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants