Skip to content

Commit 491c63c

Browse files
committed
Popup Positioning
1 parent 61aaeee commit 491c63c

File tree

2 files changed

+91
-24
lines changed

2 files changed

+91
-24
lines changed

subtitle_popup.py

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
QWidget, QHBoxLayout, QVBoxLayout, QListWidget, QLabel, QPushButton,
55
QFrame, QGridLayout, QApplication
66
)
7-
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QPoint
7+
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QPoint, QRect
88
from PyQt6.QtGui import QIcon
99

1010
from translator import tr
@@ -236,16 +236,37 @@ def _show_color_palette(self, target_btn, current_color, signal_name, colors):
236236
btn.clicked.connect(lambda checked, c=color: self._apply_color(c, target_btn, signal_name, palette))
237237
layout.addWidget(btn, row, col)
238238

239+
palette.ensurePolished()
239240
palette.adjustSize()
240-
pos = target_btn.mapToGlobal(QPoint(0, target_btn.height() + 5))
241241

242-
target_x = pos.x()
243-
target_y = pos.y()
242+
# Determine current screen based on button center
243+
btn_center_global = target_btn.mapToGlobal(target_btn.rect().center())
244+
screen = QApplication.screenAt(btn_center_global)
245+
if not screen:
246+
screen = self.window().screen() if self.window() else QApplication.primaryScreen()
247+
248+
screen_geo = screen.availableGeometry()
249+
250+
# Use the absolute maximum possible width/height for safest clamping
251+
pw = max(palette.width(), palette.sizeHint().width(), palette.minimumWidth())
252+
ph = max(palette.height(), palette.sizeHint().height(), palette.minimumHeight())
253+
254+
btn_rect_global = QRect(target_btn.mapToGlobal(QPoint(0, 0)), target_btn.size())
255+
target_x = btn_rect_global.left()
256+
target_y = btn_rect_global.bottom() + 5
257+
258+
# Clamp strictly within available geometry
259+
margin_x = 20
260+
margin_right = 30
261+
margin_top = 20
244262

245-
# Screen boundary check
246-
screen = self.screen().availableGeometry()
247-
target_x = max(screen.left(), min(target_x, screen.right() - palette.width()))
248-
target_y = max(screen.top(), min(target_y, screen.bottom() - palette.height()))
263+
min_x = screen_geo.left() + margin_x
264+
max_x = screen_geo.left() + screen_geo.width() - pw - margin_right
265+
min_y = screen_geo.top() + margin_top
266+
max_y = screen_geo.top() + screen_geo.height() - ph # No bottom margin
267+
268+
target_x = max(min_x, min(target_x, max_x))
269+
target_y = max(min_y, min(target_y, max_y))
249270

250271
palette.move(target_x, target_y)
251272
palette.show()
@@ -393,17 +414,40 @@ def show_popup(self):
393414
return
394415

395416
# Position popup above the button
396-
self.popup.adjustSize()
397417
self.popup.setSubtitlesEnabled(self.subtitles_enabled)
398-
pos = self.mapToGlobal(QPoint(0, 0))
418+
self.popup.ensurePolished()
419+
self.popup.adjustSize()
420+
421+
# Determine current screen based on button center
422+
button_rect_global = QRect(self.mapToGlobal(QPoint(0, 0)), self.size())
423+
button_center_global = button_rect_global.center()
424+
425+
screen = QApplication.screenAt(button_center_global)
426+
if not screen:
427+
screen = self.window().screen() if self.window() else QApplication.primaryScreen()
428+
429+
screen_geo = screen.availableGeometry()
430+
431+
# Use adjusted size directly
432+
pw = self.popup.width()
433+
ph = self.popup.height()
434+
435+
# Calculate ideal target (above button)
436+
target_x = button_center_global.x() - pw // 2
437+
target_y = button_rect_global.top() - ph - 5
438+
439+
# Clamp strictly within available geometry
440+
margin_x = 20
441+
margin_right = 30
442+
margin_top = 20
399443

400-
target_x = pos.x() + (self.width() - self.popup.width()) // 2
401-
target_y = pos.y() - self.popup.height() - 5
444+
min_x = screen_geo.left() + margin_x
445+
max_x = screen_geo.left() + screen_geo.width() - pw - margin_right
446+
min_y = screen_geo.top() + margin_top
447+
max_y = screen_geo.top() + screen_geo.height() - ph # No bottom margin
402448

403-
# Screen boundary check
404-
screen = self.screen().availableGeometry()
405-
target_x = max(screen.left(), min(target_x, screen.right() - self.popup.width()))
406-
target_y = max(screen.top(), min(target_y, screen.bottom() - self.popup.height()))
449+
target_x = max(min_x, min(target_x, max_x))
450+
target_y = max(min_y, min(target_y, max_y))
407451

408452
self.popup.move(target_x, target_y)
409453
self.popup.show()

volume_popup.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
QWidget, QHBoxLayout, QVBoxLayout, QLabel, QListWidget, QFrame,
55
QSlider, QPushButton, QApplication
66
)
7-
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QPoint
7+
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QPoint, QRect
88
from PyQt6.QtGui import QIcon
99

1010
from translator import tr
@@ -253,16 +253,39 @@ def show_popup(self):
253253
return
254254

255255
# Position popup above the button
256+
self.popup.ensurePolished()
256257
self.popup.adjustSize()
257-
pos = self.mapToGlobal(QPoint(0, 0))
258258

259-
target_x = pos.x() + (self.width() - self.popup.width()) // 2
260-
target_y = pos.y() - self.popup.height() - 5
259+
# Determine current screen based on button center
260+
button_rect_global = QRect(self.mapToGlobal(QPoint(0, 0)), self.size())
261+
button_center_global = button_rect_global.center()
261262

262-
# Screen boundary check
263-
screen = self.screen().availableGeometry()
264-
target_x = max(screen.left(), min(target_x, screen.right() - self.popup.width()))
265-
target_y = max(screen.top(), min(target_y, screen.bottom() - self.popup.height()))
263+
screen = QApplication.screenAt(button_center_global)
264+
if not screen:
265+
screen = self.window().screen() if self.window() else QApplication.primaryScreen()
266+
267+
screen_geo = screen.availableGeometry()
268+
269+
# Use adjusted size directly
270+
pw = self.popup.width()
271+
ph = self.popup.height()
272+
273+
# Calculate ideal target (above center)
274+
target_x = button_center_global.x() - pw // 2
275+
target_y = button_rect_global.top() - ph - 5
276+
277+
# Clamp strictly within available geometry with 20px safety margin (30px on right)
278+
margin_x = 20
279+
margin_right = 30
280+
margin_top = 20
281+
282+
min_x = screen_geo.left() + margin_x
283+
max_x = screen_geo.left() + screen_geo.width() - pw - margin_right
284+
min_y = screen_geo.top() + margin_top
285+
max_y = screen_geo.top() + screen_geo.height() - ph
286+
287+
target_x = max(min_x, min(target_x, max_x))
288+
target_y = max(min_y, min(target_y, max_y))
266289

267290
self.popup.move(target_x, target_y)
268291
self.popup.show()

0 commit comments

Comments
 (0)