More work on geometry restoration

This commit is contained in:
Kovid Goyal 2022-10-18 14:12:11 +05:30
parent e53948ca39
commit 0f05cf7655
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -13,18 +13,31 @@ from calibre.constants import DEBUG
def debug(*a, **kw): def debug(*a, **kw):
if DEBUG: if DEBUG:
from pprint import pprint from pprint import pformat
pprint(*a, **kw) items = []
for x in a:
if not isinstance(x, str):
x = pformat(x)
items.append(x)
print(*items)
def size_as_dict(self: QSize): def size_as_dict(self: QSize):
return {'width': self.width(), 'height': self.height()} return {'width': self.width(), 'height': self.height()}
def dict_as_size(x: dict) -> QSize:
return QSize(x['width'], x['height'])
def rect_as_dict(self: QRect): def rect_as_dict(self: QRect):
return {'x': self.left(), 'y': self.top(), 'width': self.width(), 'height': self.height()} return {'x': self.left(), 'y': self.top(), 'width': self.width(), 'height': self.height()}
def dict_as_rect(g: dict) -> QRect:
return QRect(g['x'], g['y'], g['width'], g['height'])
def screen_as_dict(self: QScreen): def screen_as_dict(self: QScreen):
try: try:
num = QApplication.instance().screens().index(self) num = QApplication.instance().screens().index(self)
@ -65,16 +78,17 @@ def save_geometry(self: QWidget, prefs: dict, name: str):
if DEBUG: if DEBUG:
debug('Saving geometry for:', name) debug('Saving geometry for:', name)
debug(x) debug(x)
x['qt'] = bytearray(self.saveGeometry())
prefs.set(f'geometry-of-{name}', x) prefs.set(f'geometry-of-{name}', x)
def find_matching_screen(screen_as_dict): def find_matching_screen(screen_as_dict):
screens = QApplication.instance().screens() screens = QApplication.instance().screens()
size = QSize(**screen_as_dict['size']) size = dict_as_size(screen_as_dict['size_in_logical_pixels'])
vg = QRect(**screen_as_dict['virtual_geometry']) vg = dict_as_rect(screen_as_dict['virtual_geometry'])
dpr = screen_as_dict['device_pixel_ratio']
screens_of_matching_size = tuple( screens_of_matching_size = tuple(
s for s in screens if s for s in screens if s.size() == size and vg == s.virtualGeometry() and s.devicePixelRatio() == dpr)
s.size() == size and vg == s.virtualGeometry() and s.devicePixelRatio() == screen_as_dict['device_pixel_ratio'])
if screen_as_dict['serial']: if screen_as_dict['serial']:
for q in screens_of_matching_size: for q in screens_of_matching_size:
if q.serialNumber() == screen_as_dict['serial']: if q.serialNumber() == screen_as_dict['serial']:
@ -89,7 +103,7 @@ def find_matching_screen(screen_as_dict):
return q return q
def _do_restore(self: QWidget, s: QScreen, geometry: QRect, x: dict): def _do_restore(self: QWidget, s: QScreen, geometry: QRect, saved_data: dict):
ws = self.windowState() ws = self.windowState()
if ws & (Qt.WindowState.WindowFullScreen | Qt.WindowState.WindowMaximized): if ws & (Qt.WindowState.WindowFullScreen | Qt.WindowState.WindowMaximized):
debug('Not restoring geometry as widget is already maximized or fullscreen') debug('Not restoring geometry as widget is already maximized or fullscreen')
@ -97,27 +111,25 @@ def _do_restore(self: QWidget, s: QScreen, geometry: QRect, x: dict):
if self.screen() is not s: if self.screen() is not s:
debug('Moving widget to saved screen') debug('Moving widget to saved screen')
self.setScreen(s) self.setScreen(s)
debug('Setting widget geometry to:', geometry) debug('Setting widget geometry to:', rect_as_dict(geometry))
self.setGeometry(geometry) self.setGeometry(geometry)
if x['full_screened']: if saved_data['full_screened']:
debug('Restoring widget to full screen') debug('Restoring widget to full screen')
self.showFullScreen() self.showFullScreen()
elif x['maximized']: elif saved_data['maximized']:
debug('Restoring widget to maximized') debug('Restoring widget to maximized')
self.showMaximized() self.showMaximized()
return True return True
def _restore_to_matching_screen(self: QWidget, s: QScreen, saved_data: dict) -> bool: def _restore_to_matching_screen(self: QWidget, s: QScreen, saved_data: dict) -> bool:
x = saved_data saved_geometry = dict_as_rect(saved_data['geometry'])
saved_geometry = QRect(**x['geometry']) return _do_restore(self, s, saved_geometry, saved_data)
return _do_restore(self, s, saved_geometry, x)
def _restore_to_new_screen(self: QWidget, s: QScreen, saved_data: dict) -> bool: def _restore_to_new_screen(self: QWidget, s: QScreen, saved_data: dict) -> bool:
x = saved_data saved_geometry = dict_as_rect(saved_data['geometry'])
saved_geometry = QRect(**x['geometry']) saved_frame_geometry = dict_as_rect(saved_data['frame_geometry'])
saved_frame_geometry = QRect(**x['frame_geometry'])
if not saved_geometry.isValid() or not saved_frame_geometry.isValid(): if not saved_geometry.isValid() or not saved_frame_geometry.isValid():
return False return False
frame_height = max(0, saved_frame_geometry.height() - saved_geometry.height()) frame_height = max(0, saved_frame_geometry.height() - saved_geometry.height())
@ -130,7 +142,7 @@ def _restore_to_new_screen(self: QWidget, s: QScreen, saved_data: dict) -> bool:
max_left = available_geometry.left() + (available_size.width() - sz.width()) max_left = available_geometry.left() + (available_size.width() - sz.width())
max_top = available_geometry.top() + (available_size.height() - sz.height()) max_top = available_geometry.top() + (available_size.height() - sz.height())
geometry = QRect(min(saved_geometry.left(), max_left), min(saved_geometry.top(), max_top), sz.width(), sz.height()) geometry = QRect(min(saved_geometry.left(), max_left), min(saved_geometry.top(), max_top), sz.width(), sz.height())
return _do_restore(self, s, geometry, x) return _do_restore(self, s, geometry, saved_data)
def _restore_geometry(self: QWidget, prefs: dict, name: str) -> bool: def _restore_geometry(self: QWidget, prefs: dict, name: str) -> bool:
@ -139,7 +151,9 @@ def _restore_geometry(self: QWidget, prefs: dict, name: str) -> bool:
return False return False
if DEBUG: if DEBUG:
debug('Restoring geometry for:', name) debug('Restoring geometry for:', name)
debug(x) dx = x.copy()
del dx['qt']
debug(dx)
s = find_matching_screen(x['screen']) s = find_matching_screen(x['screen'])
debug('Matching screen:', screen_as_dict(s) if s else None) debug('Matching screen:', screen_as_dict(s) if s else None)
if s is None: if s is None: