Files
libreoffice/vcl/qt5/QtObject.cxx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

178 lines
5.0 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <QtObject.hxx>
#include <QtObject.moc>
#include <QtFrame.hxx>
#include <QtWidget.hxx>
tdf#149461 qt6: Provide a QWindow for OpenGL rendering As described at [1], "QWindow supports rendering using OpenGL [...]". Using a QWindow for OpenGL rendering had been introduced in commit 56b19f9a814ae5a39ed760ee542d715493cd0bf3 Date: Fri Dec 14 12:44:20 2018 +0300 tdf#121247, tdf#121266 KDE5: Add basic support for OpenGL , but then commit 4366e0605214260e55a937173b0c2e02225dc843 Date: Tue May 24 11:34:59 2022 +0200 tdf#148864 Qt switch QtObjectWindow to QWidget had switched from QWindow to QWidget, and OpenGL slide transitions like the "Tiles" one stopped working. At least for qt6, which now uses QtMultimedia for video playback (see the tdf#145735 commits), issues like tdf#148864 ("Kubuntu 22.04 LTS LibreOffice Impress 7.3.3 Fails to Play Embedded Videos") and tdf#125517 ("LO Impress: Can't stop presentation with video and go to the next slide") related to video playback appear to be no problem, so switch back to using QWindow there. Explicitly set the window background to transparent in `QtOpenGLContext::ImplInit`, as not doing so caused slide content in presentation mode to not be updated properly when testing with the attachment 183972 from tdf#149461 on Wayland. (This was not an issue when running on XWayland, i.e. with QT_QPA_PLATFORM=xcb). With this in place, OpenGL transitions work with qt6. With QT_QPA_PLATFORM=xcb, it looks all fine in my tests on Debian testing. With QT_QPA_PLATFORM=wayland, the slide text from attachment 183972 sometimes incorrectly showed up for a fraction of a second after the slide transition finished, then disappeared again until it was triggered to show as it should (e.g. by pressing the right arrow key), s. screencast attachment 194899 in tdf#149461. A multitude of warnings like the following are shown on stderr in that case, which don't show up for xcb: warn:vcl.opengl:47352:47352:vcl/source/opengl/OpenGLHelper.cxx:709: GL Error 0506 (invalid framebuffer operation) in file /home/michi/development/git/libreoffice/slideshow/source/engine/opengl/TransitionImpl.cxx at line 398 That looks like a separate issue to me, however which would need further analysis. Keep using the QtObjectWindow approach for qt5 to not regress on video playback. [1] https://doc.qt.io/qt-5/qtgui-index.html#opengl-and-opengl-es-integration Change-Id: I6e1eb989254e2cbbfada6f719ee0518571df4c42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169347 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-06-21 19:53:50 +02:00
#include <QtCore/QLibraryInfo>
#include <QtGui/QGuiApplication>
#include <QtGui/QKeyEvent>
#include <QtGui/QMouseEvent>
tdf#145735 avmedia qt: Use QtMultimedia for Qt 6 media playback Similar to the way that GTK 4's native facilities for video playback are used for the gtk4 VCL plugin, initially added in commit commit d0a527ec09516bc7215baf229adb90cd21ffa27a Author: Caolán McNamara <caolanm@redhat.com> Date: Thu Feb 10 12:55:18 2022 +0000 first cut at using Gtk4 built in video playback , implement media playback using QtMultimedia for the Qt 6 based VCL plugins (qt6/kf6) via a new service "com.sun.star.comp.avmedia.Manager_Qt". Video playback with the mechanism used for qt5 no longer works with qt6, as "qwidget5videosink" that gets used on Wayland for qt5 wasn't ported to Qt 6 and is unmaintained, s. the commit message of commit 88d57cf241209ffec9eaed3e523942ab51af6db6 Author: Michael Weghorn <m.weghorn@posteo.de> Date: Wed Sep 29 11:09:51 2021 +0200 qt6: Add a qt6 VCL plugin for more details. Additionally, this also doesn't work properly any more on X11/with the xcb Qt QPA platform, see tdf#145735 comment 7. Instead of using GStreamer directly, let Qt handle the low-level stuff by using the QtMultimedia module [1] instead. This adds a new dependency on QtMultimedia. For building, this requires installing the Qt 6 QtMultimedia development headers (e.g. package `qt6-multimedia-dev` on current Debian testing). Except for WASM, the use of QtMultimedia is enabled by default when building with autogen options `--enable-qt6` or `--enable-kf6`, but can explicitly be disabled using `--disable-qt6-multimedia`. In tests with the qt6 VCL plugin on Debian testing, with a sample presentation containing an embedded video, attachment 145517 from tdf#120452, video playback generally works for both, the xcb and the wayland Qt QPA platforms: * Video and audio are played as expected on the external screen in presentation mode when using the presenter console * Video and audio playback work in non-presentation mode by clicking on the video and using the controls in the Impress sidebar (play, pause,...). However, the following issues were observed with the current implementation: * There's an odd frame/margin around the video. * In non-presentation mode, the placeholder shown until the video gets started using the controls in the sidebar is just an "audio icon", not a frame from the actual video. (This might be related to the fact that `QtPlayer::createFrameGrabber` currently returns an empty reference.) * At least on Wayland (issue not observed with QT_QPA_PLATFORM=xcb so far), when using the presenter console, video playback in the presenter console (i.e. on the non-presentation screen) is unreliable: The video sometimes shows, but sometimes doesn't. At least the (more important) one on the presentation screen was reliably shown in my tests, however. Tested with git dev versions of qtbase (as of commit 8d5e7d50d8dbf1ad79bd8ff9f6ef6028eba481c9), qtwayland (as of commit 6f0ebd916f176f6fbe35af28caeb52b62768ac94) and qtmultimedia (as of commit 264b7e8d7d5683252102b5e5149685c8b8a70c2d). [1] https://doc.qt.io/qt-6/qtmultimedia-index.html Change-Id: I29c3c7ded01c61b49b192fa5c313d8a92c942185 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167869 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-05-20 16:25:09 +02:00
#include <QtWidgets/QVBoxLayout>
QtObject::QtObject(QtFrame* pParent, bool bShow)
: m_pParent(pParent)
, m_pQWidget(nullptr)
, m_bForwardKey(false)
{
if (!m_pParent || !pParent->GetQWidget())
return;
tdf#149461 qt6: Provide a QWindow for OpenGL rendering As described at [1], "QWindow supports rendering using OpenGL [...]". Using a QWindow for OpenGL rendering had been introduced in commit 56b19f9a814ae5a39ed760ee542d715493cd0bf3 Date: Fri Dec 14 12:44:20 2018 +0300 tdf#121247, tdf#121266 KDE5: Add basic support for OpenGL , but then commit 4366e0605214260e55a937173b0c2e02225dc843 Date: Tue May 24 11:34:59 2022 +0200 tdf#148864 Qt switch QtObjectWindow to QWidget had switched from QWindow to QWidget, and OpenGL slide transitions like the "Tiles" one stopped working. At least for qt6, which now uses QtMultimedia for video playback (see the tdf#145735 commits), issues like tdf#148864 ("Kubuntu 22.04 LTS LibreOffice Impress 7.3.3 Fails to Play Embedded Videos") and tdf#125517 ("LO Impress: Can't stop presentation with video and go to the next slide") related to video playback appear to be no problem, so switch back to using QWindow there. Explicitly set the window background to transparent in `QtOpenGLContext::ImplInit`, as not doing so caused slide content in presentation mode to not be updated properly when testing with the attachment 183972 from tdf#149461 on Wayland. (This was not an issue when running on XWayland, i.e. with QT_QPA_PLATFORM=xcb). With this in place, OpenGL transitions work with qt6. With QT_QPA_PLATFORM=xcb, it looks all fine in my tests on Debian testing. With QT_QPA_PLATFORM=wayland, the slide text from attachment 183972 sometimes incorrectly showed up for a fraction of a second after the slide transition finished, then disappeared again until it was triggered to show as it should (e.g. by pressing the right arrow key), s. screencast attachment 194899 in tdf#149461. A multitude of warnings like the following are shown on stderr in that case, which don't show up for xcb: warn:vcl.opengl:47352:47352:vcl/source/opengl/OpenGLHelper.cxx:709: GL Error 0506 (invalid framebuffer operation) in file /home/michi/development/git/libreoffice/slideshow/source/engine/opengl/TransitionImpl.cxx at line 398 That looks like a separate issue to me, however which would need further analysis. Keep using the QtObjectWindow approach for qt5 to not regress on video playback. [1] https://doc.qt.io/qt-5/qtgui-index.html#opengl-and-opengl-es-integration Change-Id: I6e1eb989254e2cbbfada6f719ee0518571df4c42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169347 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-06-21 19:53:50 +02:00
if (QLibraryInfo::version().majorVersion() > 5)
{
m_pQWindow = new QWindow;
m_pQWidget = QWidget::createWindowContainer(m_pQWindow, pParent->GetQWidget());
}
else
{
// with the qt5 VCL plugin, the above would cause issues with video playback (s. tdf#148864, tdf#125517),
// which is not a problem with the QtMultimedia approach that the qt6 VCL plugin uses;
// stay with the QtObjectWidget introduced in commit 4366e0605214260e55a937173b0c2e02225dc843
m_pQWidget = new QtObjectWidget(*this);
// invoke QWidget::winId() to ensure a native window for OpenGL rendering is available on X11,
// don't do it on Wayland, as that breaks rendering otherwise, s.a. QtFrame::ResolveWindowHandle
if (QGuiApplication::platformName() == "xcb")
m_pQWidget->winId();
tdf#149461 qt6: Provide a QWindow for OpenGL rendering As described at [1], "QWindow supports rendering using OpenGL [...]". Using a QWindow for OpenGL rendering had been introduced in commit 56b19f9a814ae5a39ed760ee542d715493cd0bf3 Date: Fri Dec 14 12:44:20 2018 +0300 tdf#121247, tdf#121266 KDE5: Add basic support for OpenGL , but then commit 4366e0605214260e55a937173b0c2e02225dc843 Date: Tue May 24 11:34:59 2022 +0200 tdf#148864 Qt switch QtObjectWindow to QWidget had switched from QWindow to QWidget, and OpenGL slide transitions like the "Tiles" one stopped working. At least for qt6, which now uses QtMultimedia for video playback (see the tdf#145735 commits), issues like tdf#148864 ("Kubuntu 22.04 LTS LibreOffice Impress 7.3.3 Fails to Play Embedded Videos") and tdf#125517 ("LO Impress: Can't stop presentation with video and go to the next slide") related to video playback appear to be no problem, so switch back to using QWindow there. Explicitly set the window background to transparent in `QtOpenGLContext::ImplInit`, as not doing so caused slide content in presentation mode to not be updated properly when testing with the attachment 183972 from tdf#149461 on Wayland. (This was not an issue when running on XWayland, i.e. with QT_QPA_PLATFORM=xcb). With this in place, OpenGL transitions work with qt6. With QT_QPA_PLATFORM=xcb, it looks all fine in my tests on Debian testing. With QT_QPA_PLATFORM=wayland, the slide text from attachment 183972 sometimes incorrectly showed up for a fraction of a second after the slide transition finished, then disappeared again until it was triggered to show as it should (e.g. by pressing the right arrow key), s. screencast attachment 194899 in tdf#149461. A multitude of warnings like the following are shown on stderr in that case, which don't show up for xcb: warn:vcl.opengl:47352:47352:vcl/source/opengl/OpenGLHelper.cxx:709: GL Error 0506 (invalid framebuffer operation) in file /home/michi/development/git/libreoffice/slideshow/source/engine/opengl/TransitionImpl.cxx at line 398 That looks like a separate issue to me, however which would need further analysis. Keep using the QtObjectWindow approach for qt5 to not regress on video playback. [1] https://doc.qt.io/qt-5/qtgui-index.html#opengl-and-opengl-es-integration Change-Id: I6e1eb989254e2cbbfada6f719ee0518571df4c42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169347 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-06-21 19:53:50 +02:00
m_pQWindow = m_pQWidget->windowHandle();
}
// set layout, used for video playback, see QtPlayer::createPlayerWindow
QVBoxLayout* layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
m_pQWidget->setLayout(layout);
if (bShow)
m_pQWidget->show();
QtFrame::FillSystemEnvData(m_aSystemData, reinterpret_cast<sal_IntPtr>(this), m_pQWidget);
}
QtObject::~QtObject()
{
if (m_pQWidget)
{
m_pQWidget->setParent(nullptr);
delete m_pQWidget;
}
}
tdf#149461 qt6: Provide a QWindow for OpenGL rendering As described at [1], "QWindow supports rendering using OpenGL [...]". Using a QWindow for OpenGL rendering had been introduced in commit 56b19f9a814ae5a39ed760ee542d715493cd0bf3 Date: Fri Dec 14 12:44:20 2018 +0300 tdf#121247, tdf#121266 KDE5: Add basic support for OpenGL , but then commit 4366e0605214260e55a937173b0c2e02225dc843 Date: Tue May 24 11:34:59 2022 +0200 tdf#148864 Qt switch QtObjectWindow to QWidget had switched from QWindow to QWidget, and OpenGL slide transitions like the "Tiles" one stopped working. At least for qt6, which now uses QtMultimedia for video playback (see the tdf#145735 commits), issues like tdf#148864 ("Kubuntu 22.04 LTS LibreOffice Impress 7.3.3 Fails to Play Embedded Videos") and tdf#125517 ("LO Impress: Can't stop presentation with video and go to the next slide") related to video playback appear to be no problem, so switch back to using QWindow there. Explicitly set the window background to transparent in `QtOpenGLContext::ImplInit`, as not doing so caused slide content in presentation mode to not be updated properly when testing with the attachment 183972 from tdf#149461 on Wayland. (This was not an issue when running on XWayland, i.e. with QT_QPA_PLATFORM=xcb). With this in place, OpenGL transitions work with qt6. With QT_QPA_PLATFORM=xcb, it looks all fine in my tests on Debian testing. With QT_QPA_PLATFORM=wayland, the slide text from attachment 183972 sometimes incorrectly showed up for a fraction of a second after the slide transition finished, then disappeared again until it was triggered to show as it should (e.g. by pressing the right arrow key), s. screencast attachment 194899 in tdf#149461. A multitude of warnings like the following are shown on stderr in that case, which don't show up for xcb: warn:vcl.opengl:47352:47352:vcl/source/opengl/OpenGLHelper.cxx:709: GL Error 0506 (invalid framebuffer operation) in file /home/michi/development/git/libreoffice/slideshow/source/engine/opengl/TransitionImpl.cxx at line 398 That looks like a separate issue to me, however which would need further analysis. Keep using the QtObjectWindow approach for qt5 to not regress on video playback. [1] https://doc.qt.io/qt-5/qtgui-index.html#opengl-and-opengl-es-integration Change-Id: I6e1eb989254e2cbbfada6f719ee0518571df4c42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169347 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-06-21 19:53:50 +02:00
QWindow* QtObject::windowHandle() const { return m_pQWindow; }
void QtObject::ResetClipRegion()
{
if (m_pQWidget)
m_pRegion = QRegion(m_pQWidget->geometry());
else
m_pRegion = QRegion();
}
void QtObject::BeginSetClipRegion(sal_uInt32) { m_pRegion = QRegion(); }
void QtObject::UnionClipRegion(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight)
{
m_pRegion += QRect(nX, nY, nWidth, nHeight);
}
void QtObject::EndSetClipRegion()
{
if (m_pQWidget)
m_pRegion = m_pRegion.intersected(m_pQWidget->geometry());
}
void QtObject::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight)
{
if (m_pQWidget)
{
m_pQWidget->move(nX, nY);
m_pQWidget->setFixedSize(nWidth, nHeight);
}
}
void QtObject::Show(bool bVisible)
{
if (m_pQWidget)
m_pQWidget->setVisible(bVisible);
}
void QtObject::SetForwardKey(bool bEnable) { m_bForwardKey = bEnable; }
void QtObject::Reparent(SalFrame* pFrame)
{
QtFrame* pNewParent = static_cast<QtFrame*>(pFrame);
if (m_pParent == pNewParent)
return;
m_pParent = pNewParent;
m_pQWidget->setParent(m_pParent->GetQWidget());
}
QtObjectWidget::QtObjectWidget(QtObject& rParent)
: QWidget(rParent.frame()->GetQWidget())
, m_rParent(rParent)
{
assert(m_rParent.frame() && m_rParent.frame()->GetQWidget());
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
}
void QtObjectWidget::focusInEvent(QFocusEvent*)
{
SolarMutexGuard aGuard;
m_rParent.CallCallback(SalObjEvent::GetFocus);
}
void QtObjectWidget::focusOutEvent(QFocusEvent*)
{
SolarMutexGuard aGuard;
m_rParent.CallCallback(SalObjEvent::LoseFocus);
}
void QtObjectWidget::mousePressEvent(QMouseEvent* pEvent)
{
SolarMutexGuard aGuard;
m_rParent.CallCallback(SalObjEvent::ToTop);
if (m_rParent.forwardKey())
pEvent->ignore();
}
void QtObjectWidget::mouseReleaseEvent(QMouseEvent* pEvent)
{
if (m_rParent.forwardKey())
pEvent->ignore();
}
void QtObjectWidget::keyReleaseEvent(QKeyEvent* pEvent)
{
if (m_rParent.forwardKey())
pEvent->ignore();
}
void QtObjectWidget::keyPressEvent(QKeyEvent* pEvent)
{
if (m_rParent.forwardKey())
pEvent->ignore();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */