Skip to content

Commit 3c789b4

Browse files
shymegaclaude
andcommitted
Position popup windows on the screen where the mouse cursor is located
Adds get_mouse_location() function that uses tkinter to get the current mouse position, then passes this location to PySimpleGUI windows so they appear on the active screen in multi-monitor setups. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent d92506b commit 3c789b4

3 files changed

Lines changed: 62 additions & 7 deletions

File tree

src/coreutils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from typing import (
1111
Callable,
1212
Optional,
13+
Tuple,
1314
Union,
1415
List,
1516
Any,
@@ -22,6 +23,32 @@
2223
read_file,
2324
)
2425

26+
27+
def get_mouse_location(
28+
window_width: int = 400, window_height: int = 200
29+
) -> Optional[Tuple[int, int]]:
30+
"""Get a location to center a window on the mouse position.
31+
32+
Args:
33+
window_width: Estimated window width for centering calculation.
34+
window_height: Estimated window height for centering calculation.
35+
36+
Returns:
37+
Tuple of (x, y) coordinates that will center a window of the given
38+
dimensions on the current mouse position, or None if unavailable.
39+
"""
40+
try:
41+
import tkinter as tk
42+
43+
root = tk.Tk()
44+
root.withdraw()
45+
x = root.winfo_pointerx()
46+
y = root.winfo_pointery()
47+
root.destroy()
48+
return (x - window_width // 2, y - window_height // 2)
49+
except Exception:
50+
return None
51+
2552
if getattr(sys, "frozen", False):
2653
SCRIPT_IMP_FILE = os.path.realpath(sys.executable)
2754
else:
@@ -178,19 +205,22 @@ def show_message(
178205
close = True
179206
if timeout == None:
180207
close = False
208+
location = get_mouse_location()
181209
if yesno:
182210
response = sg.popup_yes_no(
183211
message,
184212
title=title,
185213
auto_close=close,
186214
auto_close_duration=timeout,
215+
location=location,
187216
)
188217
else:
189218
response = sg.popup_ok(
190219
message,
191220
title=title,
192221
auto_close=close,
193222
auto_close_duration=timeout,
223+
location=location,
194224
)
195225
return response
196226

@@ -467,6 +497,7 @@ def popup_options(
467497
finalize=True,
468498
auto_close=close,
469499
auto_close_duration=timeout,
500+
location=get_mouse_location(),
470501
)
471502

472503
# Event loop to process button clicks
@@ -508,6 +539,7 @@ def get_user_input(
508539
finalize=True,
509540
auto_close=close,
510541
auto_close_duration=timeout,
542+
location=get_mouse_location(),
511543
)
512544

513545
# Event loop to process button clicks and input

src/mainutils.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
cache,
2727
log,
2828
http_get,
29+
get_mouse_location,
2930
)
3031

3132
if getattr(sys, "frozen", False):
@@ -171,7 +172,9 @@ def popup_execute(
171172
text_str = [""]
172173
text = sg.Multiline("", disabled=True, autoscroll=True, size=(80, 30))
173174
layout = [[text]]
174-
window = sg.Window(title, layout, finalize=True)
175+
window = sg.Window(
176+
title, layout, finalize=True, location=get_mouse_location(640, 480)
177+
)
175178
exitcode = [-1]
176179

177180
def process_func() -> None:
@@ -242,7 +245,9 @@ def popup_download(title: str, link: str, file_name: str) -> str:
242245
progress = sg.ProgressBar(100, orientation="h", s=(50, 10))
243246
text = sg.Text("0%")
244247
layout = [[progress], [text]]
245-
window = sg.Window(title, layout, finalize=True)
248+
window = sg.Window(
249+
title, layout, finalize=True, location=get_mouse_location(400, 100)
250+
)
246251

247252
def update_log(status: list[int], dl: int, total: int) -> None:
248253
status.clear()
@@ -341,7 +346,12 @@ def update_progress(percentage: int) -> None:
341346
text = sg.Text("0%")
342347
extra = sg.Text("Reading directory, please wait...")
343348
layout = [[extra], [progress], [text]]
344-
window = sg.Window("De-referencing Links", layout, finalize=True)
349+
window = sg.Window(
350+
"De-referencing Links",
351+
layout,
352+
finalize=True,
353+
location=get_mouse_location(400, 120),
354+
)
345355
window.refresh()
346356

347357
window.perform_long_operation(dereference_links, "-DEREF DONE-")
@@ -477,10 +487,11 @@ def copy_files() -> None:
477487
extra = sg.Text("Reading prefix directory, please wait...")
478488
layout = [[extra], [progress], [text]]
479489

490+
location = get_mouse_location(400, 120)
480491
if zipup:
481-
window = sg.Window("Copying Prefix", layout, finalize=True)
492+
window = sg.Window("Copying Prefix", layout, finalize=True, location=location)
482493
else:
483-
window = sg.Window("Zipping File", layout, finalize=True)
494+
window = sg.Window("Zipping File", layout, finalize=True, location=location)
484495

485496
window.refresh()
486497
window.perform_long_operation(copy_files, "-COPY DONE-")
@@ -563,7 +574,12 @@ def unpack_files() -> None:
563574
text = sg.Text("0% (0/?)")
564575
extra = sg.Text("Reading ZIP file, please wait...")
565576
layout = [[extra], [progress], [text]]
566-
window = sg.Window("Unpacking Prefix", layout, finalize=True)
577+
window = sg.Window(
578+
"Unpacking Prefix",
579+
layout,
580+
finalize=True,
581+
location=get_mouse_location(400, 120),
582+
)
567583
window.refresh()
568584

569585
window.perform_long_operation(unpack_files, "-UNPACK DONE-")

src/setup.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
pip,
1313
exit_with_message,
1414
http_get,
15+
get_mouse_location,
1516
)
1617

1718
from corenodep import (
@@ -61,6 +62,7 @@ def welcome() -> bool:
6162
title="WeMod Launcher Setup",
6263
image=wemod_logo.content,
6364
icon=wemod_logo.content,
65+
location=get_mouse_location(450, 300),
6466
)
6567
return ret == "OK"
6668

@@ -76,7 +78,12 @@ def download_wemod(temp_dir: str) -> str:
7678
text = sg.Text("0%")
7779
# text = sg.Multiline(str.join("", log), key="-LOG-", autoscroll=True, size=(50,50), disabled=True)
7880
layout = [[progress], [text]]
79-
window = sg.Window("Downloading WeMod", layout, finalize=True)
81+
window = sg.Window(
82+
"Downloading WeMod",
83+
layout,
84+
finalize=True,
85+
location=get_mouse_location(400, 100),
86+
)
8087

8188
def update_log(status: list[int], dl: int, total: int) -> None:
8289
status.clear()

0 commit comments

Comments
 (0)