Skip to content

Commit a7d816c

Browse files
committed
Improve window positioning checks by using minimised/maximised offsets.
Outlook kept getting restored to maximum and then moved 8px off center. This is because I was checking for `self.get_rect() == target_rect`, which doesn't account for the fact that maximised windows have an ~8px offset. To fix this, I've reused the code from `fits_display`.
1 parent b24f340 commit a7d816c

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

src/common.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -203,25 +203,46 @@ class WindowType(JSONType):
203203
placement: Placement
204204

205205
def fits_display(self, display: 'Display') -> bool:
206-
rect = self.rect
207-
if self.placement[1] == win32con.SW_SHOWMINIMIZED:
208-
rect = self.placement[4]
209-
if self.placement[1] == win32con.SW_SHOWMAXIMIZED:
210-
offset = 8
211-
else:
206+
"""
207+
Check whether `self` fits within the bounds of a display. This function uses
208+
`fits_rect` internally along with additional logic for checking if `self` is
209+
"snapped" to the display.
210+
"""
211+
offset = None
212+
if self.placement[1] not in (win32con.SW_SHOWMINIMIZED, win32con.SW_SHOWMAXIMIZED):
212213
# check if a window might be snapped and give it a bit more room
213214
if (
214215
abs(self.size[0] - (display.resolution[0] // 2)) <= 10
215216
or abs(self.size[1] - (display.resolution[1] // 2)) <= 10
216217
):
217218
offset = 5
218-
else:
219-
offset = 0
219+
return self.fits_rect(display.rect, offset)
220+
221+
def fits_rect(self, target_rect: Rect, offset: Optional[int] = None) -> bool:
222+
"""
223+
Check whether `self` fits within a rect. This function takes into
224+
account whether `self` is minimised, maximised or floating, and applies an
225+
appropriate offset.
226+
227+
Args:
228+
target_rect: the rect to check against `self`
229+
offset: pixel offset override
230+
"""
231+
rect = self.rect
232+
if self.placement[1] == win32con.SW_SHOWMINIMIZED:
233+
rect = self.placement[4]
234+
235+
if offset is None and self.placement[1] == win32con.SW_SHOWMAXIMIZED:
236+
offset = 8
237+
238+
if offset is None:
239+
offset = 0
240+
220241
return (
221-
rect[0] >= display.rect[0] - offset
222-
and rect[1] >= display.rect[1] - offset
223-
and rect[2] <= display.rect[2] + offset
224-
and rect[3] <= display.rect[3] + offset
242+
rect[0] >= target_rect[0] - offset
243+
and rect[1] >= target_rect[1] - offset
244+
and rect[2] <= target_rect[2] + offset
245+
and rect[3] <= target_rect[3] + offset
225246
)
226247

227248
def fits_display_config(self, displays: list['Display']) -> bool:
@@ -313,7 +334,7 @@ def move(self, coords: XandY, size: Optional[XandY] = None):
313334
size = size or self.get_size()
314335
target_rect: Rect = (*coords, coords[0] + size[0], coords[1] + size[1])
315336
tries = 0
316-
while self.get_rect() != target_rect and tries < 3:
337+
while not self.fits_rect(target_rect) and tries < 3:
317338
# multi-monitor setups with different scaling often don't resize the window properly first try
318339
# so we try multiple times and force repaints after the first one
319340
win32gui.MoveWindow(self.id, *coords, *size, tries > 1)

0 commit comments

Comments
 (0)