diff --git a/README.adoc b/README.adoc index 9b94805..8f1b3d2 100644 --- a/README.adoc +++ b/README.adoc @@ -1,6 +1,6 @@ -= High level GTK3 (and GTK4) bindings for the Nim programming language -(c) Stefan Salewski -//Version 0.8.4 += High level GTK4 and GTK3 bindings for the Nim programming language +//(c) Stefan Salewski +//Version 0.8.5 :experimental: :imagesdir: http://ssalewski.de/tmp :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. 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 -libnice module now for Linux and Windows. And we added gtksourceview5 to +NOTE: This is version 0.8.5 of the gintro Nim GTK bindings. +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 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 diff --git a/examples/gtk3/webkitgtk.nim b/examples/gtk3/webkitgtk.nim new file mode 100644 index 0000000..0955682 --- /dev/null +++ b/examples/gtk3/webkitgtk.nim @@ -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() + diff --git a/gintro.nimble b/gintro.nimble index 00bed60..350d13a 100644 --- a/gintro.nimble +++ b/gintro.nimble @@ -1,6 +1,6 @@ # Package -version = "0.8.4" +version = "0.8.5" author = "Stefan Salewski" description = "High level GObject-Introspection based GTK3/GTK4 bindings" license = "MIT" diff --git a/tests/gen.nim b/tests/gen.nim index 9717dac..e6e731b 100644 --- a/tests/gen.nim +++ b/tests/gen.nim @@ -1,6 +1,6 @@ # High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language # nimpretty --maxLineLen:130 gen.nim -# v 0.8.4 2020-DEC-14 +# v 0.8.5 2021-JAN-06 # (c) S. Salewski 2018 # 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_box_new"] = "spacing int 0" 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 & '`' @@ -1913,6 +1914,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = methodBuffer.cut(p) template genBoxedFree = + #echo gBaseInfoGetName(info) if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))): if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) == G_TYPE_BOXED and @@ -1978,6 +1980,8 @@ template genDestroyFreeUnref = freeMe = gStructInfoFindMethod(info, "free") if freeMe.isNil: 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): # methodBuffer.writeLine("\nwhen compileOption(\"gc\", \"arc\"):") methodBuffer.writeLine("\nwhen defined(gcDestructors):") @@ -1986,6 +1990,13 @@ template genDestroyFreeUnref = methodBuffer.writeLine(" $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)]) 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 = var getTypeProc {.inject.}: string if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE: @@ -2095,6 +2106,9 @@ proc keymapKeyArrayToSeq(s: ptr KeymapKey; n: int): seq[KeymapKey] = proc writeStruct(info: GIStructInfo) = + if gBaseInfoGetName(info) in ["_ContextMenu", "_ContextMenuItem"]: + return # WebKit2WebExtension-4.0.gir bug + if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass": 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 @@ -2149,6 +2163,12 @@ proc writeStruct(info: GIStructInfo) = mseq.add(gStructInfoGetMethod(info, j)) if freePos < 0 and gBaseInfoGetName(gStructInfoGetMethod(info, j)) in ["free", "unref"]: 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 mangleName(gBaseInfoGetName(info)) == "List" and moduleNamespace == "glib": 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": 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": h.add(str[^5]) if gdkKeys.contains(h.toLowerAscii): @@ -3000,6 +3023,11 @@ proc getPosition*(self: Event): (float, float) = 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 = # loadFromData(self, uint8Array(data), -1) @@ -3275,6 +3303,8 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] = output.writeLine("import glib\n") elif namespace == "Gst": discard + elif namespace == "WebKit2": + output.writeLine("from atk import ImplementorIface\n") # Extern interfaces support elif namespace == "Nice": output.writeLine("import macros, nativesockets\n") output.writeLine("from strutils import `%`\n") @@ -3683,6 +3713,7 @@ proc launch() = if ISGTK3: echo "Generating bindings for GTK3..." main("Gtk", "3.0") # the 3 new 4.0 releases in old version + #main("Pango") when true: main("Gdk", "3.0") main("GdkX11", "3.0") @@ -3709,6 +3740,10 @@ proc launch() = main("Handy") main("Nice") main("cairo") + main("WebKit2") + main("JavaScriptCore") + main("Soup") + main("WebKit2WebExtension") else: 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" @@ -3765,7 +3800,7 @@ launch() # if not xcallerAlloc.contains(el): # echo el -# 3741 lines +# 3741 lines Extern import writeConst gBaseInfoGetNamespace atk writeStruct attribute destroy # gtk_icon_view_get_tooltip_context bug Candidate # gtk_tree_view_get_cursor bug #