Search code examples
pythonmatplotlibtkinterctypesresolution

Resolution of a maximized window in Python


Is there a built-in function or straight-forward way to get the resolution of a maximized window in Python (e.g. on Windows full screen without the task bar)? I have tried several things from other posts, which present some major drawbacks:

  1. ctypes
import ctypes 
user32 = ctypes.windll.user32 
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)

Simple, but I get the resolution of the full screen.

  1. tkinter
import tkinter as tk
root = tk.Tk()  # Create an instance of the class.
root.state('zoomed')  # Maximized the window.
root.update_idletasks()  # Update the display.
screensize = [root.winfo_width(), root.winfo_height()]
root.mainloop()

Works, but it isn't really straight-forward and above all, I don't know how to exit the loop with root.destroy() or root.quit() successfully. Closing the window manually is of course not an option.

  1. matplotlib
import matplotlib.pyplot as plt
plt.figure(1)
plt.switch_backend('QT5Agg')
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
print(plt.gcf().get_size_inches())

[6.4 4.8] is then printed, but if I click on the created window, and execute print(plt.gcf().get_size_inches()) again, I get [19.2 10.69] printed, which I find higly inconsistent! (As you can imagine, having to interact to get that final value is definitely not an option.)


Solution

  • According to [MS.Learn]: GetSystemMetrics function (winuser.h) (emphasis is mine):

    SM_CXFULLSCREEN

    16

    The width of the client area for a full-screen window on the primary display monitor, in pixels. To get the coordinates of the portion of the screen that is not obscured by the system taskbar or by application desktop toolbars, call the SystemParametersInfo function with the SPI_GETWORKAREA value.

    Same thing for SM_CYFULLSCREEN.

    Example:

    >>> import ctypes as cts
    >>>
    >>>
    >>> SM_CXSCREEN = 0
    >>> SM_CYSCREEN = 1
    >>> SM_CXFULLSCREEN = 16
    >>> SM_CYFULLSCREEN = 17
    >>>
    >>> user32 = cts.windll.user32
    >>> GetSystemMetrics = user32.GetSystemMetrics
    >>>
    >>> # @TODO - cfati: Don't forget about the 2 lines below !!!
    >>> GetSystemMetrics.argtypes = (cts.c_int,)
    >>> GetSystemMetrics.restype = cts.c_int
    >>>
    >>> GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)  # Entire (primary) screen
    (1920, 1080)
    >>> GetSystemMetrics(SM_CXFULLSCREEN), GetSystemMetrics(SM_CYFULLSCREEN)  # Full screen window
    (1920, 1017)
    

    Regarding the @TODO in the code: check [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer) for a common pitfall when working with CTypes (calling functions).