Rather than recreating QTimer objects on every update use a single one per context

Also change the timeout to 100ms which is the commonly accepted
threshold for human visual response. And stop the book details panel
debounce timer during shutdown.

The debounce timers in the popups are independent and use only data
local to the popup object so probably dont need to be shutdown.
This commit is contained in:
Kovid Goyal 2024-03-04 21:31:07 +05:30
parent 09cc050c0a
commit 7059a322a0
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 31 additions and 23 deletions

View File

@ -47,6 +47,7 @@ from polyglot.builtins import iteritems, string_or_bytes
del pqc, geometry_for_restore_as_dict
NO_URL_FORMATTING = QUrl.UrlFormattingOption.None_
BOOK_DETAILS_DISPLAY_DEBOUNCE_DELAY = 100 # 100 ms is threshold for human visual response
class IconResourceManager:

View File

@ -4,7 +4,6 @@
import textwrap
from enum import IntEnum
from functools import partial
from qt.core import (
QAction, QApplication, QBrush, QCheckBox, QDialog, QDialogButtonBox, QGridLayout,
@ -16,6 +15,7 @@ from qt.core import (
from calibre import fit_image
from calibre.db.constants import RESOURCE_URL_SCHEME
from calibre.gui2 import NO_URL_FORMATTING, gprefs
from calibre.gui2 import BOOK_DETAILS_DISPLAY_DEBOUNCE_DELAY
from calibre.gui2.book_details import (
create_open_cover_with_menu, resolved_css, details_context_menu_event, render_html, set_html,
)
@ -24,8 +24,6 @@ from calibre.gui2.widgets import CoverView
from calibre.gui2.widgets2 import Dialog, HTMLDisplay
from calibre.startup import connect_lambda
BOOK_DETAILS_DISPLAY_DELAY = 250 # 250ms is arbitrary
class Cover(CoverView):
@ -225,7 +223,10 @@ class BookInfo(QDialog):
self.path_to_book = None
self.current_row = None
self.slave_connected = False
self.slave_debounce_timer = QTimer()
self.slave_debounce_timer = t = QTimer(self)
t.setInterval(BOOK_DETAILS_DISPLAY_DEBOUNCE_DELAY)
t.setSingleShot(True)
t.timeout.connect(self._debounce_refresh)
if library_path is not None:
self.view = None
db = get_gui().library_broker.get_library(library_path)
@ -349,13 +350,11 @@ class BookInfo(QDialog):
QTimer.singleShot(1, self.resize_cover)
def slave(self, mi):
self.slave_debounce_timer.stop()
t = self.book_display_info_timer = QTimer()
t.setSingleShot(True)
t.timeout.connect(partial(self._timed_slave, mi))
t.start(BOOK_DETAILS_DISPLAY_DELAY)
self._mi_for_debounce = mi
self.slave_debounce_timer.start() # start() will automatically reset the timer if it was already running
def _timed_slave(self, mi):
def _debounce_refresh(self):
mi, self._mi_for_debounce = self._mi_for_debounce, None
self.refresh(mi.row_number, mi)
def move(self, delta=1):

View File

@ -18,7 +18,9 @@ from qt.core import (
from calibre import force_unicode
from calibre.constants import filesystem_encoding, islinux
from calibre.gui2 import FunctionDispatcher, error_dialog, gprefs
from calibre.gui2 import (
BOOK_DETAILS_DISPLAY_DEBOUNCE_DELAY, FunctionDispatcher, error_dialog, gprefs,
)
from calibre.gui2.dialogs.enum_values_edit import EnumValuesEdit
from calibre.gui2.gestures import GestureManager
from calibre.gui2.library import DEFAULT_SORT
@ -27,9 +29,9 @@ from calibre.gui2.library.alternate_views import (
)
from calibre.gui2.library.delegates import (
CcBoolDelegate, CcCommentsDelegate, CcDateDelegate, CcEnumDelegate,
CcLongTextDelegate, CcMarkdownDelegate, CcNumberDelegate, CcSeriesDelegate, CcTemplateDelegate,
CcTextDelegate, CompleteDelegate, DateDelegate, LanguagesDelegate, PubDateDelegate,
RatingDelegate, SeriesDelegate, TextDelegate,
CcLongTextDelegate, CcMarkdownDelegate, CcNumberDelegate, CcSeriesDelegate,
CcTemplateDelegate, CcTextDelegate, CompleteDelegate, DateDelegate,
LanguagesDelegate, PubDateDelegate, RatingDelegate, SeriesDelegate, TextDelegate,
)
from calibre.gui2.library.models import BooksModel, DeviceBooksModel
from calibre.gui2.pin_columns import PinTableView
@ -1615,16 +1617,20 @@ class BooksView(QTableView): # {{{
self._model.search_done.connect(self.alternate_views.restore_current_book_state)
def connect_to_book_display(self, bd):
self.connect_to_book_display_timer = QTimer()
self._model.new_bookdisplay_data.connect(partial(self._timed_connect_to_book_display, bd))
def _timed_connect_to_book_display(self, bd, data):
self.connect_to_book_display_timer.stop()
t = self.connect_to_book_display_timer = QTimer()
self.book_display_callback = bd
self.connect_to_book_display_timer = t = QTimer(self)
t.setSingleShot(True)
t.timeout.connect(partial(bd, data))
from calibre.gui2.dialogs.book_info import BOOK_DETAILS_DISPLAY_DELAY
t.start(BOOK_DETAILS_DISPLAY_DELAY)
t.timeout.connect(self._debounce_book_display)
t.setInterval(BOOK_DETAILS_DISPLAY_DEBOUNCE_DELAY)
self._model.new_bookdisplay_data.connect(self._timed_connect_to_book_display)
def _timed_connect_to_book_display(self, data):
self._book_display_data = data
self.connect_to_book_display_timer.start()
def _debounce_book_display(self):
data, self._book_display_data = self._book_display_data, None
self.book_display_callback(data)
def search_done(self, ok):
self._search_done(self, ok)

View File

@ -1191,6 +1191,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
def shutdown(self, write_settings=True):
self.shutting_down = True
if hasattr(self.library_view, 'connect_to_book_display_timer'):
self.library_view.connect_to_book_display_timer.stop()
self.shutdown_started.emit()
self.show_shutdown_message()
self.server_change_notification_timer.stop()