uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,37 @@
{ lib, stdenv, fetchFromGitHub, substituteAll, glib, gnome, gettext }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-EasyScreenCast";
version = "1.4.0";
src = fetchFromGitHub {
owner = "EasyScreenCast";
repo = "EasyScreenCast";
rev = version;
sha256 = "sha256-+lh/hqYC9+DUvLE016KuAY4Ybw8KrqEEG7WG4pUbg2k=";
};
patches = [
(substituteAll {
src = ./fix-gi-path.patch;
gnomeShell = gnome.gnome-shell;
})
];
nativeBuildInputs = [
glib gettext
];
makeFlags = [ "INSTALLBASE=$(out)/share/gnome-shell/extensions" ];
passthru.extensionUuid = "EasyScreenCast@iacopodeenosee.gmail.com";
meta = with lib; {
description = "Simplifies the use of the video recording function integrated in gnome shell";
homepage = "https://github.com/EasyScreenCast/EasyScreenCast";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ doronbehar ];
platforms = platforms.linux;
};
}

View file

@ -0,0 +1,16 @@
diff --git i/utilaudio.js w/utilaudio.js
index 983b29c..7a94de8 100644
--- i/utilaudio.js
+++ w/utilaudio.js
@@ -11,10 +11,7 @@
*/
const GIRepository = imports.gi.GIRepository;
-GIRepository.Repository.prepend_search_path("/usr/lib/gnome-shell");
-GIRepository.Repository.prepend_library_path("/usr/lib/gnome-shell");
-GIRepository.Repository.prepend_search_path("/usr/lib64/gnome-shell");
-GIRepository.Repository.prepend_library_path("/usr/lib64/gnome-shell");
+GIRepository.Repository.prepend_search_path("@gnomeShell@/lib/gnome-shell");
const Gvc = imports.gi.Gvc;
const Lang = imports.lang;

View file

@ -0,0 +1,27 @@
# GNOME Shell extensions
All extensions are packaged automatically. They can be found in the `pkgs.gnomeXYExtensions` for XY being a GNOME version. The package names are the extensions UUID, which can be a bit unwieldy to use. `pkgs.gnomeExtensions` is a set of manually curated extensions that match the current `gnome.gnome-shell` versions. Their name is human-friendly, compared to the other extensions sets. Some of its extensions are manually packaged.
## Automatically packaged extensions
The actual packages are created by `buildGnomeExtension.nix`, provided the correct arguments are fed into it. The important extension data is stored in `extensions.json`, one line/item per extension. That file is generated by running `update-extensions.py`. Furthermore, the automatic generated names are dumped in `collisions.json` for manual inspection. `extensionRenames.nix` contains new names for all extensions that collide.
### Extensions updates
For everyday updates,
1. Run `update-extensions.py`.
2. Update `extensionRenames.nix` according to the comment at the top.
For GNOME updates,
1. Add a new `gnomeXYExtensions` set
2. Remove old ones for GNOME versions we dont want to support any more
3. Update `supported_versions` in `./update-extensions.py` and re-run it
4. Change `gnomeExtensions` to the new version
5. Update `./extensionsRenames.nix` accordingly
6. Update `all-packages.nix` accordingly (grep for `gnomeExtensions`)
## Manually packaged extensions
Manually packaged extensions overwrite some of the automatically packaged ones in `pkgs.gnomeExtensions`. They are listed in `manuallyPackaged.nix`, every extension has its own sub-folder.

View file

@ -0,0 +1,38 @@
{ lib, stdenv, fetchFromGitLab, glib, gettext, substituteAll, gnome-menus }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-arcmenu";
version = "30";
src = fetchFromGitLab {
owner = "arcmenu";
repo = "ArcMenu";
rev = "v${version}";
sha256 = "sha256-BKV1x/MBqVeiqFzpXYt3y8zwK4f5rcGBwFZWqSSUarg=";
};
patches = [
(substituteAll {
src = ./fix_gmenu.patch;
gmenu_path = "${gnome-menus}/lib/girepository-1.0";
})
];
buildInputs = [
glib gettext
];
makeFlags = [ "INSTALLBASE=${placeholder "out"}/share/gnome-shell/extensions" ];
passthru = {
extensionUuid = "arcmenu@arcmenu.com";
extensionPortalSlug = "arcmenu";
};
meta = with lib; {
description = "Application menu for GNOME Shell, designed to provide a more traditional user experience and workflow";
license = licenses.gpl2Plus;
maintainers = with maintainers; [ dkabot ];
homepage = "https://gitlab.com/arcmenu/ArcMenu";
};
}

View file

@ -0,0 +1,11 @@
--- a/extension.js
+++ b/extension.js
@@ -23,6 +23,8 @@
const Me = imports.misc.extensionUtils.getCurrentExtension();
+imports.gi.GIRepository.Repository.prepend_search_path('@gmenu_path@');
+
const {GLib, Gio, St} = imports.gi;
const Constants = Me.imports.constants;
const Controller = Me.imports.controller;

View file

@ -0,0 +1,60 @@
{ pkgs, lib, stdenv, fetchzip }:
let
buildGnomeExtension = {
# Every gnome extension has a UUID. It's the name of the extension folder once unpacked
# and can always be found in the metadata.json of every extension.
uuid,
name,
pname,
description,
# extensions.gnome.org extension URL
link,
# Extension version numbers are integers
version,
sha256,
# Hex-encoded string of JSON bytes
metadata,
}:
stdenv.mkDerivation {
pname = "gnome-shell-extension-${pname}";
version = builtins.toString version;
src = fetchzip {
url = "https://extensions.gnome.org/extension-data/${
builtins.replaceStrings [ "@" ] [ "" ] uuid
}.v${builtins.toString version}.shell-extension.zip";
inherit sha256;
stripRoot = false;
# The download URL may change content over time. This is because the
# metadata.json is automatically generated, and parts of it can be changed
# without making a new release. We simply substitute the possibly changed fields
# with their content from when we last updated, and thus get a deterministic output
# hash.
postFetch = ''
echo "${metadata}" | base64 --decode > $out/metadata.json
'';
};
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions/
cp -r -T . $out/share/gnome-shell/extensions/${uuid}
runHook postInstall
'';
meta = {
description = builtins.head (lib.splitString "\n" description);
longDescription = description;
homepage = link;
license = lib.licenses.gpl2Plus; # https://wiki.gnome.org/Projects/GnomeShell/Extensions/Review#Licensing
maintainers = with lib.maintainers; [ piegames ];
};
passthru = {
extensionPortalSlug = pname;
# Store the extension's UUID, because we might need it at some places
extensionUuid = uuid;
};
};
in
lib.makeOverridable buildGnomeExtension

View file

@ -0,0 +1,71 @@
{ lib, stdenv
, fetchurl
, cmake
, ninja
, jq
, python3
, gnome
, wrapGAppsHook
, gobject-introspection
}:
let
inherit (python3.pkgs) python pygobject3 requests;
in
stdenv.mkDerivation rec {
pname = "chrome-gnome-shell";
version = "10.1";
src = fetchurl {
url = "mirror://gnome/sources/chrome-gnome-shell/${version}/${pname}-${version}.tar.xz";
sha256 = "0f54xyamm383ypbh0ndkza0pif6ljddg2f947p265fkqj3p4zban";
};
nativeBuildInputs = [
cmake
ninja
jq
wrapGAppsHook
gobject-introspection # for setup-hook
];
buildInputs = [
gnome.gnome-shell
python
pygobject3
requests
gobject-introspection # for Gio typelib
];
cmakeFlags = [
"-DBUILD_EXTENSION=OFF"
];
wrapPrefixVariables = [
"PYTHONPATH"
];
# cmake setup hook changes /etc/opt into /var/empty
dontFixCmake = true;
preConfigure = ''
substituteInPlace CMakeLists.txt --replace "/etc" "$out/etc"
'';
passthru = {
updateScript = gnome.updateScript {
packageName = "chrome-gnome-shell";
};
};
meta = with lib; {
description = "GNOME Shell integration for Chrome";
homepage = "https://wiki.gnome.org/Projects/GnomeShellIntegrationForChrome";
longDescription = ''
To use the integration, install the <link xlink:href="https://wiki.gnome.org/Projects/GnomeShellIntegrationForChrome/Installation">browser extension</link>, and then set <option>services.gnome.chrome-gnome-shell.enable</option> to <literal>true</literal>.
'';
license = licenses.gpl3;
maintainers = teams.gnome.members;
platforms = platforms.linux;
};
}

View file

@ -0,0 +1,40 @@
{ lib, stdenv, fetchzip, gnome, gettext, glib }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-clock-override";
version = "12";
src = fetchzip {
url = "https://extensions.gnome.org/extension-data/clock-overridegnomeshell.kryogenix.org.v${version}.shell-extension.zip";
sha256 = "1cyaszks6bwnbgacqsl1pmr24mbj05mad59d4253la9am8ibb4m6";
stripRoot = false;
};
passthru = {
extensionUuid = "clock-override@gnomeshell.kryogenix.org";
extensionPortalSlug = "clock-override";
};
nativeBuildInputs = [ gettext glib ];
buildPhase = ''
runHook preBuild
glib-compile-schemas --strict --targetdir=schemas schemas
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p "$out/share/gnome-shell/extensions/clock-override@gnomeshell.kryogenix.org"
cp -r {convenience.js,extension.js,format.js,locale,metadata.json,prefs.js,schemas} "$out/share/gnome-shell/extensions/clock-override@gnomeshell.kryogenix.org"
runHook postInstall
'';
meta = with lib; {
description = "Customize the date and time format displayed in clock in the top bar in GNOME Shell";
license = licenses.mit;
maintainers = with maintainers; [ rhoriguchi ];
homepage = "https://github.com/stuartlangridge/gnome-shell-clock-override";
broken = versionOlder gnome.gnome-shell.version "3.18";
};
}

View file

@ -0,0 +1,179 @@
{
"38": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
],
"fuzzy-clock": [
"Fuzzy_Clock@dallagi",
"fuzzy-clock@keepawayfromfire.co.uk"
],
"hide-activities-button": [
"Hide_Activities@shay.shayel.org",
"hide-activities-button@nmingori.gnome-shell-extensions.org"
],
"shutdowntimer": [
"ShutdownTimer@neumann",
"ShutdownTimer@deminder"
],
"bottompanel": [
"bottompanel@tmoer93",
"bottom-panel@sulincix"
],
"noannoyance": [
"noannoyance@sindex.com",
"noannoyance@daase.net"
],
"somafm-internet-radio": [
"SomaFm-Radio@alireza6677.gmail.com",
"SomaFm-Radio@cajhne.gmail.com"
],
"transparent-window": [
"transparent-window@pbxqdown.github.com",
"transparentwindows.mdirshad07"
],
"floating-dock": [
"floatingDock@sun.wxg@gmail.com",
"floating-dock@nandoferreira_prof@hotmail.com"
],
"gnome-trash": [
"gnome-trash@gnome-trash.b00f.gitlab.com",
"gnome-trash@b00f.github.io"
],
"volume-scroller": [
"volume_scroller@trflynn89.pm.me",
"volume_scroller@noskoski"
]
},
"40": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
],
"system-monitor": [
"system-monitor@paradoxxx.zero.gmail.com",
"System_Monitor@bghome.gmail.com"
],
"hide-activities-button": [
"Hide_Activities@shay.shayel.org",
"hide-activities-button@nmingori.gnome-shell-extensions.org"
],
"shutdowntimer": [
"ShutdownTimer@neumann",
"shutdown-timer-gnome-shell-extension",
"ShutdownTimer@deminder"
],
"noannoyance": [
"noannoyance@sindex.com",
"noannoyance@daase.net"
],
"somafm-internet-radio": [
"SomaFm-Radio@alireza6677.gmail.com",
"SomaFm-Radio@cajhne.gmail.com"
],
"fuzzy-clock": [
"fuzzy-clock@keepawayfromfire.co.uk",
"FuzzyClock@johngoetz"
],
"panel-date-format": [
"panel-date-format@keiii.github.com",
"panel-date-format@atareao.es"
],
"disable-unredirect-fullscreen-windows": [
"unredirect@vaina.lt",
"unredirect@aunetx"
],
"floating-dock": [
"floatingDock@sun.wxg@gmail.com",
"floating-dock@nandoferreira_prof@hotmail.com"
],
"extension-list": [
"extension-list@tu.berry",
"screen-lock@garciabaameiro.com"
],
"wireguard-indicator": [
"wireguard-indicator@gregos.me",
"wireguard-indicator@atareao.es"
],
"volume-scroller": [
"volume_scroller@trflynn89.pm.me",
"volume_scroller@noskoski"
]
},
"41": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
],
"shutdowntimer": [
"ShutdownTimer@neumann",
"ShutdownTimer@deminder"
],
"fuzzy-clock": [
"fuzzy-clock@keepawayfromfire.co.uk",
"FuzzyClock@johngoetz"
],
"disable-unredirect-fullscreen-windows": [
"unredirect@vaina.lt",
"unredirect@aunetx"
],
"floating-dock": [
"floatingDock@sun.wxg@gmail.com",
"floating-dock@nandoferreira_prof@hotmail.com"
],
"wireguard-indicator": [
"wireguard-indicator@gregos.me",
"wireguard-indicator@atareao.es"
],
"volume-scroller": [
"volume_scroller@trflynn89.pm.me",
"volume_scroller@noskoski"
]
},
"42": {
"applications-menu": [
"apps-menu@gnome-shell-extensions.gcampax.github.com",
"Applications_Menu@rmy.pobox.com"
],
"workspace-indicator": [
"workspace-indicator@gnome-shell-extensions.gcampax.github.com",
"horizontal-workspace-indicator@tty2.io"
],
"lock-keys": [
"lockkeys@vaina.lt",
"lockkeys@fawtytoo"
],
"wireguard-indicator": [
"wireguard-indicator@gregos.me",
"wireguard-indicator@atareao.es"
],
"volume-scroller": [
"volume_scroller@trflynn89.pm.me",
"volume_scroller@noskoski"
]
}
}

View file

@ -0,0 +1,49 @@
{ stdenv
, lib
, fetchFromGitHub
, glib
, gettext
, sassc
, gitUpdater
}:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-dash-to-dock";
version = "72";
# Temporarily switched to commit hash because stable version is buggy.
src = fetchFromGitHub {
owner = "micheleg";
repo = "dash-to-dock";
rev = "extensions.gnome.org-v${version}";
sha256 = "Cds5Fc+rnvoy01GTZBS7qPh8UC9ekrNBOs+IEkDNkJw=";
};
nativeBuildInputs = [
glib
gettext
sassc
];
makeFlags = [
"INSTALLBASE=${placeholder "out"}/share/gnome-shell/extensions"
];
passthru = {
extensionUuid = "dash-to-dock@micxgx.gmail.com";
extensionPortalSlug = "dash-to-dock";
updateScript = gitUpdater {
pname = "gnomeExtensions.dash-to-dock";
inherit version;
rev-prefix = "extensions.gnome.org-v";
};
};
meta = with lib; {
description = "A dock for the Gnome Shell";
homepage = "https://micheleg.github.io/dash-to-dock/";
license = licenses.gpl2Plus;
maintainers = with maintainers; [ eperuffo jtojnar rhoriguchi ];
};
}

View file

@ -0,0 +1,86 @@
{ lib
, callPackage
, callPackages
, config
}:
let
buildShellExtension = callPackage ./buildGnomeExtension.nix { };
# Index of all scraped extensions (with supported versions)
extensionsIndex = lib.importJSON ./extensions.json;
# A list of UUIDs that have the same pname and we need to rename them
extensionRenames = import ./extensionRenames.nix;
# Take all extensions from the index that match the gnome version, build them and put them into a list of derivations
produceExtensionsList = shell-version:
lib.trivial.pipe extensionsIndex [
# Does a given extension match our current shell version?
(builtins.filter
(extension: (builtins.hasAttr shell-version extension."shell_version_map"))
)
# Take in an `extension` object from the JSON and transform it into the correct args to call `buildShellExtension`
(map
(extension: {
inherit (extension) uuid name description link pname;
inherit (extension.shell_version_map.${shell-version}) version sha256 metadata;
})
)
# Build them
(map buildShellExtension)
];
# Map the list of extensions to an attrset based on the UUID as key
mapUuidNames = extensions:
lib.trivial.pipe extensions [
(map (extension: lib.nameValuePair extension.extensionUuid extension))
builtins.listToAttrs
];
# Map the list of extensions to an attrset based on the pname as key, which is more human readable than the UUID
# We also take care of conflict renaming in here
mapReadableNames = extensionsList: lib.trivial.pipe extensionsList [
# Filter out all extensions that map to null
(lib.filter (extension:
!(
(builtins.hasAttr extension.extensionUuid extensionRenames)
&& ((builtins.getAttr extension.extensionUuid extensionRenames) == null)
)
))
# Map all extensions to their pname, with potential overwrites
(map (extension:
lib.nameValuePair (extensionRenames.${extension.extensionUuid} or extension.extensionPortalSlug) extension
))
builtins.listToAttrs
];
in rec {
gnome38Extensions = mapUuidNames (produceExtensionsList "38");
gnome40Extensions = mapUuidNames (produceExtensionsList "40");
gnome41Extensions = mapUuidNames (produceExtensionsList "41");
gnome42Extensions = mapUuidNames (produceExtensionsList "42");
gnomeExtensions = lib.trivial.pipe (gnome40Extensions // gnome41Extensions // gnome42Extensions) [
# Apply some custom patches for automatically packaged extensions
(callPackage ./extensionOverrides.nix {})
# Add all manually packaged extensions
(extensions: extensions // (callPackages ./manuallyPackaged.nix {}))
# Map the extension UUIDs to readable names
(lib.attrValues)
(mapReadableNames)
# Add some aliases
(extensions: extensions // lib.optionalAttrs config.allowAliases {
unite-shell = gnomeExtensions.unite; # added 2021-01-19
arc-menu = gnomeExtensions.arcmenu; # added 2021-02-14
disable-unredirect = gnomeExtensions.disable-unredirect-fullscreen-windows; # added 2021-11-20
nohotcorner = throw "gnomeExtensions.nohotcorner removed since 2019-10-09: Since 3.34, it is a part of GNOME Shell configurable through GNOME Tweaks.";
mediaplayer = throw "gnomeExtensions.mediaplayer deprecated since 2019-09-23: retired upstream https://github.com/JasonLG1979/gnome-shell-extensions-mediaplayer/blob/master/README.md";
remove-dropdown-arrows = throw "gnomeExtensions.remove-dropdown-arrows removed since 2021-05-25: The extensions has not seen an update sine GNOME 3.34. Furthermore, the functionality it provides is obsolete as of GNOME 40.";
})
# Export buildShellExtension function
(extensions: extensions // { inherit buildShellExtension; })
# Make the set "public"
lib.recurseIntoAttrs
];
}

View file

@ -0,0 +1,39 @@
{ lib, stdenv, fetchFromGitHub, substituteAll, gjs, vte, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-drop-down-terminal";
version = "unstable-2020-03-25";
src = fetchFromGitHub {
owner = "zzrough";
repo = "gs-extensions-drop-down-terminal";
rev = "a59669afdb395b3315619f62c1f740f8b2f0690d";
sha256 = "0igfxgrjdqq6z6xg4rsawxn261pk25g5dw2pm3bhwz5sqsy4bq3i";
};
passthru = {
extensionUuid = "drop-down-terminal@gs-extensions.zzrough.org";
extensionPortalSlug = "drop-down-terminal";
};
patches = [
(substituteAll {
src = ./fix_vte_and_gjs.patch;
inherit gjs vte;
})
];
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions
cp -r "drop-down-terminal@gs-extensions.zzrough.org" $out/share/gnome-shell/extensions/
runHook postInstall
'';
meta = with lib; {
description = "Configurable drop down terminal shell";
license = licenses.gpl3;
maintainers = with maintainers; [ ericdallo ];
homepage = "https://github.com/zzrough/gs-extensions-drop-down-terminal";
};
}

View file

@ -0,0 +1,32 @@
--- a/drop-down-terminal@gs-extensions.zzrough.org/extension.js
+++ b/drop-down-terminal@gs-extensions.zzrough.org/extension.js
@@ -15,6 +15,8 @@
// Author: Stéphane Démurget <stephane.demurget@free.fr>
+imports.gi.GIRepository.Repository.prepend_search_path('@vte@/lib/girepository-1.0')
+
const Lang = imports.lang;
const Gettext = imports.gettext.domain("drop-down-terminal");
const Mainloop = imports.mainloop;
@@ -653,7 +655,7 @@ const DropDownTerminalExtension = new Lang.Class({
this._killingChild = false;
// finds the forking arguments
- let args = ["gjs", GLib.build_filenamev([Me.path, "terminal.js"]), Me.path];
+ let args = ["@gjs@/bin/gjs", GLib.build_filenamev([Me.path, "terminal.js"]), Me.path];
// forks the process
debug("forking '" + args.join(" ") + "'");
--- a/drop-down-terminal@gs-extensions.zzrough.org/terminal.js
+++ b/drop-down-terminal@gs-extensions.zzrough.org/terminal.js
@@ -14,6 +14,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Author: Stéphane Démurget <stephane.demurget@free.fr>
+
+imports.gi.GIRepository.Repository.prepend_search_path('@vte@/lib/girepository-1.0')
+
const Lang = imports.lang;
const Pango = imports.gi.Pango;

View file

@ -0,0 +1,41 @@
{ lib, stdenv, fetchFromGitHub, glib, gettext }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-emoji-selector";
version = "20";
src = fetchFromGitHub {
owner = "maoschanz";
repo = "emoji-selector-for-gnome";
rev = version;
sha256 = "sha256-I5aEHDC5GaGkAoH+1l4eyhBmJ+lmyZZoDw2Fq2SSlmo=";
};
passthru = {
extensionUuid = "emoji-selector@maestroschan.fr";
extensionPortalSlug = "emoji-selector";
};
nativeBuildInputs = [ glib ];
buildPhase = ''
runHook preBuild
glib-compile-schemas "./emoji-selector@maestroschan.fr/schemas"
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions
cp -r "emoji-selector@maestroschan.fr" $out/share/gnome-shell/extensions
runHook postInstall
'';
meta = with lib; {
description =
"GNOME Shell extension providing a searchable popup menu displaying most emojis";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ rawkode ];
homepage = "https://github.com/maoschanz/emoji-selector-for-gnome";
};
}

View file

@ -0,0 +1,118 @@
{ lib
, ddcutil
, gjs
, gnome
, gobject-introspection
, hddtemp
, liquidctl
, lm_sensors
, netcat-gnu
, nvme-cli
, procps
, pulseaudio
, python3
, smartmontools
, substituteAll
, touchegg
, vte
, wrapGAppsHook
, xprop
}:
let
# Helper method to reduce redundancy
patchExtension = name: override: super: (super // {
${name} = super.${name}.overrideAttrs override;
});
in
# A set of overrides for automatically packaged extensions that require some small fixes.
# The input must be an attribute set with the extensions' UUIDs as keys and the extension
# derivations as values. Output is the same, but with patches applied.
#
# Note that all source patches refer to the built extension as published on extensions.gnome.org, and not
# the upstream repository's sources.
super: lib.trivial.pipe super [
(patchExtension "caffeine@patapon.info" (old: {
meta.maintainers = with lib.maintainers; [ eperuffo ];
}))
(patchExtension "ddterm@amezin.github.com" (old: {
# Requires gjs, zenity & vte via the typelib
nativeBuildInputs = [ gobject-introspection wrapGAppsHook ];
buildInputs = [ vte ];
postPatch = ''
for file in *.js com.github.amezin.ddterm; do
substituteInPlace $file --replace "gjs" "${gjs}/bin/gjs"
substituteInPlace $file --replace "zenity" "${gnome.zenity}/bin/zenity"
done
'';
postFixup = ''
wrapGApp "$out/share/gnome-shell/extensions/ddterm@amezin.github.com/com.github.amezin.ddterm"
'';
}))
(patchExtension "display-brightness-ddcutil@themightydeity.github.com" (old: {
# Has a hard-coded path to a run-time dependency
# https://github.com/NixOS/nixpkgs/issues/136111
postPatch = ''
substituteInPlace "extension.js" --replace "/usr/bin/ddcutil" "${ddcutil}/bin/ddcutil"
'';
}))
(patchExtension "freon@UshakovVasilii_Github.yahoo.com" (old: {
patches = [
(substituteAll {
src = ./extensionOverridesPatches/freon_at_UshakovVasilii_Github.yahoo.com.patch;
inherit hddtemp liquidctl lm_sensors procps smartmontools;
netcat = netcat-gnu;
nvmecli = nvme-cli;
})
];
}))
(patchExtension "gnome-shell-screenshot@ttll.de" (old: {
# Requires gjs
# https://github.com/NixOS/nixpkgs/issues/136112
postPatch = ''
for file in *.js; do
substituteInPlace $file --replace "gjs" "${gjs}/bin/gjs"
done
'';
}))
(patchExtension "screen-autorotate@kosmospredanie.yandex.ru" (old: {
# Requires gjs
# https://github.com/NixOS/nixpkgs/issues/164865
postPatch = ''
for file in *.js; do
substituteInPlace $file --replace "gjs" "${gjs}/bin/gjs"
done
'';
}))
(patchExtension "shell-volume-mixer@derhofbauer.at" (old: {
patches = [
(substituteAll {
src = ./extensionOverridesPatches/shell-volume-mixer_at_derhofbauer.at.patch;
inherit pulseaudio;
inherit python3;
})
];
meta.maintainers = with lib.maintainers; [ rhoriguchi ];
}))
(patchExtension "unite@hardpixel.eu" (old: {
buildInputs = [ xprop ];
meta.maintainers = with lib.maintainers; [ rhoriguchi ];
}))
(patchExtension "x11gestures@joseexposito.github.io" (old: {
# Extension can't find Touchegg
# https://github.com/NixOS/nixpkgs/issues/137621
postPatch = ''
substituteInPlace "src/touchegg/ToucheggConfig.js" \
--replace "GLib.build_filenamev([GLib.DIR_SEPARATOR_S, 'usr', 'share', 'touchegg', 'touchegg.conf'])" "'${touchegg}/share/touchegg/touchegg.conf'"
'';
}))
]

View file

@ -0,0 +1,85 @@
diff --git a/hddtempUtil.js b/hddtempUtil.js
index e5d1d6d..23f6289 100644
--- a/hddtempUtil.js
+++ b/hddtempUtil.js
@@ -7,7 +7,7 @@ var HddtempUtil = class extends CommandLineUtil.CommandLineUtil {
constructor() {
super();
- let hddtempArgv = GLib.find_program_in_path('hddtemp');
+ let hddtempArgv = '@hddtemp@/bin/hddtemp';
if(hddtempArgv) {
// check if this user can run hddtemp directly.
if(!GLib.spawn_command_line_sync(hddtempArgv)[3]){
@@ -19,8 +19,8 @@ var HddtempUtil = class extends CommandLineUtil.CommandLineUtil {
// doesn't seem to be the case… is it running as a daemon?
// Check first for systemd
let systemctl = GLib.find_program_in_path('systemctl');
- let pidof = GLib.find_program_in_path('pidof');
- let nc = GLib.find_program_in_path('nc');
+ let pidof = '@procps@/bin/pidof';
+ let nc = '@netcat@/bin/nc';
let pid = undefined;
if(systemctl) {
@@ -35,7 +35,7 @@ var HddtempUtil = class extends CommandLineUtil.CommandLineUtil {
// systemd isn't used on this system, try sysvinit instead
if(!pid && pidof) {
- let output = GLib.spawn_command_line_sync("pidof hddtemp")[1].toString().trim();
+ let output = GLib.spawn_command_line_sync("@procps@/bin/pidof hddtemp")[1].toString().trim();
if(output.length)
pid = Number(output.trim());
}
diff --git a/liquidctlUtil.js b/liquidctlUtil.js
index 766bf62..2a6faf8 100644
--- a/liquidctlUtil.js
+++ b/liquidctlUtil.js
@@ -8,7 +8,7 @@ const commandLineUtil = Me.imports.commandLineUtil;
var LiquidctlUtil = class extends commandLineUtil.CommandLineUtil {
constructor() {
super();
- const path = GLib.find_program_in_path('liquidctl');
+ const path = '@liquidctl@/bin/liquidctl';
this._argv = path ? [path, 'status', '--json'] : null;
}
diff --git a/nvmecliUtil.js b/nvmecliUtil.js
index 98a61df..8a40624 100644
--- a/nvmecliUtil.js
+++ b/nvmecliUtil.js
@@ -3,7 +3,7 @@ const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
function getNvmeData (argv){
- const nvme = GLib.find_program_in_path('nvme')
+ const nvme = '@nvmecli@/bin/nvme'
return JSON.parse(GLib.spawn_command_line_sync(`${nvme} ${argv} -o json`)[1].toString())
}
diff --git a/sensorsUtil.js b/sensorsUtil.js
index bd6de61..5951b17 100644
--- a/sensorsUtil.js
+++ b/sensorsUtil.js
@@ -7,7 +7,7 @@ var SensorsUtil = class extends CommandLineUtil.CommandLineUtil {
constructor() {
super();
- let path = GLib.find_program_in_path('sensors');
+ let path = '@lm_sensors@/bin/sensors';
// -A: Do not show adapter -j: JSON output
this._argv = path ? [path, '-A', '-j'] : null;
}
diff --git a/smartctlUtil.js b/smartctlUtil.js
index 4888323..66b6c61 100644
--- a/smartctlUtil.js
+++ b/smartctlUtil.js
@@ -3,7 +3,7 @@ const GLib = imports.gi.GLib;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const ByteArray = imports.byteArray;
function getSmartData (argv){
- const smartctl = GLib.find_program_in_path('smartctl')
+ const smartctl = '@smartmontools@/bin/smartctl'
return JSON.parse(ByteArray.toString( GLib.spawn_command_line_sync(`'${smartctl}' ${argv} -j`)[1] ))
}

View file

@ -0,0 +1,32 @@
diff --git a/lib/utils/paHelper.js b/lib/utils/paHelper.js
index be28d21..a410a63 100755
--- a/lib/utils/paHelper.js
+++ b/lib/utils/paHelper.js
@@ -57,13 +57,7 @@ async function execHelper(type, index = undefined) {
return null;
}
- const python = await findPython();
-
- if (!python) {
- return null;
- }
-
- const args = ['/usr/bin/env', python, paUtilPath, type];
+ const args = ['@python3@/bin/python', paUtilPath, type];
if (!isNaN(index)) {
args.push(index);
diff --git a/pautils/lib/libpulse.py b/pautils/lib/libpulse.py
index a32c272..8225f2f 100755
--- a/pautils/lib/libpulse.py
+++ b/pautils/lib/libpulse.py
@@ -16,7 +16,7 @@
from ctypes import *
try:
- lib = CDLL('libpulse.so.0')
+ lib = CDLL('@pulseaudio@/lib/libpulse.so.0')
except:
lib = CDLL('libpulse.so')

View file

@ -0,0 +1,94 @@
# A list of UUIDs that have the same pname and we need to rename them
# MAINTENANCE:
# - Every item from ./collisions.json (for the respective Shell version) should have an entry in here
# - Set the value to `null` for filtering (duplicate or unmaintained extensions)
# - Sort the entries in order of appearance in the collisions.json
# - Make a separate section for each GNOME version. Collisions will come back eventually
# as the extensions are updated.
{
"apps-menu@gnome-shell-extensions.gcampax.github.com" = "applications-menu";
"Applications_Menu@rmy.pobox.com" = "frippery-applications-menu";
"lockkeys@vaina.lt" = "lock-keys";
"lockkeys@fawtytoo" = "lock-keys-2";
"volume_scroller@trflynn89.pm.me" = "volume-scroller";
"volume_scroller@noskoski" = "volume-scroller-2";
"wireguard-indicator@gregos.me" = "wireguard-indicator-2";
"wireguard-indicator@atareao.es" = "wireguard-indicator";
"workspace-indicator@gnome-shell-extensions.gcampax.github.com" = "workspace-indicator";
"horizontal-workspace-indicator@tty2.io" = "workspace-indicator-2";
# ############################################################################
# These are conflicts for older extensions (i.e. they don't support the latest GNOME version).
# Make sure to move them up once they are updated
# ####### GNOME 41 #######
"floatingDock@sun.wxg@gmail.com" = "floating-dock-2";
"floating-dock@nandoferreira_prof@hotmail.com" = "floating-dock";
"unredirect@vaina.lt" = "disable-unredirect-fullscreen-windows";
"unredirect@aunetx" = "disable-unredirect-fullscreen-windows-2";
"fuzzy-clock@keepawayfromfire.co.uk" = "fuzzy-clock-2";
"FuzzyClock@johngoetz" = "fuzzy-clock";
# At the moment, ShutdownTimer@deminder is a fork of ShutdownTimer@neumann which adds new features
# there seem to be upstream plans, so this should be checked periodically:
# https://github.com/Deminder/ShutdownTimer https://github.com/neumann-d/ShutdownTimer/pull/46
"ShutdownTimer@neumann" = null;
"shutdown-timer-gnome-shell-extension" = "shutdowntimer-2";
"ShutdownTimer@deminder" = "shutdowntimer";
# ####### GNOME 40 #######
"system-monitor@paradoxxx.zero.gmail.com" = "system-monitor"; # manually packaged
"System_Monitor@bghome.gmail.com" = "system-monitor-2";
"Hide_Activities@shay.shayel.org" = "hide-activities-button";
"hide-activities-button@nmingori.gnome-shell-extensions.org" = "hide-activities-button-2";
"noannoyance@sindex.com" = "noannoyance";
"noannoyance@daase.net" = "noannoyance-2";
"SomaFm-Radio@alireza6677.gmail.com" = "somafm-internet-radio";
"SomaFm-Radio@cajhne.gmail.com" = "somafm-internet-radio-2";
"panel-date-format@keiii.github.com" = "panel-date-format";
"panel-date-format@atareao.es" = "panel-date-format-2";
"extension-list@tu.berry" = "extension-list";
"screen-lock@garciabaameiro.com" = "screen-lock"; # Don't know why they got 'extension-list' as slug
# ####### GNOME 3.38 #######
"bottompanel@tmoer93" = "bottompanel";
"bottom-panel@sulincix" = "bottompanel-2";
# See https://github.com/pbxqdown/gnome-shell-extension-transparent-window/issues/12#issuecomment-800765381
"transparent-window@pbxqdown.github.com" = "transparent-window";
"transparentwindows.mdirshad07" = null;
# That extension is broken because of https://github.com/NixOS/nixpkgs/issues/118612
"flypie@schneegans.github.com" = null;
# ############################################################################
# Overrides for extensions that were manually packaged in the past but are gradually
# being replaced by automatic packaging where possible.
#
# The manually packaged ones:
"EasyScreenCast@iacopodeenosee.gmail.com" = "easyScreenCast"; # extensionPortalSlug is "easyscreencast"
"gnome-fuzzy-app-search@gnome-shell-extensions.Czarlie.gitlab.com" = "fuzzy-app-search"; # extensionPortalSlug is "gnome-fuzzy-app-search"
"TopIcons@phocean.net" = "topicons-plus"; # extensionPortalSlug is "topicons"
"paperwm@hedning:matrix.org" = "paperwm"; # is not on extensions.gnome.org
"no-title-bar@jonaspoehler.de" = "no-title-bar"; # extensionPortalSlug is "no-title-bar-forked"
# These extensions are automatically packaged at the moment. We preserve the old attribute name
# for backwards compatibility.
"appindicatorsupport@rgcjonas.gmail.com" = "appindicator"; # extensionPortalSlug is "appindicator-support"
"drawOnYourScreen@abakkk.framagit.org" = "draw-on-your-screen"; # extensionPortalSlug is "draw-on-you-screen"
"timepp@zagortenay333" = "timepp"; # extensionPortalSlug is "time"
"windowIsReady_Remover@nunofarruca@gmail.com" = "window-is-ready-remover"; # extensionPortalSlug is "window-is-ready-notification-remover"
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,119 @@
{ lib, stdenv
, fetchFromGitHub
, substituteAll
, openssl
, gsound
, meson
, ninja
, pkg-config
, gobject-introspection
, wrapGAppsHook
, glib
, glib-networking
, gtk3
, openssh
, gnome
, gjs
, nixosTests
}:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-gsconnect";
version = "50";
outputs = [ "out" "installedTests" ];
src = fetchFromGitHub {
owner = "GSConnect";
repo = "gnome-shell-extension-gsconnect";
rev = "v${version}";
hash = "sha256-uUpdjBsVeS99AYDpGlXP9fMqGxWj+XfVubNoGJs76G0=";
};
patches = [
# Make typelibs available in the extension
(substituteAll {
src = ./fix-paths.patch;
gapplication = "${glib.bin}/bin/gapplication";
})
# Allow installing installed tests to a separate output
./installed-tests-path.patch
];
nativeBuildInputs = [
meson
ninja
pkg-config
gobject-introspection # for locating typelibs
wrapGAppsHook # for wrapping daemons
];
buildInputs = [
glib # libgobject
glib-networking
gtk3
gsound
gjs # for running daemon
gnome.evolution-data-server # for libebook-contacts typelib
];
mesonFlags = [
"-Dgnome_shell_libdir=${gnome.gnome-shell}/lib"
"-Dgsettings_schemadir=${glib.makeSchemaPath (placeholder "out") "${pname}-${version}"}"
"-Dchrome_nmhdir=${placeholder "out"}/etc/opt/chrome/native-messaging-hosts"
"-Dchromium_nmhdir=${placeholder "out"}/etc/chromium/native-messaging-hosts"
"-Dopenssl_path=${openssl}/bin/openssl"
"-Dsshadd_path=${openssh}/bin/ssh-add"
"-Dsshkeygen_path=${openssh}/bin/ssh-keygen"
"-Dsession_bus_services_dir=${placeholder "out"}/share/dbus-1/services"
"-Dpost_install=true"
"-Dinstalled_test_prefix=${placeholder "installedTests"}"
];
postPatch = ''
patchShebangs meson/nmh.sh
patchShebangs meson/post-install.sh
patchShebangs installed-tests/prepare-tests.sh
# TODO: do not include every typelib everywhere
# for example, we definitely do not need nautilus
for file in src/extension.js src/prefs.js; do
substituteInPlace "$file" \
--subst-var-by typelibPath "$GI_TYPELIB_PATH"
done
'';
postFixup = ''
# Lets wrap the daemons
for file in $out/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/{daemon,nativeMessagingHost}.js; do
echo "Wrapping program $file"
wrapGApp "$file"
done
# Wrap jasmine runner for tests
for file in $installedTests/libexec/installed-tests/gsconnect/minijasmine; do
echo "Wrapping program $file"
wrapGApp "$file"
done
'';
passthru = {
extensionUuid = "gsconnect@andyholmes.github.io";
extensionPortalSlug = "gsconnect";
};
passthru = {
tests = {
installedTests = nixosTests.installed-tests.gsconnect;
};
};
meta = with lib; {
description = "KDE Connect implementation for Gnome Shell";
homepage = "https://github.com/GSConnect/gnome-shell-extension-gsconnect/wiki";
license = licenses.gpl2Plus;
maintainers = teams.gnome.members;
platforms = platforms.linux;
};
}

View file

@ -0,0 +1,37 @@
diff --git i/data/org.gnome.Shell.Extensions.GSConnect.desktop.in w/data/org.gnome.Shell.Extensions.GSConnect.desktop.in
index ffb23342..b405c73b 100644
--- i/data/org.gnome.Shell.Extensions.GSConnect.desktop.in
+++ w/data/org.gnome.Shell.Extensions.GSConnect.desktop.in
@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GSConnect
-Exec=gapplication launch org.gnome.Shell.Extensions.GSConnect %U
+Exec=@gapplication@ launch org.gnome.Shell.Extensions.GSConnect %U
Terminal=false
NoDisplay=true
Icon=org.gnome.Shell.Extensions.GSConnect
diff --git i/src/extension.js w/src/extension.js
index 5f32aa68..872c0c61 100644
--- i/src/extension.js
+++ w/src/extension.js
@@ -1,5 +1,7 @@
'use strict';
+'@typelibPath@'.split(':').forEach(path => imports.gi.GIRepository.Repository.prepend_search_path(path));
+
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
diff --git i/src/prefs.js w/src/prefs.js
index 07e93099..1c166710 100644
--- i/src/prefs.js
+++ w/src/prefs.js
@@ -1,5 +1,7 @@
'use strict';
+'@typelibPath@'.split(':').forEach(path => imports.gi.GIRepository.Repository.prepend_search_path(path));
+
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;

View file

@ -0,0 +1,30 @@
diff --git a/installed-tests/meson.build b/installed-tests/meson.build
index c7eff2fb..ef4f6052 100644
--- a/installed-tests/meson.build
+++ b/installed-tests/meson.build
@@ -1,5 +1,5 @@
-installed_tests_execdir = join_paths(libexecdir, 'installed-tests', meson.project_name())
-installed_tests_metadir = join_paths(datadir, 'installed-tests', meson.project_name())
+installed_tests_execdir = join_paths(get_option('installed_test_prefix'), 'libexec', 'installed-tests', meson.project_name())
+installed_tests_metadir = join_paths(get_option('installed_test_prefix'), 'share', 'installed-tests', meson.project_name())
installed_tests_srcdir = meson.current_source_dir()
installed_tests_builddir = meson.current_build_dir()
diff --git a/meson_options.txt b/meson_options.txt
index 8912e052..ca6ee5eb 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -116,6 +116,13 @@ option(
description: 'Native Messaging Host directory for Mozilla'
)
+option(
+ 'installed_test_prefix',
+ type: 'string',
+ value: '',
+ description: 'Prefix for installed tests'
+)
+
option(
'installed_tests',
type: 'boolean',

View file

@ -0,0 +1,34 @@
{ lib, stdenv, fetchFromGitHub, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-icon-hider";
version = "23";
src = fetchFromGitHub {
owner = "ikalnytskyi";
repo = "gnome-shell-extension-icon-hider";
rev = "v${version}";
sha256 = "18c8zkdrmdbghqqz7b450vhgpykgz25mgigwn2nggcb2lxmvm9ks";
};
passthru = {
extensionUuid = "icon-hider@kalnitsky.org";
extensionPortalSlug = "icon-hider";
};
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions
cp -r "icon-hider@kalnitsky.org" $out/share/gnome-shell/extensions
runHook postInstall
'';
meta = with lib; {
description = "Icon Hider is a GNOME Shell extension for managing status area items";
license = licenses.bsd3;
maintainers = with maintainers; [ jonafato ];
platforms = gnome.gnome-shell.meta.platforms;
homepage = "https://github.com/ikalnytskyi/gnome-shell-extension-icon-hider";
broken = versionAtLeast gnome.gnome-shell.version "3.32"; # Doesn't support 3.34
};
}

View file

@ -0,0 +1,42 @@
{ lib, stdenv, fetchFromGitHub, glib }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-impatience";
version = "unstable-2022-03-26";
src = fetchFromGitHub {
owner = "timbertson";
repo = "gnome-shell-impatience";
rev = "cf7c0bb8776af9a16e4ae114df0cc65869fb669d";
sha256 = "sha256-z/pZxSEFELtg7kueS2i6gN1+VbN0m4mxc34pOCMak5g=";
};
buildInputs = [
glib
];
buildPhase = ''
runHook preBuild
make schemas
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions
cp -r impatience "$out/share/gnome-shell/extensions/impatience@gfxmonk.net"
runHook postInstall
'';
passthru = {
extensionUuid = "impatience@gfxmonk.net";
extensionPortalSlug = "impatience";
};
meta = with lib; {
description = "Speed up builtin gnome-shell animations";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ timbertson tiramiseb ];
homepage = "http://gfxmonk.net/dist/0install/gnome-shell-impatience.xml";
};
}

View file

@ -0,0 +1,22 @@
{ callPackage }:
{
"arcmenu@arcmenu.com" = callPackage ./arcmenu { };
"clock-override@gnomeshell.kryogenix.org" = callPackage ./clock-override { };
"dash-to-dock@micxgx.gmail.com" = callPackage ./dash-to-dock { };
"drop-down-terminal@gs-extensions.zzrough.org" = callPackage ./drop-down-terminal { };
"EasyScreenCast@iacopodeenosee.gmail.com" = callPackage ./EasyScreenCast { };
"emoji-selector@maestroschan.fr" = callPackage ./emoji-selector { };
"gsconnect@andyholmes.github.io" = callPackage ./gsconnect { };
"icon-hider@kalnitsky.org" = callPackage ./icon-hider { };
"impatience@gfxmonk.net" = callPackage ./impatience { };
"no-title-bar@jonaspoehler.de" = callPackage ./no-title-bar { };
"paperwm@hedning:matrix.org" = callPackage ./paperwm { };
"pidgin@muffinmad" = callPackage ./pidgin-im-integration { };
"pop-shell@system76.com" = callPackage ./pop-shell { };
"sound-output-device-chooser@kgshank.net" = callPackage ./sound-output-device-chooser { };
"system-monitor@paradoxxx.zero.gmail.com" = callPackage ./system-monitor { };
"taskwhisperer-extension@infinicode.de" = callPackage ./taskwhisperer { };
"tilingnome@rliang.github.com" = callPackage ./tilingnome { };
"TopIcons@phocean.net" = callPackage ./topicons-plus { };
"window-corner-preview@fabiomereu.it" = callPackage ./window-corner-preview { };
}

View file

@ -0,0 +1,37 @@
{ lib, stdenv, fetchFromGitHub, substituteAll, glib, gettext, xorg }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-no-title-bar";
version = "11";
src = fetchFromGitHub {
owner = "poehlerj";
repo = "no-title-bar";
rev = "V_${version}";
sha256 = "07ddw47binlsbyvgy4xkdjvd40zyp7nwd17r6k7w54d50vmnwhvb";
};
nativeBuildInputs = [ glib gettext ];
patches = [
(substituteAll {
src = ./fix-paths.patch;
xprop = "${xorg.xprop}/bin/xprop";
xwininfo = "${xorg.xwininfo}/bin/xwininfo";
})
];
makeFlags = [ "INSTALLBASE=$(out)/share/gnome-shell/extensions" ];
passthru = {
extensionUuid = "no-title-bar@jonaspoehler.de";
};
meta = with lib; {
description = "Integrates maximized windows with the top panel";
homepage = "https://github.com/poehlerj/no-title-bar";
license = licenses.gpl2;
maintainers = with maintainers; [ jonafato svsdep maxeaubrey ];
platforms = platforms.linux;
};
}

View file

@ -0,0 +1,56 @@
diff --git a/decoration.js b/decoration.js
index d1ff3dd..ff4193f 100644
--- a/decoration.js
+++ b/decoration.js
@@ -223,7 +223,7 @@ var Decoration = class {
let winId = this._guessWindowXID(win);
- let xprops = GLib.spawn_command_line_sync(`xprop -id ${winId}`);
+ let xprops = GLib.spawn_command_line_sync(`@xprop@ -id ${winId}`);
if (!xprops[0]) {
Utils.log_debug(`Unable to determine windows '${win.get_title()}' original state`);
return win._noTitleBarOriginalState = WindowState.UNKNOWN;
@@ -237,7 +237,7 @@ var Decoration = class {
let prop = '_MOTIF_WM_HINTS';
let value = '0x2, 0x0, %s, 0x0, 0x0'.format(hide ? '0x2' : '0x1');
- GLib.spawn_command_line_sync(`xprop -id ${windId} -f ${prop} 32c -set ${prop} "${value}"`);
+ GLib.spawn_command_line_sync(`@xprop@ -id ${windId} -f ${prop} 32c -set ${prop} "${value}"`);
if (!hide && !win.titlebar_is_onscreen()) {
Utils.log_debug(`Shoving titlebar onscreen for window '${win.get_title()}'`);
win.shove_titlebar_onscreen();
@@ -354,7 +354,7 @@ var Decoration = class {
let act = win.get_compositor_private();
let xwindow = act && act['x-window'];
if (xwindow) {
- let xwininfo = GLib.spawn_command_line_sync('xwininfo -children -id 0x%x'.format(xwindow));
+ let xwininfo = GLib.spawn_command_line_sync('@xwininfo@ -children -id 0x%x'.format(xwindow));
if (xwininfo[0]) {
let str = ByteArray.toString(xwininfo[1]);
@@ -384,7 +384,7 @@ var Decoration = class {
// Try enumerating all available windows and match the title. Note that this
// may be necessary if the title contains special characters and `x-window`
// is not available.
- let result = GLib.spawn_command_line_sync('xprop -root _NET_CLIENT_LIST');
+ let result = GLib.spawn_command_line_sync('@xprop@ -root _NET_CLIENT_LIST');
if (result[0]) {
let str = ByteArray.toString(result[1]);
@@ -395,7 +395,7 @@ var Decoration = class {
// For each window ID, check if the title matches the desired title.
for (var i = 0; i < windowList.length; ++i) {
- let cmd = 'xprop -id "' + windowList[i] + '" _NET_WM_NAME _NO_TITLE_BAR_ORIGINAL_STATE';
+ let cmd = '@xprop@ -id "' + windowList[i] + '" _NET_WM_NAME _NO_TITLE_BAR_ORIGINAL_STATE';
let result = GLib.spawn_command_line_sync(cmd);
if (result[0]) {
@@ -455,4 +455,4 @@ var Decoration = class {
let styleContent = this._updateUserStyles();
GLib.file_set_contents(this._userStylesPath, styleContent);
}
-}
\ No newline at end of file
+}

View file

@ -0,0 +1,31 @@
{ lib, stdenv, fetchFromGitHub }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-paperwm";
version = "38.1";
src = fetchFromGitHub {
owner = "paperwm";
repo = "PaperWM";
rev = version;
sha256 = "1jq15qrq3khqpjsjbcc17amdr1k53jkvambdacdf56xbqkycvlgs";
};
passthru.extensionUuid = "paperwm@hedning:matrix.org";
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p "$out/share/gnome-shell/extensions/paperwm@hedning:matrix.org"
cp -r . "$out/share/gnome-shell/extensions/paperwm@hedning:matrix.org"
runHook postInstall
'';
meta = with lib; {
description = "Tiled scrollable window management for Gnome Shell";
homepage = "https://github.com/paperwm/PaperWM";
license = licenses.gpl3;
maintainers = with maintainers; [ hedning ];
};
}

View file

@ -0,0 +1,39 @@
{ lib, stdenv, fetchFromGitHub, glib, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-pidgin-im-integration";
version = "32";
src = fetchFromGitHub {
owner = "muffinmad";
repo = "pidgin-im-gnome-shell-extension";
rev = "v${version}";
sha256 = "1jyg8r0s1v83sgg6y0jbsj2v37mglh8rvd8vi27fxnjq9xmg8kpc";
};
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
share_dir="$prefix/share"
extensions_dir="$share_dir/gnome-shell/extensions/pidgin@muffinmad"
mkdir -p "$extensions_dir"
mv *.js metadata.json dbus.xml schemas locale "$extensions_dir"
runHook postInstall
'';
passthru = {
extensionUuid = "pidgin@muffinmad";
extensionPortalSlug = "pidgin-im-integration";
};
meta = with lib; {
homepage = "https://github.com/muffinmad/pidgin-im-gnome-shell-extension";
description = "Make Pidgin IM conversations appear in the Gnome Shell message tray";
license = licenses.gpl2;
platforms = platforms.linux;
maintainers = with maintainers; [ ];
broken = versionAtLeast gnome.gnome-shell.version "3.32"; # Doesn't support 3.34
};
}

View file

@ -0,0 +1,46 @@
{ stdenv, lib, fetchFromGitHub, glib, nodePackages, gjs }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-pop-shell";
version = "unstable-2022-03-25";
src = fetchFromGitHub {
owner = "pop-os";
repo = "shell";
rev = "a317816d02dd2cb20d31aeca81bf09eccc63e370";
hash = "sha256-uxoeCv25ew5+NkTpsKjQqDFrqw6ZA/+iYhyCHoCb6jM=";
};
nativeBuildInputs = [ glib nodePackages.typescript gjs ];
buildInputs = [ gjs ];
patches = [
./fix-gjs.patch
];
makeFlags = [ "XDG_DATA_HOME=$(out)/share" ];
passthru = {
extensionUuid = "pop-shell@system76.com";
extensionPortalSlug = "pop-shell";
};
postPatch = ''
for file in */main.js; do
substituteInPlace $file --replace "gjs" "${gjs}/bin/gjs"
done
'';
preFixup = ''
chmod +x $out/share/gnome-shell/extensions/pop-shell@system76.com/*/main.js
'';
meta = with lib; {
description = "Keyboard-driven layer for GNOME Shell";
license = licenses.gpl3Only;
platforms = platforms.linux;
maintainers = [ maintainers.genofire ];
homepage = "https://github.com/pop-os/shell";
};
}

View file

@ -0,0 +1,33 @@
diff --git a/src/extension.ts b/src/extension.ts
index 7417c46..00d5829 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -534,7 +534,7 @@ export class Ext extends Ecs.System<ExtEvent> {
return true
}
- const ipc = utils.async_process_ipc(["gjs", path])
+ const ipc = utils.async_process_ipc([path])
if (ipc) {
const generator = (stdout: any, res: any) => {
diff --git a/src/panel_settings.ts b/src/panel_settings.ts
index 83ff56c..1bc1e98 100644
--- a/src/panel_settings.ts
+++ b/src/panel_settings.ts
@@ -338,7 +338,7 @@ function color_selector(ext: Ext, menu: any) {
color_selector_item.add_child(color_button);
color_button.connect('button-press-event', () => {
let path = Me.dir.get_path() + "/color_dialog/main.js";
- let resp = GLib.spawn_command_line_async(`gjs ${path}`);
+ let resp = GLib.spawn_command_line_async(path);
if (!resp) {
return null;
@@ -353,4 +353,4 @@ function color_selector(ext: Ext, menu: any) {
});
return color_selector_item;
-}
\ No newline at end of file
+}

View file

@ -0,0 +1,51 @@
{ lib, stdenv
, substituteAll
, fetchFromGitHub
, fetchpatch
, libpulseaudio
, python3
}:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-sound-output-device-chooser";
# For gnome 42 support many commits not tagged yet are needed.
version = "unstable-2022-03-29";
src = fetchFromGitHub {
owner = "kgshank";
repo = "gse-sound-output-device-chooser";
rev = "76f7f59d23f5ffcd66555c7662f43c9cc1ce4742";
sha256 = "sha256-iPc95LmDsYizLg45wpU+vFx/N6MR2hewSHqoRsePC/4=";
};
patches = [
# Fix paths to libpulse and python
(substituteAll {
src = ./fix-paths.patch;
libpulse = "${libpulseaudio}/lib/libpulse.so";
python = python3.interpreter;
})
];
dontBuild = true;
passthru = {
extensionUuid = "sound-output-device-chooser@kgshank.net";
extensionPortalSlug = "sound-output-device-chooser";
};
makeFlags = [
"INSTALL_DIR=${placeholder "out"}/share/gnome-shell/extensions"
];
preInstall = ''
mkdir -p ${placeholder "out"}/share/gnome-shell/extensions
'';
meta = with lib; {
description = "GNOME Shell extension adding audio device chooser to panel";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ jtojnar ];
homepage = "https://github.com/kgshank/gse-sound-output-device-chooser";
};
}

View file

@ -0,0 +1,26 @@
diff --git a/sound-output-device-chooser@kgshank.net/convenience.js b/sound-output-device-chooser@kgshank.net/convenience.js
index 54ad06f..0860531 100644
--- a/sound-output-device-chooser@kgshank.net/convenience.js
+++ b/sound-output-device-chooser@kgshank.net/convenience.js
@@ -142,7 +142,7 @@ function refreshCards() {
if (newProfLogic) {
_log("New logic");
let pyLocation = Me.dir.get_child("utils/pa_helper.py").get_path();
- let pythonExec = ["python", "python3", "python2"].find(cmd => isCmdFound(cmd));
+ let pythonExec = '@python@';
if (!pythonExec) {
_log("ERROR: Python not found. fallback to default mode");
_settings.set_boolean(Prefs.NEW_PROFILE_ID, false);
diff --git a/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py b/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py
index c4d2484..262608d 100644
--- a/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py
+++ b/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py
@@ -82,7 +82,7 @@ else:
_libraries = {}
-libpulse_library_name = find_library('pulse')
+libpulse_library_name = '@libpulse@'
if libpulse_library_name is None:
raise Exception('No libpulse.so library found!')

View file

@ -0,0 +1,45 @@
{ lib, stdenv, substituteAll, fetchFromGitHub, glib, glib-networking, libgtop, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-system-monitor";
version = "unstable-2022-02-04";
src = fetchFromGitHub {
owner = "paradoxxxzero";
repo = "gnome-shell-system-monitor-applet";
rev = "2c6eb0a447bfc9f1a07c61956c92a55c874baf16";
hash = "sha256-JuRRlvqlqneqUdgezKGl2yg7wFYGCCo51q9CBwrxTBY=";
};
nativeBuildInputs = [
glib
gnome.gnome-shell
];
patches = [
(substituteAll {
src = ./paths_and_nonexisting_dirs.patch;
clutter_path = gnome.mutter.libdir; # only needed for GNOME < 40.
gtop_path = "${libgtop}/lib/girepository-1.0";
glib_net_path = "${glib-networking}/lib/girepository-1.0";
})
];
makeFlags = [
"VERSION=${version}"
"INSTALLBASE=$(out)/share/gnome-shell/extensions"
"SUDO="
];
passthru = {
extensionUuid = "system-monitor@paradoxxx.zero.gmail.com";
extensionPortalSlug = "system-monitor";
};
meta = with lib; {
description = "Display system informations in gnome shell status bar";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ andersk ];
homepage = "https://github.com/paradoxxxzero/gnome-shell-system-monitor-applet";
};
}

View file

@ -0,0 +1,33 @@
diff --git a/system-monitor@paradoxxx.zero.gmail.com/extension.js b/system-monitor@paradoxxx.zero.gmail.com/extension.js
index de5e3d7..2d7824d 100644
--- a/system-monitor@paradoxxx.zero.gmail.com/extension.js
+++ b/system-monitor@paradoxxx.zero.gmail.com/extension.js
@@ -18,6 +18,9 @@
// Author: Florian Mounier aka paradoxxxzero
+imports.gi.GIRepository.Repository.prepend_search_path('@gtop_path@');
+imports.gi.GIRepository.Repository.prepend_search_path('@glib_net_path@');
+
/* Ugly. This is here so that we don't crash old libnm-glib based shells unnecessarily
* by loading the new libnm.so. Should go away eventually */
@@ -407,7 +410,7 @@ const smMountsMonitor = class SystemMonitor_smMountsMonitor {
this.connected = false;
this._volumeMonitor = Gio.VolumeMonitor.get();
- let sys_mounts = ['/home', '/tmp', '/boot', '/usr', '/usr/local'];
+ let sys_mounts = ['/home', '/tmp', '/boot'];
this.base_mounts = ['/'];
sys_mounts.forEach((sMount) => {
if (this.is_sys_mount(sMount + '/')) {
diff --git a/system-monitor@paradoxxx.zero.gmail.com/prefs.js b/system-monitor@paradoxxx.zero.gmail.com/prefs.js
index 81d667c..0da4809 100644
--- a/system-monitor@paradoxxx.zero.gmail.com/prefs.js
+++ b/system-monitor@paradoxxx.zero.gmail.com/prefs.js
@@ -1,3 +1,5 @@
+imports.gi.GIRepository.Repository.prepend_search_path('@clutter_path@');
+
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const Gdk = imports.gi.Gdk;

View file

@ -0,0 +1,45 @@
{ lib, stdenv, substituteAll, fetchFromGitHub, taskwarrior, gettext, runtimeShell }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-taskwhisperer";
version = "20";
src = fetchFromGitHub {
owner = "cinatic";
repo = "taskwhisperer";
rev = "v${version}";
sha256 = "sha256-UVBLFXsbOPRXC4P5laZ82Rs08yXnNnzJ+pp5fbx6Zqc=";
};
nativeBuildInputs = [
gettext
];
buildInputs = [
taskwarrior
];
passthru = {
extensionUuid = "taskwhisperer-extension@infinicode.de";
extensionPortalSlug = "taskwhisperer";
};
makeFlags = [
"INSTALLBASE=${placeholder "out"}/share/gnome-shell/extensions"
];
patches = [
(substituteAll {
src = ./fix-paths.patch;
task = "${taskwarrior}/bin/task";
shell = runtimeShell;
})
];
meta = with lib; {
description = "GNOME Shell TaskWarrior GUI";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ jonafato ];
homepage = "https://github.com/cinatic/taskwhisperer";
};
}

View file

@ -0,0 +1,99 @@
diff --git a/taskwhisperer-extension@infinicode.de/metadata.json b/taskwhisperer-extension@infinicode.de/metadata.json
index 2f1471c..a84bdf4 100644
--- a/taskwhisperer-extension@infinicode.de/metadata.json
+++ b/taskwhisperer-extension@infinicode.de/metadata.json
@@ -6,7 +6,8 @@
"3.32",
"3.36",
"3.38",
- "40"
+ "40",
+ "41"
],
"url": "https://github.com/cinatic/taskwhisperer",
"uuid": "taskwhisperer-extension@infinicode.de",
diff --git a/taskwhisperer-extension@infinicode.de/services/taskService.js b/taskwhisperer-extension@infinicode.de/services/taskService.js
index df09cdf..df68c60 100644
--- a/taskwhisperer-extension@infinicode.de/services/taskService.js
+++ b/taskwhisperer-extension@infinicode.de/services/taskService.js
@@ -63,7 +63,7 @@ var loadTaskData = async ({ taskStatus, project, taskOrder }) => {
await syncTasks()
- const command = ['task', 'rc.json.array=on', statusFilter, projectFilter, 'export'].join(' ')
+ const command = ['@task@', 'rc.json.array=on', statusFilter, projectFilter, 'export'].join(' ')
let { output, error } = await run({ command })
@@ -110,7 +110,7 @@ var loadProjectsData = async taskStatus => {
await syncTasks()
- const command = ['task', 'rc.json.array=on', statusFilter, 'export'].join(' ')
+ const command = ['@task@', 'rc.json.array=on', statusFilter, 'export'].join(' ')
const { output: allTheTasks } = await run({ command })
let sortedUniqueProjects = []
@@ -129,7 +129,7 @@ var setTaskDone = async taskID => {
return
}
- const command = ['task', taskID.toString(), 'done'].join(' ')
+ const command = ['@task@', taskID.toString(), 'done'].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -146,7 +146,7 @@ var setTaskUndone = async taskUUID => {
return
}
- const command = ['task', `uuid:${taskUUID}`, 'modify', 'status:pending'].join(' ')
+ const command = ['@task@', `uuid:${taskUUID}`, 'modify', 'status:pending'].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -163,7 +163,7 @@ var startTask = async taskID => {
return
}
- const command = ['task', taskID.toString(), 'start'].join(' ')
+ const command = ['@task@', taskID.toString(), 'start'].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -180,7 +180,7 @@ var stopTask = async taskID => {
return
}
- const command = ['task', taskID.toString(), 'stop'].join(' ')
+ const command = ['@task@', taskID.toString(), 'stop'].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -195,7 +195,7 @@ var stopTask = async taskID => {
var createTask = async task => {
const params = _convertTaskToParams(task)
- const command = ['task', 'add', ...params].join(' ')
+ const command = ['@task@', 'add', ...params].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -212,7 +212,7 @@ var modifyTask = async (taskUUID, task) => {
const params = _convertTaskToParams(task)
- const command = ['task', `uuid:${taskUUID}`, 'modify', ...params].join(' ')
+ const command = ['@task@', `uuid:${taskUUID}`, 'modify', ...params].join(' ')
const result = await run({ command, asJson: false })
if (!result.error) {
@@ -227,7 +227,7 @@ var syncTasks = async () => {
return
}
- const command = ['task', 'sync'].join(' ')
+ const command = ['@task@', 'sync'].join(' ')
const result = await run({ command, asJson: false })
_showProcessErrorNotificationIfError(result, 'Sync Tasks')

View file

@ -0,0 +1,41 @@
{ stdenv, lib, fetchFromGitHub, glib, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-tilingnome";
version = "unstable-2019-09-19";
src = fetchFromGitHub {
owner = "rliang";
repo = "gnome-shell-extension-tilingnome";
rev = "f401c20c9721d85e6b3e30d1e822a200db370407";
sha256 = "1hq9g9bxqpzqrdj9zm0irld8r6q4w1m4b00jya7wsny8rzb1s0y2";
};
nativeBuildInputs = [ glib ];
buildPhase = ''
runHook preBuild
glib-compile-schemas .
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p "$out/share/gnome-shell/extensions/tilingnome@rliang.github.com"
cp -r * "$out/share/gnome-shell/extensions/tilingnome@rliang.github.com/"
runHook postInstall
'';
passthru = {
extensionUuid = "tilingnome@rliang.github.com";
extensionPortalSlug = "tilingnome";
};
meta = with lib; {
description = "Tiling window management for GNOME Shell";
license = licenses.gpl2;
maintainers = with maintainers; [ benley ];
homepage = "https://github.com/rliang/gnome-shell-extension-tilingnome";
platforms = gnome.gnome-shell.meta.platforms;
};
}

View file

@ -0,0 +1,28 @@
{ lib, stdenv, fetchFromGitHub, glib, gettext }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-topicons-plus";
version = "27";
src = fetchFromGitHub {
owner = "phocean";
repo = "TopIcons-plus";
rev = version;
sha256 = "1p3jlvs4zgnrvy8am7myivv4rnnshjp49kg87rd22qqyvcz51ykr";
};
buildInputs = [ glib ];
nativeBuildInputs = [ gettext ];
makeFlags = [ "INSTALL_PATH=$(out)/share/gnome-shell/extensions" ];
passthru.extensionUuid = "TopIcons@phocean.net";
meta = with lib; {
description = "Brings all icons back to the top panel, so that it's easier to keep track of apps running in the backround";
license = licenses.gpl2Only;
maintainers = with maintainers; [ eperuffo ];
homepage = "https://github.com/phocean/TopIcons-plus";
};
}

View file

@ -0,0 +1,301 @@
#!/usr/bin/env nix-shell
#!nix-shell -I nixpkgs=../../../.. -i python3 -p python3
import base64
import json
import logging
import subprocess
import urllib.error
import urllib.request
from operator import itemgetter
from pathlib import Path
from typing import List, Dict, Optional, Any, Tuple
# We don't want all those deprecated legacy extensions
# Group extensions by GNOME "major" version for compatibility reasons
supported_versions = {
"38": "3.38",
"40": "40",
"41": "41",
"42": "42",
}
# Some type alias to increase readability of complex compound types
PackageName = str
ShellVersion = str
Uuid = str
ExtensionVersion = int
# Keep track of all names that have been used till now to detect collisions.
# This works because we deterministically process all extensions in historical order
# The outer dict level is the shell version, as we are tracking duplicates only per same Shell version.
# key: shell version, value: Dict with key: pname, value: list of UUIDs with that pname
package_name_registry: Dict[ShellVersion, Dict[PackageName, List[Uuid]]] = {}
for shell_version in supported_versions.keys():
package_name_registry[shell_version] = {}
updater_dir_path = Path(__file__).resolve().parent
def fetch_extension_data(uuid: str, version: str) -> Tuple[str, str]:
"""
Download the extension and hash it. We use `nix-prefetch-url` for this for efficiency reasons.
Returns a tuple with the hash (Nix-compatible) of the zip file's content and the base64-encoded content of its metadata.json.
"""
# The download URLs follow this schema
uuid = uuid.replace("@", "")
url: str = f"https://extensions.gnome.org/extension-data/{uuid}.v{version}.shell-extension.zip"
# Download extension and add the zip content to nix-store
process = subprocess.run(
["nix-prefetch-url", "--unpack", "--print-path", url], capture_output=True, text=True
)
lines = process.stdout.splitlines()
# Get hash from first line of nix-prefetch-url output
hash = lines[0].strip()
# Get path from second line of nix-prefetch-url output
path = Path(lines[1].strip())
# Get metadata.json content from nix-store
with open(path / "metadata.json", "r") as out:
metadata = base64.b64encode(out.read().encode("ascii")).decode()
return hash, metadata
def generate_extension_versions(
extension_version_map: Dict[ShellVersion, ExtensionVersion], uuid: str
) -> Dict[ShellVersion, Dict[str, str]]:
"""
Takes in a mapping from shell versions to extension versions and transforms it the way we need it:
- Only take one extension version per GNOME Shell major version (as per `supported_versions`)
- Filter out versions that only support old GNOME versions
- Download the extension and hash it
"""
# Determine extension version per shell version
extension_versions: Dict[ShellVersion, ExtensionVersion] = {}
for shell_version, version_prefix in supported_versions.items():
# Newest compatible extension version
extension_version: Optional[int] = max(
(
int(ext_ver)
for shell_ver, ext_ver in extension_version_map.items()
if (shell_ver.startswith(version_prefix))
),
default=None,
)
# Extension is not compatible with this GNOME version
if not extension_version:
continue
extension_versions[shell_version] = extension_version
# Download information once for all extension versions chosen above
extension_info_cache: Dict[ExtensionVersion, Tuple[str, str]] = {}
for extension_version in sorted(set(extension_versions.values())):
logging.debug(
f"[{uuid}] Downloading v{extension_version}"
)
extension_info_cache[extension_version] = \
fetch_extension_data(uuid, str(extension_version))
# Fill map
extension_versions_full: Dict[ShellVersion, Dict[str, str]] = {}
for shell_version, extension_version in extension_versions.items():
sha256, metadata = extension_info_cache[extension_version]
extension_versions_full[shell_version] = {
"version": str(extension_version),
"sha256": sha256,
# The downloads are impure, their metadata.json may change at any time.
# Thus, we back it up / pin it to remain deterministic
# Upstream issue: https://gitlab.gnome.org/Infrastructure/extensions-web/-/issues/137
"metadata": metadata,
}
return extension_versions_full
def pname_from_url(url: str) -> Tuple[str, str]:
"""
Parse something like "/extension/1475/battery-time/" and output ("battery-time", "1475")
"""
url = url.split("/") # type: ignore
return url[3], url[2]
def process_extension(extension: Dict[str, Any]) -> Optional[Dict[str, Any]]:
"""
Process an extension. It takes in raw scraped data and downloads all the necessary information that buildGnomeExtension.nix requires
Input: a json object of one extension queried from the site. It has the following schema (only important key listed):
{
"uuid": str,
"name": str,
"description": str,
"link": str,
"shell_version_map": {
str: { "version": int, },
},
}
"uuid" is an extension UUID that looks like this (most of the time): "extension-name@username.domain.tld".
Don't make any assumptions on it, and treat it like an opaque string!
"link" follows the following schema: "/extension/$number/$string/"
The number is monotonically increasing and unique to every extension.
The string is usually derived from the extension name (but shortened, kebab-cased and URL friendly).
It may diverge from the actual name.
The keys of "shell_version_map" are GNOME Shell version numbers.
Output: a json object to be stored, or None if the extension should be skipped. Schema:
{
"uuid": str,
"name": str,
"pname": str,
"description": str,
"link": str,
"shell_version_map": {
str: { "version": int, "sha256": str, "metadata": <hex> },
}
}
Only "uuid" gets passed along unmodified. "name", "description" and "link" are taken from the input, but sanitized.
"pname" gets generated from other fields and "shell_version_map" has a completely different structure than the input
field with the same name.
"""
uuid = extension["uuid"]
# Yeah, there are some extensions without any releases
if not extension["shell_version_map"]:
return None
logging.info(f"Processing '{uuid}'")
# Input is a mapping str -> { version: int, … }
# We want to map shell versions to extension versions
shell_version_map: Dict[ShellVersion, int] = {
k: v["version"] for k, v in extension["shell_version_map"].items()
}
# Transform shell_version_map to be more useful for us. Also throw away unwanted versions
shell_version_map: Dict[ShellVersion, Dict[str, str]] = generate_extension_versions(shell_version_map, uuid) # type: ignore
# No compatible versions found
if not shell_version_map:
return None
# Fetch a human-readable name for the package.
(pname, _pname_id) = pname_from_url(extension["link"])
for shell_version in shell_version_map.keys():
if pname in package_name_registry[shell_version]:
logging.warning(f"Package name '{pname}' for GNOME '{shell_version}' is colliding.")
package_name_registry[shell_version][pname].append(uuid)
else:
package_name_registry[shell_version][pname] = [uuid]
return {
"uuid": uuid,
"name": extension["name"],
"pname": pname,
"description": extension["description"],
"link": "https://extensions.gnome.org" + extension["link"],
"shell_version_map": shell_version_map,
}
def scrape_extensions_index() -> List[Dict[str, Any]]:
"""
Scrape the list of extensions by sending search queries to the API. We simply go over it
page by page until we hit a non-full page or a 404 error.
The returned list is sorted by the age of the extension, in order to be deterministic.
"""
page = 0
extensions = []
while True:
page += 1
logging.info("Scraping page " + str(page))
try:
with urllib.request.urlopen(
f"https://extensions.gnome.org/extension-query/?n_per_page=25&page={page}"
) as response:
data = json.loads(response.read().decode())["extensions"]
response_length = len(data)
for extension in data:
extensions.append(extension)
# If our page isn't "full", it must have been the last one
if response_length < 25:
logging.debug(
f"\tThis page only has {response_length} entries, so it must be the last one."
)
break
except urllib.error.HTTPError as e:
if e.code == 404:
# We reached past the last page and are done now
break
else:
raise
# `pk` is the primary key in the extensions.gnome.org database. Sorting on it will give us a stable,
# deterministic ordering.
extensions.sort(key=itemgetter("pk"))
return extensions
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
raw_extensions = scrape_extensions_index()
logging.info(f"Downloaded {len(raw_extensions)} extensions. Processing …")
processed_extensions: List[Dict[str, Any]] = []
for num, raw_extension in enumerate(raw_extensions):
processed_extension = process_extension(raw_extension)
if processed_extension:
processed_extensions.append(processed_extension)
logging.debug(f"Processed {num + 1} / {len(raw_extensions)}")
with open(updater_dir_path / "extensions.json", "w") as out:
# Manually pretty-print the outer level, but then do one compact line per extension
# This allows for the diffs to be manageable (one line of change per extension) despite their quantity
for index, extension in enumerate(processed_extensions):
if index == 0:
out.write("[ ")
else:
out.write(", ")
json.dump(extension, out, ensure_ascii=False)
out.write("\n")
out.write("]\n")
logging.info(
f"Done. Writing results to extensions.json ({len(processed_extensions)} extensions in total)"
)
with open(updater_dir_path / "extensions.json", "r") as out:
# Check that the generated file actually is valid JSON, just to be sure
json.load(out)
with open(updater_dir_path / "collisions.json", "w") as out:
# Filter out those that are not duplicates
package_name_registry_filtered: Dict[ShellVersion, Dict[PackageName, List[Uuid]]] = {
# The outer level keys are shell versions
shell_version: {
# The inner keys are extension names, with a list of all extensions with that name as value.
pname: extensions for pname, extensions in collisions.items() if len(extensions) > 1
} for shell_version, collisions in package_name_registry.items()
}
json.dump(package_name_registry_filtered, out, indent=2, ensure_ascii=False)
out.write("\n")
logging.info(
"Done. Writing name collisions to collisions.json (please check manually)"
)

View file

@ -0,0 +1,35 @@
{ lib, stdenv, fetchFromGitHub, gnome }:
stdenv.mkDerivation rec {
pname = "gnome-shell-extension-window-corner-preview";
version = "unstable-2019-04-03";
src = fetchFromGitHub {
owner = "medenagan";
repo = "window-corner-preview";
rev = "a95bb1389d94474efab7509aac592fb58fff6006";
sha256 = "03v18j9l0fb64xrg3swf1vcgl0kpgwjlp8ddn068bpvghrsvgfah";
};
dontBuild = true;
passthru = {
extensionUuid = "window-corner-preview@fabiomereu.it";
extensionPortalSlug = "window-corner-preview";
};
installPhase = ''
runHook preInstall
mkdir -p $out/share/gnome-shell/extensions
cp -r "window-corner-preview@fabiomereu.it" $out/share/gnome-shell/extensions
runHook postInstall
'';
meta = with lib; {
description = "GNOME Shell extension showing a video preview on the corner of the screen";
license = licenses.mit;
maintainers = with maintainers; [ jtojnar ];
homepage = "https://github.com/medenagan/window-corner-preview";
broken = lib.versionAtLeast gnome.gnome-shell.version "3.32"; # Doesn't support 3.34
};
}