Get and set scroll position in WebGadget
Get and set scroll position in WebGadget
Hi,
I need to be able to read the vertical scroll position in a WebGadget and to move the scroll position in another WebGadget accordingy - I need those #PB_Web_ScrollY in GetGadgetAttribute() to work.
(The specific need is for a reader, to have two columns of content scrolling synchronized - two WebGadgets in the usual vertical scrolling, with the same content but offset.)
A previous recent search for the trick could not produce results. I am a bit rusty in managing GTK directly, so I may need a little help.
I suppose the documentation is that of [edit: no, see below] ; I will be checking it now.
I need to be able to read the vertical scroll position in a WebGadget and to move the scroll position in another WebGadget accordingy - I need those #PB_Web_ScrollY in GetGadgetAttribute() to work.
(The specific need is for a reader, to have two columns of content scrolling synchronized - two WebGadgets in the usual vertical scrolling, with the same content but offset.)
A previous recent search for the trick could not produce results. I am a bit rusty in managing GTK directly, so I may need a little help.
I suppose the documentation is that of [edit: no, see below] ; I will be checking it now.
Last edited by mdp on Sun Feb 06, 2022 11:44 pm, edited 1 time in total.
Re: Get and set scroll position in WebGadget
One note: I had difficulties already identifying the documentation:
on my system, it seems what I should use is what in https://webkitgtk.org/ is the "Deprecated API Reference WebKit1", https://webkitgtk.org/reference/webkitg ... index.html , as I am finding the working functions there, instead of the "Stable API Reference WebKit2".
This as I had seen that for me and many other posters functions like webkit_web_settings_new() and webkit_web_view_load_string() worked, while apparently equivalent in the new documentation, webkit_settings_new() etc. gave "undefined reference" linker errors.
I think I will stick with the installed version, which most of us seem to be using, but the upgrade from WebKitGTK+ to WebKit2GTK seems to be possible directly with an install, see Shardik's post at https://www.purebasic.fr/english/viewto ... t2#p527097
on my system, it seems what I should use is what in https://webkitgtk.org/ is the "Deprecated API Reference WebKit1", https://webkitgtk.org/reference/webkitg ... index.html , as I am finding the working functions there, instead of the "Stable API Reference WebKit2".
This as I had seen that for me and many other posters functions like webkit_web_settings_new() and webkit_web_view_load_string() worked, while apparently equivalent in the new documentation, webkit_settings_new() etc. gave "undefined reference" linker errors.
I think I will stick with the installed version, which most of us seem to be using, but the upgrade from WebKitGTK+ to WebKit2GTK seems to be possible directly with an install, see Shardik's post at https://www.purebasic.fr/english/viewto ... t2#p527097
Re: Get and set scroll position in WebGadget
In theory we are not far away; in practice, I can read the scroll position, but strangely cannot set it yet:
Edit: probably because the value parameters of are in fact of type 'gfloat'? From other examples, 'int' can be used for 'gint'... Again, the documentation for gfloat, gdouble etc. is not immediately found with a search.
Code: Select all
ImportC "-lwebkitgtk-3.0"
webkit_web_view_get_dom_document(*wkwv) ; WebKitWebView → WebKitDOMDocument
webkit_dom_document_get_default_view(*wkdd) ; WebKitDOMDocument → WebKitDOMDOMWindow
webkit_dom_dom_window_scroll_by(*wkddw, x.d, y.d)
webkit_dom_dom_window_scroll_to(*wkddw, x.d, y.d)
webkit_dom_dom_window_move_by(*wkddw, x.f, y.f)
webkit_dom_dom_window_move_to(*wkddw, x.f, y.f)
webkit_dom_dom_window_get_scroll_y(*wkddw)
EndImport
s.s = "Lorem ipsum felicitas sit amet. "
s="<p>"+s+s+s+s+"</p>"+#LF$+"<p>"+s+s+"</p>"+#LF$+"<p>"+s+s+s+"</p>"
For a=0 To 9
html.s = html+"<h1>Section #"+a+"</h1>"+s+"<hr/>"+#LF$
Next
OpenWindow(0,0,0,800,600,"Test")
WebGadget(0,0,0,800,600,"")
SetGadgetItemText(0,#PB_Web_HtmlCode,html)
*wkdd = webkit_web_view_get_dom_document(GadgetID(0)) : Debug *wkdd
*wkddw = webkit_dom_document_get_default_view(*wkdd) : Debug *wkddw
webkit_dom_dom_window_move_to(*wkddw, 0.0, 1000.0)
Repeat
EvID = WaitWindowEvent()
ypos = webkit_dom_dom_window_get_scroll_y(*wkddw)
If ypos<>old_ypos : Debug "> ypos: "+ypos : old_ypos=ypos : EndIf
Until EvID=#PB_Event_CloseWindow
Last edited by mdp on Sun Feb 06, 2022 5:40 pm, edited 3 times in total.
Re: Get and set scroll position in WebGadget
It depends on which Linux version you are using.
Therefore you must also use the library functions.
- Up to Ubuntu 18.04 : libwebkitgtk-3.0
- From Ubuntu 20.04 : libwebkit2gtk-4.0
Only with PB v6.00 (20.04) the Webkit 2 (only gtk3) is supported.
Therefore you must also use the library functions.
- Up to Ubuntu 18.04 : libwebkitgtk-3.0
- From Ubuntu 20.04 : libwebkit2gtk-4.0
Only with PB v6.00 (20.04) the Webkit 2 (only gtk3) is supported.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Get and set scroll position in WebGadget
With the new PB, I see, the version the new API, WebKit2GTK, will have to be used, and new techniques adopted for the scrolling.
Nonetheless, it would be nice to make this one work, for completeness... Reading the scrolling position works; setting it does not.
Edit: also because:
-- I just tried the #PB_Web_ScrollY attribute on the PB 6.00 beta, and it does not work;
-- I checked the documentation index for WebKit2GTK ( https://webkitgtk.org/reference/webkit2 ... x-all.html ) to find information about scrolling, position, and moving, and nothing evident appears... It must be hidden in some obscure part
Re: Get and set scroll position in WebGadget
Incidentally: I also tried the "JavaScriptCore" way, as suggested by the API documentation, and I interpreted that as meaning "using JSEvaluateScript()".
It does not work. There is a chance that I am using a bad syntax on JSEvaluateScript...
There may be also a chance that those commands require JavaScript to be enabled on the WebGadget for JavaScriptCore to work? In that case: no, never. Javascript has to remain disabled for security: it's a reader one simply needs. There must be no need for the WebGadget to process scripts /inside/ its "web contents", to achieve something as simple as scrolling. Not sure this is the case, but...
Edit: ...but I suspect it is not the case of "enabling javascript in the WebGadget", because I tried an
and it equally does not work.
Code: Select all
ImportC "-lwebkitgtk-3.0"
webkit_web_view_get_dom_document(*wkwv) ; WebKitWebView → WebKitDOMDocument
webkit_dom_document_get_default_view(*wkdd) ; WebKitDOMDocument → WebKitDOMDOMWindow
webkit_dom_dom_window_scroll_by(*wkddw, x.d, y.d)
webkit_dom_dom_window_scroll_to(*wkddw, x.d, y.d)
webkit_dom_dom_window_move_by(*wkddw, x.f, y.f)
webkit_dom_dom_window_move_to(*wkddw, x.f, y.f)
webkit_dom_dom_window_get_scroll_y(*wkddw)
;webkit_web_view_get_javascript_global_context(*wkwv) ; WebKitWebView → JSGlobalContextRef
webkit_web_view_get_main_frame(*wkwv) ; WebKitWebView → WebKitWebFrame
webkit_web_frame_get_global_context(*wkwf) ; WebKitWebFrame → JSGlobalContextRef
EndImport
ImportC ""
JSEvaluateScript(*ctx, *script, *thisObject, *sourceURL, startingLineNumber, *exception)
;Pointer ctx, Pointer script, Pointer thisObject, Pointer sourceURL, int startingLineNumber, Pointer<Pointer> exception
JSStringCreateWithUTF8CString(*s)
EndImport
s.s = "Lorem ipsum felicitas sit amet. "
s="<p>"+s+s+s+s+"</p>"+#LF$+"<p>"+s+s+"</p>"+#LF$+"<p>"+s+s+s+"</p>"
For a=0 To 9
html.s = html+"<h1>Section #"+a+"</h1>"+s+"<hr/>"+#LF$
Next
OpenWindow(0,0,0,800,600,"Test")
WebGadget(0,0,0,800,600,"")
SetGadgetItemText(0,#PB_Web_HtmlCode,html)
*wkwf = webkit_web_view_get_main_frame(GadgetID(0)) : Debug *wkwf
*jsgcr = webkit_web_frame_get_global_context(*wkwf) : Debug *jsgcr
Debug JSEvaluateScript(*jsgcr,JSStringCreateWithUTF8CString("window.scrollTo(0,1000);"),#Null,#Null,1,#Null)
Repeat
EvID = WaitWindowEvent()
Until EvID=#PB_Event_CloseWindow
There may be also a chance that those commands require JavaScript to be enabled on the WebGadget for JavaScriptCore to work? In that case: no, never. Javascript has to remain disabled for security: it's a reader one simply needs. There must be no need for the WebGadget to process scripts /inside/ its "web contents", to achieve something as simple as scrolling. Not sure this is the case, but...
Edit: ...but I suspect it is not the case of "enabling javascript in the WebGadget", because I tried an
Code: Select all
JSEvaluateScript(*jsgcr,JSStringCreateWithUTF8CString("document.body.style.background = '#ACE'"),#Null,#Null,0,#Null)
Re: Get and set scroll position in WebGadget
I have extended my modules for the WebGadget with RunJavaScript. It works
JavaScript 'window.scrollTo(0,500);'
Show Module: WebGadget Extension (PB v6.00 GTK3) and Mini Browser Example
JavaScript 'window.scrollTo(0,500);'
Show Module: WebGadget Extension (PB v6.00 GTK3) and Mini Browser Example
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Get and set scroll position in WebGadget
Thank you Mk-Soft,
it will surely be useful to extend functionality on PB6.xx, libraries webkit2gtk-4.0. Also because, I read that the multithreading feature of webkit2gtk make it a mess... By the way: can you use those javascript functions while keeping the webgadget in "disabled javascript" state?
There should be a solution though for the traditional libraries, PB 5.73... It should be much simpler than its successor!
Re: Get and set scroll position in WebGadget
I tried the third way, and again no good result but it's there, close...
In theory, the traditional WebGadget should be wrapped inside a GtkScrolledWindow (what allows the scrollbars in that version of GTK), and gtk_scrolled_window_get_vadjustment should return a GtkAdjustment which contains the scrolling. To the best of my understanding.
Now, the way below does not work, but I can see it, in memory, the value is there, changing before my eyes as I scroll,
if I check the memory at range between *ga-128 and *ga+128 ¹ it is within a structure right above, looks like a float ², it's there exactly at *ga-92, and I cannot get what it is part of...
Edit: also, said scroll value is 16 bytes after the result of gtk_adjustment_get_value(*ga) - that "get value" should return it, and instead it is two "longs or doubles" later...
It must not be the gtk_widget_get_parent(GadgetID(0)) that reaches the right window... Need to get from the WebKitWebView which is the WebGadget to its right GtkScrolledWindow...
( ¹ *ga being the vadjustment of the parent of the WebGadget... )
(² well, it should be a double, according to specifications, at *ga-96 - whatever... )
In theory, the traditional WebGadget should be wrapped inside a GtkScrolledWindow (what allows the scrollbars in that version of GTK), and gtk_scrolled_window_get_vadjustment should return a GtkAdjustment which contains the scrolling. To the best of my understanding.
Now, the way below does not work, but I can see it, in memory, the value is there, changing before my eyes as I scroll,
if I check the memory at range between *ga-128 and *ga+128 ¹ it is within a structure right above, looks like a float ², it's there exactly at *ga-92, and I cannot get what it is part of...
Edit: also, said scroll value is 16 bytes after the result of gtk_adjustment_get_value(*ga) - that "get value" should return it, and instead it is two "longs or doubles" later...
It must not be the gtk_widget_get_parent(GadgetID(0)) that reaches the right window... Need to get from the WebKitWebView which is the WebGadget to its right GtkScrolledWindow...
( ¹ *ga being the vadjustment of the parent of the WebGadget... )
(² well, it should be a double, according to specifications, at *ga-96 - whatever... )
Code: Select all
ImportC ""
gtk_scrolled_window_get_vadjustment( *scrolled_window ) ; GtkScrolledWindow* → GtkAdjustment*
gtk_widget_get_parent( *widget ) ; GtkWidget → GtkWidget
gtk_adjustment_get_value(*adjustment) ; GtkAdjustment → gdouble
gtk_adjustment_get_upper(*adjustment) ; GtkAdjustment → gdouble
EndImport
s.s = "Lorem ipsum felicitas sit amet. "
s="<p>"+s+s+s+s+"</p>"+#LF$+"<p>"+s+s+"</p>"+#LF$+"<p>"+s+s+s+"</p>"
For a=0 To 9
html.s = html+"<h1>Section #"+a+"</h1>"+s+"<hr/>"+#LF$
Next
OpenWindow(0,0,0,800,600,"Test")
WebGadget(0,0,0,800,600,"")
SetGadgetItemText(0,#PB_Web_HtmlCode,html)
*scrolledwin = gtk_widget_get_parent(GadgetID(0)) : Debug *scrolledwin
*ga = gtk_scrolled_window_get_vadjustment(*scrolledwin) : Debug *ga
ypos.d = PeekD(gtk_adjustment_get_value(*ga)) : Debug ypos
uppr.d = PeekD(gtk_adjustment_get_upper(*ga)) : Debug uppr
Repeat
EvID = WaitWindowEvent()
Until EvID=#PB_Event_CloseWindow
Last edited by mdp on Mon Feb 07, 2022 12:25 am, edited 1 time in total.
Re: Get and set scroll position in WebGadget
The 'multithreading feature' is a bit annoying.it will surely be useful to extend functionality on PB6.xx, libraries webkit2gtk-4.0. Also because, I read that the multithreading feature of webkit2gtk make it a mess...
It took me a long time to figure out why the thread for reading the content of the webgadget didn't start.
You can no longer wait for the callback with a semaphore in the same call to read the webgadget content. The thread only starts when the call is exited. And then the callback comes.
I don't known, but I think notBy the way: can you use those javascript functions while keeping the webgadget in "disabled javascript" state?
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Get and set scroll position in WebGadget
Well, that would be a critical issue. It would be like being able to load a page, but, js being disabled, not being able to scroll or zoom. But anyway, it should be verified. It's just that in these mindless times of internet-connected shoes I am scared in advance.
Re: Get and set scroll position in WebGadget
I friggin' made it, with the "GtkAdjustment vadjustment of GtkScrolledWindow" way, and it's been a #@!# journey.
So, webkit_dom_dom_window_get_scroll_y() works, but webkit_dom_dom_window_move_to() and similar do not; whereas
gtk_adjustment_get_value() does not, but gtk_adjustment_set_value() and gtk_scrolled_window_set_vadjustment() do. So,
Meanwhile, to reach that, I have seen the strangest things: gtk_adjustment_get_value(), gtk_adjustment_get_upper() etc. should return double precision values directly: instead, they all return a pointer - the same pointer -, and that pointer is 16 bytes before the actual type-double value. The source code for GtkAdjustment is at https://gitlab.gnome.org/GNOME/gtk/-/bl ... justment.c , and I do not know how such behaviour is explained.
So, webkit_dom_dom_window_get_scroll_y() works, but webkit_dom_dom_window_move_to() and similar do not; whereas
gtk_adjustment_get_value() does not, but gtk_adjustment_set_value() and gtk_scrolled_window_set_vadjustment() do. So,
Code: Select all
ImportC "-lwebkitgtk-3.0"
webkit_web_view_get_dom_document(*wkwv) ; WebKitWebView → WebKitDOMDocument
webkit_dom_document_get_default_view(*wkdd) ; WebKitDOMDocument → WebKitDOMDOMWindow
webkit_dom_dom_window_get_scroll_y(*wkddw)
EndImport
ImportC ""
gtk_scrolled_window_get_vadjustment( *scrolled_window ) ; GtkScrolledWindow* → GtkAdjustment*
gtk_widget_get_parent( *widget ) ; GtkWidget → GtkWidget
gtk_adjustment_set_value(*adjustment, v.d) ; GtkAdjustment → gdouble
gtk_scrolled_window_set_vadjustment (*scrolled_window, *vadjustment)
EndImport
s.s = "Lorem ipsum felicitas sit amet. "
s="<p>"+s+s+s+s+"</p>"+#LF$+"<p>"+s+s+"</p>"+#LF$+"<p>"+s+s+s+"</p>"
For a=0 To 9
html.s = html+"<h1>Section #"+a+"</h1>"+s+"<hr/>"+#LF$
Next
OpenWindow(0,0,0,800,600,"Test")
WebGadget( 0, 0,40,800,560,"")
ButtonGadget(1, 0, 0,400, 40,"<")
ButtonGadget(2,400, 0,400, 40,">")
SetGadgetItemText(0,#PB_Web_HtmlCode,html)
*wkdd = webkit_web_view_get_dom_document(GadgetID(0)) : Debug *wkdd
*wkddw = webkit_dom_document_get_default_view(*wkdd) : Debug *wkddw
*scrolledwin = gtk_widget_get_parent(GadgetID(0)) : Debug *scrolledwin
*ga = gtk_scrolled_window_get_vadjustment(*scrolledwin) : Debug *ga
Repeat
EvID = WaitWindowEvent()
Select EvID
Case #PB_Event_Gadget
EvG = EventGadget()
Select EvG
Case 1
ypos = webkit_dom_dom_window_get_scroll_y(*wkddw)
gtk_adjustment_set_value(*ga,ypos-100.0)
gtk_scrolled_window_set_vadjustment(*scrolledwin, *ga)
Case 2
ypos = webkit_dom_dom_window_get_scroll_y(*wkddw)
gtk_adjustment_set_value(*ga,ypos+100.0)
gtk_scrolled_window_set_vadjustment(*scrolledwin, *ga)
EndSelect
EndSelect
Until EvID=#PB_Event_CloseWindow
Re: Get and set scroll position in WebGadget
So, by the way, the "multicolumn with scroll" effect I intended would be along the lines of
with some polishing of the effect still pending.
Code: Select all
ImportC "-lwebkitgtk-3.0"
webkit_web_view_get_dom_document(*wkwv) ; WebKitWebView → WebKitDOMDocument
webkit_dom_document_get_default_view(*wkdd) ; WebKitDOMDocument → WebKitDOMDOMWindow
webkit_dom_dom_window_get_scroll_y(*wkddw)
EndImport
ImportC ""
gtk_scrolled_window_get_vadjustment( *scrolled_window ) ; GtkScrolledWindow* → GtkAdjustment*
gtk_widget_get_parent( *widget ) ; GtkWidget → GtkWidget
gtk_adjustment_set_value(*adjustment, v.d) ; GtkAdjustment → gdouble
gtk_scrolled_window_set_vadjustment (*scrolled_window, *vadjustment)
EndImport
s.s = "Lorem ipsum felicitas sit amet. "
s="<p>"+s+s+s+s+"</p>"+#LF$+"<p>"+s+s+"</p>"+#LF$+"<p>"+s+s+s+"</p>"
For a=0 To 9
html.s = html+"<h1>Section #"+a+"</h1>"+s+"<hr/>"+#LF$
Next
OpenWindow(0,0,0,1280,960,"Test",#PB_Window_ScreenCentered)
WebGadget(0, 0,0,640,960,"")
WebGadget(1,640,0,640,960,"")
SetGadgetItemText(0,#PB_Web_HtmlCode,html)
SetGadgetItemText(1,#PB_Web_HtmlCode,html)
*wkdd0 = webkit_web_view_get_dom_document(GadgetID(0)) : Debug *wkdd0
*wkddw0 = webkit_dom_document_get_default_view(*wkdd0) : Debug *wkddw0
*wkdd1 = webkit_web_view_get_dom_document(GadgetID(1)) : Debug *wkdd1
*wkddw1 = webkit_dom_document_get_default_view(*wkdd1) : Debug *wkddw1
*sdw0 = gtk_widget_get_parent(GadgetID(0)) : Debug *sdw0
*ga0 = gtk_scrolled_window_get_vadjustment(*sdw0) : Debug *ga0
*sdw1 = gtk_widget_get_parent(GadgetID(1)) : Debug *sdw1
*ga1 = gtk_scrolled_window_get_vadjustment(*sdw1) : Debug *ga1
HideGadget(1,1) : is_yettostart=1
Repeat
EvID = WaitWindowEvent()
ypos0 = webkit_dom_dom_window_get_scroll_y(*wkddw0)
If ypos0<>oldypos
If is_yettostart : HideGadget(1,0) : is_yettostart=0 : EndIf
gtk_adjustment_set_value(*ga1,ypos0+960.0)
gtk_scrolled_window_set_vadjustment(*sw1, *ga1)
oldypos=ypos
EndIf
Select EvID
Case #PB_Event_Gadget
EvG = EventGadget()
Select EvG
EndSelect
EndSelect
Until EvID=#PB_Event_CloseWindow
Re: Get and set scroll position in WebGadget
And this is an example of the desired effect - which honestly works quite well, functionally and graphically. So, it may be deserving a pic.
https://ibb.co/D550y7H
https://ibb.co/D550y7H
Re: Get and set scroll position in WebGadget
Does not run under Ubuntu 20.04/21.04 because the libwebkitgtk-3.0-dev is no longer available.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive