Question: I have an overridredirect window that I need to resize on mouse drag. The example is functioning, but when I drag any of: sw, w, nw, n and ne handles it causes flicker (most noticeable when dragging fast). This is likely due to adjusting position and size simultaneously. I tried update_idletasks to see if that would smooth out the transition but, it didn't. import tkinter as tk class Box(tk.Tk): def __init__(self): super().__init__() self.drag_point_x = None self.drag_point_y = None self.drag_margin = 15 self.width = 400 self.height = 200 self.x = 300 self.y = 300 self.geometry(f"{self.width}x{self.height}+{self.x}+{self.y}") self.overrideredirect(1) self.bind("<B1-Motion>", self.on_dragging) self.bind("<Button-1>", self.on_click) self.bind("<Motion>", self.on_motion) def on_dragging(self, event): mouse_x = self.winfo_pointerx() mouse_y = self.winfo_pointery() delta_width = self.x - mouse_x delta_height = self.y - mouse_y if self.drag_point == 'e': self.width = mouse_x - self.x elif self.drag_point == 'se': self.width = mouse_x - self.x self.height = mouse_y - self.y elif self.drag_point == 's': self.height = mouse_y - self.y elif self.drag_point == 'sw': self.height = mouse_y - self.y self.width += delta_width self.x = mouse_x elif self.drag_point == 'w': self.width += delta_width self.x = mouse_x elif self.drag_point == 'nw': self.width += delta_width self.height += delta_height self.x = mouse_x self.y = mouse_y elif self.drag_point == 'n': self.height += delta_height self.y = mouse_y elif self.drag_point == 'ne': self.width = mouse_x - self.x self.height += delta_height self.y = mouse_y self.geometry(f"{self.width}x{self.height}+{self.x}+{self.y}") def on_click(self, event): self.drag_point_x = event.x self.drag_point_y = event.y def on_motion(self, event): if event.x < self.drag_margin: if event.y < self.drag_margin: self.config(cursor="size_nw_se") self.drag_point = "nw" elif event.y > self.height - self.drag_margin: self.config(cursor="size_ne_sw") self.drag_point = "sw" else: self.config(cursor="size_we") self.drag_point = "w" elif event.x > self.width - self.drag_margin: if event.y < self.drag_margin: self.config(cursor="size_ne_sw") self.drag_point = "ne" elif event.y > self.height - self.drag_margin: self.config(cursor="size_nw_se") self.drag_point = "se" else: self.config(cursor="size_we") self.drag_point = "e" elif event.y < self.drag_margin: self.config(cursor="size_ns") self.drag_point = "n" elif event.y > self.height - self.drag_margin: self.config(cursor="size_ns") self.drag_point = "s" else: self.config(cursor="") self.drag_point = None if __name__ == "__main__": box = Box() box.mainloop()  UPDATE: Here's code based on OneMadGypsy's solution that adds multiple monitor support: import tkinter as tk from PIL import ImageGrab from screeninfo import get_monitors class Overlay(tk.Toplevel): def __init__(self, monitor, overlays): tk.Toplevel.__init__(self) self.b_x = 0 self.b_y = 0 self.e_x = 0 self.e_y = 0 self.drag = False self.overlays = overlays self.monitor = monitor self.configure(cursor='cross') self.attributes('-alpha', 0.3) self.attributes('-topmost', True) self.overrideredirect(True) self.geometry(f"{self.monitor.width}x{self.monitor.height}+{self.monitor.x}+{self.monitor.y}") self.canvas = tk.Canvas(self, bg='dark gray') self.canvas.pack(fill='both', expand=True) self.canvas.bind('<B1-Motion>', self.on_drag) self.canvas.bind('<ButtonPress-1>', self.on_press) self.canvas.bind('<ButtonRelease-1>', self.on_release) rect = dict( outline='#0052d6', fill='white', tags='snip_rect', width=2, ) self.canvas.create_rectangle(0, 0, 0, 0, **rect) def on_press(self, event): self.b_x = event.x self.b_y = event.y def on_drag(self, event): self.drag = True self.e_x = event.x self.e_y = event.y self.canvas.coords('snip_rect', self.b_x, self.b_y, self.e_x, self.e_y) def on_release(self, event): self.destroy() for window in self.overlays: if window: window.destroy() self.overlays.clear() if not self.drag: return adjusted_b_x = self.b_x + self.monitor.x adjusted_b_y = self.b_y + self.monitor.y adjusted_e_x = self.e_x + self.monitor.x adjusted_e_y = self.e_y + self.monitor.y image = ImageGrab.grab(bbox=(min(adjusted_b_x, adjusted_e_x), min(adjusted_b_y, adjusted_e_y), max(adjusted_b_x, adjusted_e_x), max(adjusted_b_y, adjusted_e_y)), all_screens=True) image.show() class Snipper: def __init__(self): self.image = None self.overlays = [] def snip(self): monitors = get_monitors() for monitor in monitors: overlay = Overlay(monitor, self.overlays) self.overlays.append(overlay) if __name__ == '__main__': class App(tk.Tk): def __init__(self, **kwargs): tk.Tk.__init__(self, **kwargs) self.image = None self.windows = [] self.snipper = Snipper() tk.Button(self, text='snip', width=50, command=self.snipper.snip).pack() app = App() app.mainloop() 

Answer: Now that you have made it clear what you actually want to do, may I suggest this method. The short explanation is: When "snip" button is pressed, the entire screen is taken over by a semi-transparent tk.Toplevel with a tk.Canvas child. You drag out a square on the canvas (ie, no window resizing), and release to lock it in. Then click "save" to save the image within the rect you just drew. It doesn't have "after-the-fact" controls for adjustment but, it works very smooth and emulates much of what you explained in the comments. Use this code all you like and in any way you like. Please note that I wrote this like 5 years ago. I see things I would definitely do differently now, but it's all "code style" related. I don't see any major refactors here. import cv2 import numpy as np import tkinter as tk from os import mkdir, path, getcwd from time import strftime from PIL import ImageGrab class Button(tk.Button): def __init__(self, master, text, command, row, column, **kwargs): self.default = {**dict( foreground = 'gray60', background = 'gray10', activebackground = 'gray60', activeforeground = 'gray10', font = 'Helvetica 28 bold', padx = 10, pady = 10, border = 2, ), **kwargs} tk.Button.__init__(self, master, text=text, command=command, **self.default) self.grid(row=row, column=column, sticky='nswe') self.hover = self.default.copy() self.hover['background'] = 'steel blue' self.hover['foreground'] = 'black' self.bind("<Enter>", self.on_enter) self.bind("<Leave>", self.on_leave) def on_enter(self, event): if self['state'] != 'disabled': self.configure(**self.hover) def on_leave(self, event): self.configure(**self.default) class ScreenSnip(tk.Toplevel): def __init__(self, master): tk.Toplevel.__init__(self, master) #config toplevel self.configure(cursor='cross') self.attributes('-fullscreen', True) self.attributes('-alpha', 0.2) #init vars self.b_x = 0 self.b_y = 0 self.e_x = 0 self.e_y = 0 self.drag= False #create and config canvas self.canvas = tk.Canvas(self, bg='dark gray') self.canvas.pack(fill='both', expand=True) self.canvas.bind('<B1-Motion>', self.on_drag) self.canvas.bind('<ButtonPress-1>', self.on_press) self.canvas.bind('<ButtonRelease-1>', self.on_release) rect = dict( outline = '#0052d6', fill = 'white', tags = 'snip_rect', width = 2, ) self.canvas.create_rectangle(0, 0, 0, 0, **rect) def on_press(self, event): #store initial click coordinates self.b_x = event.x self.b_y = event.y def on_drag(self, event): #gather drag coordinates and tag current rect in canvas self.drag = True self.e_x = event.x self.e_y = event.y self.canvas.coords('snip_rect', self.b_x, self.b_y, self.e_x, self.e_y) def on_release(self, event): self.destroy() #if the user didn't drag, grab an 800x600 image with mouse position as center if not self.drag: self.b_x -= 400 self.b_y -= 300 self.e_x = self.b_x + 800 self.e_y = self.b_y + 600 #get image based on drag coordinates self.master.image = ImageGrab.grab(bbox=(min(self.b_x, self.e_x), min(self.b_y, self.e_y), max(self.b_x, self.e_x), max(self.b_y, self.e_y))) cv2.imshow('Captured Image Preview', cv2.cvtColor(np.array(self.master.image), cv2.COLOR_BGR2RGB)) class App(tk.Tk): def __init__(self, **kwargs): tk.Tk.__init__(self, **kwargs) #for storing a snip reference self.image = None #create directory to store snips, if it doesn't exist d = path.join(getcwd(), 'snips/') if not path.isdir(d): mkdir(d) #snip button Button(self, 'Snip', self.snip, 0, 0) #save button self.save_btn = Button(self, 'Save', self.save, 0, 1) self.save_btn.configure(state='disabled') def snip(self): self.save_btn.configure(state='normal') #enable save button ScreenSnip(self) #start snipper def save(self): cv2.destroyAllWindows() #destroy image preview #save image to disk and reset reference if self.image: self.image.save(f'snips/snip_{strftime("%a_%b_%d_%Y_%I_%M_%S")}.png') self.image = None if __name__ == '__main__': app = App() app.title("Snip-N-Save") app.resizable(width=False, height=False) app.mainloop()  It may be notable that you could use a hybrid version of your method and my method. You just need to adjust my code so you can adjust the rect. You aren't likely to get a bunch of "edge jumping" with a Canvas rect, and in the long run you don't need an entire window. You just need an adjustable rect. This could be that. If you don't like having a haze over the entire window while you make a selection, do this:  class ScreenSnip(tk.Toplevel): def __init__(self, master): tk.Toplevel.__init__(self, master) #this ~ you can use any color. I chose this one because it is not likely to be used with any seriousness. self.wm_attributes("-transparentcolor", '#000001') self['background'] = '#000001' ... #and this self.canvas = tk.Canvas(self, bg='#000001')  From this example, everything that is the color '#000001' will be transparent clean down to the desktop. Make sure your rect doesn't use that color and voila', you now have something that looks like what you already have, but it should work much better because you are just moving a rect around on a Canvas. Keep in mind that you will still have a tk.Toplevel covering your entire screen while in "select mode". In other words ... ::click, click, click:: "Why isn't my mouse working?" is in your future if you don't keep this in mind.