From c706fbc6e78394db0af81d996b1488a0cdfd520c Mon Sep 17 00:00:00 2001 From: Daniel Pavel Date: Mon, 3 Jun 2013 11:17:19 +0200 Subject: [PATCH] update icon theme paths directly, don't mess with XDG_DATA_DIRS --- lib/solaar/ui/__init__.py | 38 +------------------ lib/solaar/ui/icons.py | 73 +++++++++++++++++++++++++++--------- lib/solaar/ui/status_icon.py | 26 ++++++++++--- 3 files changed, 78 insertions(+), 59 deletions(-) diff --git a/lib/solaar/ui/__init__.py b/lib/solaar/ui/__init__.py index fe9bd122..d182bc0d 100644 --- a/lib/solaar/ui/__init__.py +++ b/lib/solaar/ui/__init__.py @@ -5,40 +5,6 @@ from __future__ import absolute_import, division, print_function, unicode_literals -import logging -_DEBUG = logging.DEBUG -_log = logging.getLogger('solaar.ui') - - -def _look_for_application_icons(): - import os.path as _path - import os as _os - - import sys as _sys - _log.debug("sys.path[0] = %s", _sys.path[0]) - prefix_share = _path.normpath(_path.join(_path.realpath(_sys.path[0]), '..')) - src_share = _path.normpath(_path.join(_path.realpath(_sys.path[0]), '..', 'share')) - local_share = _os.environ.get('XDG_DATA_HOME', _path.expanduser('~/.local/share')) - data_dirs = _os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share') - del _sys - - share_solaar = [prefix_share] + list(_path.join(x, 'solaar') for x in [src_share, local_share] + data_dirs.split(':')) - for location in share_solaar: - if _log.isEnabledFor(_DEBUG): - _log.debug("looking for icons in %s", location) - solaar_png = _path.join(location, 'icons', 'solaar-logo.png') - if _path.exists(solaar_png): - _os.environ['XDG_DATA_DIRS'] = location + ':' + data_dirs - _log.info("XDG_DATA_DIRS = %s", _os.environ['XDG_DATA_DIRS']) - break - - del _os - # del _path - -# look for application-specific icons before initializing Gtk -_look_for_application_icons() - - from gi.repository import GLib, Gtk GLib.threads_init() @@ -56,7 +22,7 @@ def error_dialog(title, text): from . import status_icon from . import notify, main_window - from . import icons +# for some reason, set_icon_name does not always work on windows +Gtk.Window.set_default_icon_name(main_window.NAME.lower()) Gtk.Window.set_default_icon_from_file(icons.icon_file(main_window.NAME.lower())) -# Gtk.Window.set_default_icon_name(main_window.NAME.lower()) diff --git a/lib/solaar/ui/icons.py b/lib/solaar/ui/icons.py index db7d489b..fd47cecc 100644 --- a/lib/solaar/ui/icons.py +++ b/lib/solaar/ui/icons.py @@ -26,7 +26,34 @@ Gtk.IconSize.LARGE = Gtk.icon_size_register('large', _LARGE_SIZE, _LARGE_SIZE) APP_ICON = ('solaar-init', 'solaar', 'solaar-fail') + +def _look_for_application_icons(): + import os.path as _path + from os import environ as _environ + + import sys as _sys + _log.debug("sys.path[0] = %s", _sys.path[0]) + prefix_share = _path.normpath(_path.join(_path.realpath(_sys.path[0]), '..')) + src_share = _path.normpath(_path.join(_path.realpath(_sys.path[0]), '..', 'share')) + local_share = _environ.get('XDG_DATA_HOME', _path.expanduser('~/.local/share')) + data_dirs = _environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share') + del _sys + + share_solaar = [prefix_share] + list(_path.join(x, 'solaar') for x in [src_share, local_share] + data_dirs.split(':')) + for location in share_solaar: + location = _path.join(location, 'icons') + if _log.isEnabledFor(_DEBUG): + _log.debug("looking for icons in %s", location) + solaar_png = _path.join(location, APP_ICON[0] + '.png') + if _path.exists(solaar_png): + yield location + + del _environ + # del _path + _default_theme = Gtk.IconTheme.get_default() +for p in _look_for_application_icons(): + _default_theme.prepend_search_path(p) _log.debug("icon theme paths: %s", _default_theme.get_search_path()) # @@ -38,20 +65,29 @@ _has_oxygen_icons = _default_theme.has_icon('battery-charging-caution') and \ _default_theme.has_icon('battery-charging-040') _has_gnome_icons = _default_theme.has_icon('battery-caution-charging') and \ _default_theme.has_icon('battery-full-charged') +_has_elementary_icons = _default_theme.has_icon('battery-020-charging') -_log.debug("detected icon sets: gpm %s, oxygen %s, gnome %s", _has_gpm_icons, _has_oxygen_icons, _has_gnome_icons) -if not _has_gpm_icons and not _has_gnome_icons and not _has_oxygen_icons: +_log.debug("detected icon sets: gpm %s, oxygen %s, gnome %s, elementary %s", _has_gpm_icons, _has_oxygen_icons, _has_gnome_icons, _has_elementary_icons) +if (not _has_gpm_icons and not _has_oxygen_icons and + not _has_gnome_icons and not _has_elementary_icons): _log.warning("failed to detect a known icon set") +# +# +# + def battery(level=None, charging=False): icon_name = _battery_icon_name(level, charging) - if _log.isEnabledFor(_DEBUG): - _log.debug("battery icon for %s:%s = %s", level, charging, icon_name) + if not _default_theme.has_icon(icon_name): + _log.warning("icon %s not found in current theme", icon_name); + # elif _log.isEnabledFor(_DEBUG): + # _log.debug("battery icon for %s:%s = %s", level, charging, icon_name) return icon_name def _battery_icon_name(level, charging): if level is None or level < 0: - return 'gpm-battery-missing' if _has_gpm_icons and _default_theme.has_icon('gpm-battery-missing') \ + return 'gpm-battery-missing' \ + if _has_gpm_icons and _default_theme.has_icon('gpm-battery-missing') \ else 'battery-missing' level_approx = 20 * ((level + 10) // 20) @@ -67,6 +103,11 @@ def _battery_icon_name(level, charging): level_name = ('low', 'caution', '040', '060', '080', '100')[level_approx // 20] return 'battery%s-%s' % ('-charging' if charging else '', level_name) + if _has_elementary_icons: + if level == 100 and charging: + return 'battery-charged' + return 'battery-%03d%s' % (level_approx, '-charging' if charging else '') + if _has_gnome_icons: if level == 100 and charging: return 'battery-full-charged' @@ -75,9 +116,9 @@ def _battery_icon_name(level, charging): level_name = ('empty', 'caution', 'low', 'good', 'good', 'full')[level_approx // 20] return 'battery-%s%s' % (level_name, '-charging' if charging else '') + if level == 100 and charging: + return 'battery-charged' # fallback... most likely will fail - if level is None or level < 0: - return 'battery-missing' return 'battery-%03d%s' % (level_approx, '-charging' if charging else '') # @@ -112,7 +153,7 @@ def device_icon_set(name='_', kind=None): elif str(kind) == 'trackball': names += ('input-mouse',) names += ('input-' + str(kind),) - # names += (name,) + # names += (name.replace(' ', '-'),) source = Gtk.IconSource.new() for n in names: @@ -126,25 +167,23 @@ def device_icon_set(name='_', kind=None): def device_icon_file(name, kind=None, size=_LARGE_SIZE): icon_set = device_icon_set(name, kind) assert icon_set - theme = Gtk.IconTheme.get_default() for n in reversed(icon_set.names): - if theme.has_icon(n): - return theme.lookup_icon(n, size, 0).get_filename() + if _default_theme.has_icon(n): + return _default_theme.lookup_icon(n, size, 0).get_filename() def device_icon_name(name, kind=None): icon_set = device_icon_set(name, kind) assert icon_set - theme = Gtk.IconTheme.get_default() for n in reversed(icon_set.names): - if theme.has_icon(n): + if _default_theme.has_icon(n): return n def icon_file(name, size=_LARGE_SIZE): - theme = Gtk.IconTheme.get_default() - if theme.has_icon(name): - theme_icon = theme.lookup_icon(name, size, 0) + # _log.debug("looking for file of icon %s at size %s", name, size) + if _default_theme.has_icon(name): + theme_icon = _default_theme.lookup_icon(name, size, 0) file_name = theme_icon.get_filename() - # print ("icon", name, "->", theme_icon, file_name) + # _log.debug("icon %s => %s : %s", name, theme_icon, file_name) return file_name diff --git a/lib/solaar/ui/status_icon.py b/lib/solaar/ui/status_icon.py index 5756a5b5..6e777e5c 100644 --- a/lib/solaar/ui/status_icon.py +++ b/lib/solaar/ui/status_icon.py @@ -4,6 +4,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from logging import getLogger, DEBUG as _DEBUG +_log = getLogger('solaar.ui.tray') +del getLogger + from gi.repository import Gtk from solaar import NAME @@ -38,6 +42,8 @@ def _create_common(icon, menu_activate_callback): try: from gi.repository import AppIndicator3 as AppIndicator + _log.debug("using AppIndicator3") + # def _scroll(ind, delta, direction): # print ("scroll", ind, delta, direction) @@ -48,6 +54,9 @@ try: ind = AppIndicator.Indicator.new('indicator-solaar', _icons.APP_ICON[0], AppIndicator.IndicatorCategory.HARDWARE) ind.set_status(AppIndicator.IndicatorStatus.ACTIVE) + theme_paths = Gtk.IconTheme.get_default().get_search_path() + ind.set_icon_theme_path(':'.join(theme_paths)) + _create_common(ind, menu_activate_callback) ind.set_menu(ind._menu) @@ -60,12 +69,16 @@ try: # ind.set_status(AppIndicator.IndicatorStatus.PASSIVE) - def _update_icon(ind, image, tooltip): - ind.set_icon_full(image, tooltip) + def _update_icon(ind, icon_name, tooltip): + #ind.set_icon(icon_name) + ind.set_icon_full(icon_name, tooltip) + # _log.debug("set icon %s => %s %s %s", icon_name, ind.get_icon(), ind.get_title(), ind.get_status()) except ImportError: + _log.debug("using StatusIcon") + def create(activate_callback, menu_activate_callback): assert activate_callback assert menu_activate_callback @@ -88,8 +101,8 @@ except ImportError: # icon.set_visible(False) - def _update_icon(icon, image, tooltip): - icon.set_from_icon_name(image) + def _update_icon(icon, icon_name, tooltip): + icon.set_from_icon_name(icon_name) icon.set_tooltip_markup(tooltip) # @@ -120,7 +133,7 @@ def _generate_tooltip_lines(devices_info): yield '' -def _generate_image(icon): +def _generate_icon_name(icon): if not icon._devices_info: return _icons.APP_ICON[-1] @@ -164,6 +177,7 @@ def _add_device(icon, device): if rserial == '-': break assert rserial == device.receiver.serial + assert number != device.number if number > device.number: break index = index + 1 @@ -281,6 +295,6 @@ def update(icon, device=None): tooltip_lines = _generate_tooltip_lines(icon._devices_info) tooltip = '\n'.join(tooltip_lines).rstrip('\n') - _update_icon(icon, _generate_image(icon), tooltip) + _update_icon(icon, _generate_icon_name(icon), tooltip) # print ("icon updated", device, icon._devices_info)