How do I calculate the rectangles of the window decoration / taskbar / titlebar in tkinter

29 Views Asked by At

Many questions on this site asking about the height of the titlebar or the taskbar in tkinter.
Often is the answer simply no or there are platform specific calls to the window-manager.
So this question is about having a work-around for a cross-platform way to obtain these values.

Does someone has an answer to it ?

Examples:
How to get the height of a tkinter window title bar
Python/tkinter - How do I get the window size including borders on Windows?
How do I create a new python tkinter window so fits exactly in the available desktop area, but isn't maximized?

1

There are 1 best solutions below

0
Thingamabobs On BEST ANSWER

You can use this formula, it takes advantage of the fact that the window manager will size your window appropriately by maximizing it. By spanning a frame into the client area you get the client you can measure from the client area y point in screen coordinates to the y point of the window in screen coordinates. Therefore you can get the height of the titlebar and are able to calculate the points for the working area of your desktop, therefore you can calculate the taskbar.

By using wax1 and way1 this small script tries to take care of the possibility of having multiple screens. However this script was only tested on Windows11 and a single display.

Those 3 rectangles in the end has the form of (x1,y1, width, height) as it is usual in tkinter.

import tkinter as tk
import sys

root = tk.Tk()

f = tk.Frame(root, bg='orange')
f.place(relwidth=1,relheight=1, relx=0,rely=0)

if sys.platform == "win32":
    root.state('zoomed')
else:
    root.wm_attributes('-zoomed', True)
root.update()
bd      = borderwidth           = root.winfo_rootx()-root.winfo_x()
tbh     = titlebarheight        = f.winfo_rooty()-root.winfo_y()-bd
wax1    = working_area_x1       = root.winfo_x()+bd
way1    = working_area_y1       = root.winfo_rooty()-tbh
wax2    = working_area_x2       = wax1+root.winfo_width()
way2    = working_area_y2       = way1+root.winfo_height() + tbh
waw     = working_area_width    = wax1+root.winfo_width() - wax1
wah     = working_area_height   = way1+root.winfo_height() - way1 + tbh
if root.winfo_screenheight()-wah:
    tko = taskbar_offset = root.winfo_screenheight()-wah
    if way2+tko == root.winfo_screenheight():
        tkrect = wax1,way2,waw,tko
        screct = wax1,way1,waw,way2+tko
    else:#up
        tkrect = wax1,way1-tko,waw,tko
        screct = wax1,way1-tko,waw,way2
elif root.winfo_screenwidth()-waw:
    tko = taskbar_offset = root.winfo_screenwidth()-waw
    if wax2+tko == root.winfo_screenwidth():
        tkrect = wax2,way1,tko,wah
        screct = wax1,way1,wax2+tko,wah
    else:#left
        tkrect = wax1-tko,way1,tko,wah
        screct = wax1-tko,way1,wax2,wah
tkrect = taskbar_rect       = tkrect
warect = working_area_rect  = wax1, way1, waw, wah
screct = screen_rect        = screct

if sys.platform == "win32":
    root.state('normal')
else:
    root.wm_attributes('-zoomed', False)
print(tkrect, warect, screct)
root.mainloop()