Faster init, fixed memory leak, faster apt search, more results, fixed process name, fixed theme change events

This commit is contained in:
Clement Lefebvre 2010-10-26 12:02:47 +01:00
parent 396cda23b5
commit 294618b770
4 changed files with 103 additions and 72 deletions

12
debian/changelog vendored
View File

@ -1,3 +1,15 @@
mintmenu (5.1.5) julia; urgency=low
* Faster initialization
* Fixed memory leak
* Faster APT search
* APT search results now include packages which summary or description match the keywords
* APT search results: packages which name match the keywords are placed at the top of the list
* Fixed process name on 64-bit platforms
* Menu now properly redraws itself when theme is changed
-- Clement Lefebvre <root@linuxmint.com> Tue, 26 Oct 2010 12:00:00 +0000
mintmenu (5.1.4) julia; urgency=low mintmenu (5.1.4) julia; urgency=low
* Unicode support in GTK bookmarks * Unicode support in GTK bookmarks

View File

@ -6,6 +6,7 @@ try:
import gtk.glade import gtk.glade
import pango import pango
import os import os
import commands
import gnomeapplet import gnomeapplet
import gettext import gettext
import gnomevfs import gnomevfs
@ -29,13 +30,15 @@ except Exception, cause:
pass pass
# Rename the process # Rename the process
try: architecture = commands.getoutput("uname -a")
if (architecture.find("x86_64") >= 0):
import ctypes
libc = ctypes.CDLL('libc.so.6')
libc.prctl(15, 'mintmenu', 0, 0, 0)
else:
import dl import dl
libc = dl.open( "/lib/libc.so.6" ) libc = dl.open('/lib/libc.so.6')
libc.call( "prctl", 15, "mintmenu", 0, 0, 0 ) libc.call('prctl', 15, 'mintmenu', 0, 0, 0)
libc.close()
except ImportError:
pass
# i18n # i18n
gettext.install("mintmenu", "/usr/share/linuxmint/locale") gettext.install("mintmenu", "/usr/share/linuxmint/locale")
@ -93,7 +96,6 @@ class MainWindow( object ):
wTree.signal_autoconnect( dic ) wTree.signal_autoconnect( dic )
self.gconf = EasyGConf( "/apps/mintMenu/" ) self.gconf = EasyGConf( "/apps/mintMenu/" )
self.gconftheme = EasyGConf( "/desktop/gnome/interface/" )
self.getSetGconfEntries() self.getSetGconfEntries()
self.SetupMintMenuBorder() self.SetupMintMenuBorder()
@ -108,7 +110,6 @@ class MainWindow( object ):
self.PopulatePlugins(); self.PopulatePlugins();
self.gconf.notifyAdd( "plugins_list", self.RegenPlugins ) self.gconf.notifyAdd( "plugins_list", self.RegenPlugins )
self.gconftheme.notifyAdd( "gtk_theme", self.RegenPlugins )
self.gconf.notifyAdd( "start_with_favorites", self.toggleStartWithFavorites ) self.gconf.notifyAdd( "start_with_favorites", self.toggleStartWithFavorites )
self.gconf.notifyAdd( "/apps/panel/global/tooltips_enabled", self.toggleTooltipsEnabled ) self.gconf.notifyAdd( "/apps/panel/global/tooltips_enabled", self.toggleTooltipsEnabled )
@ -508,7 +509,8 @@ class MenuWin( object ):
self.gconf.notifyAdd( "applet_icon_size", self.gconfEntriesChanged ) self.gconf.notifyAdd( "applet_icon_size", self.gconfEntriesChanged )
self.getGconfEntries() self.getGconfEntries()
self.gconftheme = EasyGConf( "/desktop/gnome/interface/" )
self.gconftheme.notifyAdd( "gtk_theme", self.changeTheme )
self.createPanelButton() self.createPanelButton()

View File

@ -25,8 +25,6 @@ from filemonitor import monitor as filemonitor
#import xdg.Menu #import xdg.Menu
import gmenu import gmenu
import apt
from user import home from user import home
gtk.gdk.threads_init() gtk.gdk.threads_init()
@ -34,6 +32,11 @@ gtk.gdk.threads_init()
# i18n # i18n
gettext.install("mintmenu", "/usr/share/linuxmint/locale") gettext.install("mintmenu", "/usr/share/linuxmint/locale")
class PackageDescriptor():
def __init__(self, name, summary, description):
self.name = name
self.summary = summary
self.description = description
def print_timing(func): def print_timing(func):
def wrapper(*arg): def wrapper(*arg):
@ -312,20 +315,18 @@ class pluginclass( object ):
#for f in mymenu.directory.AppDirs: #for f in mymenu.directory.AppDirs:
# self.menuFileMonitors.append( filemonitor.addMonitor(f, self.onMenuChanged, mymenu.directory.Filename ) ) # self.menuFileMonitors.append( filemonitor.addMonitor(f, self.onMenuChanged, mymenu.directory.Filename ) )
self.apt_cache = None self.refresh_apt_cache()
if self.useAPT:
try:
self.apt_cache = apt.Cache()
except Exception, detail:
print "Could not initialize APT cache"
pass
self.suggestions = [] self.suggestions = []
self.current_suggestion = None self.current_suggestion = None
self.get_panel() self.get_panel()
self.wTree.get_widget("searchButton").connect( "button-release-event", self.searchPopup ) self.wTree.get_widget("searchButton").connect( "button-release-event", self.searchPopup )
def refresh_apt_cache(self):
if self.useAPT:
os.system("mkdir -p %s/.linuxmint/mintMenu/" % home)
os.system("/usr/lib/linuxmint/mintMenu/plugins/get_apt_cache.py > %s/.linuxmint/mintMenu/apt.cache &" % home)
def get_panel(self): def get_panel(self):
self.panel = None self.panel = None
self.panel_position = 0 self.panel_position = 0
@ -415,16 +416,7 @@ class pluginclass( object ):
def switchAPTUsage( self, client, connection_id, entry, args ): def switchAPTUsage( self, client, connection_id, entry, args ):
self.useAPT = entry.get_value().get_bool() self.useAPT = entry.get_value().get_bool()
if self.useAPT: self.refresh_apt_cache()
try:
apt_cache = apt.Cache()
if apt_cache != None:
self.apt_cache = apt_cache
except Exception, detail:
print "Could not refresh APT cache"
pass
else:
self.apt_cache = None
def changeShowApplicationComments( self, client, connection_id, entry, args ): def changeShowApplicationComments( self, client, connection_id, entry, args ):
self.showapplicationcomments = entry.get_value().get_bool() self.showapplicationcomments = entry.get_value().get_bool()
@ -450,16 +442,7 @@ class pluginclass( object ):
self.favoritesPositionOnGrid( fav ) self.favoritesPositionOnGrid( fav )
def RegenPlugin( self, *args, **kargs ): def RegenPlugin( self, *args, **kargs ):
if self.useAPT: self.refresh_apt_cache()
try:
apt_cache = apt.Cache()
if apt_cache != None:
self.apt_cache = apt_cache
except Exception, detail:
print "Could not refresh APT cache"
pass
else:
self.apt_cache = None
# save old config - this is necessary because the app will notified when it sets the default values and you don't want the to reload itself several times # save old config - this is necessary because the app will notified when it sets the default values and you don't want the to reload itself several times
oldcategories_mouse_over = self.categories_mouse_over oldcategories_mouse_over = self.categories_mouse_over
@ -650,7 +633,7 @@ class pluginclass( object ):
#self.applicationsBox.add(self.last_separator) #self.applicationsBox.add(self.last_separator)
#self.suggestions.append(self.last_separator) #self.suggestions.append(self.last_separator)
def add_apt_filter_results(self, cache, keyword): def add_apt_filter_results(self, keyword):
try: try:
# Wait to see if the keyword has changed.. before doing anything # Wait to see if the keyword has changed.. before doing anything
time.sleep(0.3) time.sleep(0.3)
@ -662,25 +645,42 @@ class pluginclass( object ):
gtk.gdk.threads_leave() gtk.gdk.threads_leave()
if keyword != current_keyword: if keyword != current_keyword:
return return
found_packages = [] found_packages = []
found_in_name = []
found_elsewhere = []
keywords = keyword.split(" ") keywords = keyword.split(" ")
i = 0 command = "cat %(home)s/.linuxmint/mintMenu/apt.cache" % {'home':home}
if cache is not None: for word in keywords:
for pkg in cache: command = "%(command)s | grep %(word)s" % {'command':command, 'word':word}
i = i +1 pkgs = commands.getoutput(command)
if i%1000==0: pkgs = pkgs.split("\n")
time.sleep(0.01) for pkg in pkgs:
values = string.split(pkg, "###")
if len(values) == 4:
status = values[0]
if (status == "ERROR"):
print "Could not refresh APT cache"
elif (status == "CACHE"):
name = values[1]
summary = values[2]
description = values[3].replace("~~~", "\n")
package = PackageDescriptor(name, summary, description)
#See if all keywords are in the name (so we put these results at the top of the list)
some_found = False some_found = False
some_not_found = False some_not_found = False
for word in keywords: for word in keywords:
if word in pkg.name: if word in package.name:
some_found = True some_found = True
else: else:
some_not_found = True some_not_found = True
if some_found and not some_not_found: if some_found and not some_not_found:
found_packages.append(pkg) found_in_name.append(package)
else:
found_elsewhere.append(package)
else:
print "Invalid status code: " + status
found_packages.extend(found_in_name)
found_packages.extend(found_elsewhere)
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
if keyword == self.searchEntry.get_text() and len(found_packages) > 0: if keyword == self.searchEntry.get_text() and len(found_packages) > 0:
@ -700,12 +700,12 @@ class pluginclass( object ):
suggestionButton = SuggestionButton(gtk.STOCK_ADD, self.iconSize, "") suggestionButton = SuggestionButton(gtk.STOCK_ADD, self.iconSize, "")
suggestionButton.connect("clicked", self.apturl_install, pkg.name) suggestionButton.connect("clicked", self.apturl_install, pkg.name)
suggestionButton.set_text(_("Install package '%s'") % name) suggestionButton.set_text(_("Install package '%s'") % name)
suggestionButton.set_tooltip_text("%s\n\n%s\n\n%s" % (pkg.name, pkg.summary.capitalize(), pkg.description)) suggestionButton.set_tooltip_text("%s\n\n%s\n\n%s" % (pkg.name, pkg.summary, pkg.description))
suggestionButton.set_icon_size(self.iconSize) suggestionButton.set_icon_size(self.iconSize)
self.applicationsBox.add(suggestionButton) self.applicationsBox.add(suggestionButton)
self.suggestions.append(suggestionButton) self.suggestions.append(suggestionButton)
if cache != self.current_results: #if cache != self.current_results:
self.current_results.append(pkg) # self.current_results.append(pkg)
finally: finally:
gtk.gdk.threads_leave() gtk.gdk.threads_leave()
@ -720,6 +720,7 @@ class pluginclass( object ):
except Exception, detail: except Exception, detail:
print detail print detail
def add_apt_filter_results_sync(self, cache, keyword): def add_apt_filter_results_sync(self, cache, keyword):
try: try:
found_packages = [] found_packages = []
@ -790,15 +791,15 @@ class pluginclass( object ):
if self.current_suggestion is not None and self.current_suggestion in text: if self.current_suggestion is not None and self.current_suggestion in text:
# We're restricting our search... # We're restricting our search...
self.add_search_suggestions(text) self.add_search_suggestions(text)
if (len(self.current_results) > 0): #if (len(self.current_results) > 0):
self.add_apt_filter_results_sync(self.current_results, text) #self.add_apt_filter_results_sync(self.current_results, text)
else: #else:
thr = threading.Thread(name="mint-menu-apt-filter", group=None, target=self.add_apt_filter_results, args=(self.apt_cache, text), kwargs={}) thr = threading.Thread(name="mint-menu-apt-filter", group=None, target=self.add_apt_filter_results, args=([text]), kwargs={})
thr.start() thr.start()
else: else:
self.current_results = [] self.current_results = []
self.add_search_suggestions(text) self.add_search_suggestions(text)
thr = threading.Thread(name="mint-menu-apt-filter", group=None, target=self.add_apt_filter_results, args=(self.apt_cache, text), kwargs={}) thr = threading.Thread(name="mint-menu-apt-filter", group=None, target=self.add_apt_filter_results, args=([text]), kwargs={})
thr.start() thr.start()
self.current_suggestion = text self.current_suggestion = text
else: else:

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
import apt, sys
try:
cache = apt.Cache()
for pkg in cache:
if not pkg.is_installed:
name = pkg.name
summary = pkg.candidate.summary.capitalize()
description = pkg.candidate.description.replace("\n", "~~~")
print "CACHE" + "###" + str(name) + "###" + str(summary) + "###" + str(description)
except Exception, detail:
print "ERROR###ERROR###ERROR###ERROR"
print detail
sys.exit(1)