diff --git a/openlp/core/common/platform.py b/openlp/core/common/platform.py index ca57edce8..77c34bf15 100644 --- a/openlp/core/common/platform.py +++ b/openlp/core/common/platform.py @@ -73,3 +73,12 @@ def is_64bit_instance(): :return: True if the python/OpenLP instance running is 64 bit, otherwise False. """ return (sys.maxsize > 2**32) + + +def is_xorg_server(): + """ + Returns true if the Qt is running on X.org/XWayland display server (Linux/*nix) + :return: True if the Qt is running on X.org/XWayland display server (Linux/*nix), otherwise False. + """ + from PyQt5 import QtGui + return QtGui.QGuiApplication.platformName() == 'xcb' diff --git a/openlp/core/display/window.py b/openlp/core/display/window.py index 5d7e6f42c..a22ab95d6 100644 --- a/openlp/core/display/window.py +++ b/openlp/core/display/window.py @@ -141,6 +141,9 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin): flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint if self.settings.value('advanced/x11 bypass wm'): flags |= QtCore.Qt.X11BypassWindowManagerHint + else: + # This helps the window not being hidden by KDE's "Hide utility windows for inactive applications" option + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_X11NetWmWindowTypeDialog) if is_macosx(): self.setAttribute(QtCore.Qt.WA_MacAlwaysShowToolWindow, True) # Need to import this inline to get around a QtWebEngine issue diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 344a31f21..51f558b6b 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -333,7 +333,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): if self.is_theme_background: self.is_autoplay = True if self.is_autoplay: - if not self.media_play(controller): + start_hidden = self.is_theme_background and controller.is_live and \ + (controller.current_hide_mode == HideMode.Blank or controller.current_hide_mode == HideMode.Screen) + if not self.media_play(controller, start_hidden): critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File')) return False @@ -440,11 +442,12 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): """ return self.media_play(self.live_controller) - def media_play(self, controller): + def media_play(self, controller, start_hidden=False): """ Responds to the request to play a loaded video :param controller: The controller to be played + :param start_hidden: Whether to play the video without showing the controller """ self.log_debug(f'media_play is_live:{controller.is_live}') controller.seek_slider.blockSignals(True) @@ -455,7 +458,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): controller.volume_slider.blockSignals(False) return False self.media_volume(controller, controller.media_info.volume) - self._media_set_visibility(controller, True) + if not start_hidden: + self._media_set_visibility(controller, True) controller.mediabar.actions['playbackPlay'].setVisible(False) controller.mediabar.actions['playbackPause'].setVisible(True) controller.mediabar.actions['playbackStop'].setDisabled(False) @@ -728,6 +732,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): self.live_hide_timer.stop() visible = visible and controller.media_info.media_type is not MediaType.Audio self.current_media_players[controller.controller_type].set_visible(controller, visible) + if controller.is_live and visible: + display = self._define_display(controller) + display.raise_() def media_blank(self, msg): """ @@ -756,7 +763,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): else: self.live_hide_timer.stop() else: - if playing: + if playing and not self.is_theme_background: self.media_pause(self.live_controller) self._media_set_visibility(self.live_controller, False) diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index 7936cffa4..faf0ff6ad 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -107,8 +107,8 @@ class VlcPlayer(MediaPlayer): """ vlc = get_vlc() if controller.is_live: - controller.vlc_widget = QtWidgets.QFrame() - controller.vlc_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | + controller.vlc_widget = QtWidgets.QFrame(controller) + controller.vlc_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowType.Tool | QtCore.Qt.WindowStaysOnTopHint) else: controller.vlc_widget = QtWidgets.QFrame(display) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 0718fa028..dc965048d 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -212,6 +212,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): def display(self): return self.displays[0] if self.displays else None + @property + def current_hide_mode(self): + return self._current_hide_mode + def setup_ui(self): """ Initialise the UI elements of the controller @@ -1019,8 +1023,13 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): self.preview_widget.replace_service_item(self.service_item, width, slide_no) # Tidy up aspects associated with the old item if old_item: + new_item_has_background_video = self.service_item.is_capable(ItemCapabilities.HasBackgroundVideo) or \ + self.service_item.is_capable(ItemCapabilities.HasBackgroundStream) + # Media Manager cannot play background videos on preview pane yet + is_unsupported_preview_background = not self.is_live and new_item_has_background_video # 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(): + if not self.service_item.is_media() and (not self.service_item.requires_media() or + is_unsupported_preview_background): 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]) diff --git a/tests/openlp_core/ui/media/test_mediacontroller.py b/tests/openlp_core/ui/media/test_mediacontroller.py index 5fa62c71c..bec95938d 100644 --- a/tests/openlp_core/ui/media/test_mediacontroller.py +++ b/tests/openlp_core/ui/media/test_mediacontroller.py @@ -87,7 +87,7 @@ def test_load_video(media_env, settings): # The controls should have been made visible media_env.media_controller.media_reset.assert_called_once_with(mocked_slide_controller) assert mocked_slide_controller.media_info.volume == 1 - media_env.media_controller.media_play.assert_called_once_with(mocked_slide_controller) + media_env.media_controller.media_play.assert_called_once_with(mocked_slide_controller, False) media_env.media_controller.set_controls_visible.assert_called_once_with(mocked_slide_controller, True)