Under Windows I prefer to disable the window when the user trys to reposition the window, but apparently this is not a cross platform option. Another option, is to use the overrideredirect flag to abort the movement. Just to reposition the window to your desired location ends in flickering all over the screen. With overrideredirect you still experience a blinking but at the same location and it gives me the feel of trying to access a disabled window on MS-Windows where they blink the window.
The technique explained in little more depth:
- The Configure event is triggered when the user try to relocate the window
- The sequence
surpress_move is called and checks the event details to match the specific case we are looking for:
- First Condition the widget that calls is not a child of root, it hast to be the root window
- The x and y detail differ from our specified ones.
- We set the overrideredirect flag to true which results in an undecorated window (no titlebar) and therefore no movement, cause the movement isn't managed anymore, by the operating systems window manager.
- We relocate our Window back to our desired location and decorate the Window again.
Here is the code:
import tkinter as tk
XCOORD = 0
YCOORD = 0
def surpress_move(event):
if event.widget == root:
if event.x != XCOORD or event.y != YCOORD:
#event.widget.attributes('-disabled',True) #winows only
event.widget.overrideredirect(True)
event.widget.geometry(f'+{XCOORD}+{YCOORD}')
event.widget.overrideredirect(False)
#event.widget.attributes('-disabled',False)
root = tk.Tk()
root.bind('<Configure>',surpress_move)
root.mainloop()
If you want to work with tkinters anchor constants, you could do something like:
import tkinter as tk
root = tk.Tk()
def get_anchor_coords(anchor):
if anchor in ('NW',tk.NW):
return 0,0
elif anchor in ('NE',tk.NE):
return root.winfo_screenwidth-root.winfo_width(),0
###for South you should find the workspace or a constant for the taskbar
elif anchor in ('SW', tk.SW):
return 0,root.winfo_screenheight()-root.winfo_height()
elif anchor in ('SE', tk.SE):
return (root.winfo_screenwidth-root.winfo_width(),
root.winfo_screenheight()-root.winfo_height())
else:
raise ValueError(f'anchor: {repr(anchor)}, not recognized!')
def surpress_move(event, anchor):
if event.widget == root:
xy = event.x,event.y
anchor_coords = get_anchor_coords(anchor)
if xy != anchor_coords:
#event.widget.attributes('-disabled',True)
event.widget.overrideredirect(True)
event.widget.geometry(f'+{anchor_coords[0]}+{anchor_coords[1]}')
event.widget.overrideredirect(False)
#event.widget.attributes('-disabled',False)
root.bind('<Configure>',lambda e:surpress_move(e,'wW'))
root.mainloop()