From c6783b703779cba3033b064b063aa6d90d7ddfd9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Dec 2023 23:47:59 +0530 Subject: [PATCH] Avoid flashing during startup due to cover browser During startup while the multiple resizes due to the various splitters adjusting their sizes happens, paint the cover browser in the window background color to avoid flashing. --- src/calibre/gui2/cover_flow.py | 29 ++++++++++++++++++++++++++--- src/calibre/gui2/widgets.py | 13 +++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/cover_flow.py b/src/calibre/gui2/cover_flow.py index b527947747..67b448e7a6 100644 --- a/src/calibre/gui2/cover_flow.py +++ b/src/calibre/gui2/cover_flow.py @@ -13,12 +13,13 @@ import os import sys import time from qt.core import ( - QAction, QApplication, QDialog, QFont, QImage, QItemSelectionModel, - QKeySequence, QLabel, QSize, QSizePolicy, QStackedLayout, Qt, QTimer, pyqtSignal + QAction, QApplication, QDialog, QFont, QImage, QItemSelectionModel, QKeySequence, + QLabel, QPainter, QPalette, QSize, QSizePolicy, QStackedLayout, Qt, QTimer, + pyqtSignal, ) from calibre.constants import islinux -from calibre.ebooks.metadata import rating_to_stars, authors_to_string +from calibre.ebooks.metadata import authors_to_string, rating_to_stars from calibre.gui2 import config, gprefs, rating_font from calibre_extensions import pictureflow @@ -186,10 +187,32 @@ class CoverFlow(pictureflow.PictureFlow): dc_signal = pyqtSignal() context_menu_requested = pyqtSignal() + _ignore_paint_events = False + + @property + def ignore_paint_events(self): + return self._ignore_paint_events + + @ignore_paint_events.setter + def ignore_paint_events(self, val): + if val != self._ignore_paint_events: + self._ignore_paint_events = val + if not val: + self.update() + + def paintEvent(self, ev): + if self.ignore_paint_events and time.monotonic() - self.created_at < 1: + # Paint blank during startup to avoid flashing + p = QPainter(self) + p.fillRect(self.rect(), self.palette().color(QPalette.ColorRole.Window)) + p.end() + else: + super().paintEvent(ev) def __init__(self, parent=None): pictureflow.PictureFlow.__init__(self, parent, config['cover_flow_queue_length']+1) + self.created_at = time.monotonic() self.setMinimumSize(QSize(300, 150)) self.setFocusPolicy(Qt.FocusPolicy.WheelFocus) self.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 033431388a..9cbac3049a 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -1246,6 +1246,11 @@ class Splitter(QSplitter): # when the event loop ticks self.reapply_sizes.emit(sizes) + def ignore_child_paints(self, ignore=True): + for widget in self: + if hasattr(widget, 'ignore_paint_events'): + widget.ignore_paint_events = ignore + def do_resize(self, *args): orig = self.desired_side_size super().resizeEvent(self._resize_ev) @@ -1254,10 +1259,14 @@ class Splitter(QSplitter): while abs(self.side_index_size - orig) > 10 and c < 5: self.apply_state(self.get_state(), save_desired=False) c += 1 + self.ignore_child_paints(False) + + def __iter__(self): + for i in range(self.count()): + yield self.widget(i) def resizeEvent(self, ev): - if self.resize_timer.isActive(): - self.resize_timer.stop() + self.ignore_child_paints() self._resize_ev = ev self.resize_timer.start()