You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Date: 2026-07-13 Status: Research/scoping only — no implementation started
Summary
Gramps' path to GTK4 is blocked by the Geography view's dependency on osm-gps-map, a GObject-introspection
C library that only supports GTK3. There is no drop-in GTK4-compatible map
widget available today. This document lays out the evidence for that claim
and scopes what a rewrite against libshumate (GNOME's own GTK4-native
map widget, used by GNOME Maps) would actually involve.
Upstream status of osm-gps-map
Effectively a single-maintainer project (johnny-bit on GitHub), with the
original author (nzjrs) having stepped back years ago.
Issue #102 — "Is anyone
interested in maintaining this project?" — was opened in October 2023 by Nick Hall, a Gramps maintainer, directly. Nick confirmed there: "We
are using Gtk3 at the moment, but are definitely interested in moving to
Gtk4 in the future."
A GTK4 port exists as PR #97
(opened June 2022). It's still a draft, unmerged, and per the author's
own description "not finished/final yet" — click-drag panning is disabled
with a TODO comment. It's a partial port (748 additions / 179 deletions
across 14 files), not something Gramps could adopt as-is.
A comment on that PR from March 2026 suggests abandoning osm-gps-map
altogether in favor of libshumate, precisely because the GTK4 port has
stalled.
Separately, there's an active, unrelated crash bug right now: osm-gps-map
and GeocodeGlib (also used by Gramps, for place lookup) disagree on
libsoup2 vs libsoup3, and loading both in the same process core-dumps.
Distros are hand-patching around it — a sign of how fragile this dependency
has become even on GTK3.
In the [Gramps-devel] Migration from Gtk3 to Gtk4 mailing list thread,
Nick Hall noted there's no urgency since GTK4 availability is still limited
to newer distros; John Ralls argued against maintaining two GTK flavors of
Gramps simultaneously.
Bottom line: this isn't "GTK4 migration is hard" in the abstract — it's a
specific, named, unresolved upstream dependency problem.
The architectural difference
OsmGpsMap's layer model hands every layer a raw cairo context each frame
(do_draw(gpsmap, ctx)), and the caller manually converts lat/lon to pixel
coordinates every draw (gpsmap.convert_geographic_to_screen(point)). Every
custom layer in Gramps follows this pattern.
libshumate's model is different: ShumateLayer is a real GtkWidget
subclass positioned by a ShumateViewport. Custom layers override the
standard GTK4 snapshot vfunc and call viewport.location_to_widget_coords() instead of manual conversion.
Built-in ShumateMarkerLayer and ShumatePathLayer handle marker and
line/polygon positioning automatically — so part of the migration isn't a
mechanical translation, it's dropping hand-rolled bookkeeping that libshumate
now does for you.
File-by-file scope
All files are under gramps/plugins/lib/maps/ unless noted.
File
Disposition
Notes
constants.py
Rewrite
OsmGpsMap.MapSource_t enum → construct ShumateMapSource/ShumateTileDownloader per provider with URL templates. Several providers (Google, Yahoo, Virtual Earth) aren't in libshumate's built-in registry and need the same manual template definitions Gramps already has today.
dummylayer.py
Delete
No-op stub existed only to satisfy OsmGpsMap's layer-list requirements.
dummynogps.py
Delete
Worked around an OsmGpsMap built-in "draw GPS point" feature libshumate doesn't have.
selectionlayer.py
Rewrite
Small custom ShumateLayer + snapshot() override; same cairo drawing code, new coordinate call and redraw trigger (viewport::changed → queue_draw()).
datelayer.py, messagelayer.py
Simplify
These draw at a fixed pixel offset, not a lat/lon — not real geo-layers. Can become plain GtkLabels in a GtkOverlay over the map, dropping the custom-layer machinery entirely.
markerlayer.py
Rewrite (moderate)
Best done as ShumateMarkerLayer + a custom ShumateMarker subclass (a GtkWidget holding a sized GtkImage/GtkPicture). Variable icon size based on place-reference count carries over; positioning bookkeeping is now handled by libshumate.
lifewaylayer.py, kmllayer.py
Rewrite (moderate)
Lines/polygons map fairly well onto ShumatePathLayer (add_node, set_closed, stroke/fill color) — less custom cairo needed. Wrinkle: KML's "InnerPolygon" hole trick (OPERATOR_ADD compositing) has no direct libshumate equivalent and needs a workaround.
osmgps.py
Full rewrite
Map construction (ShumateMap/ShumateSimpleMap + ShumateMapLayer(source)), tile cache (ShumateFileCache), and all event wiring — button_press_event/motion-notify-event signals don't exist in GTK4, replaced by GtkGestureClick/GtkEventControllerMotion/GtkEventControllerScroll. Keyboard shortcuts need a hand-built GtkEventControllerKey. Zoom buttons and the crosshair overlay (MapOsd) have no libshumate equivalent widget (libshumate only ships Compass/Scale/License OSDs) — becomes custom overlay widgets.
geography.py (1552 lines)
Partial rewrite
Roughly half touches OsmGpsMap directly (add_marker, add_selection_layer, _visible_marker's get_bbox, _autozoom's set_zoom/set_center, build_nav_menu's right-click detection, printview) and needs rewriting. The other half — querying the Gramps DB for places/events/people, building coordinate tables, config-dialog logic — is GTK-version-agnostic and survives untouched.
cairoprint.py + geography.py:printview
Rewrite (different technique)
Current code calls self.osm.do_draw(gpsmap, ctx) directly to render the map into an arbitrary print-sized cairo context — that vfunc doesn't exist in GTK4. Replacement: render via widget.snapshot() → GskRenderNode → node.draw(cairo_ctx).
placeselection.py
Rewrite (mixed)
Needs the map API swap plus ordinary GTK3→4 dialog updates unrelated to mapping (show_all() removed, Gtk.Box.pack_start → .append(), dialog content-area access changed).
libkml.py
No change
Pure xml.etree parsing, zero GTK/OsmGpsMap dependency.
geography.gpr.py, grampsapp.py, gen/config.py
Trivial
Swap the Repository.enumerate_versions("OsmGpsMap") capability probe for "Shumate"; update the missing-dependency warning text/install instructions.
None reference OsmGpsMap directly — they only call the GeoGraphyView/OsmGps base-class API (add_marker, add_place, etc.). As long as those method signatures are preserved, these seven view subclasses shouldn't need edits.
Bottom line
Of the ~4,400 lines in gramps/plugins/lib/maps/, roughly 2,000–2,500 touch
osm-gps-map directly and need rewriting or deleting; the DB-query/dialog
logic and the seven view subclasses outside lib/maps/ are largely
insulated.
It's not a mechanical API swap — the rendering model genuinely changes from
"draw-callback + manual math" to "positioned widgets" — but it's not
uniformly harder either: markers/paths get simpler (libshumate does
positioning bookkeeping Gramps currently hand-rolls), while event handling
and on-screen controls (zoom buttons, crosshair) get more custom code since
libshumate ships fewer built-in overlay widgets than OsmGpsMap did.
Estimate: a multi-week focused effort for one person, touching ~10
files, plus manual re-testing of all five geography views and the
place-selection dialog — there's no unit-test coverage for rendering
behavior, so verification has to be by hand.
Open questions / not yet investigated
Exact API for defining custom ShumateMapSource entries for non-standard
providers (Google/Yahoo/Virtual Earth tile URL templates) — needs a spike.
Whether ShumateFileCache supports the same on-disk tile cache layout
Gramps users already have populated (~/.cache/gramps/maps/...), or
whether a migration/re-download would be needed.
Real fix for the KML inner-polygon (hole) rendering case.
Whether to wait on upstream nzjrs/osm-gps-map#97
(the draft GTK4 port, not a gramps-project/gramps PR) instead of
committing to a libshumate rewrite — depends on whether that PR gets
unstuck.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Date: 2026-07-13
Status: Research/scoping only — no implementation started
Summary
Gramps' path to GTK4 is blocked by the Geography view's dependency on
osm-gps-map, a GObject-introspection
C library that only supports GTK3. There is no drop-in GTK4-compatible map
widget available today. This document lays out the evidence for that claim
and scopes what a rewrite against libshumate (GNOME's own GTK4-native
map widget, used by GNOME Maps) would actually involve.
Upstream status of osm-gps-map
johnny-biton GitHub), with theoriginal author (
nzjrs) having stepped back years ago.interested in maintaining this project?" — was opened in October 2023 by
Nick Hall, a Gramps maintainer, directly. Nick confirmed there: "We
are using Gtk3 at the moment, but are definitely interested in moving to
Gtk4 in the future."
(opened June 2022). It's still a draft, unmerged, and per the author's
own description "not finished/final yet" — click-drag panning is disabled
with a TODO comment. It's a partial port (748 additions / 179 deletions
across 14 files), not something Gramps could adopt as-is.
altogether in favor of libshumate, precisely because the GTK4 port has
stalled.
and
GeocodeGlib(also used by Gramps, for place lookup) disagree onlibsoup2 vs libsoup3, and loading both in the same process core-dumps.
Distros are hand-patching around it — a sign of how fragile this dependency
has become even on GTK3.
[Gramps-devel] Migration from Gtk3 to Gtk4mailing list thread,Nick Hall noted there's no urgency since GTK4 availability is still limited
to newer distros; John Ralls argued against maintaining two GTK flavors of
Gramps simultaneously.
Bottom line: this isn't "GTK4 migration is hard" in the abstract — it's a
specific, named, unresolved upstream dependency problem.
The architectural difference
OsmGpsMap's layer model hands every layer a raw cairo context each frame
(
do_draw(gpsmap, ctx)), and the caller manually converts lat/lon to pixelcoordinates every draw (
gpsmap.convert_geographic_to_screen(point)). Everycustom layer in Gramps follows this pattern.
libshumate's model is different:
ShumateLayeris a realGtkWidgetsubclass positioned by a
ShumateViewport. Custom layers override thestandard GTK4
snapshotvfunc and callviewport.location_to_widget_coords()instead of manual conversion.Built-in
ShumateMarkerLayerandShumatePathLayerhandle marker andline/polygon positioning automatically — so part of the migration isn't a
mechanical translation, it's dropping hand-rolled bookkeeping that libshumate
now does for you.
File-by-file scope
All files are under
gramps/plugins/lib/maps/unless noted.constants.pyOsmGpsMap.MapSource_tenum → constructShumateMapSource/ShumateTileDownloaderper provider with URL templates. Several providers (Google, Yahoo, Virtual Earth) aren't in libshumate's built-in registry and need the same manual template definitions Gramps already has today.dummylayer.pydummynogps.pyselectionlayer.pyShumateLayer+snapshot()override; same cairo drawing code, new coordinate call and redraw trigger (viewport::changed→queue_draw()).datelayer.py,messagelayer.pyGtkLabels in aGtkOverlayover the map, dropping the custom-layer machinery entirely.markerlayer.pyShumateMarkerLayer+ a customShumateMarkersubclass (aGtkWidgetholding a sizedGtkImage/GtkPicture). Variable icon size based on place-reference count carries over; positioning bookkeeping is now handled by libshumate.lifewaylayer.py,kmllayer.pyShumatePathLayer(add_node,set_closed, stroke/fill color) — less custom cairo needed. Wrinkle: KML's "InnerPolygon" hole trick (OPERATOR_ADDcompositing) has no direct libshumate equivalent and needs a workaround.osmgps.pyShumateMap/ShumateSimpleMap+ShumateMapLayer(source)), tile cache (ShumateFileCache), and all event wiring —button_press_event/motion-notify-eventsignals don't exist in GTK4, replaced byGtkGestureClick/GtkEventControllerMotion/GtkEventControllerScroll. Keyboard shortcuts need a hand-builtGtkEventControllerKey. Zoom buttons and the crosshair overlay (MapOsd) have no libshumate equivalent widget (libshumate only ships Compass/Scale/License OSDs) — becomes custom overlay widgets.geography.py(1552 lines)add_marker,add_selection_layer,_visible_marker'sget_bbox,_autozoom'sset_zoom/set_center,build_nav_menu's right-click detection,printview) and needs rewriting. The other half — querying the Gramps DB for places/events/people, building coordinate tables, config-dialog logic — is GTK-version-agnostic and survives untouched.cairoprint.py+geography.py:printviewself.osm.do_draw(gpsmap, ctx)directly to render the map into an arbitrary print-sized cairo context — that vfunc doesn't exist in GTK4. Replacement: render viawidget.snapshot()→GskRenderNode→node.draw(cairo_ctx).placeselection.pyshow_all()removed,Gtk.Box.pack_start→.append(), dialog content-area access changed).libkml.pyxml.etreeparsing, zero GTK/OsmGpsMap dependency.geography.gpr.py,grampsapp.py,gen/config.pyRepository.enumerate_versions("OsmGpsMap")capability probe for"Shumate"; update the missing-dependency warning text/install instructions.plugins/view/geoclose.py,geoevents.py,geofamclose.py,geofamily.py,geomoves.py,geoperson.py,geoplaces.pyGeoGraphyView/OsmGpsbase-class API (add_marker,add_place, etc.). As long as those method signatures are preserved, these seven view subclasses shouldn't need edits.Bottom line
Of the ~4,400 lines in
gramps/plugins/lib/maps/, roughly 2,000–2,500 touchosm-gps-map directly and need rewriting or deleting; the DB-query/dialog
logic and the seven view subclasses outside
lib/maps/are largelyinsulated.
It's not a mechanical API swap — the rendering model genuinely changes from
"draw-callback + manual math" to "positioned widgets" — but it's not
uniformly harder either: markers/paths get simpler (libshumate does
positioning bookkeeping Gramps currently hand-rolls), while event handling
and on-screen controls (zoom buttons, crosshair) get more custom code since
libshumate ships fewer built-in overlay widgets than OsmGpsMap did.
Estimate: a multi-week focused effort for one person, touching ~10
files, plus manual re-testing of all five geography views and the
place-selection dialog — there's no unit-test coverage for rendering
behavior, so verification has to be by hand.
Open questions / not yet investigated
ShumateMapSourceentries for non-standardproviders (Google/Yahoo/Virtual Earth tile URL templates) — needs a spike.
ShumateFileCachesupports the same on-disk tile cache layoutGramps users already have populated (
~/.cache/gramps/maps/...), orwhether a migration/re-download would be needed.
(the draft GTK4 port, not a gramps-project/gramps PR) instead of
committing to a libshumate rewrite — depends on whether that PR gets
unstuck.
Sources
All reactions