4

I want the X/Y pixel dimensions of the entire desktop (potentially spanning multiple monitors), e.g. to determine the optimal resolution of a background image.

This Python code still works:

from gi import require_version
require_version("Gdk", "3.0")
from gi.repository import Gdk
screen = Gdk.Screen.get_default()
print(screen.get_width(), " ", screen.get_height())

but prints a deprecation warning:

<string>:7: DeprecationWarning: Gdk.Screen.get_width is deprecated
<string>:7: DeprecationWarning: Gdk.Screen.get_height is deprecated

The Gdk.Screen API docs just note:

Deprecated since version 3.22: Use per-monitor information instead

Other answers (like How do I get monitor resolution in Python or How to detect a computer's physical screen size in GTK) mention lots of other APIs and toolkits, or just give per-monitor information (like this for PyGtk), but I think it should still be possible (also in the future) to get the dimensions of the entire desktop via PyGtk. (After all, the deprecated function also still provides this.)

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • What do you mean by ‘dimensions of the entire desktop’? – user3840170 Jan 25 '21 at 18:51
  • @user3840170: Basically the union of the resolutions of all attached monitors; if the monitors are next to each other on the desk, this would be _sum(X resolutions)_ / _max(Y resolutions)_. It could be more complex if you consider the 6+ monitor setups that e.g. stock brokers have, but somehow GTK has had this all figured out in `Gdk.Screen.get_default().get_width()` already. – Ingo Karkat Jan 25 '21 at 20:15

3 Answers3

6

Based on the commit which removed those API calls, the algorithm that GDK uses to compute the screen size seems to be basically this:

def get_screen_size(display):
    mon_geoms = [
        display.get_monitor(i).get_geometry()
        for i in range(display.get_n_monitors())
    ]

    x0 = min(r.x            for r in mon_geoms)
    y0 = min(r.y            for r in mon_geoms)
    x1 = max(r.x + r.width  for r in mon_geoms)
    y1 = max(r.y + r.height for r in mon_geoms)

    return x1 - x0, y1 - y0

# example use
print(get_screen_size(Gdk.Display.get_default()))
user3840170
  • 26,597
  • 4
  • 30
  • 62
  • Yes, that's giving me the same results as the deprecated GTK function, and is what I had in mind (but couldn't come up with on my own, with limited exposure to Python and GTK so far). Very nice! I hope this will serve as the authoritative answer for future questions. – Ingo Karkat Jan 26 '21 at 07:29
0

I have no GTK installed so unfortunately can't test, but I think something like this should work:

from gi.repository import Gdk

display = Gdk.Display.get_default()
monitor = display.get_primary_monitor()
scale_factor = monitor.get_scale_factor()
geometry = monitor.get_geometry()
x = geometry.x * scale_factor
y = geometry.y * scale_factor

print(f'Screen Size: {x}x{y}')

Based on this: https://developer.gnome.org/gdk3/stable/GdkMonitor.html#gdk-monitor-get-scale-factor

This: https://github.com/AdoptOpenJDK/openjdk-support/issues/172#issuecomment-497111004

And this: https://stackoverflow.com/a/63535459/7200940

kasztp
  • 11
  • 1
  • 4
  • That unfortunately only returns the resolution of the _primary monitor_, and ignores any other connected monitors. The old GTK had this (now deprecated) notion of a _screen_ that encompasses all active monitors; I'm searching for a corresponding abstraction in the new GTK functions (or at least a simple way to implement such abstraction myself). – Ingo Karkat Jan 25 '21 at 21:16
0

I think this is the simplest to be honest

from gi import require_version
require_version("Gdk", "3.0")
from gi.repository import Gdk

screen = Gdk.Display.get_default()
w=0
h=0
for x in range(0, screen.get_n_monitors()):
     w += screen.get_monitor(x).get_geometry().width
     if ( h < screen.get_monitor(x).get_geometry().height ):
          h = screen.get_monitor(x).get_geometry().height
print (w, ' ', h)
Tch
  • 1,055
  • 5
  • 11
  • the height depends on your needs actually, if you need the highest number or the lower or your screens have all the same height – Tch Jan 26 '21 at 00:19