Hello community, here is the log from the commit of package eolie for openSUSE:Factory checked in at 2018-10-17 08:43:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/eolie (Old) and /work/SRC/openSUSE:Factory/.eolie.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "eolie" Wed Oct 17 08:43:25 2018 rev:10 rq:642510 version:0.9.45 Changes: -------- --- /work/SRC/openSUSE:Factory/eolie/eolie.changes 2018-10-08 17:47:14.250345252 +0200 +++ /work/SRC/openSUSE:Factory/.eolie.new/eolie.changes 2018-10-17 08:44:14.769711207 +0200 @@ -1,0 +2,13 @@ +Sat Oct 13 15:39:29 UTC 2018 - [email protected] + +- Update to version 0.9.45: + * Fix a regression in grouping (glgo#World/eolie#316). +- Changes from version 0.9.44: + * Don't intercept CTRL+RET outside the location bar + (glgo#World/eolie#315). +- Changes from version 0.9.43: + * Fix hang. +- Changes from version 0.9.42: + * Rework favicons code. + +------------------------------------------------------------------- Old: ---- eolie-0.9.41.tar.xz New: ---- eolie-0.9.45.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ eolie.spec ++++++ --- /var/tmp/diff_new_pack.u1eJFx/_old 2018-10-17 08:44:15.205710839 +0200 +++ /var/tmp/diff_new_pack.u1eJFx/_new 2018-10-17 08:44:15.205710839 +0200 @@ -20,7 +20,7 @@ %global __requires_exclude typelib\\(Unity\\) Name: eolie -Version: 0.9.41 +Version: 0.9.45 Release: 0 Summary: Web browser for GNOME License: GPL-3.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.u1eJFx/_old 2018-10-17 08:44:15.233710816 +0200 +++ /var/tmp/diff_new_pack.u1eJFx/_new 2018-10-17 08:44:15.233710816 +0200 @@ -1,6 +1,6 @@ <services> <service mode="disabled" name="tar_scm"> - <param name="revision">0.9.41</param> + <param name="revision">0.9.45</param> <param name="scm">git</param> <param name="url">https://gitlab.gnome.org/World/eolie.git</param> <param name="versionformat">@PARENT_TAG@</param> ++++++ eolie-0.9.41.tar.xz -> eolie-0.9.45.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/.gitlab-ci.yml new/eolie-0.9.45/.gitlab-ci.yml --- old/eolie-0.9.41/.gitlab-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/eolie-0.9.45/.gitlab-ci.yml 2018-10-13 16:56:57.000000000 +0200 @@ -0,0 +1,32 @@ +stages: + - flatpak + +variables: + BUNDLE: "eolie-git.flatpak" + GIT_SUBMODULE_STRATEGY: normal + + + + +flatpak: + image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master + stage: flatpak + variables: + MANIFEST_PATH: "org.gnome.Eolie.json" + RUNTIME_REPO: "https://sdk.gnome.org/gnome-nightly.flatpakrepo" + FLATPAK_MODULE: "Eolie" + script: + - flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH} + - flatpak build app meson --prefix=/app ${MESON_ARGS} _build + - flatpak build app ninja -C _build install + - flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH} + - flatpak build-export repo app + - flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} org.gnome.Eolie + artifacts: + paths: + - ${BUNDLE} + - _build/meson-logs/meson-log.txt + expire_in: 30 days + cache: + paths: + - .flatpak-builder/cache diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/data/application.css new/eolie-0.9.45/data/application.css --- old/eolie-0.9.41/data/application.css 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/data/application.css 2018-10-13 16:56:57.000000000 +0200 @@ -227,9 +227,10 @@ } .page-child-row:selected { - border-color: alpha(@theme_selected_bg_color, 0.8); - border-bottom-color:alpha(@theme_selected_bg_color, 0.9); - background-image: linear-gradient(to bottom, alpha(@theme_selected_bg_color, 0.2), alpha(@theme_selected_bg_color, 0.3), alpha(@theme_selected_bg_color, 0.4)); + border: solid; + border-radius: 0px; + border-color: @theme_fg_color; + border-bottom-width: 1px; } .page-child-row:selected *{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/data/org.gnome.Eolie.appdata.xml.in new/eolie-0.9.45/data/org.gnome.Eolie.appdata.xml.in --- old/eolie-0.9.41/data/org.gnome.Eolie.appdata.xml.in 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/data/org.gnome.Eolie.appdata.xml.in 2018-10-13 16:56:57.000000000 +0200 @@ -9,10 +9,10 @@ <p>Eolie is a new GNOME web browser.</p> </description> <releases> - <release version="0.9.41" date="2018-09-26"> + <release version="0.9.42" date="2018-10-11"> <description> <ul> - <li>Fix an issue with download button</li> + <li>Better favicons code</li> </ul> </description> </release> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/application.py new/eolie-0.9.45/eolie/application.py --- old/eolie-0.9.41/eolie/application.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/application.py 2018-10-13 16:56:57.000000000 +0200 @@ -23,6 +23,7 @@ from pickle import dump, load from urllib.parse import urlparse from time import time +from getpass import getuser import json from signal import signal, SIGINT, SIGTERM @@ -52,6 +53,8 @@ Eolie application """ + __FAVICONS_PATH = "/tmp/eolie_%s" % getuser() + def __init__(self, version, extension_dir): """ Create application @@ -327,6 +330,13 @@ """ return self.__extension_dir + @property + def favicons_path(self): + """ + Cookies sqlite DB path + """ + return self.__FAVICONS_PATH + ####################### # PRIVATE # ####################### @@ -465,8 +475,6 @@ ["<Control>KP_0", "<Control>0"]) self.set_accels_for_action("win.shortcut::mse_enabled", ["<Control>m"]) - self.set_accels_for_action("win.shortcut::add_dot_com", - ["<Control>Return"]) def __vacuum(self): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/context.py new/eolie-0.9.45/eolie/context.py --- old/eolie-0.9.41/eolie/context.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/context.py 2018-10-13 16:56:57.000000000 +0200 @@ -32,7 +32,7 @@ self.__context = context if not context.is_ephemeral(): context.set_cache_model(WebKit2.CacheModel.WEB_BROWSER) - context.set_favicon_database_directory(None) + context.set_favicon_database_directory(App().favicons_path) cookie_manager = context.get_cookie_manager() cookie_manager.set_accept_policy( App().settings.get_enum("cookie-storage")) @@ -214,7 +214,7 @@ # We use internal:// because resource:// is already used by WebKit2 icon_name = request.get_uri().replace("internal://", "") icon_info = Gtk.IconTheme.get_default().lookup_icon( - icon_name, Gtk.IconSize.BUTTON, + icon_name, 22, Gtk.IconLookupFlags.FORCE_SVG) filename = icon_info.get_filename() if filename.endswith(".png"): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/extension_proxy.py new/eolie-0.9.45/eolie/extension_proxy.py --- old/eolie-0.9.41/eolie/extension_proxy.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/extension_proxy.py 2018-10-13 16:56:57.000000000 +0200 @@ -577,6 +577,7 @@ @param forms as FormsExtension @param variant as GLib.Variant """ + self.__elements_history = {} if self.__bus is not None: self.__bus.emit_signal( None, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/pages_manager_child.py new/eolie-0.9.45/eolie/pages_manager_child.py --- old/eolie-0.9.41/eolie/pages_manager_child.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/pages_manager_child.py 2018-10-13 16:56:57.000000000 +0200 @@ -16,6 +16,7 @@ from eolie.label_indicator import LabelIndicator from eolie.define import App, ArtSize +from eolie.utils import resize_favicon class PagesManagerChild(Gtk.FlowBoxChild): @@ -32,7 +33,6 @@ Gtk.FlowBoxChild.__init__(self) self.__view = view self.__window = window - self.__favicon = None self.__connected_ids = [] self.__scroll_timeout_id = None builder = Gtk.Builder() @@ -77,7 +77,7 @@ view.connect("destroying", self.__on_view_destroying) self.__view.webview.connect("snapshot-changed", self.__on_webview_snapshot_changed) - self.__view.webview.connect("favicon-changed", + self.__view.webview.connect("notify::favicon", self.__on_webview_favicon_changed) self.__view.webview.connect("notify::is-playing-audio", self.__on_webview_notify_is_playing_audio) @@ -242,34 +242,29 @@ """ self.__on_webview_favicon_changed(webview) - def __on_webview_favicon_changed(self, webview, surface=None): + def __on_webview_favicon_changed(self, webview, *ignore): """ Set favicon @param webview as WebView - @param surface as cairo.Surface """ + if webview.current_event == WebKit2.LoadEvent.STARTED: + return image = self.__close_button.get_image() if webview.is_playing_audio(): image.set_from_icon_name("audio-speakers-symbolic", Gtk.IconSize.INVALID) return - - if surface is not None: - image.set_from_surface(surface) - return - - favicon_path = App().art.get_favicon_path(webview.uri) - if favicon_path is not None: - image.set_from_file(favicon_path) - return - artwork = App().art.get_icon_theme_artwork(webview.uri, webview.ephemeral) if artwork is not None: image.set_from_icon_name(artwork, Gtk.IconSize.INVALID) - return - - image.set_from_icon_name("applications-internet", Gtk.IconSize.INVALID) + else: + surface = webview.get_favicon() + if surface is not None: + image.set_from_surface(resize_favicon(surface)) + else: + image.set_from_icon_name("applications-internet", + Gtk.IconSize.INVALID) def __on_webview_title_changed(self, webview, title): """ @@ -287,13 +282,15 @@ """ uri = webview.uri if event == WebKit2.LoadEvent.STARTED: - self.__favicon = None - self.__image.clear() + image = self.__close_button.get_image() + image.set_from_icon_name("content-loading-symbolic", + Gtk.IconSize.INVALID) self.__spinner.start() self.__indicator_label.set_text(uri) elif event == WebKit2.LoadEvent.COMMITTED: self.__indicator_label.set_text(uri) elif event == WebKit2.LoadEvent.FINISHED: + self.__on_webview_favicon_changed(webview) self.__spinner.stop() def __on_webview_snapshot_changed(self, webview, surface): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/sites_manager_child.py new/eolie-0.9.45/eolie/sites_manager_child.py --- old/eolie-0.9.41/eolie/sites_manager_child.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/sites_manager_child.py 2018-10-13 16:56:57.000000000 +0200 @@ -14,6 +14,7 @@ from eolie.label_indicator import LabelIndicator from eolie.define import App, ArtSize +from eolie.utils import resize_favicon from eolie.logger import Logger @@ -192,7 +193,11 @@ if view not in self.__views: self.__views.append(view) view.webview.connect("shown", self.__on_webview_shown) - view.webview.connect("favicon-changed", + view.webview.connect("load-changed", + self.__on_webview_load_changed) + view.webview.connect("notify::is-playing-audio", + self.__on_webview_notify_is_playing_audio) + view.webview.connect("notify::favicon", self.__on_webview_favicon_changed) self.update_label() self.__indicator_label.update_count(True) @@ -214,6 +219,9 @@ self.__views.remove(view) view.webview.disconnect_by_func(self.__on_webview_shown) view.webview.disconnect_by_func(self.__on_webview_favicon_changed) + view.webview.disconnect_by_func(self.__on_webview_load_changed) + view.webview.disconnect_by_func( + self.__on_webview_notify_is_playing_audio) self.update_label() self.__indicator_label.update_count(False) if not view.webview.shown: @@ -403,34 +411,38 @@ elif hasattr(widget, "forall"): GLib.idle_add(widget.forall, self.__update_popover_internals) - def __on_webview_favicon_changed(self, webview, surface=None): + def __on_webview_notify_is_playing_audio(self, webview, playing): + """ + Update favicon + @param webview as WebView + @param playing as bool + """ + self.__on_webview_favicon_changed(webview) + + def __on_webview_favicon_changed(self, webview, *ignore): """ Set favicon @param webview as WebView - @param surface as cairo.Surface """ - if self.get_style_context().has_class("item-selected") and\ - len(self.__views) > 1 and\ - webview.view != self.__window.container.current: + if webview.current_event == WebKit2.LoadEvent.STARTED: return - if not webview.ephemeral: - if surface is not None: - self.__image.set_from_surface(surface) - return - favicon_path = App().art.get_favicon_path(webview.uri) - if favicon_path is not None: - self.__image.set_from_file(favicon_path) - return + if webview.is_playing_audio(): + self.__image.set_from_icon_name("audio-speakers-symbolic", + Gtk.IconSize.INVALID) + return artwork = App().art.get_icon_theme_artwork(webview.uri, webview.ephemeral) if artwork is not None: - self.__image.set_from_icon_name(artwork, - Gtk.IconSize.INVALID) + self.__image.set_from_icon_name(artwork, Gtk.IconSize.INVALID) else: - self.__image.set_from_icon_name("applications-internet", - Gtk.IconSize.INVALID) + surface = webview.get_favicon() + if surface is not None: + self.__image.set_from_surface(resize_favicon(surface)) + else: + self.__image.set_from_icon_name("applications-internet", + Gtk.IconSize.INVALID) def __on_query_tooltip(self, widget, x, y, keyboard, tooltip): """ @@ -533,3 +545,15 @@ """ self.__indicator_label.mark_shown(webview) self.__on_webview_favicon_changed(webview) + + def __on_webview_load_changed(self, webview, event): + """ + Update widget content + @param webview as WebView + @param event as WebKit2.LoadEvent + """ + if event == WebKit2.LoadEvent.STARTED: + self.__image.set_from_icon_name("content-loading-symbolic", + Gtk.IconSize.INVALID) + elif event == WebKit2.LoadEvent.FINISHED: + self.__on_webview_favicon_changed(webview) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/toolbar_title.py new/eolie-0.9.45/eolie/toolbar_title.py --- old/eolie-0.9.41/eolie/toolbar_title.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/toolbar_title.py 2018-10-13 16:56:57.000000000 +0200 @@ -224,17 +224,6 @@ self.__signal_id = self.__entry.connect("changed", self.__on_entry_changed) - def add_dot_com(self): - """ - Add dot com to URI - """ - bounds = self.__entry.get_selection_bounds() - if bounds: - current = self.__entry.get_text()[:bounds[0]] - else: - current = self.__entry.get_text() - self.set_text_entry(current + ".com") - def set_uri(self, uri): """ Update internal uri @@ -565,6 +554,13 @@ value = webview.get_prev_text_entry(uri) elif event.keyval == Gdk.KEY_Z: value = webview.get_next_text_entry() + elif event.keyval == Gdk.KEY_Return: + bounds = self.__entry.get_selection_bounds() + if bounds: + current = self.__entry.get_text()[:bounds[0]] + else: + current = self.__entry.get_text() + value = current + ".com" if value is not None: self.set_text_entry(value) self.__entry.emit("changed") @@ -821,6 +817,7 @@ def model_append(array): if self.__completion_model_clear_timeout_id is not None: GLib.source_remove(self.__completion_model_clear_timeout_id) + self.__completion_model_clear_timeout_id = None if self.__completion_model_append_timeout_id is not None: GLib.source_remove(self.__completion_model_append_timeout_id) self.__completion_model_append_timeout_id = \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/utils.py new/eolie-0.9.45/eolie/utils.py --- old/eolie-0.9.41/eolie/utils.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/utils.py 2018-10-13 16:56:57.000000000 +0200 @@ -15,6 +15,7 @@ import unicodedata import string import cairo +import sqlite3 from urllib.parse import urlparse from random import choice from base64 import b64encode @@ -81,6 +82,32 @@ return GLib.getenv("XDG_CURRENT_DESKTOP") == "ubuntu:GNOME" +def get_favicon_best_uri(favicons_path, uri): + """ + Search in WebKit DB for best uri + @param favicons_path as str + @param uri as str + @return str + """ + favicon_uri = None + try: + parsed = urlparse(uri) + if parsed.path == "/": + return None + for uri in [parsed.netloc + parsed.path, parsed.netloc]: + sql = sqlite3.connect(favicons_path, 600.0) + result = sql.execute("SELECT url\ + FROM PageURL\ + WHERE url LIKE ?", ("%{}%".format(uri),)) + v = result.fetchone() + if v is not None: + favicon_uri = v[0] + break + except Exception as e: + Logger.error("get_favicon_best_uri(): %s", e) + return favicon_uri + + def resize_favicon(favicon): """ Resize surface to match favicon size @@ -98,45 +125,6 @@ return surface -def get_char_surface(char): - """ - Draw a char with a random color - @param char as str - @return cairo surface - """ - size = ArtSize.FAVICON - 1 - colors = [[0.102, 0.737, 0.612], # Turquoise - [0.204, 0.596, 0.859], # Peterriver - [0.608, 0.349, 0.714], # Amethyst - [0.204, 0.286, 0.369], # Wetasphalt - [0.086, 0.627, 0.522], # Greensea - [0.153, 0.682, 0.376], # Nephritis - [0.161, 0.502, 0.725], # Belizehole - [0.557, 0.267, 0.678], # Wisteria - [0.173, 0.243, 0.314], # Midnightblue - [0.827, 0.329, 0.0], # Pumpkin - [0.753, 0.224, 0.169], # Pomegranate - [0.498, 0.549, 0.553] # Asbestos - ] - surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, - size, - size) - context = cairo.Context(surface) - color = choice(colors) - context.set_source_rgb(color[0], color[1], color[2]) - context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, - cairo.FONT_WEIGHT_BOLD) - context.set_font_size(size) - (xbearing, ybearing, - width, height, - xadvance, yadvance) = context.text_extents(char) - context.move_to(size / 2 - (xadvance + xbearing) / 2, - size / 2 - ybearing - height / 2) - context.show_text(char) - context.stroke() - return surface - - def get_snapshot(webview, result, callback, *args): """ Set snapshot on main image diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/webview.py new/eolie-0.9.45/eolie/webview.py --- old/eolie-0.9.41/eolie/webview.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/webview.py 2018-10-13 16:56:57.000000000 +0200 @@ -446,10 +446,10 @@ WebViewErrors.__init__(self) WebViewNavigation.__init__(self, related_view) WebViewSignals.__init__(self) + self.__context = context WebViewArtwork.__init__(self) self._window = window self.__view = view - self.__context = context self.__content_manager = content_manager self.__atime = 0 self.__children = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/webview_artwork.py new/eolie-0.9.45/eolie/webview_artwork.py --- old/eolie-0.9.41/eolie/webview_artwork.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/webview_artwork.py 2018-10-13 16:56:57.000000000 +0200 @@ -14,10 +14,9 @@ from urllib.parse import urlparse -from eolie.define import App +from eolie.define import App, ArtSize from eolie.helper_task import TaskHelper -from eolie.utils import get_snapshot, resize_favicon, get_char_surface -from eolie.utils import remove_www +from eolie.utils import get_snapshot, resize_favicon, get_favicon_best_uri class WebViewArtwork: @@ -30,39 +29,44 @@ Init class """ self.__helper = TaskHelper() + self.__cancellable = Gio.Cancellable() self.__snapshot_id = None - self.__save_favicon_timeout_id = None self.__cancellable = Gio.Cancellable() self.__initial_uri = None - self.__favicon_width = {} - self.__current_netloc = None + self.__favicon_db = self.context.get_favicon_database() + self.__favicon_db.connect("favicon-changed", self.__on_favicon_changed) self.connect("notify::uri", self.__on_uri_changed) def set_favicon(self): """ Set favicon based on current webview favicon """ - if self.ephemeral or\ - self.error or\ - self.current_event != WebKit2.LoadEvent.FINISHED: + parsed = urlparse(self.uri) + if self.ephemeral or parsed.scheme not in ["http", "https"]: return - - self.__set_favicon_from_surface( - self.get_favicon(), - self.uri, - self.__initial_uri) + self.__cancellable.cancel() + self.__cancellable.reset() + self.__favicon_db.get_favicon(self.uri, + self.__cancellable, + self.__on_get_favicon, + self.uri, + self.__initial_uri) def set_current_favicon(self): """ Set favicon based on current webview favicon Use this for JS update (do not update initial uri) """ - if self.ephemeral: + parsed = urlparse(self.uri) + if self.ephemeral or parsed.scheme not in ["http", "https"]: return - self.__set_favicon_from_surface( - self.get_favicon(), - self.uri, - None) + self.__cancellable.cancel() + self.__cancellable.reset() + self.__favicon_db.get_favicon(self.uri, + self.__cancellable, + self.__on_get_favicon, + self.uri, + None) ####################### # PROTECTED # @@ -73,33 +77,39 @@ @param webview as WebView @param event as WebKit2.LoadEvent """ - parsed = urlparse(self.uri) if event == WebKit2.LoadEvent.STARTED: + parsed = urlparse(self.uri) self.__cancellable.cancel() self.__cancellable.reset() + if self.__snapshot_id is not None: + GLib.source_remove(self.__snapshot_id) + self.__snapshot_id = None if parsed.scheme in ["http", "https"]: self.__initial_uri = self.uri.rstrip('/') else: self.__initial_uri = None elif event == WebKit2.LoadEvent.FINISHED: - is_http = parsed.scheme in ["http", "https"] if self.__snapshot_id is not None: GLib.source_remove(self.__snapshot_id) self.__snapshot_id = GLib.timeout_add(2500, - self.__set_snapshot, - is_http) + self.__set_snapshot) self.set_favicon() - self.__current_netloc = parsed.netloc or None ####################### # PRIVATE # ####################### - def __set_snapshot(self, save): + def __set_snapshot(self): """ Set webpage preview - @param save as bool """ self.__snapshot_id = None + # Only save http page if bookmarked + parsed = urlparse(self.uri) + save = parsed.scheme in ["http", "https"] + bookmark_id = App().bookmarks.get_id(self.uri) + ibookmark_id = App().bookmarks.get_id(self.__initial_uri) + if bookmark_id is None and ibookmark_id is None: + save = False self.get_snapshot(WebKit2.SnapshotRegion.FULL_DOCUMENT, WebKit2.SnapshotOptions.NONE, self.__cancellable, @@ -119,41 +129,20 @@ resized = None # Save webview favicon if surface is not None: - cache_exists = App().art.exists(uri, "favicon") - cached_width = 0 - if cache_exists: - cached = App().art.get_favicon(uri, self.get_scale_factor()) - if cached is not None: - cached_width = cached.get_width() - favicon_width = surface.get_width() - if uri not in self.__favicon_width.keys() or ( - favicon_width >= self.__favicon_width[uri] and - favicon_width >= cached_width): - if self.__save_favicon_timeout_id is not None: - GLib.source_remove(self.__save_favicon_timeout_id) - self.__save_favicon_timeout_id = None - self.__favicon_width[uri] = favicon_width - resized = resize_favicon(surface) + if surface.get_width() >= ArtSize.FAVICON: favicon_type = "favicon" - else: - netloc = remove_www(urlparse(uri).netloc) - if netloc: - resized = None - cached = App().art.get_favicon(uri, - self.get_scale_factor()) - if cached is None: - resized = get_char_surface(netloc[0]) - favicon_type = "favicon_alt" - + else: + # Low quality favicon + favicon_type = "favicon_alt" + exists = App().art.exists(uri, favicon_type) + if not exists: + resized = resize_favicon(surface) # We wait for a better favicon - if resized is not None and uri == self.uri: - self.__save_favicon_timeout_id = GLib.timeout_add( - 500, - self.__save_favicon_to_cache, - resized, - uri, - initial_uri, - favicon_type) + if resized is not None: + self.__save_favicon_to_cache(resized, + uri, + initial_uri, + favicon_type) def __save_favicon_to_cache(self, surface, uri, initial_uri, favicon_type): """ @@ -163,8 +152,6 @@ @param initial_uri as str @param favicon_type as str """ - self.__save_favicon_timeout_id = None - self.emit("favicon-changed", surface) # Save favicon for URI self.__helper.run(App().art.save_artwork, uri, @@ -190,8 +177,50 @@ if self.__snapshot_id is not None: GLib.source_remove(self.__snapshot_id) self.__snapshot_id = GLib.timeout_add(2500, - self.__set_snapshot, - True) + self.__set_snapshot) + self.__on_favicon_changed(self.__favicon_db, webview.uri) + + def __on_get_favicon(self, favicon_db, result, uri, + initial_uri, first=True): + """ + Get result and set from it + @param favicon_db as WebKit2.FaviconDatabase + @param result as Gio.AsyncResult + @param uri as str + @param initial_uri as str + @internal first as bool + """ + try: + surface = favicon_db.get_favicon_finish(result) + self.__set_favicon_from_surface(surface, + uri, + initial_uri) + except: + if not first: + return + favicons_path = App().favicons_path + "/WebpageIcons.db" + best_uri = get_favicon_best_uri(favicons_path, uri) + if best_uri is not None: + self.__favicon_db.get_favicon(best_uri, + None, + self.__on_get_favicon, + uri, + self.__initial_uri, + False) + + def __on_favicon_changed(self, favicon_db, uri, *ignore): + """ + Reload favicon + @param favicon_db as WebKit2.FaviconDatabase + @param uri as str + """ + if uri != self.uri or self.ephemeral: + return + self.__favicon_db.get_favicon(uri, + None, + self.__on_get_favicon, + uri, + self.__initial_uri) def __on_snapshot(self, surface, save, first_pass): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/webview_navigation.py new/eolie-0.9.45/eolie/webview_navigation.py --- old/eolie-0.9.41/eolie/webview_navigation.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/webview_navigation.py 2018-10-13 16:56:57.000000000 +0200 @@ -47,7 +47,6 @@ self.__on_insecure_content_detected) self.connect("run-as-modal", self.__on_run_as_modal) self.connect("permission_request", self.__on_permission_request) - self.connect("notify::favicon", self.__on_notify_favicon) self.connect("notify::title", self.__on_title_changed) self.connect("notify::uri", self.__on_uri_changed) @@ -267,13 +266,12 @@ @param webview as WebKit2.WebView @param param as GObject.ParamSpec """ - # Js update, force favicon caching for current uri + # Js update if not self.is_loading(): uri = webview.get_property(param.name) # JS bookmark (Bookmarklet) if not uri.startswith("javascript:") and not self.error: self.emit("uri-changed", uri) - self.set_current_favicon() def __on_title_changed(self, webview, param): """ @@ -285,14 +283,6 @@ if title: self.emit("title-changed", title) - def __on_notify_favicon(self, webview, favicon): - """ - Set favicon - @param webview as WebView - @param favicon as GObject.ParamSpec - """ - self.set_favicon() - def __on_decide_policy(self, webview, decision, decision_type): """ Navigation policy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/webview_signals.py new/eolie-0.9.45/eolie/webview_signals.py --- old/eolie-0.9.41/eolie/webview_signals.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/webview_signals.py 2018-10-13 16:56:57.000000000 +0200 @@ -34,8 +34,6 @@ "shown": (GObject.SignalFlags.RUN_FIRST, None, ()), "title-changed": (GObject.SignalFlags.RUN_FIRST, None, (str,)), "uri-changed": (GObject.SignalFlags.RUN_FIRST, None, (str,)), - "favicon-changed": (GObject.SignalFlags.RUN_FIRST, None, - (GObject.TYPE_PYOBJECT,)), "snapshot-changed": (GObject.SignalFlags.RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/widget_bookmark_edit.py new/eolie-0.9.45/eolie/widget_bookmark_edit.py --- old/eolie-0.9.41/eolie/widget_bookmark_edit.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/widget_bookmark_edit.py 2018-10-13 16:56:57.000000000 +0200 @@ -91,6 +91,7 @@ tag_id = App().bookmarks.get_tag_id(tag_title) if tag_id is not None: App().bookmarks.del_tag_from(tag_id, self.__bookmark_id) + App().bookmarks.clean_tags() self.destroy() return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/eolie/window.py new/eolie-0.9.45/eolie/window.py --- old/eolie-0.9.41/eolie/window.py 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/eolie/window.py 2018-10-13 16:56:57.000000000 +0200 @@ -482,8 +482,6 @@ elif string == "expose": active = self.toolbar.actions.view_button.get_active() self.toolbar.actions.view_button.set_active(not active) - elif string == "add_dot_com": - self.toolbar.title.add_dot_com() elif string == "jsblock": current_webview = self.container.current.webview App().helper.call("EnableJS", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/meson.build new/eolie-0.9.45/meson.build --- old/eolie-0.9.41/meson.build 2018-10-05 12:29:33.000000000 +0200 +++ new/eolie-0.9.45/meson.build 2018-10-13 16:56:57.000000000 +0200 @@ -1,5 +1,5 @@ project('eolie', 'c', - version: '0.9.41', + version: '0.9.45', meson_version: '>= 0.40.0', ) i18n = import('i18n') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eolie-0.9.41/org.gnome.Eolie.json new/eolie-0.9.45/org.gnome.Eolie.json --- old/eolie-0.9.41/org.gnome.Eolie.json 1970-01-01 01:00:00.000000000 +0100 +++ new/eolie-0.9.45/org.gnome.Eolie.json 2018-10-13 16:56:57.000000000 +0200 @@ -0,0 +1,397 @@ +{ + "app-id": "org.gnome.Eolie", + "runtime": "org.gnome.Platform", + "runtime-version": "master", + "sdk": "org.gnome.Sdk", + "command": "eolie", + "finish-args": [ + "--share=ipc", + "--share=network", + "--socket=x11", + "--socket=wayland", + "--socket=pulseaudio", + "--device=dri", + "--env=GST_PLUGIN_PATH_1_0=/app/lib/gstreamer-1.0", + "--env=SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt", + "--filesystem=xdg-run/dconf", + "--filesystem=home", + "--filesystem=~/.config/dconf:rw", + "--filesystem=~/.mozilla/firefox:rw", + "--filesystem=~/.config/chromium:rw", + "--filesystem=~/.config/chrome:rw", + "--talk-name=org.freedesktop.secrets", + "--own-name=org.gnome.Eolie.Proxy.*", + "--talk-name=ca.desrt.dconf", + "--env=DCONF_USER_CONFIG_DIR=.config/dconf" + ], + "modules": [ + { + "name": "gst-libav", + "config-opts": [ + "--disable-gtk-doc" + ], + "cleanup": [ + "*.la", + "/share/gtk-doc" + ], + "sources": [ + { + "type": "archive", + "url": "https://gstreamer.freedesktop.org/src/gst-libav/gst-libav-1.12.4.tar.xz", + "sha256": "2a56aa5d2d8cd912f2bce17f174713d2c417ca298f1f9c28ee66d4aa1e1d9e62" + } + ] + }, + { + "name": "gst-plugins-ugly", + "config-opts": [ + "--disable-gtk-doc" + ], + "cleanup": [ + "*.la", + "/share/gtk-doc" + ], + "sources": [ + { + "type": "archive", + "url": "https://gstreamer.freedesktop.org/src/gst-plugins-ugly/gst-plugins-ugly-1.12.4.tar.xz", + "sha256": "1c165b8d888ed350acd8e6ac9f6fe06508e6fcc0a3afc6ccc9fbeb30df9be522" + } + ] + }, + { + "name": "enchant", + "cleanup": [ + "/include", + "/lib/pkgconfig", + "*.la", + "/share" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/AbiWord/enchant/releases/download/v2.2.3/enchant-2.2.3.tar.gz", + "sha256": "abd8e915675cff54c0d4da5029d95c528362266557c61c7149d53fa069b8076d" + } + ] + }, + { + "name": "gtkspell", + "cleanup": [ + "*.la", + "/share/gtk-doc" + ], + "sources": [ + { + "type": "archive", + "url": "https://sourceforge.net/projects/gtkspell/files/3.0.10/gtkspell3-3.0.10.tar.xz", + "sha256": "b040f63836b347eb344f5542443dc254621805072f7141d49c067ecb5a375732" + } + ] + }, + { + "name": "python-requests", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app requests-2.14.2-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/e4/b0/286e8a936158e5cc5791d5fa3bc4b1d5a7e1ff4e5b3f3766b63d8e97708a/requests-2.14.2-py2.py3-none-any.whl#md5=a1b2f02e7ba45dff7c76f621cde042c4", + "sha256": "3b39cde35be51762885631cf586f4dc2284951b44d479a4454020758d767cc2f" + } + ] + }, + { + "name": "python-beautifulsoup4", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app beautifulsoup4-4.6.0-py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/9e/d4/10f46e5cfac773e22707237bfcd51bbffeaf0a576b0a847ec7ab15bd7ace/beautifulsoup4-4.6.0-py3-none-any.whl#md5=f6becf1889e5697734cc98798d2f0111", + "sha256": "11a9a27b7d3bddc6d86f59fb76afb70e921a25ac2d6cc55b40d072bd68435a76" + } + ] + }, + { + "name": "six", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/benjaminp/six/archive/1.11.0.tar.gz", + "sha256": "927dc6fcfccd4e32e1ce161a20bf8cda39d8c9d5f7a845774486907178f69bd4" + } + ] + }, + { + "name": "mohawk", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/19/22/10f696548a8d41ad41b92ab6c848c60c669e18c8681c179265ce4d048b03/mohawk-0.3.4.tar.gz#md5=b65196bb05b9c96d9286c7cd6b110920", + "sha256": "e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3" + } + ] + }, + { + "name": "requests_hawk", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app requests_hawk-1.0.0-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/3b/6a/d1aa3fab0b788bf4cf3d60898ff6b80852c8a6d82a8a7ac6d163487b8e30/requests_hawk-1.0.0-py2.py3-none-any.whl#md5=621d1ba4dabfc3ace8a3472753807d04", + "sha256": "c2626ab31ebef0c81b97781c44c2275bfcc6d8e8520fc4ced495f0f386f8fe26" + } + ] + }, + { + "name": "hawkauthlib", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/46/62/54729cbfc8d115f07f41f74a43a8e3711be358541295ff76fcec5bfd81d2/hawkauthlib-0.1.1.tar.gz#md5=86cd5e4577397fbb75975dd8b6fb939e", + "sha256": "7ac93c892e7629721dde196193c9af3bde1f20540945569f7c7d34d3ea92680a" + } + ] + }, + { + "name": "cffi", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/5b/b9/790f8eafcdab455bcd3bd908161f802c9ce5adbf702a83aa7712fcc345b7/cffi-1.10.0.tar.gz#md5=2b5fa41182ed0edaf929a789e602a070", + "sha256": "b3b02911eb1f6ada203b0763ba924234629b51586f72a21faacc638269f4ced5" + } + ] + }, + { + "name": "pycparser", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/be/64/1bb257ffb17d01f4a38d7ce686809a736837ad4371bcc5c42ba7a715c3ac/pycparser-2.17.tar.gz#md5=ca98dcb50bc1276f230118f6af5a40c7", + "sha256": "0aac31e917c24cb3357f5a4d5566f2cc91a19ca41862f6c3c22dc60a629673b6" + } + ] + }, + { + "name": "cryptography", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/ --skip-build" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/ec/5f/d5bc241d06665eed93cd8d3aa7198024ce7833af7a67f6dc92df94e00588/cryptography-1.8.1.tar.gz#md5=9f28a9c141995cd2300d0976b4fac3fb", + "sha256": "323524312bb467565ebca7e50c8ae5e9674e544951d28a2904a50012a8828190" + } + ] + }, + { + "name": "PyYAML", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950", + "sha256": "592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab" + } + ] + }, + { + "name": "PyBrowserID", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/d7/fd/729ef9ff743bc1758f24c5dbbe4c650f892bd4b04e60cec26b1f73b2f100/PyBrowserID-0.11.0.tar.gz#md5=881db380326010ed41f6a529591b5095", + "sha256": "bf72f57eaa4d2ea36c6888e868f49e588c7b9c0b78dfbf2bc79fee93e97f39d2" + } + ] + }, + { + "name": "pyparsing", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app pyparsing-2.2.0-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/6a/8a/718fd7d3458f9fab8e67186b00abdd345b639976bc7fb3ae722e1b026a50/pyparsing-2.2.0-py2.py3-none-any.whl#md5=7247e7896688eff4bc8c7fc5d0cdd2b0", + "sha256": "fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010" + } + ] + }, + { + "name": "packaging", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app packaging-16.8-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/87/1b/c39b7c65b5612812b83d6cab7ef2885eac9f6beb0b7b8a7071a186aea3b1/packaging-16.8-py2.py3-none-any.whl#md5=c7326351bf015fa53c74b0075923ab02", + "sha256": "99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388" + } + ] + }, + { + "name": "asn1crypto", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app asn1crypto-0.22.0-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/97/ba/7e8117d8efcee589f4d96dd2b2eb1d997f96d27d214cf2b7134ad8acf6ab/asn1crypto-0.22.0-py2.py3-none-any.whl#md5=5f8356d63fb715160b00fe764f6790ea", + "sha256": "d232509fefcfcdb9a331f37e9c9dc20441019ad927c7d2176cf18ed5da0ba097" + } + ] + }, + { + "name": "WebOb", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app WebOb-1.6.0-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/12/5a/b6ef092cf8e70d2d63fdd8d2c6d479b1896d815cb256585213ed86e10196/WebOb-1.6.0-py2.py3-none-any.whl#md5=8ff68c5fce011abd8c3ef714a24450ec", + "sha256": "69356a75980172f3e76717f6899b6c75d95ccdc7a2cb6a3b8bd6a7de3fc72401" + } + ] + }, + { + "name": "idna", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app idna-2.5-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/11/7d/9bbbd7bb35f34b0169542487d2a8859e44306bb2e6a4455d491800a5621f/idna-2.5-py2.py3-none-any.whl#md5=a7e9abecc669f5bd2ddb53b453008d32", + "sha256": "cc19709fd6d0cbfed39ea875d29ba6d4e22c0cebc510a76d6302a28385e8bb70" + } + ] + }, + { + "name": "Naked", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app Naked-0.1.31-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/02/36/b8107b51adca73402ec1860d88f41d958e275e60eea6eeaa9c39ddb89a40/Naked-0.1.31-py2.py3-none-any.whl#md5=fb3c6f2ec6c32ed11d00f1b1d80984f8", + "sha256": "19de9961f4edb29e75cf837e8e031d6b52fbba4f0033515893d26f69c74b3b1f" + } + ] + }, + { + "name": "shellescape", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app shellescape-3.4.1-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/51/b6/986c99a10040beaaefca1ad6c93bd7738cb8e4f52f6caed13d3ed1caa7e4/shellescape-3.4.1-py2.py3-none-any.whl#md5=5bc6f494f210878685dc9492fbce52e2", + "sha256": "3ff2aeb6ce2c5a4e6059fe4a2a745a824f5a3834fe8365a39c5ea691073cfdb6" + } + ] + }, + { + "name": "pycrypto", + "buildsystem": "simple", + "build-commands": [ + "python3 setup.py install --prefix=/app --root=/" + ], + "sources": [ + { + "type": "archive", + "url": "https://pypi.python.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz#md5=55a61a054aa66812daf5161a0d5d7eda", + "sha256": "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c" + } + ] + }, + { + "name": "python-dateutil", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app python_dateutil-2.6.1-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/4b/0d/7ed381ab4fe80b8ebf34411d14f253e1cf3e56e2820ffa1d8844b23859a2/python_dateutil-2.6.1-py2.py3-none-any.whl#md5=342c025339de1e7c2138c74983c111d7", + "sha256": "95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c" + } + ] + }, + { + "name": "PyFxA", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app PyFxA-0.3.0-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://pypi.python.org/packages/b6/97/91b810a1b5678c2b84e0e1fc8a47736fd8d41c0425bcb5daa84ca11b6b97/PyFxA-0.3.0-py2.py3-none-any.whl#md5=605546678d7e81de31e40b083622edcc", + "sha256": "e5963db092b71bff0f51e0695eeeb59405e5646c51998c2d3f06b96d5aca6ace" + } + ] + }, + { + "name": "Eolie", + "buildsystem": "meson", + "sources": [ + { + "type": "git", + "url": "https://gitlab.gnome.org/World/eolie.git" + } + ] + } + ] +}
