Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- ##
- # ADesk Menu
- # - v0.2 : add signal , get cursor position and show menu whith it
- # - v0.1 : check if 'Terminal=true' in .desktop file, always above other windows
- #
- # by ADcomp <david.madbox@gmail.com>
- # http://www.ad-comp.be/
- #
- # This program is distributed under the terms of the GNU General Public License
- # For more info see http://www.gnu.org/licenses/gpl.txt
- #####################################################################################
- #
- # 7/25/11
- #
- # This script was edited from the original by sliphot and MoD from silver irc.
- # I thhought it might come in handy with tint2s's new launcher feature.
- # We re-worked it so it will open the menu in a designated area of the screen when the script is executed.
- # by default it opens in the top left corner of the screen. To adjust go to line 369 and adjust x= and y=
- # Make this script executable and move it to /usr/bin after that make a .desktop file pointing to it.
- # Point tint2 to the .desktop file and presto! tint2 desktop menu. It can be a little slow to load.
- # It helps to run it once in a terminal with the -s option. it saves a config file of all your .desktop files.
- # If you install a new app after you have ran the -s option you will have to run it again to update the config.
- #
- #####################################################################################
- MENU_WIDTH = 380
- import os
- import sys
- import gtk
- import signal
- cat_name = {'accessories':('Utility','Accessories'),
- 'development':('Development'),
- 'engineering':(),
- 'games':('Game'),
- 'graphics':('Graphics'),
- 'internet':('Internet', 'Network'),
- 'multimedia':('AudioVideo', 'Audio', 'Video', 'Multimedia'),
- 'office':('Office'),
- 'other':('Other'),
- 'science':(),
- 'system':('System', 'Administration'),
- 'settings':('Settings', 'X-XFCE'),
- 'utilities':()
- }
- def exec_cmd(cmd=None):
- if cmd and not cmd=='':
- os.system('%s &' % cmd)
- # Find the Name / Command / Icon from .desktop file
- def info_desktop(file):
- cmd, icon, name, category = None, None, None, None
- terminal = False
- try:
- cfile = open(file,"r")
- for line in cfile:
- if 'NoDisplay=true' in line or 'OnlyShowIn=KDE' in line:
- icon, category = None, None
- break
- elif 'Terminal=true' in line:
- terminal = True
- elif '=' in line:
- words = line.split('=')
- if words[0] == 'Name':
- name = words[1].replace('\n','')
- # print 'Name =', name
- elif words[0] == 'Icon':
- icon = words[1].replace('\n','')
- # print 'Icon =', icon
- elif words[0] == 'Exec':
- cmd = words[1].replace('\n','')
- cmd = cmd.split('%')[0]
- # print 'Exec :', cmd
- elif words[0] == 'Categories':
- tab = words[1].replace('\n','')
- tab = tab.split(';')
- #~ category = '***************************'
- #~ if not 'X-XFCE' in tab:
- for cat in tab:
- found = False
- for c_name in cat_name:
- if cat in cat_name[c_name]:
- category = c_name
- found = True
- break
- if found:
- break
- # if command is 'console only', launch it with terminal ..
- if terminal:
- cmd = "x-terminal-emulator -e %s" % cmd
- cfile.close()
- except:
- #~ print("# Error : parsing %s" % file)
- pass
- return (cmd, icon, name, category)
- # Find the best icon with highest resolution for the launcher
- def find_icon(icon):
- foundiconfile=None
- if icon == '':
- return foundiconfile
- if icon[0] == '/':
- return icon
- iconbase=('','Madbox','gnome','hicolor','locolor')
- iconpath='/usr/share/icons'
- sizelist =('', 'scalable', '256x256', '128x128', '64x64', '48x48', '32x32', '24x24')
- categorylist=('actions', 'apps',"devices", 'categories','filesystems', 'places', 'status', '')
- extensionlist = ('png', 'svg', 'xpm')
- iconimagelist=[]
- for extension in extensionlist:
- if (icon.find('.'+extension) != -1):
- icon = icon.replace('.'+extension,'')
- for size in sizelist:
- for extension in extensionlist:
- for category in categorylist:
- for iconbasecat in iconbase:
- iconfile = iconpath+"/"+iconbasecat+'/'+size+'/'+category+'/'+icon+'.'+extension
- iconimagelist.append(iconfile)
- for extension in extensionlist:
- iconfile = '/usr/share/pixmaps/'+icon+'.'+extension
- iconimagelist.append(iconfile)
- for extension in extensionlist:
- iconfile = '/usr/share/app-install/icons/'+icon+'.'+extension
- iconimagelist.append(iconfile)
- # Seek if the files in pre-generated list exists.. first match is the best
- # return it
- for iconimage in iconimagelist:
- if os.path.exists(iconimage):
- return iconimage
- return foundiconfile
- def parse_desktop_dir(check_config=True):
- config = {}
- cfg_file = home = os.getenv('HOME') + '/.config/adesk-menu/config'
- if os.access(cfg_file, os.F_OK|os.R_OK) and check_config:
- print('found user config ..')
- f = open(cfg_file,'r')
- for line in f:
- if line == '\n' or line.startswith('#'):
- continue
- elif line.startswith('@'):
- cat = line[1:]
- cat = cat.strip('\n')
- cat = cat.strip(' ')
- config[cat] = []
- cat_index = cat
- else:
- line = line.strip('\n')
- line = line.strip(' ')
- config[cat_index].append(line.split('##'))
- f.close()
- else:
- print('scan /usr/share/applications and parse .desktop file ..')
- APP_PATH = '/usr/share/applications/'
- listdir = os.listdir(APP_PATH)
- for i in listdir:
- if '.desktop' in i:
- #~ print i
- (cmd, icon, name, category) = info_desktop(APP_PATH + i)
- #~ print cmd, icon, name, category
- if category:
- if not config.has_key(category):
- #~ print "@ add :", category
- config[category] = []
- if icon:
- icon_path = find_icon(icon)
- config[category].append((cmd, icon_path, name))
- else:
- pass
- #~ print "File =", i
- #~ print '=> NO ICON ...'
- else:
- pass
- #~ print "File =", i
- #~ print '=> NO CATEGORY ...'
- #~ print config
- return config
- def write_config():
- home = os.environ['HOME']
- cfg_file = "%s/.config/adesk-menu/config" % home
- if not os.path.exists("%s/.config/adesk-menu" % home):
- os.makedirs("%s/.config/adesk-menu" % home)
- f = open(cfg_file,'w')
- m = parse_desktop_dir(False)
- m_tmp = []
- for cat in m:
- m_tmp.append(cat)
- m_tmp.sort()
- for cat in m_tmp:
- f.write('@%s\n' % cat)
- for item in m[cat]:
- (cmd, icon, text) = item
- f.write('%s##%s##%s\n' % item)
- f.close()
- print "menu saved to %s" % cfg_file
- class Menu():
- def __init__(self):
- self.hide_me = False
- self.focus_check = False
- self.mode = None
- self.create_window()
- # Menu
- self.popupMenu = gtk.Menu()
- menuPopup = gtk.ImageMenuItem (gtk.STOCK_QUIT)
- menuPopup.connect("activate", self.doquit)
- self.popupMenu.add(menuPopup)
- self.popupMenu.show_all()
- def doquit(self, widget=None, data=None):
- gtk.main_quit()
- def run(self):
- gtk.main()
- def create_window(self):
- self.window = gtk.Window() #gtk.WINDOW_POPUP) ## gtk.WINDOW_TOPLEVEL)
- self.window.connect("destroy", self.doquit)
- #~ self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
- self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
- self.window.add_events(gtk.gdk.FOCUS_CHANGE_MASK)
- self.window.connect("focus-out-event", self.lost_focus)
- self.window.connect("key-press-event", self.onkeypress)
- self.window.stick()
- self.window.set_decorated(False)
- self.window.set_keep_below(False)
- self.window.set_keep_above(True)
- self.window.set_resizable(True)
- self.window.set_border_width(2)
- self.window.set_app_paintable(True)
- self.frame = gtk.Frame()
- self.frame.show()
- self.frame.set_size_request(MENU_WIDTH,-1)
- self.nbook = gtk.Notebook()
- self.nbook.show()
- self.nbook.set_tab_pos(gtk.POS_LEFT)
- self.nbook.set_border_width(2)
- self.frame.add(self.nbook)
- self.window.add(self.frame)
- m = parse_desktop_dir()
- m_tmp = []
- for cat in m:
- m_tmp.append(cat)
- m_tmp.sort()
- self.cat_but = []
- self.cur_pos = 0
- self.cat_visible = True
- for cat in m_tmp:
- bBox = gtk.VBox()
- bBox.show()
- bBox.set_spacing(4)
- bBox.set_border_width(2)
- scrolled = gtk.ScrolledWindow()
- scrolled.show()
- scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- scrolled.add_with_viewport(bBox)
- label = gtk.Label(cat[0].upper() + cat[1:])
- label.show()
- label.set_alignment(0, 1)
- self.nbook.append_page(scrolled, label)
- for item in m[cat]:
- (cmd, icon, text) = item
- widget = gtk.Button() # item.label)
- widget.set_relief(gtk.RELIEF_NONE)
- widget.set_border_width(0)
- widget.set_focus_on_click(False)
- #~ widget.set_property('can-focus', False)
- image = gtk.Image()
- image.show()
- image.set_size_request(24,24)
- label = gtk.Label(text)
- label.show()
- label.set_alignment(0.2, 1)
- align = gtk.Alignment(1, 0, 0.5, 0.5)
- align.show()
- align.add(label)
- box = gtk.HBox(False, 4)
- box.show()
- box.pack_start(image, False, False)
- box.pack_start(align, False, False)
- widget.add(box)
- try:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon, 24, 24)
- except:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size('/usr/share/pixmaps/debian-logo.png', 24, 24)
- image.set_from_pixbuf(pixbuf)
- image.show()
- widget.connect("button-release-event", self.ExecuteAction, cmd)
- bBox.pack_start(widget,False,False)
- widget.show()
- def ExecuteAction(self, widget, event, cmd):
- self.focus_check = False
- exec_cmd(cmd)
- self.doquit()
- def toggle_hide(self, widget=None, event=None):
- if self.hide_me:
- self.hide_me = False
- self.show_menu(self.mode)
- self.window.show()
- self.focus_check = True
- else:
- self.hide_me = True
- self.focus_check = False
- self.window.hide()
- def show_menu(self, mode=None):
- screen_width, screen_height = gtk.gdk.screen_width(), gtk.gdk.screen_height()
- rootwin = self.window.get_screen().get_root_window()
- w_width , w_height = self.window.get_size()
- x, y, mods = rootwin.get_pointer()
- if x + MENU_WIDTH > screen_width:
- x = screen_width - MENU_WIDTH
- if y + w_height > screen_height:
- y = screen_height - w_height
- #to move the menu adjust the x= and y=
- #this should not be commented out
- self.window.move(x=10, y=40)
- def lost_focus(self, widget, event):
- if self.focus_check:
- self.doquit()
- def onkeypress(self, widget, event):
- if event.keyval == gtk.keysyms.Escape:
- self.doquit()
- def status_icon_popup(self, widget, button, active_time):
- self.popupMenu.popup(None, None, None, 1, 0)
- def callback_signal(self):
- #~ print "callback_signal .."
- self.mode = "mouse"
- self.toggle_hide()
- self.mode = None
- ##--
- global g_menu
- def SigUSR1Handler(signum, frame):
- """ grab signal to reload config """
- # kill -10 <adesk-menu pid>
- global g_menu
- g_menu.callback_signal()
- return
- def save_pid():
- home = os.environ['HOME']
- pid_file = "%s/.config/adesk-menu/pid" % home
- pid = os.getpid()
- print "PID = %s" % pid
- if not os.path.exists("%s/.config/adesk-menu" % home):
- os.makedirs("%s/.config/adesk-menu" % home)
- f = open(pid_file,'w')
- f.write('%s' % pid)
- f.close()
- print "PID saved to %s" % pid_file
- if __name__ == "__main__":
- if len(sys.argv) == 2:
- if sys.argv[1] == '-s':
- write_config()
- elif sys.argv[1] == '-t':
- cmd = "kill -10 `cat ~/.config/adesk-menu/pid`"
- os.system(cmd)
- else:
- print "Unknow option .."
- print "Usage : adesk-menu [-s|-t]"
- print " -s : save menu list ( ~/.config/adesk-menu/config )"
- print " -t : show menu ( cursor position )"
- else:
- global g_menu
- signal.signal(signal.SIGUSR1, SigUSR1Handler)
- save_pid()
- ## need to change directory
- SRC_PATH = os.path.dirname(os.path.realpath( __file__ ))
- os.chdir(SRC_PATH)
- g_menu = Menu()
- # change directory to Home
- os.chdir(os.getenv('HOME'))
- g_menu.hide_me = False
- g_menu.show_menu(g_menu.mode)
- g_menu.window.show()
- g_menu.focus_check = True
- g_menu.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement