SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#1 2011-07-25 16:05:53

slipshot
#! CrunchBanger
Registered: 2009-05-13
Posts: 171

My little adeskmenu project.

I found an old version of adeskmenu on launchpad and figured it would be nice to take advantage of tint2's new launcher feature. So with a help from MoD from silver.irc we re-worked the script to just open the menu when clicked. Here is a screenshot.

desktophb.png

All you need is the single page menu script and a .desktop pointing to it.
Here is the code for the menu script.

#!/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()

and here is the .desktop file.

[Desktop Entry]
Type=Application
Name=menu
Exec=/usr/bin/adesk-menu2
Icon=/usr/share/pixmaps/debian-logo.png

Make the menu script executable and move it to /usr/bin "sudo chmod +x adesk-menu2 && sudo mv adesk-menu2 /usr/bin/"
After that put the .desktop file somewhere like ~/.scripts and point tint2 to it. After that you should be good to go. By default the menu opens in the top left corner of the screen. If you need to adjust where
the menu opens edit line 369 in the script.

Offline

Help fund CrunchBang, donate to the project!

#2 2011-08-02 19:42:07

Sector11
77345 ¡#
From: SR11 Cockpit
Registered: 2010-05-05
Posts: 12,827
Website

Re: My little adeskmenu project.

Dumb question:  Is adeskmenu different from adeskbar?

Looks nice what version of tint2 is that?

Can you show me the tint2 config?

Last edited by Sector11 (2011-08-02 19:42:29)

Offline

#3 2011-08-02 19:54:43

jeffreyC
#! Die Hard
Registered: 2010-09-02
Posts: 596

Re: My little adeskmenu project.

@ Sector11
ADeskmenu is the menu for ADeskbar, although it will work independently.


There's a reason you separate military and the police. One fights the enemies of the state, the other serves and protects the people. When the military becomes both, then the enemies of the state tend to become the people.

Offline

#4 2011-08-02 20:12:27

Sector11
77345 ¡#
From: SR11 Cockpit
Registered: 2010-05-05
Posts: 12,827
Website

Re: My little adeskmenu project.

jeffreyC wrote:

@ Sector11
ADeskmenu is the menu for ADeskbar, although it will work independently.

When one downloads ADeskbar the "ADeskmenu" is with it?

I don't know I don't use it but I have a link to ADeskbar on Conky PitStop as ADComp is gone and some, ie mrpeach for one, have come up with scripts for using ADeskbar interactive with conky.

Do I need anything else? I'm collecting any and all links of what is available out there as I find them.

Offline

#5 2011-08-02 20:14:26

jeffreyC
#! Die Hard
Registered: 2010-09-02
Posts: 596

Re: My little adeskmenu project.

They are separate
See my post;

             http://crunchbanglinux.org/forums/post/135076/#p135076

what I found yesterday.


There's a reason you separate military and the police. One fights the enemies of the state, the other serves and protects the people. When the military becomes both, then the enemies of the state tend to become the people.

Offline

#6 2011-08-02 23:00:08

Sector11
77345 ¡#
From: SR11 Cockpit
Registered: 2010-05-05
Posts: 12,827
Website

Re: My little adeskmenu project.

jeffreyC wrote:

They are separate
See my post;

             http://crunchbanglinux.org/forums/post/135076/#p135076

what I found yesterday.

I saw that but forgot about it, I'll like to that site as well as the first post here for the "menu".

Just too good to loose.

Offline

#7 2011-08-05 23:12:00

VastOne
#! Ranger
From: V-Ger
Registered: 2011-04-26
Posts: 10,163
Website

Re: My little adeskmenu project.

@ slipshot..

Nice ... 

What dock is that you are using on the bottom of the screenie?

I made a width adjustment along with where I wanted it (x,y ) and here is a screenie

screenshot-08052011-061917pm.png

Last edited by VastOne (2011-08-05 23:21:21)


VSIDO | Words That Build Or Destroy

We do not run from challenges, they become new innovations within VSIDO!

Offline

#8 2011-08-08 06:22:19

slipshot
#! CrunchBanger
Registered: 2009-05-13
Posts: 171

Re: My little adeskmenu project.

Sorry i aint posted. life gets a little crazy sometimes.

Sector11 Wrote:
Looks nice what version of tint2 is that?

Can you show me the tint2 config?

Yeah. im running tint2 version 0.11-svn, its in the crunchbang repos.
Here is my tint2 config. I found it on the 'My tint2 config' thread and tweaked it to suit my needs.

# Tint2 config file
# Generated by tintwizard (http://code.google.com/p/tintwizard/)
# For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure

# Background definitions
# ID 1
rounded = 2
border_width = 1
background_color = #222222 50
border_color = #A0A0A0 50

# ID 2
rounded = 1
border_width = 1
background_color = #888888 60
border_color = #FFFFFF 40

# ID 3
rounded = 1
border_width = 1
background_color = #888888 20
border_color = #FFFFFF 20

# ID 4
rounded = 1
border_width = 1
background_color = #888888 20
border_color = #ED2323 60

# ID 5
rounded = 2
border_width = 1
background_color = #222222 40
border_color = #FFFFFF 20

# ID 6
rounded = 2
border_width = 1
background_color = #222222 60
border_color = #FFFFFF 50

# ID 7
rounded = 3
border_width = 1
background_color = #222222 48
border_color = #FFFFFF 40

# ID 8
rounded = 1
border_width = 1
background_color = #888888 20
border_color = #888888 20

# Panel
panel_monitor = all
panel_position = top center horizontal
panel_items = LTSCB
panel_size = 98% 40
panel_margin = 0 0
panel_padding = 6 2 4
panel_dock = 0
wm_menu = 1
panel_layer = top
panel_background_id = 1

# Panel Autohide
autohide = 0
autohide_show_timeout = 0.3
autohide_hide_timeout = 1.5
autohide_height = 6
strut_policy = follow_size

# Taskbar
taskbar_mode = multi_desktop
taskbar_padding = 6 0 6
taskbar_background_id = 5
taskbar_active_background_id = 6
taskbar_name = 1
taskbar_name_background_id = 0
taskbar_name_active_background_id = 0
taskbar_name_font = sans 10
taskbar_name_font_color = #9F9F9F 100
taskbar_name_active_font_color = #FFFFFF 100

# Tasks
urgent_nb_of_blink = 20
task_icon = 1
task_text = 0
task_centered = 1
task_maximum_size = 40 40
task_padding = 6 3
task_background_id = 3
task_active_background_id = 2
task_urgent_background_id = 4
task_iconified_background_id = 0

# Task Icons
task_icon_asb = 90 0 0
task_active_icon_asb = 100 0 0
task_urgent_icon_asb = 100 0 0
task_iconified_icon_asb = 90 0 0

# Fonts
task_font = kroeger 06_55 6
task_font_color = #222222 100
task_active_font_color = #000000 100
task_urgent_font_color = #000000 100
task_iconified_font_color = #222222 100
font_shadow = 0

# Launcher
launcher_padding = 8 4 4
launcher_background_id = 0
launcher_icon_size = 24
# Specify icon theme names with launcher_icon_theme. 
# if you have an XSETTINGS manager running (like xfsettingsd), tint2 will follow your current theme.
launcher_icon_theme = gnome
# Each launcher_item_app must be a full path to a .desktop file
launcher_item_app = /home/slipshot/.local/share/applications/menu.desktop
launcher_item_app = /usr/share/applications/Thunar.desktop
launcher_item_app = /usr/share/applications/terminator.desktop

# System Tray
systray = 1
systray_padding = 4 4 5
systray_sort = ascending
systray_background_id = 0
systray_icon_size = 20
systray_icon_asb = 100 0 0

# Tooltips
tooltip = 1
tooltip_padding = 4 2
tooltip_show_timeout = 0.3
tooltip_hide_timeout = 0.3
tooltip_background_id = 7
tooltip_font = sans normal 8.5
tooltip_font_color = #FFFFFF 70

tooltip_padding = 2 2
tooltip_show_timeout = 0.0
tooltip_hide_timeout = 0.0
tooltip_background_id = 1
tooltip_font_color = #FFFFFF 70
tooltip_font = sans normal 7.5

# Mouse
mouse_middle = none
mouse_right = close
mouse_scroll_up = toggle
mouse_scroll_down = iconify

# Clock
time1_format = %I:%M
time1_font = Sans 11
time2_format = %A %b %d
time2_font = Sans 8.5
clock_font_color = #FFFFFF 100
clock_padding = 2 0
clock_background_id = 0
clock_lclick_command = gsimplecal

# Battery
#battery = 1
#battery_low_status = 20
#battery_low_cmd = notify-send "battery low"
#battery_hide = 96
#bat1_font = Sans 10
#bat2_font = Sans 8
#battery_font_color = #FFFFFF 100
#battery_padding = 2 0
#battery_background_id = 0

# End of config

and

VastOne Wrote:
What dock is that you are using on the bottom of the screenie?

It is ADeskbar 4.2

If anyone knows any python and can make the script run better are more than welcome to do so. Might be fun to tinker with.

Offline

#9 2011-08-08 06:31:54

rstrcogburn
CrunchRanger
From: New Mexico
Registered: 2010-06-12
Posts: 1,941
Website

Re: My little adeskmenu project.

whoah.. gonna try this out soon.  Adcomp must be proud.


That hawk just kept flying! -Ben Lilly

Offline

#10 2011-08-08 22:44:06

Sector11
77345 ¡#
From: SR11 Cockpit
Registered: 2010-05-05
Posts: 12,827
Website

Re: My little adeskmenu project.

slipshot wrote:

Sorry i aint posted. life gets a little crazy sometimes.

Happens to the best of us, I blame my mind - it's going!
Or as my friend use to say:  My forgetter is getting better!

Just my looking at yours, I fixed a problem I was having with mine regarding the launcher.

Thank you.

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.

Debian Logo