mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
webview2: Add user-data-folder property
Adding a propery to specify location of WebView2's user data folder location. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6921>
This commit is contained in:
parent
05f9eadcaf
commit
a4dfca3ae4
3 changed files with 60 additions and 6 deletions
|
@ -30,6 +30,7 @@
|
||||||
#include "gstwebview2object.h"
|
#include "gstwebview2object.h"
|
||||||
#include <gst/d3d11/gstd3d11-private.h>
|
#include <gst/d3d11/gstd3d11-private.h>
|
||||||
#include <webview2.h>
|
#include <webview2.h>
|
||||||
|
#include <WebView2EnvironmentOptions.h>
|
||||||
#include <dcomp.h>
|
#include <dcomp.h>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -76,6 +77,7 @@ enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_DEVICE,
|
PROP_DEVICE,
|
||||||
|
PROP_USER_DATA_FOLDER,
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename InterfaceType, PCNZWCH runtime_class_id > static HRESULT
|
template < typename InterfaceType, PCNZWCH runtime_class_id > static HRESULT
|
||||||
|
@ -132,7 +134,7 @@ public:
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
RuntimeClassInitialize (GstWebView2Object * obj, GstD3D11Device * device,
|
RuntimeClassInitialize (GstWebView2Object * obj, GstD3D11Device * device,
|
||||||
HANDLE event_handle, HWND hwnd)
|
HANDLE event_handle, HWND hwnd, PCWSTR user_data_folder)
|
||||||
{
|
{
|
||||||
obj_ = obj;
|
obj_ = obj;
|
||||||
device_ = device;
|
device_ = device;
|
||||||
|
@ -186,6 +188,12 @@ public:
|
||||||
hr = webview_visual_->put_IsVisible (TRUE);
|
hr = webview_visual_->put_IsVisible (TRUE);
|
||||||
CHECK_HR_AND_RETURN (hr, put_IsVisible);
|
CHECK_HR_AND_RETURN (hr, put_IsVisible);
|
||||||
|
|
||||||
|
if (user_data_folder) {
|
||||||
|
auto option = Make<CoreWebView2EnvironmentOptions>();
|
||||||
|
return CreateCoreWebView2EnvironmentWithOptions (nullptr,
|
||||||
|
user_data_folder, option.Get (), this);
|
||||||
|
}
|
||||||
|
|
||||||
return CreateCoreWebView2Environment (this);
|
return CreateCoreWebView2Environment (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,6 +720,7 @@ struct GstWebView2ObjectPrivate
|
||||||
ComPtr<IDispatcherQueue> queue;
|
ComPtr<IDispatcherQueue> queue;
|
||||||
GThread *main_thread = nullptr;
|
GThread *main_thread = nullptr;
|
||||||
std::string location;
|
std::string location;
|
||||||
|
std::string user_data_folder;
|
||||||
HANDLE shutdown_begin_handle;
|
HANDLE shutdown_begin_handle;
|
||||||
HANDLE shutdown_end_handle;
|
HANDLE shutdown_end_handle;
|
||||||
WebView2State state = WEBVIEW2_STATE_INIT;
|
WebView2State state = WEBVIEW2_STATE_INIT;
|
||||||
|
@ -750,6 +759,13 @@ gst_webview2_object_class_init (GstWebView2ObjectClass * klass)
|
||||||
GST_TYPE_D3D11_DEVICE, (GParamFlags)
|
GST_TYPE_D3D11_DEVICE, (GParamFlags)
|
||||||
(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS)));
|
G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER,
|
||||||
|
g_param_spec_string ("user-data-folder", "User Data Folder",
|
||||||
|
"User data folder location. Default location is ${APP_EXE}.WebView2 "
|
||||||
|
"but can be varying depending on platform",
|
||||||
|
nullptr, (GParamFlags) (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -801,6 +817,13 @@ gst_webview2_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_DEVICE:
|
case PROP_DEVICE:
|
||||||
priv->device = (GstD3D11Device *) g_value_dup_object (value);
|
priv->device = (GstD3D11Device *) g_value_dup_object (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_USER_DATA_FOLDER:
|
||||||
|
{
|
||||||
|
auto udf = g_value_get_string (value);
|
||||||
|
if (udf)
|
||||||
|
priv->user_data_folder = udf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -820,6 +843,12 @@ gst_webview2_event_loop (GstWebView2Object * self)
|
||||||
HANDLE waitables[] = { priv->shutdown_begin_handle,
|
HANDLE waitables[] = { priv->shutdown_begin_handle,
|
||||||
priv->shutdown_end_handle
|
priv->shutdown_end_handle
|
||||||
};
|
};
|
||||||
|
gunichar2 *udf_location = nullptr;
|
||||||
|
|
||||||
|
if (!priv->user_data_folder.empty ()) {
|
||||||
|
udf_location = g_utf8_to_utf16 (priv->user_data_folder.c_str (),
|
||||||
|
-1, nullptr, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
GST_D3D11_CALL_ONCE_BEGIN {
|
GST_D3D11_CALL_ONCE_BEGIN {
|
||||||
WNDCLASSEXA wc = { };
|
WNDCLASSEXA wc = { };
|
||||||
|
@ -864,7 +893,7 @@ gst_webview2_event_loop (GstWebView2Object * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = MakeAndInitialize < GstWebView2Item > (&priv->item, self, priv->device,
|
hr = MakeAndInitialize < GstWebView2Item > (&priv->item, self, priv->device,
|
||||||
priv->shutdown_begin_handle, hwnd);
|
priv->shutdown_begin_handle, hwnd, (PCWSTR) udf_location);
|
||||||
if (FAILED (hr)) {
|
if (FAILED (hr)) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't initialize item");
|
GST_ERROR_OBJECT (self, "Couldn't initialize item");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -919,6 +948,8 @@ out:
|
||||||
priv->queue = nullptr;
|
priv->queue = nullptr;
|
||||||
if (hwnd)
|
if (hwnd)
|
||||||
CloseWindow (hwnd);
|
CloseWindow (hwnd);
|
||||||
|
|
||||||
|
g_free (udf_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
|
@ -964,14 +995,16 @@ gst_webview2_object_frame_arrived (GstWebView2Object * obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
GstWebView2Object *
|
GstWebView2Object *
|
||||||
gst_webview2_object_new (GstD3D11Device * device)
|
gst_webview2_object_new (GstD3D11Device * device,
|
||||||
|
const std::string & user_data_folder)
|
||||||
{
|
{
|
||||||
GstWebView2Object *self;
|
GstWebView2Object *self;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
|
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
|
||||||
|
|
||||||
self = (GstWebView2Object *)
|
self = (GstWebView2Object *)
|
||||||
g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device, nullptr);
|
g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device,
|
||||||
|
"user-data-folder", user_data_folder.c_str (), nullptr);
|
||||||
gst_object_ref_sink (self);
|
gst_object_ref_sink (self);
|
||||||
|
|
||||||
if (self->priv->state != WEBVIEW2_STATE_RUNNING) {
|
if (self->priv->state != WEBVIEW2_STATE_RUNNING) {
|
||||||
|
|
|
@ -31,7 +31,8 @@ G_BEGIN_DECLS
|
||||||
G_DECLARE_FINAL_TYPE (GstWebView2Object, gst_webview2_object,
|
G_DECLARE_FINAL_TYPE (GstWebView2Object, gst_webview2_object,
|
||||||
GST, WEBVIEW2_OBJECT, GstObject);
|
GST, WEBVIEW2_OBJECT, GstObject);
|
||||||
|
|
||||||
GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device);
|
GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device,
|
||||||
|
const std::string & user_data_folder);
|
||||||
|
|
||||||
gboolean gst_webview2_object_set_location (GstWebView2Object * client,
|
gboolean gst_webview2_object_set_location (GstWebView2Object * client,
|
||||||
const std::string & location,
|
const std::string & location,
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum
|
||||||
PROP_LOCATION,
|
PROP_LOCATION,
|
||||||
PROP_PROCESSING_DEADLINE,
|
PROP_PROCESSING_DEADLINE,
|
||||||
PROP_JAVASCRIPT,
|
PROP_JAVASCRIPT,
|
||||||
|
PROP_USER_DATA_FOLDER,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_LOCATION "about:blank"
|
#define DEFAULT_LOCATION "about:blank"
|
||||||
|
@ -130,6 +131,7 @@ struct GstWebView2SrcPrivate
|
||||||
std::string location = DEFAULT_LOCATION;
|
std::string location = DEFAULT_LOCATION;
|
||||||
GstClockTime processing_deadline = DEFAULT_PROCESSING_DEADLINE;
|
GstClockTime processing_deadline = DEFAULT_PROCESSING_DEADLINE;
|
||||||
std::string script;
|
std::string script;
|
||||||
|
std::string user_data_folder;
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
@ -205,6 +207,12 @@ gst_webview2_src_class_init (GstWebView2SrcClass * klass)
|
||||||
nullptr, (GParamFlags) (G_PARAM_READWRITE |
|
nullptr, (GParamFlags) (G_PARAM_READWRITE |
|
||||||
G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING)));
|
G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING)));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER,
|
||||||
|
g_param_spec_string ("user-data-folder", "User Data Folder",
|
||||||
|
"Absolute path to WebView2 user data folder location.", nullptr,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE |
|
||||||
|
G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)));
|
||||||
|
|
||||||
gst_element_class_set_static_metadata (element_class,
|
gst_element_class_set_static_metadata (element_class,
|
||||||
"WebView2 Source", "Source/Video",
|
"WebView2 Source", "Source/Video",
|
||||||
"Creates a video stream rendered by WebView2",
|
"Creates a video stream rendered by WebView2",
|
||||||
|
@ -314,6 +322,15 @@ gst_webview2_src_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PROP_USER_DATA_FOLDER:
|
||||||
|
{
|
||||||
|
auto udf = g_value_get_string (value);
|
||||||
|
if (udf)
|
||||||
|
priv->user_data_folder = udf;
|
||||||
|
else
|
||||||
|
priv->user_data_folder.clear ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -341,6 +358,9 @@ gst_win32_video_src_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_JAVASCRIPT:
|
case PROP_JAVASCRIPT:
|
||||||
g_value_set_string (value, priv->script.c_str ());
|
g_value_set_string (value, priv->script.c_str ());
|
||||||
break;
|
break;
|
||||||
|
case PROP_USER_DATA_FOLDER:
|
||||||
|
g_value_set_string (value, priv->script.c_str ());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -417,7 +437,7 @@ gst_webview2_src_start (GstBaseSrc * src)
|
||||||
GST_DEBUG_OBJECT (self, "D3D12 copy support: %d", priv->can_d3d12_copy);
|
GST_DEBUG_OBJECT (self, "D3D12 copy support: %d", priv->can_d3d12_copy);
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lk (priv->lock);
|
std::lock_guard < std::mutex > lk (priv->lock);
|
||||||
priv->object = gst_webview2_object_new (priv->device);
|
priv->object = gst_webview2_object_new (priv->device, priv->user_data_folder);
|
||||||
if (!priv->object) {
|
if (!priv->object) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't create object");
|
GST_ERROR_OBJECT (self, "Couldn't create object");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue