I’ve been trying to patch up the Workrave GNOME extension so that it works under NixOS, so that I can provide a solution to my own bug report for the Nix Workrave package. Here’s what I’ve managed so far.
Currently, my Workrave package is compiled with the following overlay:
nixpkgs.overlays = [
(final: prev: {
workrave = prev.workrave.overrideAttrs (
finalAttrs: prevAttrs: {
configureFlags = # prevAttrs.configureFlags ++
[ "--enable-gnome45" ];
buildInputs = prevAttrs.buildInputs ++ [ pkgs.gtk4 ];
}
);
})
];
This much is needed in order to get an extension installed that can work on GNOME 45 and later.
I then started working on my own version of the extension in ~/.local/share/gnome-shell/extensions
that’s a copy of the original Workrave one, but renamed. The extension directory is renamed workrave2-hack@workrave.org
, and in metadata.json
, the values of the keys "extension-id"
, "uuid"
, and "name"
are "workrave2-hack"
, "workrave2-hack@workrave.org"
, and "Workrave2-hack"
, respectively.
Following examples from the Nixpkgs manual, in extension.js
, I replaced the line
import Workrave from "gi://Workrave?version=2.0";
with
import GIRepository from 'gi://GIRepository';
GIRepository.Repository.prepend_search_path('/nix/store/j4aw5jqby0vwyinjayjidxldlqs0v7q9-workrave-1.10.53/lib/girepository-1.0');
const Workrave = (await import("gi://Workrave?version=2.0")).default;
Yes, for now, the argument of prepend_search_path
is a hardcoded path to a /nix/store
location, but I figured that once I got the basics working, I could set up a patch with replaceVars
, etc., to do things properly.
However, this was not enough. When I debugged the extension by running a nested GNOME Wayland session, it crashed once this hacked extension was activated, leaving behind the following errors:
(gnome-shell:8097): GLib-GIO-ERROR **: 17:19:18.767: Settings schema 'org.workrave.gui' is not installed
== Stack trace for context 0x3cb11010 ==
#0 3cc09ab0 i file:///home/jjramsey/.local/share/gnome-shell/extensions/workrave2-hack@workrave.org/extension.js:175 (22f25dcc0380 @ 50)
#1 3cc09a10 i resource:///org/gnome/shell/ui/panelMenu.js:10 (22f25dc3d290 @ 27)
#2 3cc09950 i resource:///org/gnome/shell/ui/panelMenu.js:95 (22f25dc3d5b0 @ 27)
#3 3cc09890 i file:///home/jjramsey/.local/share/gnome-shell/extensions/workrave2-hack@workrave.org/extension.js:171 (3683a98996f0 @ 27)
#4 3cc097e0 i file:///home/jjramsey/.local/share/gnome-shell/extensions/workrave2-hack@workrave.org/extension.js:534 (3683a986db00 @ 36)
#5 3cc09738 i resource:///org/gnome/shell/ui/extensionSystem.js:266 (22f25dc22a60 @ 423)
#6 3cc09698 i self-hosted:1423 (22f25dcf4ce0 @ 30)
#7 7fff12558d20 b self-hosted:804 (22f25dcf4d80 @ 15)
#8 3cc09608 i resource:///org/gnome/shell/ui/init.js:21 (3683a987ea60 @ 48)
What did help was including /nix/store/j4aw5jqby0vwyinjayjidxldlqs0v7q9-workrave-1.10.53/share/gsettings-schemas/workrave-1.10.53
in the XDG_DATA_DIRS
path, but this still left the extension relying on some outside global state, which is not the NixOS way.
I then thought I could get rid of this dependence on XDG_DATA_DIRS
after reading Gnome extention Hanabi on nixos - #12 by jtojnar, which said,
I then used GNOME JavaScript docs as guide to putting the schemas in the extension directory and setting metadata.json
accordingly. First, I created a symbolic link schemas
in that directory, which pointed to the /nix/store/j4aw5jqby0vwyinjayjidxldlqs0v7q9-workrave-1.10.53/share/gsettings-schemas/workrave-1.10.53/glib-2.0/schemas
directory. Next, I saw that in the example from the GNOME docs that the example schema,
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema id="org.gnome.shell.extensions.example" path="/org/gnome/shell/extensions/example/">
<key name="show-indicator" type="b">
<default>true</default>
</key>
</schema>
</schemalist>
had "org.gnome.shell.extensions.example"
as the schema id, and in the example metadata:
{
"uuid": "example@gjs.guide",
"name": "Example Extension",
"description": "An example extension with preferences",
"shell-version": [ "45" ],
"url": "https://gjs.guide/extensions",
"gettext-domain": "example@gjs.guide",
"settings-schema": "org.gnome.shell.extensions.example"
}
the value for the key "settings-schema"
was set to that schema id.
Since the error message from GLib said, “Settings schema ‘org.workrave.gui’ is not installed”, and one of the XML files in /nix/store/j4aw5jqby0vwyinjayjidxldlqs0v7q9-workrave-1.10.53/share/gsettings-schemas/workrave-1.10.53/glib-2.0/schemas
, org.workrave.gui.gschema.xml
had the schema id "org.workrave.gui"
, I set the “settings-schema” value in my metadata.json
file to "org.workrave.gui"
.
Unfortunately, this did not help. My hacked extension still doesn’t work without modifying XDG_DATA_DIRS
.
What am I missing here? How do I get GNOME shell to find the schemas properly?
ETA: Well, I’ve found an answer that at least works on the local level, thanks to these links:
While having the schemas directory under the extensions directory doesn’t work, putting links to the schemas (both compiled and not) under ~/.local/share/glib-2.0
does. Unfortunately, that also means that if any other files are added to that directory, glib-compile-schemas
needs to be re-run.
And of course, that won’t work for system-wide extensions.
Not sure why the GNOME Shell docs don’t agree with the actual shell implementation.
ETA again: Judging from my inspections of the Dash-to-Dock and Dash-to-Panel, it looks like schemas with IDs that begin with “org.gnome.shell.extensions” do get read from the extension directories. I guess it’s just the schemas that pertain to external apps that don’t?