From 05db887bc226b85befe2c2b9e84b796020a6ca05 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 21 Feb 2022 10:01:42 +0000 Subject: gtk4: media dimensions are only reliably available async MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this is also the case for the direct gstreamer use in gtk3 but more egregious when abstracted away from it in gtk4 Change-Id: If90069308d67929585722c079c482cd4ad196e1f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130468 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- sd/source/ui/func/fuinsert.cxx | 99 ++++++++++++++++++++++++++++-------------- sd/source/ui/inc/View.hxx | 3 ++ sd/source/ui/inc/fuinsert.hxx | 5 +++ sd/source/ui/view/sdview.cxx | 7 +++ sd/source/ui/view/sdview4.cxx | 57 ++++++++++++++---------- 5 files changed, 117 insertions(+), 54 deletions(-) (limited to 'sd/source') diff --git a/sd/source/ui/func/fuinsert.cxx b/sd/source/ui/func/fuinsert.cxx index 5d95335e48ca..d65e7c8b2ff2 100644 --- a/sd/source/ui/func/fuinsert.cxx +++ b/sd/source/ui/func/fuinsert.cxx @@ -21,16 +21,21 @@ #include #include +#include +#include #include #include #include +#include #include #include #include #include -#include +#include +#include #include +#include #include #include #include @@ -664,6 +669,11 @@ void FuInsertAVMedia::DoExecute( SfxRequest& rReq ) const SfxItemSet* pReqArgs = rReq.GetArgs(); bool bAPI = false; + const SvxSizeItem* pSizeItem = rReq.GetArg(FN_PARAM_1); + const SfxBoolItem* pLinkItem = rReq.GetArg(FN_PARAM_2); + const bool bSizeUnknown = !pSizeItem; + Size aPrefSize; + if( pReqArgs ) { const SfxStringItem* pStringItem = dynamic_cast( &pReqArgs->Get( rReq.GetSlot() ) ); @@ -675,58 +685,83 @@ void FuInsertAVMedia::DoExecute( SfxRequest& rReq ) } } - bool bLink(true); + bool bLink(pLinkItem ? pLinkItem->GetValue() : true); if (!(bAPI || ::avmedia::MediaWindow::executeMediaURLDialog(mpWindow ? mpWindow->GetFrameWeld() : nullptr, aURL, & bLink) )) return; - Size aPrefSize; - - if( mpWindow ) - mpWindow->EnterWait(); - - if( !::avmedia::MediaWindow::isMediaURL( aURL, "", true, &aPrefSize ) ) + if (!bSizeUnknown) { - if( mpWindow ) - mpWindow->LeaveWait(); - - if( !bAPI ) - ::avmedia::MediaWindow::executeFormatErrorBox(mpWindow->GetFrameWeld()); + aPrefSize = pSizeItem->GetSize(); } else { - Point aPos; - Size aSize; - sal_Int8 nAction = DND_ACTION_COPY; + // If we don't have a size then try and find that out, the resulted might be deliver async, so dispatch a follow up + // effort to insert the video, this time with a size. + if( mpWindow ) + mpWindow->EnterWait(); - if( aPrefSize.Width() && aPrefSize.Height() ) - { - if( mpWindow ) - aSize = mpWindow->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); - else - aSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); - } - else - aSize = Size( 5000, 5000 ); + css::uno::Reference xDispatchProvider(mpViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), css::uno::UNO_QUERY); - if( mpWindow ) - { - aPos = mpWindow->PixelToLogic( ::tools::Rectangle( aPos, mpWindow->GetOutputSizePixel() ).Center() ); - aPos.AdjustX( -(aSize.Width() >> 1) ); - aPos.AdjustY( -(aSize.Height() >> 1) ); - } + rtl::Reference xPlayerListener(new avmedia::PlayerListener( + [xDispatchProvider, aURL, bLink](const css::uno::Reference& rPlayer){ + css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize(); + avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, aSize, aURL, bLink); + })); - mpView->InsertMediaURL( aURL, nAction, aPos, aSize, bLink ) ; + const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, "", true, xPlayerListener); if( mpWindow ) mpWindow->LeaveWait(); + + if (!bIsMediaURL && !bAPI) + ::avmedia::MediaWindow::executeFormatErrorBox(mpWindow->GetFrameWeld()); + + return; } + + InsertMediaURL(aURL, aPrefSize, bLink); + #else (void)rReq; #endif } +#if HAVE_FEATURE_AVMEDIA +void FuInsertAVMedia::InsertMediaURL(const OUString& rURL, const Size& rPrefSize, bool bLink) +{ + if( mpWindow ) + mpWindow->EnterWait(); + + Point aPos; + Size aSize; + sal_Int8 nAction = DND_ACTION_COPY; + + if (rPrefSize.Width() && rPrefSize.Height()) + { + if( mpWindow ) + aSize = mpWindow->PixelToLogic(rPrefSize, MapMode(MapUnit::Map100thMM)); + else + aSize = Application::GetDefaultDevice()->PixelToLogic(rPrefSize, MapMode(MapUnit::Map100thMM)); + } + else + aSize = Size( 5000, 5000 ); + + if( mpWindow ) + { + aPos = mpWindow->PixelToLogic( ::tools::Rectangle( aPos, mpWindow->GetOutputSizePixel() ).Center() ); + aPos.AdjustX( -(aSize.Width() >> 1) ); + aPos.AdjustY( -(aSize.Height() >> 1) ); + } + + mpView->InsertMediaURL(rURL, nAction, aPos, aSize, bLink); + + if( mpWindow ) + mpWindow->LeaveWait(); +} +#endif + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx index 8d211d0c3533..4e530e3f9227 100644 --- a/sd/source/ui/inc/View.hxx +++ b/sd/source/ui/inc/View.hxx @@ -40,6 +40,8 @@ class ImageMap; class Graphic; class SdrOutliner; +namespace avmedia { class PlayerListener; } + namespace sd { class DrawDocShell; @@ -268,6 +270,7 @@ protected: sal_Int8 mnAction; Idle maDropErrorIdle; Idle maDropInsertFileIdle; + rtl::Reference mxDropMediaSizeListener; sal_uInt16 mnLockRedrawSmph; bool mbIsDropAllowed; diff --git a/sd/source/ui/inc/fuinsert.hxx b/sd/source/ui/inc/fuinsert.hxx index 0ad622df36b8..a2b33596162d 100644 --- a/sd/source/ui/inc/fuinsert.hxx +++ b/sd/source/ui/inc/fuinsert.hxx @@ -19,6 +19,7 @@ #pragma once +#include #include "fupoor.hxx" namespace sd { @@ -101,6 +102,10 @@ private: ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq); + +#if HAVE_FEATURE_AVMEDIA + void InsertMediaURL(const OUString& rURL, const Size& rPrefSize, bool bLink); +#endif }; } // end of namespace sd diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx index b1ddd90c95cf..100374ae8205 100644 --- a/sd/source/ui/view/sdview.cxx +++ b/sd/source/ui/view/sdview.cxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -142,6 +143,12 @@ View::~View() // release content of selection clipboard, if we own the content ClearSelectionClipboard(); + if (mxDropMediaSizeListener) + { + mxDropMediaSizeListener->dispose(); + mxDropMediaSizeListener.clear(); + } + maDropErrorIdle.Stop(); maDropInsertFileIdle.Stop(); diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx index 2b08a5a041f8..7a3c7c2267a5 100644 --- a/sd/source/ui/view/sdview4.cxx +++ b/sd/source/ui/view/sdview4.cxx @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -425,7 +426,7 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void) { OUString aCurrentDropFile( *aIter ); INetURLObject aURL( aCurrentDropFile ); - bool bOK = false; + bool bHandled = false; if( aURL.GetProtocol() == INetProtocol::NotValid ) { @@ -458,9 +459,9 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void) if( aIter == maDropFileVector.begin() ) mnAction = nTempAction; - bOK = true; + bHandled = true; } - if( !bOK ) + if (!bHandled) { std::shared_ptr pFoundFilter; SfxMedium aSfxMedium( aCurrentDropFile, StreamMode::READ | StreamMode::SHARE_DENYNONE ); @@ -493,36 +494,48 @@ IMPL_LINK_NOARG(View, DropInsertFileHdl, Timer *, void) aReq.AppendItem( aItem1 ); aReq.AppendItem( aItem2 ); FuInsertFile::Create( mpViewSh, pWin, this, &mrDoc, aReq ); - bOK = true; + bHandled = true; } } } } - if( !bOK ) - { #if HAVE_FEATURE_AVMEDIA - Size aPrefSize; - - if( ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile, ""/*TODO?*/ ) && - ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile, ""/*TODO?*/, true, &aPrefSize ) ) + if (!bHandled) + { + bool bShallowDetect = ::avmedia::MediaWindow::isMediaURL(aCurrentDropFile, ""/*TODO?*/); + if (bShallowDetect) { - if( aPrefSize.Width() && aPrefSize.Height() ) - { - ::sd::Window* pWin = mpViewSh->GetActiveWindow(); + mxDropMediaSizeListener.set(new avmedia::PlayerListener( + [this, aCurrentDropFile](const css::uno::Reference& rPlayer){ + SolarMutexGuard g; - if( pWin ) - aPrefSize = pWin->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); - else - aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); - } - else - aPrefSize = Size( 5000, 5000 ); + css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize(); + Size aPrefSize(aSize.Width, aSize.Height); + + if (aPrefSize.Width() && aPrefSize.Height()) + { + ::sd::Window* pWin = mpViewSh->GetActiveWindow(); - InsertMediaURL( aCurrentDropFile, mnAction, maDropPos, aPrefSize, true ) ; + if( pWin ) + aPrefSize = pWin->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); + else + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MapMode(MapUnit::Map100thMM)); + } + else + aPrefSize = Size( 5000, 5000 ); + + InsertMediaURL(aCurrentDropFile, mnAction, maDropPos, aPrefSize, true); + + mxDropMediaSizeListener.clear(); + })); } - else + bHandled = bShallowDetect && ::avmedia::MediaWindow::isMediaURL(aCurrentDropFile, ""/*TODO?*/, true, mxDropMediaSizeListener); + } #endif + + if (!bHandled) + { if( mnAction & DND_ACTION_LINK ) static_cast< DrawViewShell* >( mpViewSh )->InsertURLButton( aCurrentDropFile, aCurrentDropFile, OUString(), &maDropPos ); else -- cgit