#1 Le 10/06/2009, à 15:55
- monsieurzik
Problème Quod Libet et systray...
Bonjour à tous !
Depuis mon passage à Jaunty ( c'est sous Mint 7) je n'arrive plus à minimiser Quodlibet dans le Systray...
Quand je clique sur la croix de fermeture de fenêtre, il se ferme.
En vérifiant les greffons, j'ai une erreur qui s'affiche me créant ce fichier dans le .quolibet de mon /home :
=== SYSTEM INFORMATION:
Quod Libet 2.0
Mutagen 1.14
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] linux2=== STACK TRACE
Traceback (most recent call last):File "/usr/lib/python2.6/dist-packages/quodlibet/plugins/events/trayicon.py", line 190, in __prefs_destroy
self.plugin_on_song_started(player.info)File "/usr/lib/python2.6/dist-packages/quodlibet/plugins/events/trayicon.py", line 250, in plugin_on_song_started
items = self.__menu.sensitivesAttributeError: 'NoneType' object has no attribute 'sensitives'
Une solution ?
Merci Camarades par avance !
Jo
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#2 Le 12/06/2009, à 11:19
- monsieurzik
Re : Problème Quod Libet et systray...
Up!
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#3 Le 12/06/2009, à 14:48
- 21ch181
Re : Problème Quod Libet et systray...
Bonjour,
Je suis sous 8.04 et j'avais eu le même pb avec Quodlibet 1.0 après avoir tenté d'utiliser la V 2.0. J'ai procédé ainsi pour rétablir tout :
1- synaptic : désinstallation complète de quodlibet* (3 lignes)
2- suppression du répertoire .quodlibet de mon home
3- synpatic : installation de quodlibet (3 paquets dont ext et plugins)
4- ouverture de quodlibet, musique, greffons, trayicon
et tout refonctionne correctement
Cordialement
Hors ligne
#4 Le 15/06/2009, à 23:38
- monsieurzik
Re : Problème Quod Libet et systray...
Salut,
J'ai fait toutes les manip' que tu m'as donné mais l'erreur reste la même...
Dommage, c'est un lecteur que j'aimais bien, les touches multimedia de mon laptop fonctionnait nickel...
Y-a-t-il un autre lecteur qui prend cela en charge nativement ? Exaile ? Listen ?
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#5 Le 16/06/2009, à 16:47
- monsieurzik
Re : Problème Quod Libet et systray...
Bon,
j'ai essayé Exaile mais il me pompait toutes mes ressources processeur...
J'ai également testé Listen mais pas de prise en charge des touches mutimédia de mon laptop...
Là je suis avec Banshee ça a l'air pas mal pour l'instant
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#6 Le 18/06/2009, à 11:25
- monsieurzik
Re : Problème Quod Libet et systray...
Un ptit retour à Amarok mais cette fois le 2. Ça va pour l'instant...
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#7 Le 19/06/2009, à 14:22
- monsieurzik
Re : Problème Quod Libet et systray...
Bon je vous saoûle encore mais amarok m'a foutu un bordel monstre dans ma bibliothèque... Retour à Amarok 1.4, c'est de la balle !
Ubuntu Mate 20.04.3 - DELL Inspiron 1545
"Tôt ou tard, nous devrons répondre à cet appel des ténèbres, aller voir ce qu'il y a derrière cette impérieuse mélancolie qui sort des saxophones." P. Morand
Hors ligne
#8 Le 22/08/2009, à 23:08
- Pyros
Re : Problème Quod Libet et systray...
Bon je crois avoir trouvé la solution (en tout cas chez moi ça marche):
Dans la console, on va éditer le fichier trayicon:
sudo gedit '/usr/lib/python2.6/dist-packages/quodlibet/plugins/events/trayicon.py
puis remplacer tout le contenu par:
# -*- coding: utf-8 -*-
# Copyright 2004-2006 Joe Wreschnig, Michael Urman, Iñigo Serna
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation
import os
import gtk
import pango
gtk_216 = gtk.gtk_version >= (2, 16)
if not gtk_216:
try:
import egg.trayicon as trayicon
except ImportError:
import _trayicon as trayicon
from quodlibet import browsers
from quodlibet import config
from quodlibet import const
from quodlibet import qltk
from quodlibet import stock
from quodlibet import util
from quodlibet.parse import Pattern
from quodlibet.plugins.events import EventPlugin
from quodlibet.qltk.browser import LibraryBrowser
from quodlibet.qltk.information import Information
from quodlibet.qltk.properties import SongProperties
from quodlibet.qltk.controls import StopAfterMenu
from quodlibet.player import playlist as player
from quodlibet.widgets import main as window, watcher
from quodlibet.qltk.playorder import ORDERS
from quodlibet.library import library
from gtk.gdk import SCROLL_LEFT, SCROLL_RIGHT, SCROLL_UP, SCROLL_DOWN
class Preferences(gtk.VBox):
"""A small window to configure the tray icon's tooltip."""
def __init__(self, activator):
super(Preferences, self).__init__(spacing=12)
self.set_border_width(6)
combo = gtk.combo_box_new_text()
combo.append_text(_("Scroll wheel adjusts volume\n"
"Shift and scroll wheel changes song"))
combo.append_text(_("Scroll wheel changes song\n"
"Shift and scroll wheel adjusts volume"))
try: combo.set_active(int(
config.getboolean("plugins", "icon_modifier_swap")))
except config.error: combo.set_active(0)
combo.connect('changed', self.__changed_combo)
self.pack_start(qltk.Frame(_("Scroll _Wheel"), child=combo))
box = gtk.VBox(spacing=12)
table = gtk.Table(2, 4)
table.set_row_spacings(6)
table.set_col_spacings(12)
tips = qltk.Tooltips(self)
cbs = []
for i, tag in enumerate([
"genre", "artist", "album", "discnumber", "part", "tracknumber",
"title", "version"]):
cb = gtk.CheckButton(util.tag(tag))
cb.tag = tag
cbs.append(cb)
table.attach(cb, i%3, i%3+1, i//3, i//3+1)
box.pack_start(table)
entry = gtk.Entry()
box.pack_start(entry, expand=False)
preview = gtk.Label()
preview.set_ellipsize(pango.ELLIPSIZE_END)
ev = gtk.EventBox()
ev.add(preview)
box.pack_start(ev, expand=False)
frame = qltk.Frame(_("Tooltip Display"), child=box)
frame.get_label_widget().set_mnemonic_widget(entry)
self.pack_start(frame)
for cb in cbs:
cb.connect('toggled', self.__changed_cb, cbs, entry)
entry.connect(
'changed', self.__changed_entry, cbs, preview, player, tips)
try:
entry.set_text(config.get("plugins", "icon_tooltip"))
except:
entry.set_text(
"<album|<album~discnumber~part~tracknumber~title~version>|"
"<artist~title~version>>")
self.show_all()
def __changed_combo(self, combo):
config.set(
"plugins", "icon_modifier_swap", str(bool(combo.get_active())))
def __changed_cb(self, cb, cbs, entry):
text = "<%s>" % "~".join([cb.tag for cb in cbs if cb.get_active()])
entry.set_text(text)
def __changed_entry(self, entry, cbs, label, player, tips):
text = entry.get_text()
if text[0:1] == "<" and text[-1:] == ">":
parts = text[1:-1].split("~")
for cb in cbs:
if parts and parts[0] == cb.tag:
parts.pop(0)
if parts:
for cb in cbs:
cb.set_inconsistent(True)
else:
parts = text[1:-1].split("~")
for cb in cbs:
cb.set_inconsistent(False)
cb.set_active(cb.tag in parts)
else:
for cb in cbs: cb.set_inconsistent(True)
if player.info is None: text = _("Not playing")
else: text = Pattern(entry.get_text()) % player.info
label.set_text(text)
tips.set_tip(label.get_parent(), text)
config.set("plugins", "icon_tooltip", entry.get_text())
class EggTrayIconWrapper():
__popup_sig = None
__activate_sig = None
__button_press_sig = None
__size_changed_sig = None
__icon = None
def __init__(self):
self.__icon = trayicon.TrayIcon("quodlibet")
self.__tips = qltk.Tooltips(self.__icon)
self.__eb = gtk.EventBox()
self.__image = gtk.Image()
self.__eb.add(self.__image)
self.__icon.add(self.__eb)
self.__tips = qltk.Tooltips(self.__icon)
self.__icon.show_all()
def destroy(self):
if self.__icon:
self.__icon.destroy()
def connect(self, *args):
if args[0] == "size-changed":
self.__size_changed_sig = args[1]
self.__eb.connect('size-allocate', self.__size_changed)
elif args[0] == "activate":
self.__activate_sig = args[1]
elif args[0] == "popup-menu":
self.__popup_sig = args[1]
elif args[0] == "button-press-event":
self.__button_press_sig = args[1]
self.__eb.connect(args[0], self.__button_press)
elif args[0] == "scroll-event":
return self.__eb.connect(*args)
return None
def __button_press(self, eb, event):
if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS:
self.__activate_sig(eb)
elif event.button == 2:
self.__button_press_sig(eb, event)
elif event.button == 3:
self.__popup_sig(eb, event.button, event.time)
def __size_changed(self, eb, rect):
self.__size_changed_sig(eb, rect.height)
def set_visible(self, val):
if val:
self.__icon.show()
else:
self.__icon.hide()
def set_from_pixbuf(self, pb):
self.__image.set_from_pixbuf(pb)
def set_tooltip(self, tip):
self.__tips.set_tip(self.__icon, tip)
def place_menu(self, menu):
(width, height) = menu.size_request()
(menu_xpos, menu_ypos) = self.__icon.window.get_origin()
menu_xpos += self.__icon.allocation.x
menu_ypos += self.__icon.allocation.y
if menu_ypos > self.__icon.get_screen().get_height() / 2:
menu_ypos -= height
else:
menu_ypos += self.__icon.allocation.height
return (menu_xpos, menu_ypos, True)
class TrayIcon(EventPlugin):
__icon = None
__pixbuf = None
__pixbuf_paused = None
__icon_theme = None
__position = None
__size = -1
__w_sig_map = None
__w_sig_del = None
__stop_after = None
__pattern = Pattern(
"<album|<album~discnumber~part~tracknumber~title~version>|"
"<artist~title~version>>")
PLUGIN_ID = "Tray Icon"
PLUGIN_NAME = _("Tray Icon")
PLUGIN_DESC = _("Control Quod Libet from the system tray.")
PLUGIN_VERSION = "2.0"
def enabled(self):
global gtk_216
filename = os.path.join(const.IMAGEDIR, "quodlibet.")
if gtk_216:
self.__icon = gtk.StatusIcon()
else:
self.__icon = EggTrayIconWrapper()
self.__update_icon()
self.__icon_theme = gtk.icon_theme_get_default()
self.__icon_theme.connect('changed', self.__theme_changed)
self.__icon.connect('size-changed', self.__size_changed)
self.__icon.connect('popup-menu', self.__button_right)
self.__icon.connect('activate', self.__button_left)
self.__icon.connect('scroll-event', self.__scroll)
self.__icon.connect('button-press-event', self.__button_middle)
self.__w_sig_map = window.connect('map-event', self.__window_map)
self.__w_sig_del = window.connect('delete-event', self.__window_delete)
self.__stop_after = StopAfterMenu(player)
self.plugin_on_paused()
self.plugin_on_song_started(player.song)
def disabled(self):
global gtk_216
if window.handler_is_connected(self.__w_sig_map):
window.disconnect(self.__w_sig_map)
if window.handler_is_connected(self.__w_sig_del):
window.disconnect(self.__w_sig_del)
if self.__icon:
self.__icon.set_visible(False)
try:
self.__icon.destroy()
except AttributeError:
pass
self.__icon = None
self.__show_window()
def PluginPreferences(self, parent):
p = Preferences(self)
p.connect('destroy', self.__prefs_destroy)
return p
def __update_icon(self):
if self.__size <= 0:
return
filename = os.path.join(const.IMAGEDIR, "quodlibet") + ".svg"
if not self.__pixbuf:
self.__pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename,
self.__size * 2, self.__size * 2)
self.__pixbuf = self.__pixbuf.scale_simple(
self.__size, self.__size, gtk.gdk.INTERP_BILINEAR)
if player.paused:
if not self.__pixbuf_paused:
base = self.__pixbuf.copy()
overlay = self.__icon_theme.load_icon(
gtk.STOCK_MEDIA_PAUSE,
self.__size, gtk.ICON_LOOKUP_FORCE_SVG)
w, h = base.get_width(), base.get_height()
wo, ho = overlay.get_width(), overlay.get_height()
r = 2
b = 8
l = b - r
overlay.composite(base, w * r // b, h * r // b,
l * w // b, l * h // b,
w * r // b, h * r // b + 1,
float(l * w) / b / wo, float(l * h) / b / ho,
gtk.gdk.INTERP_BILINEAR, 255)
self.__pixbuf_paused = base
self.__icon.set_from_pixbuf(self.__pixbuf_paused)
else:
self.__icon.set_from_pixbuf(self.__pixbuf)
def __theme_changed(self, theme, *args):
self.__pixbuf_paused = None
self.__update_icon()
def __size_changed(self, icon, size, *args):
new_size = int(size * 0.75)
if new_size != self.__size:
self.__pixbuf = None
self.__pixbuf_paused = None
self.__size = new_size
self.__update_icon()
def __prefs_destroy(self, *args):
if self.__icon:
self.plugin_on_song_started(player.song)
def __window_delete(self, win, event):
self.__hide_window()
return True
def __window_map(self, win, event):
try:
visible = config.getboolean("plugins", "icon_window_visible")
except config.error:
return
if not visible:
self.__hide_window()
def __hide_window(self):
self.__position = window.get_position()
window.hide()
config.set("plugins", "icon_window_visible", "false")
def __show_window(self):
if self.__position:
window.move(*self.__position)
window.present()
window.deiconify()
config.set("plugins", "icon_window_visible", "true")
def __button_left(self, icon):
if window.get_property('visible'):
self.__hide_window()
else:
self.__show_window()
def __button_middle(self, widget, event):
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 2:
self.__play_pause()
def __play_pause(self, *args):
if player.song:
player.paused ^= True
else:
player.reset()
def __scroll(self, widget, event):
try:
event.state ^= config.getboolean("plugins", "icon_modifier_swap")
except config.error:
pass
if event.direction in [SCROLL_LEFT, SCROLL_RIGHT]:
event.state = gtk.gdk.SHIFT_MASK
if event.state & gtk.gdk.SHIFT_MASK:
if event.direction in [SCROLL_UP, SCROLL_LEFT]:
player.previous()
elif event.direction in [SCROLL_DOWN, SCROLL_RIGHT]:
player.next()
else:
if event.direction in [SCROLL_UP, SCROLL_LEFT]:
player.volume += 0.05
elif event.direction in [SCROLL_DOWN, SCROLL_RIGHT]:
player.volume -= 0.05
def plugin_on_song_started(self, song):
if song:
try:
pattern = Pattern(config.get("plugins", "icon_tooltip"))
except (ValueError, config.error):
pattern = self.__pattern
tooltip = pattern % song
else:
tooltip = _("Not playing")
self.__icon.set_tooltip(tooltip)
def __button_right(self, icon, button, time):
global gtk_216
menu = gtk.Menu()
pp_icon = [gtk.STOCK_MEDIA_PAUSE, gtk.STOCK_MEDIA_PLAY][player.paused]
playpause = gtk.ImageMenuItem(pp_icon)
playpause.connect('activate', self.__play_pause)
previous = gtk.ImageMenuItem(gtk.STOCK_MEDIA_PREVIOUS)
previous.connect('activate', lambda *args: player.previous())
next = gtk.ImageMenuItem(gtk.STOCK_MEDIA_NEXT)
next.connect('activate', lambda *args: player.next())
orders = gtk.MenuItem(_("Play _Order"))
repeat = gtk.CheckMenuItem(_("_Repeat"))
repeat.set_active(window.repeat.get_active())
repeat.connect('toggled',
lambda s: window.repeat.set_active(s.get_active()))
def set_safter(widget, stop_after):
stop_after.active = widget.get_active()
safter = gtk.CheckMenuItem(_("Stop _after this song"))
safter.set_active(self.__stop_after.active)
safter.connect('activate', set_safter, self.__stop_after)
def set_order(widget, num):
window.order.set_active(num)
order_items = [None]
for i, Kind in enumerate(ORDERS):
name = Kind.accelerated_name
order_items.append(gtk.RadioMenuItem(order_items[-1], name))
order_items[-1].connect('toggled', set_order, i)
del order_items[0]
order_items[window.order.get_active()].set_active(True)
order_sub = gtk.Menu()
order_sub.append(repeat)
order_sub.append(safter)
order_sub.append(gtk.SeparatorMenuItem())
map(order_sub.append, order_items)
orders.set_submenu(order_sub)
browse = gtk.MenuItem(_("_Browse Library"), gtk.STOCK_FIND)
browse_sub = gtk.Menu()
for Kind in browsers.browsers:
i = gtk.MenuItem(Kind.accelerated_name)
i.connect_object('activate', LibraryBrowser, Kind, library)
browse_sub.append(i)
browse.set_submenu(browse_sub)
props = gtk.ImageMenuItem(stock.EDIT_TAGS)
props.connect('activate', self.__properties)
info = gtk.ImageMenuItem(gtk.STOCK_INFO)
info.connect('activate', self.__information)
rating = gtk.MenuItem(_("_Rating"))
rating_sub = gtk.Menu()
def set_rating(value):
song = player.song
if song is None: return
else:
song["~#rating"] = value
watcher.changed([song])
for i in range(0, int(1.0 / util.RATING_PRECISION) + 1):
j = i * util.RATING_PRECISION
item = gtk.MenuItem("%0.2f\t%s" % (j, util.format_rating(j)))
item.connect_object('activate', set_rating, j)
rating_sub.append(item)
rating.set_submenu(rating_sub)
quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
quit.connect('activate', window.destroy)
menu.append(playpause)
menu.append(gtk.SeparatorMenuItem())
menu.append(previous)
menu.append(next)
menu.append(orders)
menu.append(gtk.SeparatorMenuItem())
menu.append(browse)
menu.append(gtk.SeparatorMenuItem())
menu.append(props)
menu.append(info)
menu.append(rating)
menu.append(gtk.SeparatorMenuItem())
menu.append(quit)
menu.show_all()
if gtk_216:
menu.popup(None, None, gtk.status_icon_position_menu,
button, time, self.__icon)
else:
menu.popup(None, None, self.__icon.place_menu, button, time)
plugin_on_paused = __update_icon
plugin_on_unpaused = __update_icon
def __properties(self, *args):
if player.song:
SongProperties(watcher, [player.song])
def __information(self, *args):
if player.song:
Information(watcher, [player.song])
def destroy(self):
self.disabled()
Et là normalement ça devrait fonctionner...enfin en théorie ^^
Pense a faire une sauvegarde, on ne sait jamais.
Hors ligne