Page 1 of 3

WebGadget Extensions (PB v6.xx GTK3)

Posted: Sat Nov 27, 2021 2:45 pm
by mk-soft
WebGadget extensions for PB version v6.xx (GTK3) from Linux version Ubuntu 20.04 LTS and Raspberry PI.

- New: WebGadget EventTypes
- New: WebGadget HitTest Callback
- WebKit_LoadHTML
- WebKit_LoadFile
- WebKit_GetHtmlCode ; Get resource data asynchronous. With synchron not longer work!

Update v1.01.2
- Fix: Now send event with right window id

Update v1.2.1
- Added: #PB_Eventtype_WebLoadFailed ; Detail over EventData()
- Added: #PB_Eventtype_WebLoadFailedTLS ; Detail over EventData()

Update v1.03.2
- Added: WebKit_RunJavaScript(...)
- Added: #PB_EventType_WebRunJavaScriptFinished
- Added: #PB_EventType_WebRunJavaScriptFailed

Update v1.03.3
- WebKit_RunJavaScript added optional parameter ScriptID. Use EventData() to get ScriptID

Update v1.04.1
- Remove WebKit_GetDataAsynchron
- Remove Webkit_GetDataHTML
- Remove #PB_EventType_WebGetDataFinished
- Added WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
- ----
- Remove #PB_EventType_WebRunJavaScriptFinished
- Remove #PB_EventType_WebRunJavaScriptFailed
- Change WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
- ----
- Added WebKit_DisableJavaScript(Gadget, State)
- Added WebKit_IsEnableJavaScript(Gadget)

Update v1.05.1
- Added WebKit_SetNavigationCallback(Gadget, *Callback.Webkit_NavigationCallback)
* This fixed too the "web-process-crashed" on Raspberry Arm64 the click on a link

Update v1.06.2
- Added #PB_EventType_WebProcessCrashed

Update v1.06.3
- Bugfix: Forgot some 'ProcedureC' for callback

Update v1.06.4
- Added WebKit_SetAcceleration(Gadget, Policy)

Update v1.06.6
- Added WebViewGadget
- Optimize Java Result

Update v1.06.7
- Added Settings Get/SetProperty
- Added SetPermissionCallback
- Update Example

Update v1.06.8
- Change: Query the permission request name for better gobject checking

Update v1.06.9
- Added: WebKit_GetVersion as String
- Bugfix: Navigation Callback only with URL

Update v1.06.10
- Change: Move gvalue types to global

WebGadgetEx.pb

Code: Select all

;-TOP

; Comment : WebGadgetEx (GTK3)
; Compiler: Purebasic v6.xx (Ubuntu, Mint Linux, Raspberry PI)
; Author  : mk-soft
; File    : WebGadgetEx.pb
; Version : v1.06.10
; Create  : 26.11.2021
; Update  : 22.06.2025

; Link    : https://www.purebasic.fr/english/viewtopic.php?t=78274

; ---------------------

; Linux Libraries (deb)

; sudo apt-get install libwebkit2gtk-4.0
; sudo apt-get install libwebkit2gtk-4.0-dev

; Syntax Callback:
; - HitTestCallback(Gadget, Type, Text.s)
; - NavigationCallback(Gadget, URI.s)
;   * Return true to enable load uri 
; - GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
; - RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)

; ********************* 

;- Global glib gvalue

CompilerIf Not Defined(__G_TYPE_H__, #PB_Constant)
  #__G_TYPE_H__ = #True
  
  Macro G_TYPE_MAKE_FUNDAMENTAL(x)
    x << 2
  EndMacro
  
  #G_TYPE_INVALID = G_TYPE_MAKE_FUNDAMENTAL(0)
  #G_TYPE_NONE = G_TYPE_MAKE_FUNDAMENTAL(1)
  #G_TYPE_INTERFACE = G_TYPE_MAKE_FUNDAMENTAL(2)
  #G_TYPE_CHAR = G_TYPE_MAKE_FUNDAMENTAL(3)
  #G_TYPE_UCHAR = G_TYPE_MAKE_FUNDAMENTAL(4)
  #G_TYPE_BOOLEAN = G_TYPE_MAKE_FUNDAMENTAL(5)
  #G_TYPE_INT = G_TYPE_MAKE_FUNDAMENTAL(6)
  #G_TYPE_UINT = G_TYPE_MAKE_FUNDAMENTAL(7)
  #G_TYPE_LONG = G_TYPE_MAKE_FUNDAMENTAL(8)
  #G_TYPE_ULONG = G_TYPE_MAKE_FUNDAMENTAL(9)
  #G_TYPE_INT64 = G_TYPE_MAKE_FUNDAMENTAL(10)
  #G_TYPE_UINT64 = G_TYPE_MAKE_FUNDAMENTAL(11)
  #G_TYPE_ENUM = G_TYPE_MAKE_FUNDAMENTAL(12)
  #G_TYPE_FLAGS = G_TYPE_MAKE_FUNDAMENTAL(13)
  #G_TYPE_FLOAT = G_TYPE_MAKE_FUNDAMENTAL(14)
  #G_TYPE_DOUBLE = G_TYPE_MAKE_FUNDAMENTAL(15)
  #G_TYPE_STRING = G_TYPE_MAKE_FUNDAMENTAL(16)
  #G_TYPE_POINTER = G_TYPE_MAKE_FUNDAMENTAL(17)
  #G_TYPE_BOXED = G_TYPE_MAKE_FUNDAMENTAL(18)
  #G_TYPE_PARAM = G_TYPE_MAKE_FUNDAMENTAL(19)
  #G_TYPE_OBJECT = G_TYPE_MAKE_FUNDAMENTAL(20)
  
CompilerEndIf

DeclareModule WebKit2
  
  ImportC ""
    webkit_user_media_permission_is_for_audio_device(*request)
    webkit_user_media_permission_is_for_video_device(*request)
  EndImport
  
  Enumeration #PB_EventType_FirstCustomValue
    #PB_EventType_WebLoadStarted
    #PB_EventType_WebLoadRedirected
    #PB_EventType_WebLoadCommitted
    #PB_EventType_WebLoadFinished
    #PB_EventType_WebLoadFailed
    #PB_EventType_WebLoadFailedTLS
    #PB_EventType_WebProcessCrashed
  EndEnumeration
    
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT  = 1 << 1
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK      = 1 << 2
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE     = 1 << 3
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA     = 1 << 4
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE  = 1 << 5
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6
  #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION = 1 << 7
  
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND = 0
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS = 1
  #WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER = 2
  
  Structure WebKitLoadError
    Link.s
    Code.i
    Message.s
  EndStructure
  
  Structure WebKitLoadErrorTLS
    Link.s
    Errors.i
    *Certificate
  EndStructure
  
  Prototype WebKit_HitTestCallback(Gadget, Type, Text.s)
  Prototype WebKit_GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
  Prototype WebKit_RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)
  Prototype Webkit_NavigationCallback(Gadget, URI.s)
  Prototype Webkit_PermissionCallback(Gadget, RequestName.s, *Request)
  
  Declare WebKit_Init(Gadget)
  Declare WebKit_Free(Gadget)
  
  Declare WebKit_LoadURI(Gadget, URI.s)
  Declare WebKit_LoadHTML(Gadget, content.s, base_uri.s = "localhost")
  Declare WebKit_LoadFile(Gadget, FileName.s)
  
  Declare.s WebKit_GetVersion()
  Declare.s WebKit_GetURI(Gadget)
  Declare.s WebKit_GetTitle(Gadget)
  Declare.i WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
  
  Declare WebKit_SetHitTestCallback(Gadget, *Callback.WebKit_HitTestCallback)
  Declare WebKit_SetNavigationCallback(Gadget, *Callback.WebKit_NavigationCallback)
  Declare WebKit_SetPermissionCallback(Gadget, *Callback.Webkit_PermissionCallback)
  
  Declare WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
  Declare WebKit_DisableJavaScript(Gadget, State)
  Declare WebKit_IsEnableJavaScript(Gadget)
  
  Declare WebKit_EnablePrivateBrowsing(Gadget, State)
  Declare WebKit_IsEnablePrivateBrowsing(Gadget)
  
  Declare WebKit_SetAcceleration(Gadget, Policy)
  
  Declare WebKit_GetProperty(Gadget, Property.s, *Value.gvalue)
  Declare WebKit_SetProperty(Gadget, Property.s, *Value.gvalue)
  
  ; ----
  
EndDeclareModule

Module WebKit2
  
  EnableExplicit
  
  ; ---- Force compiler to link webkit
  
  If 0 : WebGadget(0, 0, 0, 0, 0, "") : EndIf
  
  ; ----
  
  Enumeration
    #WEBKIT_LOAD_STARTED
    #WEBKIT_LOAD_REDIRECTED
    #WEBKIT_LOAD_COMMITTED
    #WEBKIT_LOAD_FINISHED
  EndEnumeration
  
  ; ----
  
  ImportC ""
    webkit_web_view_new()
    webkit_web_view_load_uri(*web_view, url.p-utf8)
    webkit_web_view_load_html(*web_view, content.p-utf8, base_uri.p-utf8);
    webkit_web_view_get_uri(*web_view)
    webkit_web_view_get_title(*web_view)
    
    webkit_hit_test_result_get_context(*hit_test_result)
    
    webkit_hit_test_result_context_is_link(*hit_test_result)
    webkit_hit_test_result_context_is_image(*hit_test_result)
    webkit_hit_test_result_context_is_media(*hit_test_result)
    webkit_hit_test_result_context_is_editable(*hit_test_result)
    webkit_hit_test_result_context_is_selection(*hit_test_result)
    webkit_hit_test_result_context_is_scrollbar(*hit_test_result)
    
    webkit_hit_test_result_get_link_uri(*hit_test_result)
    webkit_hit_test_result_get_link_title(*hit_test_result)
    webkit_hit_test_result_get_link_label(*hit_test_result)
    webkit_hit_test_result_get_image_uri(*hit_test_result)
    webkit_hit_test_result_get_media_uri(*hit_test_result)
    
    webkit_permission_request_allow(*request)
    webkit_permission_request_deny(*request)
    
    webkit_web_view_get_main_resource(*web_view) ; Result WebKitWebResource
    webkit_web_resource_get_data(*resource, *cancellable, *callback, user_data)
    webkit_web_resource_get_data_finish(*resource, *result, *length, *p_error)
    
    webkit_web_view_get_settings(*web_view)
    webkit_web_view_set_settings(*web_view, *settings)
    webkit_settings_get_enable_javascript(*settings)
    webkit_settings_set_enable_javascript(*settings, enabled)
    webkit_settings_set_hardware_acceleration_policy(*settings, policy)
    
    webkit_settings_get_enable_private_browsing(*settings)
    webkit_settings_set_enable_private_browsing(*settings, enabled)
    
    webkit_web_view_run_javascript(*web_view, script.p-utf8, *cancellable, *callback, user_data)
    webkit_web_view_run_javascript_finish(*web_view, *result, *p_error) ; *js_result
    webkit_javascript_result_unref (*js_result)
    webkit_javascript_result_get_global_context(*js_result)
    webkit_javascript_result_get_value(*js_result)
    
    JSValueIsString(*context, value)
    JSValueIsNumber(*context, value)
    JSValueIsInt32(*context, value)
    JSValueToStringCopy(*context, value, outException)
    JSValueToNumber.d(*context, value, outException)
    JSStringGetMaximumUTF8CStringSize(*js_str_value)
    JSStringGetUTF8CString(*js_str_value, *str_value, str_length)
    JSStringRelease(*js_str_value)
    
    ; gobject
    g_type_check_instance(*instance)
    g_type_name(Type)
    g_type_name_from_instance(*instance)
    g_type_name_from_class(*class)
    
    webkit_get_major_version()
    webkit_get_minor_version()
    webkit_get_micro_version()
    
  EndImport
  
  ; ----
  
  Structure udtWebKitGadget
    ; Widgets
    Window.i
    Gadget.i
    WebView.i
    ; Signal handle
    signal_load_changed.i
    signal_mouse_target_changed.i
    signal_load_failed.i
    signal_load_failed_with_tls_errors.i
    signal_web_process_crashed.i
    signal_button_press_event.i
    signal_permission_request.i
    ; Data
    *Resource
    HitTestURI.s
    ; User callback hit test
    *HitTestCallback.WebKit_HitTestCallback
    ; User callback navigation
    *NavigationCallback.WebKit_NavigationCallback
    ; Permission Request
    *PermissionCallback.Webkit_PermissionCallback
    ; User callback get data
    *GetDataCallback.WebKit_GetHtmlCodeCallback
    ; Last load failed
    LoadError.WebKitLoadError
    ; Last load failed tls
    LoadErrorTLS.WebKitLoadErrorTLS
  EndStructure
  
  Structure udtJavaScriptData
    Gadget.i
    ScriptID.i
    *RunJavaScriptCallback.WebKit_RunJavaScriptCallback
  EndStructure
  
  ; ----
  
  Global NewMap mapWebKitGadget.udtWebKitGadget()
  
  ; ----
  
  ProcedureC _signal_load_changed_cb(*web_view, load_event, *GadgetData.udtWebKitGadget)
    With *GadgetData
      Select load_event
        Case #WEBKIT_LOAD_STARTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadStarted)
        Case #WEBKIT_LOAD_COMMITTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadCommitted)
        Case #WEBKIT_LOAD_REDIRECTED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadRedirected)
        Case #WEBKIT_LOAD_FINISHED
          PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFinished)
      EndSelect
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_mouse_target_changed_cb(*web_view, *hit_test_result, modifiers, *GadgetData.udtWebKitGadget)
    Protected gint, *gchar, text.s
    gint = webkit_hit_test_result_get_context(*hit_test_result)
    With *GadgetData
      If *GadgetData
        If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
          *gchar = webkit_hit_test_result_get_link_uri(*hit_test_result)
          \HitTestURI = PeekS(*gchar, -1, #PB_UTF8)
          If \HitTestCallback
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK, \HitTestURI)
          EndIf
        Else
          \HitTestURI = ""
        EndIf
          
        If \HitTestCallback
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE
            *gchar = webkit_hit_test_result_get_image_uri(*hit_test_result)
            text = PeekS(*gchar, -1, #PB_UTF8)
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE, text)
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA
            *gchar = webkit_hit_test_result_get_media_uri(*hit_test_result)
            text = PeekS(*gchar, -1, #PB_UTF8)
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA, text)
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR, "")
          EndIf
          If gint & #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION, "")
          EndIf
          If gint = #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT
            \HitTestCallback(\Gadget, #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT, "")
          EndIf
          
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_load_failed_cb(*web_view, load_event, *failing_uri, *error.gerror, *GadgetData.udtWebKitGadget)
    With *GadgetData
      \LoadError\Link = PeekS(*failing_uri, -1, #PB_UTF8)
      \LoadError\Code = *error\code
      \LoadError\Message + PeekS(*error\message, -1, #PB_UTF8)
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFailed, @\LoadError)
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_load_failed_with_tls_errors_cb(*web_view, *failing_uri, *certificate, errors, *GadgetData.udtWebKitGadget)
    With *GadgetData
      \LoadErrorTLS\Link = PeekS(*failing_uri, -1, #PB_UTF8)
      \LoadErrorTLS\Errors = errors
      \LoadErrorTLS\Certificate = *certificate
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_Eventtype_WebLoadFailedTLS, @\LoadErrorTLS)
    EndWith
    ProcedureReturn #False
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_web_process_crashed_cb(*web_view, *GadgetData.udtWebKitGadget)
    With *GadgetData
      PostEvent(#PB_Event_Gadget, \Window, \Gadget, #PB_EventType_WebProcessCrashed)
      webkit_web_view_load_html(*web_view, "Web Process Crashed!", "")
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_button_press_event_cb(*web_view, *Event.GdkEventButton, *WidgetData.udtWebKitGadget)
    With *WidgetData
      If *Event\button = 1 And \HitTestURI <> ""
        If \NavigationCallback
          If FindString(\HitTestURI, "://")
            If \NavigationCallback(\Gadget, \HitTestURI)
              webkit_web_view_load_uri(*web_view, *WidgetData\HitTestURI)
            Else
              ProcedureReturn 1; Botton process finished
            EndIf
          EndIf
        EndIf
      EndIf
      ProcedureReturn 0 ; Botton process continue
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _signal_permission_request_cb(*web_view, *request.gobject, *GadgetData.udtWebKitGadget)
    Protected r1, *instance_name, request_name.s
    With *GadgetData
      If \PermissionCallback
        If Not g_type_check_instance(*request\g_type_instance)
          ProcedureReturn #True
        EndIf
        *instance_name = g_type_name_from_instance(*request\g_type_instance)
        If Not *instance_name
          ProcedureReturn #True
        EndIf
        request_name = PeekS(*instance_name, -1, #PB_UTF8)
        If \PermissionCallback(\Gadget, request_name, *request)
          webkit_permission_request_allow(*request)
          ProcedureReturn #True
        EndIf
      EndIf
      webkit_permission_request_deny(*request)
    EndWith
    ProcedureReturn #True
  EndProcedure
  
  ; ----
  
  ProcedureC _get_response_data_finish_cb(*resource, *result, *GadgetData.udtWebKitGadget)
    Protected HtmlResult.s, *guchar, length.i, *error.gerror
    With *GadgetData
      *guchar = webkit_web_resource_get_data_finish(*resource, *result, @length, @*error)
      If *guchar
        If \GetDataCallback
          HtmlResult = PeekS(*guchar, length, #PB_UTF8)
          \GetDataCallback(\Gadget, #True, HtmlResult)
        EndIf
        g_free_(*guchar)
      Else
        HtmlResult = PeekS(*error\message, -1, #PB_UTF8)
        g_error_free_(*error)
        If \GetDataCallback
          HtmlResult = PeekS(*guchar, length, #PB_UTF8)
          \GetDataCallback(\Gadget, #False, HtmlResult)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  ProcedureC _web_view_javascript_finished_cb(*object, *result, *ScriptData.udtJavaScriptData)
    Protected JavaResult.s, *js_result, *error.gerror
    Protected *context, value, *js_str_value, *str_value, str_length, dbl_value.d, int_value.i
    
    With *ScriptData
      *js_result = webkit_web_view_run_javascript_finish(*object, *result, @*error)
      If *js_result
        *context = webkit_javascript_result_get_global_context(*js_result);
        value = webkit_javascript_result_get_value(*js_result);
        If value
          *js_str_value = JSValueToStringCopy(*context, value, #Null);
          If *js_str_value
            str_length = JSStringGetMaximumUTF8CStringSize(*js_str_value);
            *str_value = g_malloc_(str_length);
            JSStringGetUTF8CString(*js_str_value, *str_value, str_length);
            JSStringRelease(*js_str_value)                               ;
            JavaResult = PeekS(*str_value, -1, #PB_UTF8)
            g_free_(*str_value)
          EndIf
        Else
          JavaResult = "Java Value is Nil"
        EndIf
        webkit_javascript_result_unref(*js_result)
        If \RunJavaScriptCallback
          \RunJavaScriptCallback(\Gadget, #True, \ScriptID, JavaResult)
        EndIf
      Else
        JavaResult = PeekS(*error\message, -1, #PB_UTF8)
        g_error_free_(*error)
        If \RunJavaScriptCallback
          \RunJavaScriptCallback(\Gadget, #False, \ScriptID, JavaResult)
        EndIf
      EndIf
    EndWith
    FreeStructure(*ScriptData)
  EndProcedure
  
  ; ----
  
  Procedure WebKit_Init(Gadget)
    Protected r1, *GadgetData.udtWebKitGadget, cancel
    
    If Not (GadgetType(Gadget) = #PB_GadgetType_Web Or GadgetType(Gadget) = #PB_GadgetType_WebView)
      ProcedureReturn 0
    EndIf
    
    *GadgetData = AddMapElement(mapWebKitGadget(), Str(Gadget))
    If Not *GadgetData
      ProcedureReturn 0
    EndIf
    
    With *GadgetData
      \Gadget = Gadget
      Select GadgetType(Gadget)
        Case #PB_GadgetType_Web
          \WebView = GadgetID(Gadget)
        Case #PB_GadgetType_WebView
          \WebView = gtk_bin_get_child_(GadgetID(Gadget))
      EndSelect
      \Window = g_object_get_data_(gtk_widget_get_toplevel_(\WebView), "pb_id")
      ; Bind Signals
      \signal_load_changed = g_signal_connect_(\WebView, "load-changed", @_signal_load_changed_cb(), *GadgetData)
      \signal_mouse_target_changed = g_signal_connect_(\WebView, "mouse-target-changed", @_signal_mouse_target_changed_cb(), *GadgetData)
      \signal_load_failed = g_signal_connect_(\WebView, "load-failed", @_signal_load_failed_cb(), *GadgetData)
      \signal_load_failed_with_tls_errors = g_signal_connect_(\WebView, "load-failed-with-tls-errors", @_signal_load_failed_with_tls_errors_cb(), *GadgetData)
      \signal_web_process_crashed = g_signal_connect_(\WebView, "web-process-crashed", @_signal_web_process_crashed_cb(), *GadgetData)
      \signal_button_press_event = g_signal_connect_(\WebView, "button-press-event", @_signal_button_press_event_cb(), *GadgetData)
      \signal_permission_request = g_signal_connect_(\WebView, "permission-request", @_signal_permission_request_cb(), *GadgetData)
    EndWith
    ProcedureReturn *GadgetData
  EndProcedure
  
  ; ----
  
  Procedure WebKit_Free(Gadget)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If Not *GadgetData
      ProcedureReturn 0
    EndIf
    
    With *GadgetData
      ; Unbind Signals
      If g_signal_handler_is_connected_(\WebView, \signal_load_changed)
        g_signal_handler_disconnect_(\WebView, \signal_load_changed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_mouse_target_changed)
        g_signal_handler_disconnect_(\WebView, \signal_mouse_target_changed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_load_failed)
        g_signal_handler_disconnect_(\WebView, \signal_load_failed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_load_failed_with_tls_errors)
        g_signal_handler_disconnect_(\WebView, \signal_load_failed_with_tls_errors)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_web_process_crashed)
        g_signal_handler_disconnect_(\WebView, \signal_web_process_crashed)
      EndIf
      If g_signal_handler_is_connected_(\WebView, \signal_button_press_event)
        g_signal_handler_disconnect_(\WebView, \signal_button_press_event)
      EndIf
      DeleteMapElement(mapWebKitGadget())
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadURI(Gadget, URI.s)
    Protected r1, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      r1 = webkit_web_view_load_uri(*GadgetData\WebView, URI)
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadHTML(Gadget, Content.s, Base_URI.s = "localhost")
    Protected r1, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      r1 = webkit_web_view_load_html(*GadgetData\WebView, Content, Base_URI)
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_LoadFile(Gadget, FileName.s)
    Protected r1, file.s, *GadgetData.udtWebKitGadget
    
    If FileSize(FileName) > 0
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        file = "file://" + FileName
        r1 = webkit_web_view_load_uri(*GadgetData\WebView, file)
      EndIf
    EndIf
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure.s WebKit_GetURI(Gadget)
    Protected s1.s, *gchar, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *gchar = webkit_web_view_get_uri(*GadgetData\WebView)
      If *gchar
        s1 = PeekS(*gchar, -1, #PB_Ascii)
      EndIf
    EndIf
    ProcedureReturn s1
  EndProcedure
  
  ; ----
  
  Procedure.s WebKit_GetTitle(Gadget)
    Protected s1.s, *gchar, *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *gchar = webkit_web_view_get_title(*GadgetData\WebView)
      If *gchar
        s1 = PeekS(*gchar, -1, #PB_Ascii)
      EndIf
    EndIf
    ProcedureReturn s1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetHitTestCallback(Gadget, *Callback.WebKit_HitTestCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\HitTestCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetNavigationCallback(Gadget, *Callback.WebKit_NavigationCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\NavigationCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetPermissionCallback(Gadget, *Callback.Webkit_PermissionCallback)
    Protected *GadgetData.udtWebKitGadget
    
    *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
    If *GadgetData
      *GadgetData\PermissionCallback = *Callback
    EndIf
  EndProcedure
  
  ; ----
  
  Procedure WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
    Protected r1, *GadgetData.udtWebKitGadget
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        \Resource = webkit_web_view_get_main_resource(\WebView)
        If \Resource
          \GetDataCallback = *Callback
          webkit_web_resource_get_data(\Resource, 0, @_get_response_data_finish_cb(), *GadgetData)
          r1 = #True
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
    Protected *GadgetData.udtWebKitGadget, *ScriptData.udtJavaScriptData
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *ScriptData = AllocateStructure(udtJavaScriptData)
        If *ScriptData
          *ScriptData\Gadget = \Gadget
          *ScriptData\ScriptID = ScriptID
          *ScriptData\RunJavaScriptCallback = *Callback
          webkit_web_view_run_javascript(\WebView, JavaScript, #Null, @_web_view_javascript_finished_cb(), *ScriptData)
          r1 = #True
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1  
  EndProcedure
  
  ; ----
  
  Procedure WebKit_DisableJavaScript(Gadget, State)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        If State
          webkit_settings_set_enable_javascript(*settings, #False)
        Else
          webkit_settings_set_enable_javascript(*settings, #True)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure WebKit_IsEnableJavaScript(Gadget)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        r1 = webkit_settings_get_enable_javascript(*settings)
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_EnablePrivateBrowsing(Gadget, State)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        If State
          webkit_settings_set_enable_private_browsing(*settings, #True)
        Else
          webkit_settings_set_enable_private_browsing(*settings, #False)
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure WebKit_IsEnablePrivateBrowsing(Gadget)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1
    
    With *GadgetData
      *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
      If *GadgetData
        *settings = webkit_web_view_get_settings(*GadgetData\WebView)
        r1 = webkit_settings_get_enable_private_browsing(*settings)
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_GetProperty(Gadget, Property.s, *Value.gvalue)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1, value.gvalue
    
    With *GadgetData
      If *value
        *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
        If *GadgetData
          *settings = webkit_web_view_get_settings(*GadgetData\WebView)
          g_object_get_property_(*settings, Property, *value)
          r1 = *Value\g_type
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetProperty(Gadget, Property.s, *Value.gvalue)
    Protected *GadgetData.udtWebKitGadget, *settings
    Protected r1, value.gvalue
    
    With *GadgetData
      If *value
        *GadgetData = FindMapElement(mapWebKitGadget(), Str(Gadget))
        If *GadgetData
          *settings = webkit_web_view_get_settings(*GadgetData\WebView)
          r1 = g_object_set_property_(*settings, Property, *value)
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  ; ----
  
  Procedure WebKit_SetAcceleration(Gadget, Policy)
    Protected webview, *settings
    Select GadgetType(gadget)
      Case #PB_GadgetType_Web
        webview = GadgetID(Gadget)
      Case #PB_GadgetType_WebView
        webview = gtk_bin_get_child_(GadgetID(Gadget))
      Default
        ProcedureReturn 0
    EndSelect
    *settings = webkit_web_view_get_settings(webview)
    webkit_settings_set_hardware_acceleration_policy(*settings, Policy)
  EndProcedure
  
  ; ----
  
  Procedure.s WebKit_GetVersion()
    ProcedureReturn Str(webkit_get_major_version()) + "." + Str(webkit_get_minor_version()) + "." + Str(webkit_get_micro_version())
  EndProcedure
  
EndModule

; ****

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Nov 27, 2021 2:46 pm
by mk-soft
Mini Browser Example
- Update v1.06.8

Code: Select all

;-TOP

; Comment : WebGadgetEx Example (GTK3)
; Compiler: Purebasic v6.xx (Ubuntu 20.04 LTS, Raspberry PI)
; Author  : mk-soft
; Version : v1.06.8
; Create  : 26.11.2021
; Update  : 16.06.2024

; ---------------------

IncludeFile "WebGadgetEx.pb"

; TOP by mk-soft, v1.01.2, 16.06.2024, LGPL

; Link: https://www.purebasic.fr/english/viewtopic.php?t=84557

ImportC ""
  gtk_label_set_ellipsize(Label, Mode)
EndImport

Enumeration
  #PANGO_ELLIPSIZE_NONE
  #PANGO_ELLIPSIZE_START
  #PANGO_ELLIPSIZE_MIDDLE
  #PANGO_ELLIPSIZE_END
EndEnumeration

Procedure SetStatusBarFieldMode(StatusBar, Item, Mode)
  Protected *widget, *list.glist, *frame, *label, *name, cnt
  
  *widget = StatusBarID(StatusBar)
  *list = gtk_container_get_children_(*widget)
  If *list
    cnt = g_list_length_(*list)
    If Item >= cnt
      g_list_free_(*list)
      ProcedureReturn #False
    EndIf
    *frame = g_list_nth_data_(*list, Item)
    g_list_free_(*list)
    If Not *frame
      ProcedureReturn #False
    EndIf
    *list = gtk_container_get_children_(*frame)
    *label = g_list_nth_data_(*list, 0)
    g_list_free_(*list)
    If Not *label
      ProcedureReturn #False
    EndIf
    *name = gtk_widget_get_name_(*label)
    If *name And PeekS(*name, -1, #PB_UTF8) = "GtkLabel"
      gtk_label_set_ellipsize(*label, Mode)
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; ********

UseModule WebKit2

Enumeration Windows 1
  #Main
EndEnumeration

Enumeration Menu
  #MainMenu
EndEnumeration

Enumeration MenuItem
  #MainMenuExit
  #MainMenuGetHtmlData
  #MainMenuLoadHTML
  #MainMenuLoadFile
  #MainMenuDisableJavaScript
  #MainMenuRunJavaScript
EndEnumeration

Enumeration Gadgets
  #MainButtonLoad
  #MainButtonStop
  #MainButtonBack
  #MainButtonForward
  #MainButtonReload
  #MainStringURI
  #MainWebGadget
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

Global ExitApplication

; ****

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight() - 45
  ResizeGadget(#MainWebGadget, 0, 45, dx, dy)
EndProcedure

; ----

Procedure MyHitTestCB(Gadget, Type, Text.s)
  
  Select Type
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
      StatusBarText(#MainStatusBar, 1, "HitTest: " + Text)
      ;Debug "HitTestCB Link: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE
      ;Debug "HitTestCB Image: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA
      ;Debug "HitTestCB Media: " + Text
      
    Case #WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT
      StatusBarText(#MainStatusBar, 1, "HitTest: Dokument")
      ;Debug "HitTestCB Dokument"
      
  EndSelect
                      
EndProcedure  

; ----

Procedure MyGetHtmlDataCB(Gadget, State, Text.s)
  
  If State
    Debug "*** Get Data Callback ***"
    Debug Text
    Debug "*************************"
  Else
    Debug "*** Get Data Callback ***"
    Debug "Error: " + Text
    Debug "*************************"
  EndIf
  
EndProcedure

Procedure MyJavaScripCB(Gadget, State, ScriptID, Result.s)
  
  If State
    Debug "*** JavaScript Callback ***"
    Debug "ScriptID: " + ScriptID
    Debug "Result: " + Result
    Debug "*************************"
  Else
    Debug "*** JavaScript Callback ***"
    Debug "ScriptID " + ScriptID
    Debug "Error: " + Result
    Debug "*************************"
  EndIf
  
EndProcedure

; ----

Procedure MyNavigationCB(Gadget, Uri.s)
  
  If FindString(uri, "#top")
    ProcedureReturn #True
  EndIf
    
  If MessageRequester("Questions", "Open: " + URI, #PB_MessageRequester_YesNo | #PB_MessageRequester_Warning) = #PB_MessageRequester_Yes
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure

Procedure MyPermissionCB(Gadget, RequestName.s, *Request)
  Protected r1, permission_str.s
  Select RequestName
    Case "WebKitGeolocationPermissionRequest"
      permission_str = "Allow this site to see your location?";
    Case "WebKitNotificationPermissionRequest"
      permission_str = "Allow notifications from this website?";
    Case "WebKitDeviceInfoPermissionRequest"
      permission_str = "Allow this site to see your device info?";
    Case "WebKitUserMediaPermissionRequest"
      If webkit_user_media_permission_is_for_audio_device(*request)
        permission_str = "Allow this site to access your microphone?";
      ElseIf webkit_user_media_permission_is_for_video_device(*request)
        permission_str = "Allow this site to access your webcam?";
      Else
        ProcedureReturn #False
      EndIf
    Default
      ProcedureReturn #False
  EndSelect
  
  r1 = MessageRequester("Permission Request", permission_str, #PB_MessageRequester_YesNo)
  If r1 = #PB_MessageRequester_Yes
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure Main()
  Protected x, dx, dy, text.s, file.s, *Error.WebKitLoadError, *ErrorTLS.WebKitLoadErrorTLS
  Protected Script.s
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, 100, 100, 800, 600, "WebKit" , #MainStyle)
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("File")
    MenuItem(#MainMenuGetHtmlData, "&Get HTML Code")
    MenuItem(#MainMenuLoadHTML, "Load &HTLM")
    MenuItem(#MainMenuLoadFile, "Load &File")
    MenuBar()
    MenuItem(#MainMenuDisableJavaScript, "Disable JavaScript")
    MenuItem(#MainMenuRunJavaScript, "Run JavaScript")
    MenuBar()
    MenuItem(#MainMenuExit, "E&xit")
    
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(160)
    AddStatusBarField(#PB_Ignore)
    SetStatusBarFieldMode(#MainStatusBar, 0, #PANGO_ELLIPSIZE_END)
    SetStatusBarFieldMode(#MainStatusBar, 1, #PANGO_ELLIPSIZE_END)
    
    x = 5
    ButtonGadget(#MainButtonReload, x, 5, 90, 30, "Reload")
    x + 95
    ButtonGadget(#MainButtonStop, x, 5, 90, 30, "Stop")
    x + 95
    ButtonGadget(#MainButtonBack, x, 5, 90, 30, "Back")
    x + 95
    ButtonGadget(#MainButtonForward, x, 5, 90, 30, "Forward")
    x + 95
    ButtonGadget(#MainButtonLoad, x, 5, 90, 30, "Load")
    x + 95
    StringGadget(#MainStringURI, x, 5, WindowWidth(#Main) - x - 5, 30, "about:blank")
    
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight() - 45
    WebGadget(#MainWebGadget, 0, 45, dx, dy, "about:blank")
    WebKit_Init(#MainWebGadget)
    ;WebKit_LoadURI(#MainWebGadget, "https://www.purebasic.com")
    WebKit_LoadURI(#MainWebGadget, "https://www.google.com")
    WebKit_SetHitTestCallback(#MainWebGadget, @MyHitTestCB())
    WebKit_SetNavigationCallback(#MainWebGadget, @MyNavigationCB())
    WebKit_SetPermissionCallback(#MainWebGadget, @MyPermissionCB())
    
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow())
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          ExitApplication = #True
          
        Case #PB_Event_Menu
          Select EventMenu()
            Case #MainMenuGetHtmlData
              WebKit_GetHtmlCode(#MainWebGadget, @MyGetHtmlDataCB())
              
            Case #MainMenuLoadHTML
              file = OpenFileRequester("File", "", "", 0)
              If ReadFile(0, file)
                text = ReadString(0, #PB_File_IgnoreEOL | #PB_UTF8)
                WebKit_LoadHTML(#MainWebGadget, text)
              EndIf
              
            Case #MainMenuLoadFile
              file = OpenFileRequester("HTML File", "", "", 0)
              If file
                WebKit_LoadFile(#MainWebGadget, file)
              EndIf
              
            Case #MainMenuDisableJavaScript
              If GetMenuItemState(#MainMenu, #MainMenuDisableJavaScript)
                WebKit_DisableJavaScript(#MainWebGadget, #False)
                SetMenuItemState(#MainMenu, #MainMenuDisableJavaScript, #False)
              Else
                WebKit_DisableJavaScript(#MainWebGadget, #True)
                SetMenuItemState(#MainMenu, #MainMenuDisableJavaScript, #True)
              EndIf
              
            Case #MainMenuRunJavaScript
              Script = InputRequester("JavaScript", "Code:", "window.scrollTo(0,500);")
              If Script
                Debug WebKit_RunJavaScript(#MainWebGadget, 1, Script, @MyJavaScripCB())
              EndIf
              
            Case #MainMenuExit
              ExitApplication = #True
              
          EndSelect
                      
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainButtonLoad
              ;SetGadgetText(#MainWebGadget, GetGadgetText(#MainStringURI))
              WebKit_LoadURI(#MainWebGadget, GetGadgetText(#MainStringURI))
              
            Case #MainButtonReload
              SetGadgetState(#MainWebGadget, #PB_Web_Refresh)
              
            Case #MainButtonStop
              SetGadgetState(#MainWebGadget, #PB_Web_Stop)
              
            Case #MainButtonBack
              SetGadgetState(#MainWebGadget, #PB_Web_Back)
              
            Case #MainButtonForward
              SetGadgetState(#MainWebGadget, #PB_Web_Forward)
              
            Case #MainWebGadget
              Select EventType()
                Case #PB_Eventtype_WebLoadStarted
                  StatusBarText(#MainStatusBar, 0, "Load started")
                  
                Case #PB_Eventtype_WebLoadCommitted
                  StatusBarText(#MainStatusBar, 0, "Load committed")
                  
                Case #PB_Eventtype_WebLoadFinished
                  StatusBarText(#MainStatusBar, 0, "Load finished")
                  SetWindowTitle(#Main, "WebKit - " + WebKit_GetURI(#MainWebGadget))
                  SetGadgetText(#MainStringURI, WebKit_GetURI(#MainWebGadget))
                  
                Case #PB_Eventtype_WebLoadRedirected
                  StatusBarText(#MainStatusBar, 0, "Load redirected")
                  SetWindowTitle(#Main, "WebKit - " + WebKit_GetURI(#MainWebGadget))
                  
                Case #PB_Eventtype_WebLoadFailed
                  *Error = EventData()
                  text = "Link: " + *Error\Link + #LF$ + #LF$
                  text + *Error\Message
                  MessageRequester("Error", text, #PB_MessageRequester_Error)
                  
                Case #PB_Eventtype_WebLoadFailedTLS
                  *ErrorTLS = EventData()
                  text = "Link: " + *ErrorTLS\Link + #LF$ + #LF$
                  text + "Code: " + Hex(*ErrorTLS\Errors)
                  MessageRequester("TLS Error", text, #PB_MessageRequester_Error)
                  
                Case #PB_EventType_WebProcessCrashed
                  StatusBarText(#MainStatusBar, 0, "Web process crashed")
                
              EndSelect
          EndSelect
          
      EndSelect
    Until ExitApplication
    
    WebKit_Free(#MainWebGadget)
    
  EndIf
  
EndProcedure : Main()

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Nov 27, 2021 4:43 pm
by useful
I usually use mint xfce or xubuntu, but for pure experimentation I put classic ubuntu 20.04.3
Everything compiles and works fine, including your example, but I expected that with 6.0 we would be spared:

[22:37:01] Waiting for executable to start...
[22:37:01] Executable type: Linux - x64 (64bit, Unicode)
[22:37:01] Executable started.
[22:37:02] [WARNING] wg.pb (Line: 1)
[22:37:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
[22:37:02] [WARNING] wg.pb (Line: 112)
[22:37:02] [WARNING] GLib (DEBUG): posix_spawn avoided (child_setup specified)
[22:37:02] [WARNING] wg.pb (Line: 112)
[22:37:02] [WARNING] GLib (DEBUG): posix_spawn avoided (child_setup specified)
[22:37:04] [WARNING] wg.pb (Line: 120)
[22:37:04] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gnutls (GTlsBackendGnutls) for ‘gio-tls-backend’
[22:37:08] The Program execution has finished.


Do you have these warnings too?

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Nov 27, 2021 5:43 pm
by mk-soft
Update v1.01.2
- Fix: Now send event with right window id

; ----

I also have some warnings. But not only with my code.
It depends on the GCC compiler and developers libraries which warnings come up.

But you can ignore them.

OS: Ubuntu 2104 LTS

[17:29:02] Executable-Typ: Linux - x64 (64bit, Unicode)
[17:29:02] Executable gestartet.
[17:29:02] [WARNING] WebGadgetEx_Example.pb (Zeile: 1)
[17:29:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
[17:29:02] [WARNING] WebGadgetEx_Example.pb (Zeile: 120)
[17:29:02] [WARNING] GLib-GIO (DEBUG): _g_io_module_get_default: Found default implementation gnutls (GTlsBackendGnutls) for ‘gio-tls-backend’

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sun Nov 28, 2021 6:56 pm
by mk-soft
Update v1.2.1
- Added: #PB_Eventtype_WebLoadFailed ; Detail over EventData()
- Added: #PB_Eventtype_WebLoadFailedTLS ; Detail over EventData()

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Tue Jan 04, 2022 4:49 pm
by Borstensohn
I use Xubuntu 21.10 and PureBasic 5.73 LTS, your test program refuses to run, and this is the error message I get:

/usr/bin/ld: purebasic.o: in function `PB_DEBUGGER_ModuleBank':
(.data+0x15d8): undefined reference to `webkit_web_view_get_main_resource'
/usr/bin/ld: (.data+0x15e0): undefined reference to `webkit_web_resource_get_data'
/usr/bin/ld: (.data+0x15e8): undefined reference to `webkit_web_view_load_html'
/usr/bin/ld: (.data+0x15f0): undefined reference to `webkit_hit_test_result_get_context'
/usr/bin/ld: (.data+0x15f8): undefined reference to `webkit_web_view_load_uri'
/usr/bin/ld: (.data+0x1600): undefined reference to `webkit_hit_test_result_get_link_uri'
...
collect2: error: ld returned 1 exit status

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Tue Jan 04, 2022 6:04 pm
by mk-soft
PB v5.73 does not support Webkit2gtk-4.0, only Webkitgtk and Webkitgtk-3.0.

The Webkitgtk and Webkitgtk-3.0 is no longer supported since Ubuntu 19.04.

Use PB v6.00 Beta (20.04)
Webkit2gtk-4.0 supports gtk3 (gtk2 is no longer supported)

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sun Feb 06, 2022 9:05 pm
by mk-soft
Update v1.03.2
- Added: WebKit_RunJavaScript(...)
- Added: #PB_EventType_WebRunJavaScriptFinished
- Added: #PB_EventType_WebRunJavaScriptFailed

Update v1.03.3
- WebKit_RunJavaScript added optional parameter ScriptID. Use EventData() to get ScriptID

For example java script :wink:

scroll window to
window.scrollTo(0,500);
get scroll y
window.scrollY;

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sun Feb 27, 2022 2:48 pm
by mk-soft
Update v1.04.1
- Remove WebKit_GetDataAsynchron
- Remove Webkit_GetDataHTML
- Remove #PB_EventType_WebGetDataFinished
- Added WebKit_GetHtmlCode(Gadget, *Callback.WebKit_GetHtmlCodeCallback)
- ----
- Remove #PB_EventType_WebRunJavaScriptFinished
- Remove #PB_EventType_WebRunJavaScriptFailed
- Change WebKit_RunJavaScript(Gadget, ScriptID, JavaScript.s, *Callback.WebKit_RunJavaScriptCallback)
- ----
- Added WebKit_DisableJavaScript(Gadget, State)
- Added WebKit_IsEnableJavaScript(Gadget)

The callbacks are hooked into the MainScope by webkit2gtk.
Thus, no 'ThreadSafe' is required as the callback is called internally in the event loop.

Syntax Callback:
- HitTestCallback(Gadget, Type, Text.s)
- GetHtmlCodeCallback(Gadget, State, HtmlCode.s)
- RunJavaScriptCallback(Gadget, State, ScriptID, JavaResult.s)

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Apr 02, 2022 2:26 am
by StarBootics
Hello everyone,

Something completely weird if I load the source "WebGadgetEx.pb" and I run the compiler with the debugger active I get
/usr/bin/ld : purebasic.o : dans la fonction « PB_DEBUGGER_ModuleBank » :
(.data+0xfc8) : référence indéfinie vers « webkit_web_view_get_main_resource »
/usr/bin/ld : (.data+0xfd0) : référence indéfinie vers « webkit_javascript_result_get_value »
/usr/bin/ld : (.data+0xfd8) : référence indéfinie vers « webkit_web_resource_get_data »
/usr/bin/ld : (.data+0xfe0) : référence indéfinie vers « JSValueIsNumber »
/usr/bin/ld : (.data+0xfe8) : référence indéfinie vers « webkit_web_view_get_settings »
/usr/bin/ld : (.data+0xff0) : référence indéfinie vers « webkit_settings_get_enable_javascript »
...
collect2: error: ld returned 1 exit status
And without the debugger I get :
/usr/bin/ld : purebasic.o : dans la fonction « _SYS_StaticStringEnd » :
(.data+0x1c8) : référence indéfinie vers « webkit_web_view_get_main_resource »
/usr/bin/ld : (.data+0x1d0) : référence indéfinie vers « webkit_javascript_result_get_value »
/usr/bin/ld : (.data+0x1d8) : référence indéfinie vers « webkit_web_resource_get_data »
/usr/bin/ld : (.data+0x1e0) : référence indéfinie vers « JSValueIsNumber »
/usr/bin/ld : (.data+0x1e8) : référence indéfinie vers « webkit_web_view_get_settings »
/usr/bin/ld : (.data+0x1f0) : référence indéfinie vers « webkit_settings_get_enable_javascript »
...
collect2: error: ld returned 1 exit status
If I try the example "WebGadgetEx Example.pb" that include "WebGadgetEx.pb" everything work fine.

I'm using Ubuntu 21.10 and PB V6.00 Beta 6.

Best regards
StarBootics

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Apr 02, 2022 10:09 am
by mk-soft
Without using the WegGadget the compiler not linked the webkit library!

You can add this line inside the Module to force the webkit library.

Code: Select all

If 0 : WebGadget(0, 0, 0, 0, 0, "") : EndIf
But normality not needed

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Mon Apr 04, 2022 12:45 am
by StarBootics
Hello again,

I'm trying to make the following code to work :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Gtk WebView Widget
; File Name : Gtk WebView Widget - OOP.pb
; File version: 0.0.0
; Programming : Linker Errors problem
; Programmed by : StarBootics
; Date : April 3rd, 2022
; Last Update : April 3rd, 2022
; PureBasic code : V6.00 Beta 6
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule GtkWindow
  
  Interface Window
    
    GetID.i()
    GetPosition(*PosX, *PosY)
    SetPosition(Position.i = #GTK_WIN_POS_NONE)
    SetSize(Width.l, Height.l)
    SetTitle(Title.s)
    SetResizable(Resizable.i)
    SetBorderWidth(BorderWidth.l)
    SetTransientFor(*Parent)
    SetKeepAbove(Setting.i)
    Move(X.l, Y.l)
    Show()
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    AddWidget(*Widget)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWindow
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WindowID
  EndProcedure
  
  Procedure GetPosition(*This.Private_Members, *PosX, *PosY)
    
    gtk_window_get_position_(*This\WindowID, *PosX, *PosY)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetPosition(*This.Private_Members, Position.i = #GTK_WIN_POS_NONE)
    
    gtk_window_set_position_(*This\WindowID, Position)
    
  EndProcedure
  
  Procedure SetSize(*This.Private_Members, Width.l, Height.l)
    
    gtk_window_set_default_size_(*This\WindowID, Width, Height)
    
  EndProcedure
  
  Procedure SetTitle(*This.Private_Members, Title.s)
    
    gtk_window_set_title_(*This\WindowID, Title)
    
  EndProcedure
  
  Procedure SetResizable(*This.Private_Members, Resizable.i)
    
    gtk_window_set_resizable_(*This\WindowID, Resizable)
    
  EndProcedure
  
  Procedure SetBorderWidth(*This.Private_Members, BorderWidth.l)
    
    gtk_container_set_border_width_(*This\WindowID, BorderWidth)
    
  EndProcedure
  
  Procedure SetTransientFor(*This.Private_Members, *Parent)
    
    gtk_window_set_transient_for_(*This\WindowID, *Parent)
    
  EndProcedure

  Procedure SetKeepAbove(*This.Private_Members, Setting.i)
    
    gtk_window_set_keep_above_(*This\WindowID, Setting)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Move <<<<<
  
  Procedure Move(*This.Private_Members, X.l, Y.l)
    
    gtk_window_move_(*This\WindowID, X, Y)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Show <<<<<
  
  Procedure Show(*This.Private_Members)
    
     gtk_widget_show_all_(*This\WindowID)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\WindowID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure AddWidget(*This.Private_Members, *Widget)
    
    gtk_container_add_(*This\WindowID, *Widget)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WindowID = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetPosition()
    Data.i @SetPosition()
    Data.i @SetSize()
    Data.i @SetTitle()
    Data.i @SetResizable()
    Data.i @SetBorderWidth()
    Data.i @SetTransientFor()
    Data.i @SetKeepAbove()
    Data.i @Move()
    Data.i @Show()
    Data.i @SignalConnect()
    Data.i @AddWidget()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule GtkWebView
  
  Interface WebView
    
    GetID.i()
    GetUri.s()
    GetTitle.s()
    LoadUri.i(Uri.s)
    LoadHtml.i(Content.s, Base_URI.s = "localhost")
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWebView
  
  ImportC ""
    
    webkit_web_view_new()
    webkit_web_view_load_uri(*web_view, url.p-utf8)
    webkit_web_view_load_html(*web_view, content.p-utf8, base_uri.p-utf8)
    webkit_web_view_get_uri(*web_view)
    webkit_web_view_get_title(*web_view)
    
;     webkit_hit_test_result_get_context(*hit_test_result)
;     
;     webkit_hit_test_result_context_is_link(*hit_test_result)
;     webkit_hit_test_result_context_is_image(*hit_test_result)
;     webkit_hit_test_result_context_is_media(*hit_test_result)
;     webkit_hit_test_result_context_is_editable(*hit_test_result)
;     webkit_hit_test_result_context_is_selection(*hit_test_result)
;     webkit_hit_test_result_context_is_scrollbar(*hit_test_result)
;     
;     webkit_hit_test_result_get_link_uri(*hit_test_result)
;     webkit_hit_test_result_get_link_title(*hit_test_result)
;     webkit_hit_test_result_get_link_label(*hit_test_result)
;     webkit_hit_test_result_get_image_uri(*hit_test_result)
;     webkit_hit_test_result_get_media_uri(*hit_test_result)
;     
;     webkit_web_view_get_main_resource(*web_view) ; Result WebKitWebResource
;     webkit_web_resource_get_data(*resource, *cancellable, *callback, user_data)
;     webkit_web_resource_get_data_finish(*resource, *result, *length, *p_error)
;     
;     webkit_web_view_get_settings(*web_view)
;     webkit_web_view_set_settings(*web_view, *settings)
;     webkit_settings_get_enable_javascript(*settings)
;     webkit_settings_set_enable_javascript(*settings, enabled)
;     
;     webkit_web_view_run_javascript(*web_view, script.p-utf8, *cancellable, *callback, user_data)
;     webkit_web_view_run_javascript_finish(*web_view, *result, *p_error) ; *js_result
;     webkit_javascript_result_unref (*js_result)
;     webkit_javascript_result_get_global_context(*js_result)
;     webkit_javascript_result_get_value(*js_result)
;     
;     JSValueIsString(*context, value)
;     JSValueIsNumber(*context, value)
;     JSValueToStringCopy(*context, value, outException)
;     JSValueToNumber.d(*context, value, outException)
;     JSStringGetMaximumUTF8CStringSize(*js_str_value)
;     JSStringGetUTF8CString(*js_str_value, *str_value, str_length)
;     JSStringRelease(*js_str_value)
    
  EndImport
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WebViewID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WebViewID
  EndProcedure
  
  Procedure.s GetUri(*This.Private_Members)
    
    *gchar = webkit_web_view_get_uri(*This\WebViewID)
    
    If *gchar
      s1.s = PeekS(*gchar, -1, #PB_UTF8)
    EndIf
    
    ProcedureReturn s1
  EndProcedure
  
  Procedure.s GetTitle(*This.Private_Members)
    
    *gchar = webkit_web_view_get_title(*This\WebViewID)
    
    If *gchar
      s1.s = PeekS(*gchar, -1, #PB_UTF8)
    EndIf
    
    ProcedureReturn s1
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.i LoadUri(*This.Private_Members, Uri.s)
    
    ProcedureReturn webkit_web_view_load_uri(*This\WebViewID, Uri)
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.i LoadHtml(*This.Private_Members, Content.s, Base_URI.s = "localhost")
    
    ProcedureReturn webkit_web_view_load_html(*This\WebViewID, Content, Base_URI)
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WebViewID = webkit_web_view_new()

    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetUri()
    Data.i @GetTitle()
    Data.i @LoadUri()
    Data.i @LoadHtml()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
  If 0
    *This.Private_Members = New()
    GetUri(*This)
    GetTitle(*This)
    LoadUri(*This, "")
    LoadHtml(*This, "")
  EndIf
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  ProcedureC WindowDeleteEventHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    Debug "WindowDeleteEventHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
  EndProcedure
  
  ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    gtk_main_quit_()
    
  EndProcedure

  gtk_init_(0, 0)
  
  MainWin.GtkWindow::Window = GtkWindow::New()
  MainWin\SetSize(800, 600)
  MainWin\SetTitle("Gtk WebView")
  MainWin\SetPosition(#GTK_WIN_POS_CENTER)
  MainWin\SetResizable(#False)
  MainWin\Move(100, 100)
  MainWin\SignalConnect("delete-event", @WindowDeleteEventHandler(), 25)
  MainWin\SignalConnect("destroy", @WindowCloseHandler(), 0)
  
  WebView.GtkWebView::WebView = GtkWebView::New()
  
  WebView\LoadUri("https://www.purebasic.com")
  
  MainWin\AddWidget(WebView\GetID())
  
  MainWin\Show()
  
  gtk_main_()
  
  MainWin\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Unfortunately I get linker errors and I can't figure out why. Any ideas !?!

Best regards
StarBootics

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Mon Apr 04, 2022 8:36 am
by mk-soft
For the webkit you need something more.

Pack the WebkitView into a ScrolledWindow. Even if you can't control the ScrolledWindow from the outside, because internally only the Webkit does that.
I once had the Webkit (without Java) running with PB. The structure for the WebKit2gtk I had somewhere from a C++ example

Link: https://www.purebasic.fr/english/viewtopic.php?t=78246

I have not yet found the path to the library for ImportC. I use OpenLibrary ...

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sun May 29, 2022 3:00 pm
by mk-soft
Update v1.05.1
- Added WebKit_SetNavigationCallback(Gadget, Callback)
* This fixed too the "web-process-crashed" on Raspberry Arm64 the click on a link

Re: WebGadget Extension (PB v6.00 GTK3)

Posted: Sat Jun 18, 2022 12:02 pm
by mk-soft
Update v1.06.2
- Added #PB_EventType_WebProcessCrashed