Get display count and resolution for each display in Python without xrandr
Solution 1
xrandr
is just a client to access the "RandR" X11 extension from the command line. You can access the functionality directly from Python-Xlib. Here's an example (from Python-Xlib's own code!).
Just in case the URL changes again, here's a minimal piece of code that gets us the display modes. We need to create window (it doesn't matter the size, etc):
from __future__ import print_function
from Xlib import X, display
from Xlib.ext import randr
d = display.Display()
s = d.screen()
window = s.root.create_window(0, 0, 1, 1, 1, s.root_depth)
Then we can query the screen resources using it. Eg, following OP's example:
res = randr.get_screen_resources(window)
for mode in res.modes:
w, h = mode.width, mode.height
print("Width: {}, height: {}".format(w, h))
In my computer I get:
$ python minimal.py
Xlib.protocol.request.QueryExtension
Width: 1600, height: 900
Width: 1440, height: 900
Width: 1360, height: 768
Width: 1360, height: 768
Width: 1152, height: 864
Width: 1024, height: 768
Width: 800, height: 600
Width: 800, height: 600
Width: 640, height: 480
Solution 2
Latest snippet. It extracts all modes with current resolution from all connected monitors.
from Xlib import display
from Xlib.ext import randr
def find_mode(id, modes):
for mode in modes:
if id == mode.id:
return "{}x{}".format(mode.width, mode.height)
def get_display_info():
d = display.Display(':0')
screen_count = d.screen_count()
default_screen = d.get_default_screen()
result = []
screen = 0
info = d.screen(screen)
window = info.root
res = randr.get_screen_resources(window)
for output in res.outputs:
params = d.xrandr_get_output_info(output, res.config_timestamp)
if not params.crtc:
continue
crtc = d.xrandr_get_crtc_info(params.crtc, res.config_timestamp)
modes = set()
for mode in params.modes:
modes.add(find_mode(mode, res.modes))
result.append({
'name': params.name,
'resolution': "{}x{}".format(crtc.width, crtc.height),
'available_resolutions': list(modes)
})
return result
print(get_display_info())
Comments
-
Wolkenarchitekt almost 2 years
I'm running Ubuntu and I want to get the number of attached displays, their current resolution and, if possible, their position in relation to each other. Because I don't like parsing Console output of xrandr - at least not if I don't have to - I would like to do that with Python-XLib or a similar Pythonic approach.
This is the xrandr output for my display config:
$ xrandr Screen 0: minimum 320 x 200, current 2960 x 1050, maximum 8192 x 8192 DVI-0 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 473mm x 296mm 1680x1050 60.0*+ 1400x1050 60.0 1280x1024 75.0 60.0 1440x900 59.9 1280x960 75.0 60.0 1152x864 75.0 1280x720 75.0 1024x768 75.1 70.1 60.0 832x624 74.6 800x600 72.2 75.0 60.3 56.2 640x480 72.8 75.0 66.7 60.0 720x400 70.1 VGA-0 connected 1280x1024+1680+26 (normal left inverted right x axis y axis) 376mm x 301mm 1280x1024 60.0 + 75.0* 1024x768 75.1 70.1 60.0 832x624 74.6 800x600 72.2 75.0 60.3 56.2 640x480 72.8 75.0 66.7 60.0 720x400 70.1
I want to get these values with Python, in a way like this:
displays = get_displays() print displays[0].width # out: 1680 print displays[1].width # out: 1280 print displays[0].x_position # out: 0 print displays[1].x_position # out: 1680
When trying to get informations via Python-XLib (or other libs like pyGTK and pygame), it seems that all displays are always handled as one single display. For example this is what I got with XLib so far:
import Xlib import Xlib.display display = Xlib.display.Display(':0') print display.screen_count() # output: 1 root = display.screen().root print root.get_geometry().width # output: 2960 -> no way to get width of single display? print root.get_geometry().height # output: 1050
I know how to get display informations calling xrandr within Python:
import subprocess output = subprocess.Popen('xrandr | grep "\*" | cut -d" " -f4',shell=True, stdout=subprocess.PIPE).communicate()[0] displays = output.strip().split('\n') for display in displays: values = display.split('x') width = values[0] height = values[1] print "Width:" + width + ",height:" + height
But as I said I would prefer a cleaner approach without having to parse Console output. Is there really no way to get (detailed) Display informations with Python without having to parse xrandr output?
-
Ben Davis over 9 yearsAny ideas how to get the connected output names from xilb/xrandr?
-
Ricardo Cárdenes over 9 years@BenDavis you could get the possible outputs querying
randr.get_screen_resources(window).outputs
(returns a list of integers), and then get info about the output usingrandr.get_output_info(window, ID, timestamp)
(I've usedtimestamp=0
). From the "output info" you should be able to figure out if an output is connected -
Martlark over 4 yearsNot really an answer to the question on linux, but handy for bad google searching.
-
delica over 4 years@Martlark indeed! That's why I wrote this 'answer'. For those who arrive here looking for a windows solution.
-
winbina over 3 yearsThis seems to be the entire logical screen, i.e. all monitors added together into one screen. I have 3 monitors, but this just prints 1 screen that's 2640x2520.
-
Rob over 3 yearsI arrived here from Review Posts and recommended deletion for not answering the question.
-
WinEunuuchs2Unix almost 3 yearsJust having a quick glance at the code and it seems like
mode.width, mode.height
should be prefaced bymode.x, mode.y
for the monitors' coordinates on extended desktop? -
WinEunuuchs2Unix almost 3 yearsAnswer posted below yours may never be updated, I wonder if you would consider incorporating it along with my comment below his answer into an all-inclusive answer?
-
Kalma about 2 yearsHI @Max Ivanov! This was really useful! I'm having troubles with res.config_timestamp in xrandr_get_crtc_info() on LXDE (though surprisingly NOT in xrandr_get_output_info() and NOT in other Desktop environments). Can you please point where to find info about these "xrandr_*" methods so I can investigate?