Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnome extension #2398

Open
wants to merge 73 commits into
base: master
from
Open
Changes from 5 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
289f5db
Initial gnome desktop extension
diddledan Nov 8, 2018
64914e8
add extensions to schema/snapcraft.yaml
diddledan Nov 8, 2018
bf68218
spelling error in desktop-exports script from desktop extension
diddledan Nov 8, 2018
f0da7d8
appease shellcheck
diddledan Nov 8, 2018
1ba844e
Merge branch 'master' into desktop-gnome-extension
sergiusens Nov 11, 2018
23595d3
refactor gnome extension
diddledan Jan 7, 2019
58a7efc
Merge branch 'desktop-gnome-extension' of github.com:diddledan/snapcr…
diddledan Jan 7, 2019
0c85fb3
Merge branch 'master' of https://github.com/snapcore/snapcraft into d…
diddledan Jan 7, 2019
87fd118
merge desktop extension script
diddledan Jan 7, 2019
89a2db9
fix references to content interfaces paths
diddledan Jan 7, 2019
54215e3
add shared snap mountpoints and update launcher
diddledan Jan 7, 2019
ae2e4c5
squash test errors
diddledan Jan 7, 2019
e845f79
fix GIO modules symlinks; update gnome-extension
diddledan Jan 8, 2019
ab8285b
add layout to fix libwebkitgtk
diddledan Jan 8, 2019
844e6e1
Merge branch 'master' into desktop-gnome-extension
diddledan Jan 8, 2019
5d14973
set environment in command-chain scripts
diddledan Jan 14, 2019
e83ec34
fix gnome extension for core/core16 usage
diddledan Jan 14, 2019
80ab417
fix gnome extension usage of 'nil' plugin
diddledan Jan 14, 2019
61111ac
ensure static tests pass for gnome extension
diddledan Jan 14, 2019
4d24738
fix bugs in gnome extension scripts
diddledan Jan 15, 2019
6a301ca
Initial gnome desktop extension
diddledan Nov 8, 2018
a5642d2
add extensions to schema/snapcraft.yaml
diddledan Nov 8, 2018
478f7d2
spelling error in desktop-exports script from desktop extension
diddledan Nov 8, 2018
58121d1
appease shellcheck
diddledan Nov 8, 2018
1836ba5
refactor gnome extension
diddledan Jan 7, 2019
e06d7ec
merge desktop extension script
diddledan Jan 7, 2019
5f091b9
fix references to content interfaces paths
diddledan Jan 7, 2019
601d71f
add shared snap mountpoints and update launcher
diddledan Jan 7, 2019
9bf1939
squash test errors
diddledan Jan 7, 2019
745cd43
fix GIO modules symlinks; update gnome-extension
diddledan Jan 8, 2019
f668e50
add layout to fix libwebkitgtk
diddledan Jan 8, 2019
aa917d4
set environment in command-chain scripts
diddledan Jan 14, 2019
7e25ef9
fix gnome extension for core/core16 usage
diddledan Jan 14, 2019
72b2bd0
fix gnome extension usage of 'nil' plugin
diddledan Jan 14, 2019
4054ef4
ensure static tests pass for gnome extension
diddledan Jan 14, 2019
8fd0c49
fix bugs in gnome extension scripts
diddledan Jan 15, 2019
53ed8bc
further refinements to gnome extension
diddledan Jan 18, 2019
728ac4d
Fix GDK Pixbuf loaders
diddledan Jan 19, 2019
aed7404
Merge branch 'desktop-gnome-extension' of github.com:diddledan/snapcr…
diddledan Jan 19, 2019
5a6ff32
Update extensions/desktop-common/desktop-common
diddledan Jan 22, 2019
ddd64ce
update extensions/gnome/desktop-gnome-specific
diddledan Jan 22, 2019
16247ab
Add bindtextdomain for localisations
diddledan Jan 22, 2019
6aa832f
Desktop extension: Fix bindtextdomain.so build
diddledan Jan 23, 2019
d3afb53
Add locale-langpack path to bindtextdomain.c
diddledan Jan 25, 2019
cdafbe2
Add iso-codes layout to gnome extension
diddledan Feb 12, 2019
fa73f54
Merge remote-tracking branch 'origin/master' into desktop-gnome-exten…
diddledan Feb 12, 2019
21787d2
Merge branch 'master' into desktop-gnome-extension
sergiusens Feb 13, 2019
04e059e
ci: shallow clones for CLA checks on travis
sergiusens Feb 19, 2019
5092330
Merge remote-tracking branch 'origin/master' into desktop-gnome-exten…
sergiusens Feb 19, 2019
5b37480
rename gnome extension to gnome-3-28
diddledan Feb 19, 2019
e1361d0
Minor syntax errors on gnome-3-28 extension
diddledan Feb 20, 2019
712c0d8
incorrect quote style in extensions/_utils.py
diddledan Feb 20, 2019
0720c4d
force supported_cores to be a tuple in gnome ext
diddledan Feb 20, 2019
9f31943
Merge branch 'master' into desktop-gnome-extension
sergiusens Feb 20, 2019
1ecd076
Backport ubuntu/snapcraft-desktop-helpers#176
diddledan Mar 15, 2019
8b9084f
Merge branch 'master' of https://github.com/snapcore/snapcraft into d…
diddledan Mar 15, 2019
723257d
Merge branch 'desktop-gnome-extension' of github.com:diddledan/snapcr…
diddledan Mar 15, 2019
364960e
Gnome extension: variable name changes
diddledan Mar 24, 2019
3f5ec4f
Extensions: refactor away gnome exceptions
diddledan Mar 24, 2019
31b92f5
Gnome extension: remove duplicate test
diddledan Mar 24, 2019
ab20600
Desktop extensions: Remove -mark-and-exec script
diddledan Mar 24, 2019
d9aacdf
Gnome extension: Remove unused dependency vars
diddledan Mar 24, 2019
2c133da
Extensions: spelling mistake in error message
diddledan Mar 26, 2019
fd9cdd9
Gnome extension: Remove fedora $SNAP override
diddledan Apr 17, 2019
6c46d4b
Gnome extension: Fix missed var change
diddledan Apr 17, 2019
0347854
Gnome extension: Dont add empties to XDG_*_PATHS
diddledan Apr 17, 2019
11a90b4
Merge branch 'master' into desktop-gnome-extension
diddledan Apr 17, 2019
27c30c2
Gnome extension: Attempt to resolve double-frees
diddledan Apr 17, 2019
136e210
Merge branch 'desktop-gnome-extension' of github.com:diddledan/snapcr…
diddledan Apr 17, 2019
e6e6503
Desktop extensions: last-updated move to common
diddledan Apr 17, 2019
c18b474
Desktop extensions: prevent memory leak
diddledan Apr 23, 2019
c004c55
Gnome extension: code formatting fixes
diddledan Apr 23, 2019
ba86605
Desktop extensions: incorrect shell quoting
diddledan Apr 23, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+792 −0
Diff settings

Always

Just for now

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,55 @@
#!/bin/bash

#################
# Launcher init #
#################

# On Fedora $SNAP is under /var and there is some magic to map it to /snap.
# # We need to handle that case and reset $SNAP
SNAP="${SNAP//\/var\/lib\/snapd/}"

needs_update="true"

# shellcheck source=/dev/null
. "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true
if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then
needs_update="false"
fi

# Set $REALHOME to the users real home directory
REALHOME="$(getent passwd $UID | cut -d ':' -f 6)"

# Set config folder to local path
export XDG_CONFIG_HOME="$SNAP_USER_DATA/.config"
mkdir -p "$XDG_CONFIG_HOME" && chmod 700 "$XDG_CONFIG_HOME"

# If the user has modified their user-dirs settings, force an update
if [[ -f "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" && -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" ]]; then
if [[ "$(md5sum < "$REALHOME/.config/user-dirs.dirs")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum")" ||
"$(md5sum < "$REALHOME/.config/user-dirs.locale")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.locale.md5sum")" ]]; then
needs_update="true"
fi
fi

export DESKTOP_LAUNCHER_NEEDS_UPDATE="$needs_update"

if [ "$SNAP_ARCH" == "amd64" ]; then
ARCH="x86_64-linux-gnu"
elif [ "$SNAP_ARCH" == "armhf" ]; then
ARCH="arm-linux-gnueabihf"
elif [ "$SNAP_ARCH" == "arm64" ]; then
ARCH="aarch64-linux-gnu"
else
ARCH="$SNAP_ARCH-linux-gnu"
fi

export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH"

# Don't LD_PRELOAD bindtextdomain for classic snaps
if ! grep -qs "^\s*confinement:\s*classic\s*" "$SNAP/meta/snap.yaml"; then
if [ -f "$SNAP/lib/bindtextdomain.so" ]; then
export LD_PRELOAD="$LD_PRELOAD:$SNAP/lib/bindtextdomain.so"
fi
fi

exec "$@"
This conversation was marked as resolved by diddledan

This comment has been minimized.

Copy link
@niemeyer

niemeyer Mar 23, 2019

Besides these minor comments, the code overall in this wrapper feels reasonable and easy to maintain working over time.

@@ -0,0 +1,15 @@
#!/bin/bash

###############################
# Mark update and exec binary #
###############################

[ "$DESKTOP_LAUNCHER_NEEDS_UPDATE" = "true" ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision"
unset DESKTOP_LAUNCHER_NEEDS_UPDATE

if [ -n "$SNAP_DESKTOP_DEBUG" ]; then
echo "desktop-launch elapsed time: $(date +%s.%N --date="$START seconds ago")"
echo "Now running: exec $*" # lint told me not to use $@
fi

exec "$@"
@@ -0,0 +1,31 @@
#!/bin/bash

##############################
# GTK launcher specific part #
##############################

if [ "$DESKTOP_LAUNCHER_WAYLAND_AVAILABLE" = "true" ]; then
export GDK_BACKEND="wayland"
export CLUTTER_BACKEND="wayland"
# Does not hurt to specify this as well, just in case
export QT_QPA_PLATFORM=wayland-egl
fi

export GTK_EXE_PREFIX="$RUNTIME/usr"

# ibus and fcitx integration
GTK_IM_MODULE_DIR="$XDG_CACHE_HOME/immodules"
export GTK_IM_MODULE_FILE="$GTK_IM_MODULE_DIR/immodules.cache"
if [ "$DESKTOP_LAUNCHER_NEEDS_UPDATE" = "true" ]; then
rm -rf "$GTK_IM_MODULE_DIR"
mkdir -p "$GTK_IM_MODULE_DIR"
if [ -x "$RUNTIME/usr/lib/$ARCH/libgtk-3-0/gtk-query-immodules-3.0" ]; then
ln -s "$RUNTIME/usr/lib/$ARCH/gtk-3.0/3.0.0/immodules"/*.so "$GTK_IM_MODULE_DIR"
"$RUNTIME/usr/lib/$ARCH/libgtk-3-0/gtk-query-immodules-3.0" > "$GTK_IM_MODULE_FILE"
elif [ -x "$RUNTIME/usr/lib/$ARCH/libgtk2.0-0/gtk-query-immodules-2.0" ]; then
ln -s "$RUNTIME/usr/lib/$ARCH/gtk-2.0/2.10.0/immodules"/*.so "$GTK_IM_MODULE_DIR"
"$RUNTIME/usr/lib/$ARCH/libgtk2.0-0/gtk-query-immodules-2.0" > "$GTK_IM_MODULE_FILE"
fi
fi

exec "$@"
@@ -367,6 +367,12 @@ properties:
passthrough:
type: object
description: properties to be passed into snap.yaml as-is
extensions:
type: array
minitems: 1
uniqueItems: true
items:
type: string
hooks:
type: object
additionalProperties: false
@@ -0,0 +1,52 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2018 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from typing import Any, Dict

from ._extension import Extension


class DesktopCommonExtension(Extension):
"""The Common Desktop extension.
This extension is to be subclassed by the gnome and kde extensions.
It includes common code that each desktop extension would otherwise
need to duplicate.

This comment has been minimized.

Copy link
@niemeyer

niemeyer Mar 23, 2019

Nice abstraction.

Also, the whole file here feels quite clean and readable. It's not clear how the underlying Extension type will handle that data (will it override or append? when? etc), but it looks good indeed.

This comment has been minimized.

Copy link
@diddledan

diddledan Mar 24, 2019

Author Contributor

The idea now is to just append. The base class settings will be accessible in the subclasses allowing them to either replace or augment as they desire. The way I have done this in the gnome extension is to append the gnome-specific values via code like:

        self.parts = {
            **self.parts,
            "gnome-extension": {
                "after": after_dependencies,
                "plugin": "dump",
                "source": "$SNAPCRAFT_EXTENSIONS_DIR/gnome",
                "source-type": "local",
                "organize": {"desktop-*": "snap/command-chain/"},
                "build-packages": ["build-essential", "libgtk-3-dev"],
            },
        }

Here you see I directly reference the self.parts when constructing a replacement value to insert the previous content as-is into the new value. This results in the equivalent combined definition of:

        self.parts = {
            "desktop-common-extension": { # expanded from **self.parts when setting new value
                "plugin": "dump",
                "source": "$SNAPCRAFT_EXTENSIONS_DIR/desktop-common",
                "organize": {"desktop-*": "snap/command-chain/"},
            },
            "desktop-common-bindtextdomain": { # expanded from **self.parts when setting new value
                "plugin": "make",
                "source": "$SNAPCRAFT_EXTENSIONS_DIR/bindtextdomain",
            },
            "gnome-extension": { # defined explicitly when setting new value
                "after": after_dependencies,
                "plugin": "dump",
                "source": "$SNAPCRAFT_EXTENSIONS_DIR/gnome",
                "source-type": "local",
                "organize": {"desktop-*": "snap/command-chain/"},
                "build-packages": ["build-essential", "libgtk-3-dev"],
            },
        }
"""

def __init__(self, yaml_data: Dict[str, Any]) -> None:
"""Create a new DesktopCommonExtension.
:param dict yaml_data: Loaded snapcraft.yaml data.
"""

super().__init__(yaml_data)

self.root_snippet = {"assumes": ["command-chain"]}

self.app_snippet = {
"command-chain": [
"snap/command-chain/desktop-init",
"snap/command-chain/desktop-exports",
"snap/command-chain/desktop-mark-and-exec",
]
}

self.parts = {
"desktop-common-extension": {
"plugin": "dump",
"source": "$SNAPCRAFT_EXTENSIONS_DIR/desktop-common",
"organize": {"desktop-*": "snap/command-chain/"},
}
}
@@ -0,0 +1,117 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2018 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from typing import Any, Dict

from snapcraft.internal import errors
from ._desktop_common import DesktopCommonExtension


class GnomeExtensionClassicConfinementError(errors.SnapcraftError):
fmt = "The gnome extension doesn't support classic confinement."


class GnomeExtension(DesktopCommonExtension):
"""The Gnome extension.
This extension is to be used by applications that require GTK+.
Examples might include productivity applications or utilities.
Note that this extension does not support classically-confined snaps at this time.
"""

supported_bases = ("core16", "core18")

This comment has been minimized.

Copy link
@sergiusens

sergiusens Feb 18, 2019

Collaborator

Potentially missing feature
supported_architectures = ....


def __init__(self, yaml_data: Dict[str, Any]) -> None:
"""Create a new GnomeExtension.
Note that this extension does not support classic snaps.
:param dict yaml_data: Loaded snapcraft.yaml data.
"""

super().__init__(yaml_data)

if yaml_data.get("confinement") == "classic":
raise GnomeExtensionClassicConfinementError()

# This extension utilizes command-chain; add the proper assumes so a snap using
# this extension can't be installed on a snapd that doesn't support
# command-chain.
self.root_snippet = {
**self.root_snippet,
"plugs": {
"gnome-extension-common-themes": {
"interface": "content",
"target": "$SNAP/data-dir/themes",
"default-provider": "gtk-common-themes:gtk-3-themes",
},
"gnome-extension-common-icons": {
"interface": "content",
"target": "$SNAP/data-dir/icons",
"default-provider": "gtk-common-themes:icon-themes",
},
"gnome-extension-common-sounds": {
"interface": "content",
"target": "$SNAP/data-dir/sounds",
"default-provider": "gtk-common-themes:sounds-themes",
},
},
}

command_chain = self.app_snippet["command-chain"]
exec_command = command_chain.pop()

command_chain = command_chain + [
"snap/command-chain/desktop-gnome-specific",
exec_command,
]

# Add the following snippet to each app that uses the glib extension
self.app_snippet = {**self.app_snippet, "command-chain": command_chain}

# Add the following part
self.parts = {
**self.parts,
"gnome-extension": {
"plugin": "dump",
"source": "$SNAPCRAFT_EXTENSIONS_DIR/gnome",
"source-type": "local",
"organize": {
"desktop-*": "snap/command-chain/",
# The next line moves files into a location to allow GTK_EXE_DIR
# to be suitable to find the GTK files. This allows us to use GTK2
# and GTK3 together in the same snap.
# If you need GTK2 support, duplicate this organize line replacing
# gtk-3.0 with gtk-2.0 in an additional part ensuring that the part
# also pulls GTK2 libraries. It should then seamlessly work with
# this extension.
"usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gtk-3.0": "usr/lib/gtk-3.0",
},
"build-packages": ["build-essential", "libgtk-3-dev"],
"stage-packages": [
"libxkbcommon0",
"shared-mime-info",
"libgtk-3-0",
"libgdk-pixbuf2.0-0",
"libglib2.0-bin",
"libgtk-3-bin",
"unity-gtk3-module",
"libappindicator3-1",
"locales-all",
"xdg-user-dirs",
"ibus-gtk3",
"libibus-1.0-5",
"fcitx-frontend-gtk3",
],
},
}
@@ -244,6 +244,12 @@ suites:
# Keep this 18.04 only for now as it is the only stable base.
systems: [ubuntu-18.04*]

# Extensions tests
tests/spread/extensions/gnome/:
summary: tests of snapcraft's gnome extension
# Keep this 18.04 only for now as it is the only stable base.
systems: [ubuntu-18.04*]

# Legacy tests
tests/spread/legacy/:
summary: legacy snapcraft tests
@@ -0,0 +1,40 @@
summary: Build and run a basic gnome snap

environment:
SNAP_DIR: ../snaps/glib-hello

# This is a manual test until v2.36 of core is in stable
manual: true

prepare: |
sudo snap refresh --edge core
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
set_base "$SNAP_DIR/snap/snapcraft.yaml"
restore: |
cd "$SNAP_DIR"
snapcraft clean
rm -f ./*.snap
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
restore_yaml "snap/snapcraft.yaml"
sudo snap refresh --stable core
execute: |
cd "$SNAP_DIR"
snapcraft
sudo snap install glib-hello_*.snap --dangerous
[ "$(glib-hello)" = "hello world" ]
# Verify that the extension command chain went through the proper setup procedure
snap_user_data="$HOME/snap/glib-hello/current"
[ -d "$snap_user_data/.config" ]
[ -d "$snap_user_data/.local" ]
[ -h "$snap_user_data/.themes" ]
[ -f "$snap_user_data/.last_revision" ]
[ "$(cat "$snap_user_data/.last_revision")" = "SNAP_DESKTOP_LAST_REVISION=x1" ]
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 2.6)
project(glib-hello C)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
add_executable(hello hello.c)
target_include_directories(hello PRIVATE ${GLIB_INCLUDE_DIRS})
target_link_libraries(hello PRIVATE ${GLIB_LDFLAGS})
install(TARGETS hello RUNTIME DESTINATION bin)
@@ -0,0 +1,7 @@
#include <glib.h>

int main ()
{
g_print("hello world\n");
return 0;
}
@@ -0,0 +1,19 @@
name: glib-hello
version: "1.0"
summary: test the gnome extension
description: This is a basic gnome snap (*only* uses glib). It simply prints a hello world.

grade: devel
confinement: strict
base: core18

apps:
glib-hello:
command: bin/hello
adapter: full
extensions: [gnome]

parts:
project:
plugin: cmake
source: .
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.