forked from openlp/openlp
Fix song flash
This commit is contained in:
parent
59f625bd8f
commit
aff97c0e27
@ -262,6 +262,7 @@ var Display = {
|
|||||||
_animationState: AnimationState.NoAnimation,
|
_animationState: AnimationState.NoAnimation,
|
||||||
_doTransitions: false,
|
_doTransitions: false,
|
||||||
_doItemTransitions: false,
|
_doItemTransitions: false,
|
||||||
|
_skipNextTransition: false,
|
||||||
_themeApplied: true,
|
_themeApplied: true,
|
||||||
_revealConfig: {
|
_revealConfig: {
|
||||||
margin: 0.0,
|
margin: 0.0,
|
||||||
@ -365,7 +366,7 @@ var Display = {
|
|||||||
Display.applyTheme(new_slides, is_text);
|
Display.applyTheme(new_slides, is_text);
|
||||||
Display._slidesContainer.prepend(new_slides);
|
Display._slidesContainer.prepend(new_slides);
|
||||||
var currentSlide = Reveal.getIndices();
|
var currentSlide = Reveal.getIndices();
|
||||||
if (Display._doItemTransitions && Display._slidesContainer.children.length >= 2) {
|
if (Display._doItemTransitions && Display._slidesContainer.children.length >= 2 && !Display._skipNextTransition) {
|
||||||
// Set the slide one section ahead so we'll stay on the old slide after reinit
|
// Set the slide one section ahead so we'll stay on the old slide after reinit
|
||||||
Reveal.slide(1, currentSlide.v);
|
Reveal.slide(1, currentSlide.v);
|
||||||
Display.reinit();
|
Display.reinit();
|
||||||
@ -375,6 +376,7 @@ var Display = {
|
|||||||
Reveal.slide(0, currentSlide.v);
|
Reveal.slide(0, currentSlide.v);
|
||||||
Reveal.sync();
|
Reveal.sync();
|
||||||
Display._removeLastSection();
|
Display._removeLastSection();
|
||||||
|
Display._skipNextTransition = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -1121,6 +1123,18 @@ var Display = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Called whenever openlp wants to finish completely with the current text/image slides
|
||||||
|
* because a different window (eg presentation or vlc) is going to be displaying the next item
|
||||||
|
* and we don't want any flashbacks to the current slide contents
|
||||||
|
*/
|
||||||
|
finishWithCurrentItem: function () {
|
||||||
|
Display.setTextSlide('');
|
||||||
|
var documentBody = $("body")[0];
|
||||||
|
documentBody.style.opacity = 1;
|
||||||
|
Display._skipNextTransition = true;
|
||||||
|
displayWatcher.pleaseRepaint();
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Return the video types supported by the video tag
|
* Return the video types supported by the video tag
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +51,10 @@ class DisplayWatcher(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
initialised = QtCore.pyqtSignal(bool)
|
initialised = QtCore.pyqtSignal(bool)
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__()
|
||||||
|
self._display_window = parent
|
||||||
|
|
||||||
@QtCore.pyqtSlot(bool)
|
@QtCore.pyqtSlot(bool)
|
||||||
def setInitialised(self, is_initialised):
|
def setInitialised(self, is_initialised):
|
||||||
"""
|
"""
|
||||||
@ -59,6 +63,13 @@ class DisplayWatcher(QtCore.QObject):
|
|||||||
log.info('Display is initialised: {init}'.format(init=is_initialised))
|
log.info('Display is initialised: {init}'.format(init=is_initialised))
|
||||||
self.initialised.emit(is_initialised)
|
self.initialised.emit(is_initialised)
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot()
|
||||||
|
def pleaseRepaint(self):
|
||||||
|
"""
|
||||||
|
Called from the js in the webengine view when it's requesting a repaint by Qt
|
||||||
|
"""
|
||||||
|
self._display_window.webview.update()
|
||||||
|
|
||||||
|
|
||||||
class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin):
|
class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin):
|
||||||
"""
|
"""
|
||||||
@ -451,6 +462,16 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin):
|
|||||||
if self.is_display and self.hide_mode == HideMode.Screen:
|
if self.is_display and self.hide_mode == HideMode.Screen:
|
||||||
self.setVisible(False)
|
self.setVisible(False)
|
||||||
|
|
||||||
|
def finish_with_current_item(self):
|
||||||
|
"""
|
||||||
|
This is called whenever the song/image display is followed by eg a presentation or video which
|
||||||
|
has its own display.
|
||||||
|
This function ensures that the current item won't flash momentarily when the webengineview
|
||||||
|
is displayed for a subsequent song or image.
|
||||||
|
"""
|
||||||
|
self.run_javascript('Display.finishWithCurrentItem();', True)
|
||||||
|
self.webview.update()
|
||||||
|
|
||||||
def set_scale(self, scale):
|
def set_scale(self, scale):
|
||||||
"""
|
"""
|
||||||
Set the HTML scale
|
Set the HTML scale
|
||||||
|
@ -945,23 +945,19 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
[self.service_item, self.is_live, self._current_hide_mode, slide_no])
|
[self.service_item, self.is_live, self._current_hide_mode, slide_no])
|
||||||
else:
|
else:
|
||||||
self._set_theme(self.service_item)
|
self._set_theme(self.service_item)
|
||||||
# Reset blanking if needed
|
|
||||||
if old_item and self.is_live and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
|
||||||
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
|
|
||||||
self._reset_blank(self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay))
|
|
||||||
self.info_label.setText(self.service_item.title)
|
self.info_label.setText(self.service_item.title)
|
||||||
self.slide_list = {}
|
self.slide_list = {}
|
||||||
if old_item:
|
# if the old item was text or images (ie doesn't provide its own display) and the new item provides its own
|
||||||
# Close the old item if it's not to be used by the new service item
|
# display then clear out the old item so that it doesn't flash momentarily when next showing text/image
|
||||||
if not self.service_item.is_media() and not self.service_item.requires_media():
|
# An item provides its own display if the capability ProvidesOwnDisplay is set or if it's a media item
|
||||||
self.on_media_close()
|
old_item_provides_own_display = old_item and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||||
if old_item.is_command() and not old_item.is_media():
|
old_item.is_media())
|
||||||
Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live])
|
new_item_provides_own_display = (self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||||
# if the old item was media which hid the main display then need to reset it if new service item uses it
|
self.service_item.is_media())
|
||||||
if self.is_live and self._current_hide_mode is None and old_item.is_media() and not \
|
if self.is_live and not old_item_provides_own_display and new_item_provides_own_display:
|
||||||
old_item.requires_media() and not self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
|
for display in self.displays:
|
||||||
for display in self.displays:
|
display.finish_with_current_item()
|
||||||
display.show_display()
|
# Prepare the new slides for text / image items
|
||||||
row = 0
|
row = 0
|
||||||
width = self.main_window.control_splitter.sizes()[self.split]
|
width = self.main_window.control_splitter.sizes()[self.split]
|
||||||
if self.service_item.is_text():
|
if self.service_item.is_text():
|
||||||
@ -997,7 +993,23 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
row += 1
|
row += 1
|
||||||
self.slide_list[str(row)] = row - 1
|
self.slide_list[str(row)] = row - 1
|
||||||
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
|
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
|
||||||
|
# Tidy up aspects associated with the old item
|
||||||
|
if old_item:
|
||||||
|
# Close the old item if it's not to be used by the new service item
|
||||||
|
if not self.service_item.is_media() and not self.service_item.requires_media():
|
||||||
|
self.on_media_close()
|
||||||
|
if old_item.is_command() and not old_item.is_media():
|
||||||
|
Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live])
|
||||||
|
# if the old item was media which hid the main display then need to reset it if new service item uses it
|
||||||
|
if self.is_live and self._current_hide_mode is None and old_item.is_media() and not \
|
||||||
|
old_item.requires_media() and not self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
|
||||||
|
for display in self.displays:
|
||||||
|
display.show_display()
|
||||||
self.enable_tool_bar(self.service_item)
|
self.enable_tool_bar(self.service_item)
|
||||||
|
# Reset blanking if needed
|
||||||
|
if old_item and self.is_live and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||||
|
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
|
||||||
|
self._reset_blank(self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay))
|
||||||
if self.service_item.is_media() or self.service_item.requires_media():
|
if self.service_item.is_media() or self.service_item.requires_media():
|
||||||
self._set_theme(self.service_item)
|
self._set_theme(self.service_item)
|
||||||
if self.service_item.is_command():
|
if self.service_item.is_command():
|
||||||
|
@ -622,3 +622,18 @@ def test_display_watcher_set_initialised():
|
|||||||
|
|
||||||
# THEN: initialised should have been emitted
|
# THEN: initialised should have been emitted
|
||||||
mocked_initialised.emit.assert_called_once_with(True)
|
mocked_initialised.emit.assert_called_once_with(True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_display_watcher_please_repaint(display_window_env, mock_settings):
|
||||||
|
"""
|
||||||
|
Test that the repaint is initiated
|
||||||
|
"""
|
||||||
|
# GIVEN: A DisplayWindow instance with mocked out webview
|
||||||
|
display_window = DisplayWindow()
|
||||||
|
display_window.webview = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: pleaseRepaint is called on the DisplayWatcher
|
||||||
|
display_window.display_watcher.pleaseRepaint()
|
||||||
|
|
||||||
|
# THEN: Qt update for the webview should have been triggered
|
||||||
|
assert display_window.webview.update.call_count == 1
|
||||||
|
Loading…
Reference in New Issue
Block a user