webkitgtk support
This commit is contained in:
parent
ad70b68564
commit
fc520f71eb
4 changed files with 71 additions and 8 deletions
18
README.adoc
18
README.adoc
|
|
@ -1,6 +1,6 @@
|
||||||
= High level GTK3 (and GTK4) bindings for the Nim programming language
|
= High level GTK4 and GTK3 bindings for the Nim programming language
|
||||||
(c) Stefan Salewski
|
//(c) Stefan Salewski
|
||||||
//Version 0.8.4
|
//Version 0.8.5
|
||||||
:experimental:
|
:experimental:
|
||||||
:imagesdir: http://ssalewski.de/tmp
|
:imagesdir: http://ssalewski.de/tmp
|
||||||
:source-highlighter: pygments
|
:source-highlighter: pygments
|
||||||
|
|
@ -25,8 +25,16 @@ with code inserted from files directly.
|
||||||
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
|
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
|
||||||
The `combinatorics` module was kindly provided by R. Behrends.
|
The `combinatorics` module was kindly provided by R. Behrends.
|
||||||
|
|
||||||
NOTE: This is version 0.8.4 of the gintro Nim GTK bindings. We do support the
|
NOTE: This is version 0.8.5 of the gintro Nim GTK bindings.
|
||||||
libnice module now for Linux and Windows. And we added gtksourceview5 to
|
Due to a serious request we have added webkitgtk support.
|
||||||
|
Unfortunately still only for GTK3, as the latest webkitgtk package 2.30.4
|
||||||
|
does not compile with stable GTK4. But we should get
|
||||||
|
webkitgtk for GTK4 in a few weeks. One question is still how to name the GTK4
|
||||||
|
version then. The official name of the version for GTK3 is webkit2, so shall
|
||||||
|
we call the version for GTK4 webkitgtk4 or webkit4? Or different?
|
||||||
|
|
||||||
|
NOTE: Since version 0.8.4 we do support the
|
||||||
|
libnice module for Linux and Windows. And we added gtksourceview5 to
|
||||||
support gtksourceview usage for GTK4. The module is called gtksourceview5
|
support gtksourceview usage for GTK4. The module is called gtksourceview5
|
||||||
because the underlying C library has mayor version 5 already. So you can
|
because the underlying C library has mayor version 5 already. So you can
|
||||||
write your own GTK4 Nim editor now. Additional optional var out parameters
|
write your own GTK4 Nim editor now. Additional optional var out parameters
|
||||||
|
|
|
||||||
20
examples/gtk3/webkitgtk.nim
Normal file
20
examples/gtk3/webkitgtk.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# https://wiki.gnome.org/Projects/WebKitGtk/ProgrammingGuide/Tutorial
|
||||||
|
# nim c --gc:arc webkitgtk.nim
|
||||||
|
import gintro/[gtk, glib, gobject, gio, webkit2]
|
||||||
|
|
||||||
|
proc appActivate (app: Application) =
|
||||||
|
let window = newApplicationWindow(app)
|
||||||
|
window.title = "WebKitGtk"
|
||||||
|
window.defaultSize = (800, 600)
|
||||||
|
let view = newWebView()
|
||||||
|
view.loadUri("https://nim-lang.org/")
|
||||||
|
window.add(view)
|
||||||
|
window.showAll
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
let app = newApplication("org.gtk.example")
|
||||||
|
connect(app, "activate", appActivate)
|
||||||
|
discard app.run
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
author = "Stefan Salewski"
|
author = "Stefan Salewski"
|
||||||
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
|
||||||
# nimpretty --maxLineLen:130 gen.nim
|
# nimpretty --maxLineLen:130 gen.nim
|
||||||
# v 0.8.4 2020-DEC-14
|
# v 0.8.5 2021-JAN-06
|
||||||
# (c) S. Salewski 2018
|
# (c) S. Salewski 2018
|
||||||
|
|
||||||
# usefull for finding death code:
|
# usefull for finding death code:
|
||||||
|
|
@ -251,6 +251,7 @@ defaultParameters["gtk_application_new"] = "flags gio.ApplicationFlags {}"
|
||||||
defaultParameters["gtk_builder_new_from_string"] = "length int64 -1"
|
defaultParameters["gtk_builder_new_from_string"] = "length int64 -1"
|
||||||
defaultParameters["gtk_box_new"] = "spacing int 0"
|
defaultParameters["gtk_box_new"] = "spacing int 0"
|
||||||
defaultParameters["gtk_grid_attach"] = "width int 1|height int 1"
|
defaultParameters["gtk_grid_attach"] = "width int 1|height int 1"
|
||||||
|
defaultParameters["gtk_adjustment_new"] = "pageSize cdouble 1.0"
|
||||||
|
|
||||||
for i in keywords: mangledNames[i] = '`' & i & '`'
|
for i in keywords: mangledNames[i] = '`' & i & '`'
|
||||||
|
|
||||||
|
|
@ -1913,6 +1914,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
||||||
methodBuffer.cut(p)
|
methodBuffer.cut(p)
|
||||||
|
|
||||||
template genBoxedFree =
|
template genBoxedFree =
|
||||||
|
#echo gBaseInfoGetName(info)
|
||||||
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
|
||||||
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) ==
|
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) ==
|
||||||
G_TYPE_BOXED and
|
G_TYPE_BOXED and
|
||||||
|
|
@ -1978,6 +1980,8 @@ template genDestroyFreeUnref =
|
||||||
freeMe = gStructInfoFindMethod(info, "free")
|
freeMe = gStructInfoFindMethod(info, "free")
|
||||||
if freeMe.isNil:
|
if freeMe.isNil:
|
||||||
freeMe = gStructInfoFindMethod(info, "unref")
|
freeMe = gStructInfoFindMethod(info, "unref")
|
||||||
|
if freeMe.isNil:
|
||||||
|
freeMe = gStructInfoFindMethod(info, "destroy") # pango, new in v0.8.5
|
||||||
if freeMe != nil and gCallableInfoGetNArgs(freeMe) == (if gCallableInfoIsMethod(freeMe): 0 else: 1):
|
if freeMe != nil and gCallableInfoGetNArgs(freeMe) == (if gCallableInfoIsMethod(freeMe): 0 else: 1):
|
||||||
# methodBuffer.writeLine("\nwhen compileOption(\"gc\", \"arc\"):")
|
# methodBuffer.writeLine("\nwhen compileOption(\"gc\", \"arc\"):")
|
||||||
methodBuffer.writeLine("\nwhen defined(gcDestructors):")
|
methodBuffer.writeLine("\nwhen defined(gcDestructors):")
|
||||||
|
|
@ -1986,6 +1990,13 @@ template genDestroyFreeUnref =
|
||||||
methodBuffer.writeLine(" $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)])
|
methodBuffer.writeLine(" $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)])
|
||||||
methodBuffer.writeLine(" self.impl = nil")
|
methodBuffer.writeLine(" self.impl = nil")
|
||||||
|
|
||||||
|
# new in v0.8.5
|
||||||
|
methodBuffer.writeLine("\nproc newWithFinalizer*(x: var " & mangleName(gBaseInfoGetName(info)) & ") =")
|
||||||
|
methodBuffer.writeLine(" when defined(gcDestructors):")
|
||||||
|
methodBuffer.writeLine(" new(x)")
|
||||||
|
methodBuffer.writeLine(" else:")
|
||||||
|
methodBuffer.writeLine(" new(x, $1)" % [$gBaseInfoGetName(freeMe)])
|
||||||
|
|
||||||
template writeGetTypeProc =
|
template writeGetTypeProc =
|
||||||
var getTypeProc {.inject.}: string
|
var getTypeProc {.inject.}: string
|
||||||
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
|
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
|
||||||
|
|
@ -2095,6 +2106,9 @@ proc keymapKeyArrayToSeq(s: ptr KeymapKey; n: int): seq[KeymapKey] =
|
||||||
|
|
||||||
proc writeStruct(info: GIStructInfo) =
|
proc writeStruct(info: GIStructInfo) =
|
||||||
|
|
||||||
|
if gBaseInfoGetName(info) in ["_ContextMenu", "_ContextMenuItem"]:
|
||||||
|
return # WebKit2WebExtension-4.0.gir bug
|
||||||
|
|
||||||
if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
|
if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
|
||||||
return # we should not need the class and interface structs
|
return # we should not need the class and interface structs
|
||||||
if gBaseInfoGetName(info).endsWith("Private"): # since v0.5.3 we do not write private structs
|
if gBaseInfoGetName(info).endsWith("Private"): # since v0.5.3 we do not write private structs
|
||||||
|
|
@ -2149,6 +2163,12 @@ proc writeStruct(info: GIStructInfo) =
|
||||||
mseq.add(gStructInfoGetMethod(info, j))
|
mseq.add(gStructInfoGetMethod(info, j))
|
||||||
if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) in ["free", "unref"]:
|
if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) in ["free", "unref"]:
|
||||||
freePos = j
|
freePos = j
|
||||||
|
|
||||||
|
if freePos < 0:
|
||||||
|
for j in 0.cint ..< gStructInfoGetNMethods(info):
|
||||||
|
if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) in ["destroy"]: # add destroy for v0.8.5
|
||||||
|
freePos = j
|
||||||
|
|
||||||
if freePos > 0: swap(mseq[0], mseq[freePos])
|
if freePos > 0: swap(mseq[0], mseq[freePos])
|
||||||
if mangleName(gBaseInfoGetName(info)) == "List" and moduleNamespace == "glib":
|
if mangleName(gBaseInfoGetName(info)) == "List" and moduleNamespace == "glib":
|
||||||
output.writeLine("\nproc g_list_free*(list: ptr glib.List) {.importc: \"g_list_free\", libprag.}")
|
output.writeLine("\nproc g_list_free*(list: ptr glib.List) {.importc: \"g_list_free\", libprag.}")
|
||||||
|
|
@ -2582,6 +2602,9 @@ proc writeConst(info: GIConstantInfo) =
|
||||||
if h == "ATTR_INDEX_FROM_TEXT_BEGINNING":
|
if h == "ATTR_INDEX_FROM_TEXT_BEGINNING":
|
||||||
return # gint in gir, but should be guint
|
return # gint in gir, but should be guint
|
||||||
|
|
||||||
|
if gBaseInfoGetNamespace(info) == "Soup":
|
||||||
|
h.add("_STR") # too many name conflicts with enums!
|
||||||
|
|
||||||
if h.replace("_", "").toLowerAscii == "keych":
|
if h.replace("_", "").toLowerAscii == "keych":
|
||||||
h.add(str[^5])
|
h.add(str[^5])
|
||||||
if gdkKeys.contains(h.toLowerAscii):
|
if gdkKeys.contains(h.toLowerAscii):
|
||||||
|
|
@ -3000,6 +3023,11 @@ proc getPosition*(self: Event): (float, float) =
|
||||||
|
|
||||||
const GTK_EPI = """
|
const GTK_EPI = """
|
||||||
|
|
||||||
|
# allow connecting GtkText and GtkEntry to "changed" signal of GtkEditable!
|
||||||
|
proc editable*(x: Text): Editable = cast[Editable](x)
|
||||||
|
|
||||||
|
proc editable*(x: Entry): Editable = cast[Editable](x)
|
||||||
|
|
||||||
#proc loadFromData*(self: CssProvider; data: cstring): bool =
|
#proc loadFromData*(self: CssProvider; data: cstring): bool =
|
||||||
# loadFromData(self, uint8Array(data), -1)
|
# loadFromData(self, uint8Array(data), -1)
|
||||||
|
|
||||||
|
|
@ -3275,6 +3303,8 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
|
||||||
output.writeLine("import glib\n")
|
output.writeLine("import glib\n")
|
||||||
elif namespace == "Gst":
|
elif namespace == "Gst":
|
||||||
discard
|
discard
|
||||||
|
elif namespace == "WebKit2":
|
||||||
|
output.writeLine("from atk import ImplementorIface\n") # Extern interfaces support
|
||||||
elif namespace == "Nice":
|
elif namespace == "Nice":
|
||||||
output.writeLine("import macros, nativesockets\n")
|
output.writeLine("import macros, nativesockets\n")
|
||||||
output.writeLine("from strutils import `%`\n")
|
output.writeLine("from strutils import `%`\n")
|
||||||
|
|
@ -3683,6 +3713,7 @@ proc launch() =
|
||||||
if ISGTK3:
|
if ISGTK3:
|
||||||
echo "Generating bindings for GTK3..."
|
echo "Generating bindings for GTK3..."
|
||||||
main("Gtk", "3.0") # the 3 new 4.0 releases in old version
|
main("Gtk", "3.0") # the 3 new 4.0 releases in old version
|
||||||
|
#main("Pango")
|
||||||
when true:
|
when true:
|
||||||
main("Gdk", "3.0")
|
main("Gdk", "3.0")
|
||||||
main("GdkX11", "3.0")
|
main("GdkX11", "3.0")
|
||||||
|
|
@ -3709,6 +3740,10 @@ proc launch() =
|
||||||
main("Handy")
|
main("Handy")
|
||||||
main("Nice")
|
main("Nice")
|
||||||
main("cairo")
|
main("cairo")
|
||||||
|
main("WebKit2")
|
||||||
|
main("JavaScriptCore")
|
||||||
|
main("Soup")
|
||||||
|
main("WebKit2WebExtension")
|
||||||
else:
|
else:
|
||||||
echo "First we try generating bindings for GTK4, this may fail when GTK4 is not properly installed"
|
echo "First we try generating bindings for GTK4, this may fail when GTK4 is not properly installed"
|
||||||
echo "on your computer. But don't worry, you can still use GTK3"
|
echo "on your computer. But don't worry, you can still use GTK3"
|
||||||
|
|
@ -3765,7 +3800,7 @@ launch()
|
||||||
# if not xcallerAlloc.contains(el):
|
# if not xcallerAlloc.contains(el):
|
||||||
# echo el
|
# echo el
|
||||||
|
|
||||||
# 3741 lines
|
# 3741 lines Extern import writeConst gBaseInfoGetNamespace atk writeStruct attribute destroy
|
||||||
# gtk_icon_view_get_tooltip_context bug Candidate
|
# gtk_icon_view_get_tooltip_context bug Candidate
|
||||||
# gtk_tree_view_get_cursor bug
|
# gtk_tree_view_get_cursor bug
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue