適当なところが多い、、(エラー処理とかないし
トレイに出るアイコンを右クリックとか左クリックとかしてください
そのうちFedoracubeに入れる予定
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import sys, pygtk, gtk, subprocess
class PopupMenu(gtk.Menu):
 def __init__(self, icon):
  gtk.Menu.__init__(self)
  self.icon = icon
  # コントロール
  controls = []
  group = None
  for i in self.GetControls():
   controls.append(gtk.RadioMenuItem(group, i))
   control = controls[-1]
   control.connect("activate", self.activate_ChangeControl, i)
   group = control
   self.append(control)
  controls[0].set_active(True)
  # 区切り線
  self.append(gtk.SeparatorMenuItem())
  # PulseAudio Volume Control
  self.pavucontrol = gtk.ImageMenuItem("PulseAudio Volume Control")
  self.pavucontrol.set_image(gtk.image_new_from_icon_name("multimedia-volume-control", gtk.ICON_SIZE_MENU))
  self.pavucontrol.connect("activate", self.activate_RunPavucontrol)
  self.append(self.pavucontrol)
  # 終了
  self.exit = gtk.ImageMenuItem(stock_id = gtk.STOCK_QUIT)
  self.exit.connect("activate", gtk.main_quit)
  self.append(self.exit)
  self.show_all()
 
 def GetControls(self):
  amixer = subprocess.Popen(["/usr/bin/amixer", "scontrols"], stdout = subprocess.PIPE).communicate()[0]
  
  controls = []
  for control in amixer.rstrip().split("\n"):
   controls.append(control.split(" ")[3])
  
  return controls
 
 def activate_RunPavucontrol(self, widget):
  subprocess.Popen(["/usr/bin/pavucontrol"])
 def activate_ChangeControl(self, widget, control):
  if widget.get_active() == True:
   self.icon.active_control = control
class VolumeControl(gtk.Window):
 def __init__(self, icon):
  gtk.Window.__init__(self)
      
  self.icon = icon
  self.vbox = gtk.VBox(False, 0)
  self.plus = gtk.Button()
  self.scale = gtk.VScale(gtk.Adjustment(50, 0, 101, 1, 1, 1))
  self.minus = gtk.Button()
  self.mute = gtk.Button()
  
  self.plus.set_relief(gtk.RELIEF_NONE)
  self.plus.set_image(gtk.image_new_from_stock(gtk.STOCK_GO_UP, gtk.ICON_SIZE_MENU))
  self.plus.connect("clicked", self.clicked_ChangeVolume, 5)
  
  self.minus.set_relief(gtk.RELIEF_NONE)
  self.minus.set_image(gtk.image_new_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_MENU))
  self.minus.connect("clicked", self.clicked_ChangeVolume, -5)
  
  self.mute.set_relief(gtk.RELIEF_NONE)
  self.mute.connect("clicked", self.clicked_ToggleMute)
  
  self.scale.set_size_request(28, 128)
  self.scale.set_draw_value(False)
  self.scale.set_inverted(True)
  self.scale.connect("adjust-bounds", self.adjust_bounds_ChangeVolume)
  
  self.vbox.pack_start(self.plus, False, True, 0)
  self.vbox.pack_start(self.scale, False, True, 0)
  self.vbox.pack_start(self.minus, False, True, 0)
  self.vbox.pack_start(self.mute, False, True, 0)
  
  self.set_skip_pager_hint(True)
  self.set_skip_taskbar_hint(True)
  self.set_decorated(False)
  self.resize(28, 212)
  self.add(self.vbox)
  self.connect("show", self.show_ShowWindow)
  self.connect("focus-out-event", self.focus_out_event_CloseWindow)
 
 def GetMuteStatus(self):
  amixer = subprocess.Popen(["/usr/bin/amixer", "sget", self.icon.active_control], stdout = subprocess.PIPE)
  grep = subprocess.Popen(["/bin/grep", "-e", "\[on\]$"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]
  
  if grep == "":
   ret = gtk.STOCK_MEDIA_PLAY
  else:
   ret = gtk.STOCK_MEDIA_STOP
  
  return ret
 def GetVolume(self):
  amixer = subprocess.Popen(["/usr/bin/amixer", "sget", self.icon.active_control], stdout = subprocess.PIPE)
  grep = subprocess.Popen(["/bin/grep", "-oe", "[0-9]*%"], stdin = amixer.stdout, stdout = subprocess.PIPE).communicate()[0]
  ret = int(grep.split("%")[0])
  
  return ret
 def ChangeVolume(self, adjust):
  value = adjust.value
  
  if value > adjust.upper:
   value = adjust.upper
  elif value < adjust.lower:
   value = adjust.lower
  
  subprocess.Popen(["/usr/bin/amixer", "sset", self.icon.active_control, str(int(value)) + "%"], stdout = subprocess.PIPE).communicate()[0]
 
 def show_ShowWindow(self, widget):
  self.scale.grab_focus()
  self.scale.set_value(self.GetVolume())
  self.mute.set_image(gtk.image_new_from_stock(self.GetMuteStatus(), gtk.ICON_SIZE_MENU))
 
 def focus_out_event_CloseWindow(self, widget, event):
  self.hide_all()
  
 def clicked_ChangeVolume(self, button, value):
  self.scale.set_value(self.scale.get_value() + value)
  self.ChangeVolume(self.scale.get_adjustment())
 
 def clicked_ToggleMute(self, button):
  subprocess.Popen(["/usr/bin/amixer", "sset", self.icon.active_control, "toggle"], stdout = subprocess.PIPE).communicate()[0]
  self.hide_all()
 
 def adjust_bounds_ChangeVolume(self, range, value):
  self.ChangeVolume(self.scale.get_adjustment())
class StatusIconVolumeControl(gtk.StatusIcon):
 def __init__(self):
  gtk.StatusIcon.__init__(self)
  
  self.menu = PopupMenu(self)
  self.control = VolumeControl(self)
  
  self.set_from_icon_name("multimedia-volume-control")
  self.connect("activate", self.activate_VolumeControl)
  self.connect("popup-menu", self.popup_menu_PopupMenu)
 
 def activate_VolumeControl(self, widget):
  if self.control.is_active() == True:
   self.control.hide_all()
  else:
   (screen, rectangle, orientation) = self.get_geometry()
   
   if (screen.get_width() / rectangle.x) > 2:
    x = rectangle.x + rectangle.width
   else:
    x = rectangle.x - self.control.get_size()[0]
   
   if (screen.get_height() / rectangle.y) > 2:
    y = rectangle.y + rectangle.height
   else:
    y = rectangle.y - self.control.get_size()[1]
   
   self.control.move(x, y)
   self.control.show_all()
 
 def popup_menu_PopupMenu(self, widget, button, time):
  self.menu.popup(None, None, gtk.status_icon_position_menu, button, time, self)
if __name__ == '__main__':
 StatusIconVolumeControl()
 gtk.main()
 
0 件のコメント:
コメントを投稿