From 09439cba21e401fca91b080d6048be97d6addcec Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 30 Aug 2018 09:58:51 +1000 Subject: [PATCH] Fetch file descriptors for the SVGs, not paths This allows us to read SVGs when we're sandboxed and don't have direct access to the file system. This requires an up-to-date ratbagd to get access to GetSvgFd() See https://github.com/libratbag/libratbag/pull/523 Fixes #245 --- piper/devicerow.py | 14 ++++++++------ piper/mousemap.py | 18 +++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/piper/devicerow.py b/piper/devicerow.py index 6885cee..8885300 100644 --- a/piper/devicerow.py +++ b/piper/devicerow.py @@ -14,14 +14,13 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -import os import sys from .gi_composites import GtkTemplate import gi gi.require_version("Gtk", "3.0") -from gi.repository import GdkPixbuf, GObject, Gtk, Rsvg +from gi.repository import GdkPixbuf, GObject, Gtk, Rsvg, Gio @GtkTemplate(ui="/org/freedesktop/Piper/ui/DeviceRow.ui") @@ -40,9 +39,12 @@ class DeviceRow(Gtk.ListBoxRow): self._device = device self.title.set_text(device.name) - svg_path = device.get_svg("gnome") - if os.path.isfile(svg_path): - handle = Rsvg.Handle.new_from_file(svg_path) + try: + fd = device.get_svg_fd("gnome") + uis = Gio.UnixInputStream.new(fd.fileno(), False) + handle = Rsvg.Handle.new_from_stream_sync(uis, None, + Rsvg.HandleFlags.FLAGS_NONE, + None) svg = handle.get_pixbuf_sub("#Device") handle.close() if svg is None: @@ -53,7 +55,7 @@ class DeviceRow(Gtk.ListBoxRow): print("Cannot resize device SVG", file=sys.stderr) else: self.image.set_from_pixbuf(svg) - else: + except FileNotFoundError: print("Device {} has no image or its path is invalid".format(device.name), file=sys.stderr) self.show_all() diff --git a/piper/mousemap.py b/piper/mousemap.py index c23de68..5590af7 100644 --- a/piper/mousemap.py +++ b/piper/mousemap.py @@ -16,14 +16,13 @@ import cairo import gi -import os import sys from lxml import etree gi.require_version("Gdk", "3.0") gi.require_version("Gtk", "3.0") gi.require_version("Rsvg", "2.0") -from gi.repository import Gdk, GLib, Gtk, GObject, Rsvg +from gi.repository import Gdk, GLib, Gtk, GObject, Rsvg, Gio """This module contains the MouseMap widget (and its helper class _MouseMapChild), which is central to the button and LED configuration stack @@ -106,8 +105,16 @@ class MouseMap(Gtk.Container): raise ValueError("Layer cannot be None") if ratbagd_device is None: raise ValueError("Device cannot be None") - svg_path = ratbagd_device.get_svg("gnome") - if not os.path.isfile(svg_path): + try: + fd = ratbagd_device.get_svg_fd("gnome") + uis = Gio.UnixInputStream.new(fd.fileno(), False) + self._handle = Rsvg.Handle.new_from_stream_sync(uis, None, + Rsvg.HandleFlags.FLAGS_NONE, + None) + # separate fd for the XML parsing to avoid file offset issues + fd = ratbagd_device.get_svg_fd("gnome") + self._svg_data = etree.parse(fd) + except FileNotFoundError: raise ValueError("Device has no image or its path is invalid") Gtk.Container.__init__(self, *args, **kwargs) @@ -119,9 +126,6 @@ class MouseMap(Gtk.Container): self._children = [] self._highlight_element = None - self._handle = Rsvg.Handle.new_from_file(svg_path) - self._svg_data = etree.parse(svg_path) - # TODO: remove this when we're out of the transition to toned down SVGs device = self._handle.has_sub("#Device") buttons = self._handle.has_sub("#Buttons")