CustomTkinter icon indicating copy to clipboard operation
CustomTkinter copied to clipboard

[BUG] CustomTkInter renders incorrectly on Linux when desktop scaling is used.

Open Arcitec opened this issue 1 year ago • 9 comments

System:

  • GNOME 46 on Fedora Workstation 40

I have seen this bug in a lot of tickets here. Many people might not realize what's wrong.

The issue is that CustomTkInter renders all controls and their borders in a squashed way when desktop UI scaling is used:

Here, my desktop is set to 200% scale:

image

This is how CustomTkInter renders (buggy) at 200%:

image

This is how it renders (correctly) when I set the desktop to 100%:

image

To support desktop scaling, it looks like the issue is that CustomTkInter needs to detect the desktop scale and enlarge its own widgets to fit everything correctly. Right now, it seems like the widgets at 200% are rendering with larger widgets but within the exact same PHYSICAL space as 100% widgets would use.

Arcitec avatar Sep 29 '24 16:09 Arcitec

Did you try it with scaling manually? For example:

from customtkinter import CTk, CTkLabel
from customtkinter import set_window_scaling, set_widget_scaling

if __name__ == "__main__":
    app = CTk()
    app.geometry("500x300")


    set_window_scaling(2)  # 2 for 200% scaling.
    set_widget_scaling(2)


    lab = CTkLabel(app, text="Sample Text", fg_color="darkblue", corner_radius=10)
    lab.place(relx=0.5, anchor="center", rely=0.5)



    app.mainloop()

Regards

dipeshSam avatar Sep 29 '24 17:09 dipeshSam

@dipeshSam Thanks for the suggestion. I tried it now, but it made things worse. CustomTkInter is clearly scaling to 200% from my desktop settings. And with your change, it's also scaling to +200% inside its own GUI. This means with your suggested changes, I now have a total of 400% GUI scaling. So everything is now bigger, but the widgets are still broken in the exact same way as before. :rofl:

This means that CustomTkInter's widget rendering itself is broken on high desktop scaling on Linux (at least on GNOME, I don't have KDE to test).

image

Arcitec avatar Sep 29 '24 20:09 Arcitec

Oh! @TomSchimansky should take a look into this matter.

dipeshSam avatar Sep 30 '24 02:09 dipeshSam

You can call xdpyinfo from linux with subprocess to check the scale. Next step is to make a function to calculate the scale factor and one more which will update all widgets.

import subprocess
import customtkinter as ctk


def scaling_info():
    output = subprocess.check_output("xdpyinfo | grep dots", shell=True).decode("utf-8")
    dpi = int(output.split()[1].split('x')[0])
    scaling_factor = dpi / 96.0
    return scaling_factor



app = ctk.CTk()
app.geometry("500x400")

scaling_factor = scaling_info()

def update_all_widgets_scaling():
    for widget in app.winfo_children():
        if isinstance(widget, ctk.CTkButton):
            widget.configure(width=int(150 * scaling_factor), height=int(50 * scaling_factor))
        
        elif isinstance(widget, ctk.CTkLabel):
            widget.configure(font=("Arial", int(14 * scaling_factor)))
        
    app.update()


label = ctk.CTkLabel(app, text=f"Scale DPI factor: {scaling_factor:.2f}")
label.pack(pady=20)
button = ctk.CTkButton(app, text="Button 1")
button.pack(pady=10)

button2 = ctk.CTkButton(app, text="Button 2")
button2.pack(pady=10)


label2 = ctk.CTkLabel(app, text="label")
label2.pack(pady=10)
update_all_widgets_scaling()

app.mainloop()

ghost avatar Sep 30 '24 05:09 ghost

I do have the same issue on the KDE Plasma version of fedora 40 workstation. I’ll try to switch to Gnome and try it on my machine. Thanks!

hacker-3342 avatar Sep 30 '24 08:09 hacker-3342

You can call xdpyinfo from linux with subprocess to check the scale. Next step is to make a function to calculate the scale factor and one more which will update all widgets.

Thanks @mst4ck for the suggestion and code. I tried it and it did not work, unfortunately:

My desktop at 200% scale shows this broken rendering as usual:

image

My desktop at 100% scale shows this correct rendering:

image

So yeah that's full confirmation that CustomTkInter's scaling is bugged on Linux.

@hacker-3342

I do have the same issue on the KDE Plasma version of fedora 40 workstation. I’ll try to switch to Gnome and try it on my machine. Thanks!

Don't bother trying GNOME. I am on GNOME and it's bugged there too. But thank you for confirming that KDE Is broken too so I don't have to wonder about it. :)

Arcitec avatar Sep 30 '24 12:09 Arcitec

And yeah X11 scaling is saying the same thing no matter what the GNOME monitor scaling is set to (ran with 200% and 100% desktop scaling here):

image

This makes sense because those deprecated APIs are not used anymore. Scaling uses something else nowadays, and is probably window manager-specific (GNOME vs KDE vs Hyprland etc).

Arcitec avatar Sep 30 '24 12:09 Arcitec

You can try another thing to check the scale factor in gnome. Maybe will work now:)

def dpi_scale_info():
    dpi_scale = int(os.environ.get('GDK_SCALE', 1))
    dpi_dpi_scale = float(os.environ.get('GDK_DPI_SCALE', 1))
    dpi_factor = dpi_scale * dpi_dpi_scale
    return dpi_factor

ghost avatar Sep 30 '24 19:09 ghost

I also notice issues with scaling in KDE. When I try to create a button with a corner radius, it looks bad with any display scaling not set to 100%. The corner circle center points are not set correctly, which is apparent by setting border-width = 10

Image

When I change my desktop scaling back to 100% the corner radii render correctly.

jack-obrien avatar Aug 25 '25 06:08 jack-obrien