Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions umalauncher/carrotjuicer.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def open_helper(self):

def get_browser_reset_position(self):
if self.threader.windowmover.window is None:
return None
return [0, 0, 720, 480]
game_rect, _ = self.threader.windowmover.window.get_rect()
workspace_rect = self.threader.windowmover.window.get_workspace_rect()
left_side = abs(workspace_rect[0] - game_rect[0])
Expand All @@ -178,7 +178,18 @@ def get_browser_reset_position(self):
else:
left_x = game_rect[2] + 5
width = right_side
return [left_x, workspace_rect[1], width, workspace_rect[3] - workspace_rect[1] + 6]
height = workspace_rect[3] - workspace_rect[1] + 6
# Enforce a 100-pixel minimum width and height
if width < 100:
width = 100
if height < 100:
height = 100
rect = [left_x, workspace_rect[1], width, height]
if util.rect_is_onscreen( rect ):
return rect
else:
return util.move_rect_to_screen(rect)



def close_browser(self):
Expand All @@ -190,6 +201,7 @@ def close_browser(self):

def save_rect(self, rect_var, setting):
if rect_var:
#TODO: actually check window dimensions
if (rect_var['x'] == -32000 and rect_var['y'] == -32000):
logger.warning(f"Browser minimized, cannot save position for {setting}: {rect_var}")
rect_var = None
Expand Down
49 changes: 49 additions & 0 deletions umalauncher/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,55 @@ def monitor_from_window(*args, **kwargs):
except pywinerror:
return None

def get_monitor_from_point(*args, **kwargs):
try:
return win32api.MonitorFromPoint(*args, **kwargs)
except pywinerror:
return None

def rect_is_onscreen(rect):
top_left = (rect[0], rect[1])
top_right = (rect[0] + rect[2], rect[1])
bottom_left = (rect[0], rect[1] + rect[3])
bottom_right = (rect[0] + rect[2], rect[1] + rect[3])
return get_monitor_from_point(top_left) is not None \
and get_monitor_from_point(top_right) is not None \
and get_monitor_from_point(bottom_left) is not None \
and get_monitor_from_point(bottom_right)

def move_rect_to_screen(rect):
if rect_is_onscreen(rect):
return rect

#TODO: this is nasty AI-generated code that I haven't looked at too closely

# Get closest monitor for top-left corner
monitor = get_monitor_from_point((rect[0], rect[1]))
if monitor is None:
# Try top-right corner
monitor = get_monitor_from_point((rect[0] + rect[2], rect[1]))

if monitor is None:
# Both top corners are offscreen, move them onscreen
monitor = get_monitor_from_point((rect[0], rect[1]), win32con.MONITOR_DEFAULTTONEAREST)
monitor_info = get_monitor_info(monitor)
if not monitor_info:
logger.error("Cannot get monitor info.")
# raise Exception("Cannot get monitor info.")
monitor_info = {"Work": (0, 0, 1920, 1080)}
work_area = monitor_info.get("Work")

# Calculate new position while preserving dimensions
new_x = max(work_area[0], min(work_area[2] - rect[2], rect[0]))
new_y = max(work_area[1], min(work_area[3] - rect[3], rect[1]))

return [new_x, new_y, rect[2], rect[3]]
else:
# Both top corners are onscreen, should be visible
return rect



def get_monitor_info(*args, **kwargs):
try:
return win32api.GetMonitorInfo(*args, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion umalauncher/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import gui
import glob

VERSION = "1.17.13"
VERSION = "1.17.14"

def parse_version(version_string: str):
"""Convert version string to tuple."""
Expand Down
23 changes: 22 additions & 1 deletion umalauncher/windowmover.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os
import time

import win32con
from loguru import logger
import util
import win32gui
Expand Down Expand Up @@ -45,8 +47,27 @@ def set_pos(self, pos, is_portrait):

return success

def is_window_onscreen(self):
return util.monitor_from_window(self.handle, win32con.MONITOR_DEFAULTTONULL) is not None

def move_window_onscreen(self):
if not self.is_window_onscreen():
nearest_monitor = util.monitor_from_window(self.handle, win32con.MONITOR_DEFAULTTONEAREST)
if not nearest_monitor:
logger.error("Cannot determine monitor nearest to game window.")
return False
monitor_info = util.get_monitor_info(nearest_monitor)
if not monitor_info:
logger.error("Cannot get monitor info.")
# raise Exception("Cannot get monitor info.")
return False
monitor_rect = monitor_info.get("Work")
prev_rect = util.get_window_rect(self.handle)
util.move_window(self.handle, monitor_rect[0], monitor_rect[1], prev_rect[2], prev_rect[3], True )
return True

def get_workspace_rect(self):
monitor = util.monitor_from_window(self.handle)
monitor = util.monitor_from_window(self.handle, win32con.MONITOR_DEFAULTTOPRIMARY)
if not monitor:
logger.error("Cannot determine monitor used by game window.")
# raise Exception("Cannot determine monitor used by game window.")
Expand Down