mintmenu/usr/lib/linuxmint/mintMenu/mintMenu.py

857 lines
34 KiB
Python
Raw Normal View History

2009-07-27 11:45:34 +01:00
#!/usr/bin/env python
2013-03-01 16:56:54 +00:00
import gi
gi.require_version("Gtk", "2.0")
from gi.repository import Gtk, GdkPixbuf, Gdk, GObject
2013-03-01 16:56:54 +00:00
from gi.repository import MatePanelApplet
2013-03-04 15:01:20 +00:00
from gi.repository import Gio
2013-03-01 16:56:54 +00:00
2009-07-27 11:45:34 +01:00
try:
2010-09-13 12:10:43 +01:00
import sys
2013-03-04 12:57:17 +00:00
from gi.repository import Pango
2010-09-13 12:10:43 +01:00
import os
import commands
2010-09-13 12:10:43 +01:00
import gettext
import traceback
import time
import gc
2013-03-06 02:56:17 +00:00
import ctypes
from ctypes import *
import capi
2010-09-13 12:10:43 +01:00
import xdg.Config
2013-03-09 19:26:22 +00:00
import keybinding
import pointerMonitor
2009-07-27 11:45:34 +01:00
except Exception, e:
2010-09-13 12:10:43 +01:00
print e
sys.exit( 1 )
2009-07-27 11:45:34 +01:00
GObject.threads_init()
2013-03-06 02:56:17 +00:00
gtk = CDLL("libgtk-x11-2.0.so.0")
gdk = CDLL("libgdk-x11-2.0.so.0")
2009-07-27 11:45:34 +01:00
# Rename the process
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:
2010-09-13 12:10:43 +01:00
import dl
if os.path.exists('/lib/libc.so.6'):
libc = dl.open('/lib/libc.so.6')
libc.call('prctl', 15, 'mintmenu', 0, 0, 0)
elif os.path.exists('/lib/i386-linux-gnu/libc.so.6'):
libc = dl.open('/lib/i386-linux-gnu/libc.so.6')
libc.call('prctl', 15, 'mintmenu', 0, 0, 0)
2009-07-27 11:45:34 +01:00
2009-07-29 21:50:43 +01:00
# i18n
2009-11-03 11:29:52 +00:00
gettext.install("mintmenu", "/usr/share/linuxmint/locale")
2009-07-27 11:45:34 +01:00
2009-07-29 21:50:43 +01:00
NAME = _("Menu")
2009-07-27 11:45:34 +01:00
PATH = os.path.abspath( os.path.dirname( sys.argv[0] ) )
2009-07-27 11:45:34 +01:00
sys.path.append( os.path.join( PATH , "plugins") )
windowManager = os.getenv("DESKTOP_SESSION")
if not windowManager:
windowManager = "MATE"
xdg.Config.setWindowManager( windowManager.upper() )
2009-07-27 11:45:34 +01:00
2013-03-07 03:08:11 +00:00
from execute import *
2009-07-27 11:45:34 +01:00
class MainWindow( object ):
2010-09-13 12:10:43 +01:00
"""This is the main class for the application"""
def __init__( self, toggleButton, settings, keybinder ):
2013-03-04 15:01:20 +00:00
self.settings = settings
self.keybinder = keybinder
2010-09-13 12:10:43 +01:00
self.path = PATH
sys.path.append( os.path.join( self.path, "plugins") )
self.detect_desktop_environment()
2013-03-04 15:01:20 +00:00
self.icon = "/usr/lib/linuxmint/mintMenu/visualisation-logo.png"
2010-09-13 12:10:43 +01:00
self.toggle = toggleButton
2013-03-04 16:50:14 +00:00
# Load UI file and extract widgets
builder = Gtk.Builder()
2013-05-21 03:07:56 +01:00
builder.add_from_file(os.path.join( self.path, "mintMenu.glade" ))
2013-03-04 16:50:14 +00:00
self.window = builder.get_object( "mainWindow" )
self.paneholder = builder.get_object( "paneholder" )
self.border = builder.get_object( "border" )
builder.connect_signals(self)
2010-09-13 12:10:43 +01:00
self.panesToColor = [ ]
self.headingsToColor = [ ]
self.window.connect( "key-press-event", self.onKeyPress )
self.window.connect( "focus-in-event", self.onFocusIn )
self.loseFocusId = self.window.connect( "focus-out-event", self.onFocusOut )
2010-09-13 12:10:43 +01:00
self.window.stick()
plugindir = os.path.join( os.path.expanduser( "~" ), ".linuxmint/mintMenu/plugins" )
sys.path.append( plugindir )
self.panelSettings = Gio.Settings.new("org.mate.panel")
self.panelSettings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
2010-09-13 12:10:43 +01:00
2013-03-09 16:43:54 +00:00
self.settings.connect( "changed::plugins-list", self.RegenPlugins )
self.settings.connect( "changed::start-with-favorites", self.toggleStartWithFavorites )
self.settings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
self.settings.connect( "changed::use-custom-color", self.toggleUseCustomColor )
self.settings.connect( "changed::custom-border-color", self.toggleCustomBorderColor )
self.settings.connect( "changed::custom-heading-color", self.toggleCustomHeadingColor )
self.settings.connect( "changed::custom-color", self.toggleCustomBackgroundColor )
self.settings.connect( "changed::border-width", self.toggleBorderWidth )
2013-03-04 15:01:20 +00:00
self.settings.connect( "changed::opacity", self.toggleOpacity )
self.getSetGSettingEntries()
self.tooltips = Gtk.Tooltips()
if self.globalEnableTooltips and self.enableTooltips:
self.tooltips.enable()
else:
self.tooltips.disable()
self.PopulatePlugins();
self.firstTime = True;
2010-09-13 12:10:43 +01:00
2013-03-04 16:50:14 +00:00
def on_window1_destroy (self, widget, data=None):
2013-03-04 12:57:17 +00:00
Gtk.main_quit()
2010-09-13 12:10:43 +01:00
sys.exit(0)
def wakePlugins( self ):
# Call each plugin and let them know we're showing up
for plugin in self.plugins.values():
2013-05-21 16:24:01 +01:00
if hasattr( plugin, "wake" ):
2010-09-13 12:10:43 +01:00
plugin.wake()
2013-03-09 00:31:58 +00:00
def toggleTooltipsEnabled( self, settings, key, args = None):
if key == "tooltips-enabled":
self.globalEnableTooltips = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
else:
2013-03-09 00:31:58 +00:00
self.enableTooltips = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
if self.globalEnableTooltips and self.enableTooltips:
self.tooltips.enable()
else:
self.tooltips.disable()
2013-03-09 00:31:58 +00:00
def toggleStartWithFavorites( self, settings, key, args = None ):
self.startWithFavorites = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
2013-03-09 00:31:58 +00:00
def toggleBorderWidth( self, settings, key, args = None ):
self.borderwidth = settings.get_int(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
2013-03-09 00:31:58 +00:00
def toggleOpacity( self, settings, key, args = None ):
self.opacity = settings.get_int(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuOpacity()
2013-03-09 00:31:58 +00:00
def toggleUseCustomColor( self, settings, key, args = None ):
self.usecustomcolor = settings.get_boolean(key)
self.loadTheme()
2010-09-13 12:10:43 +01:00
2013-03-09 00:31:58 +00:00
def toggleCustomBorderColor( self, settings, key, args = None ):
self.custombordercolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
2013-03-09 00:31:58 +00:00
def toggleCustomBackgroundColor( self, settings, key, args = None):
self.customcolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetPaneColors( self.panesToColor )
2013-03-09 00:31:58 +00:00
def toggleCustomHeadingColor( self, settings, key, args = None ):
self.customheadingcolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetHeadingStyle( self.headingsToColor )
2013-03-09 02:29:49 +00:00
def getSetGSettingEntries( self ):
2010-09-13 12:10:43 +01:00
self.dottedfile = os.path.join( self.path, "dotted.png")
2013-03-04 15:01:20 +00:00
self.pluginlist = self.settings.get_strv( "plugins-list" )
self.usecustomcolor = self.settings.get_boolean( "use-custom-color" )
self.customcolor = self.settings.get_string( "custom-color" )
self.customheadingcolor = self.settings.get_string( "custom-heading-color" )
self.custombordercolor = self.settings.get_string( "custom-border-color" )
self.borderwidth = self.settings.get_int( "border-width" )
self.opacity = self.settings.get_int( "opacity" )
self.offset = self.settings.get_int( "offset" )
self.enableTooltips = self.settings.get_boolean( "tooltips-enabled" )
self.startWithFavorites = self.settings.get_boolean( "start-with-favorites" )
self.globalEnableTooltips = self.panelSettings.get_boolean( "tooltips-enabled" )
2010-09-13 12:10:43 +01:00
def SetupMintMenuBorder( self, defaultStyle = None ):
2013-03-09 00:31:58 +00:00
if self.usecustomcolor:
self.window.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.custombordercolor ) )
elif defaultStyle is not None:
self.window.modify_bg( Gtk.StateType.NORMAL, defaultStyle.lookup_color('bg_color')[1] )
2010-09-13 12:10:43 +01:00
self.border.set_padding( self.borderwidth, self.borderwidth, self.borderwidth, self.borderwidth )
def SetupMintMenuOpacity( self ):
print "Opacity is: " + str(self.opacity)
opacity = float(self.opacity) / float(100)
print "Setting opacity to: " + str(opacity)
self.window.set_opacity(opacity)
def detect_desktop_environment (self):
self.de = "mate"
try:
de = os.environ["DESKTOP_SESSION"]
if de in ["gnome", "gnome-shell", "mate", "kde", "xfce"]:
self.de = de
2012-06-28 13:26:15 +01:00
else:
if os.path.exists("/usr/bin/caja"):
self.de = "mate"
elif os.path.exists("/usr/bin/thunar"):
self.de = "xfce"
except Exception, detail:
print detail
2010-09-13 12:10:43 +01:00
def PopulatePlugins( self ):
self.panesToColor = [ ]
self.headingsToColor = [ ]
start = time.time()
2013-03-04 12:57:17 +00:00
PluginPane = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
PluginPane.show()
2013-03-04 12:57:17 +00:00
PaneLadder = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
PluginPane.add( PaneLadder )
2013-03-04 12:57:17 +00:00
ImageBox = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
ImageBox.show()
self.panesToColor.extend( [ PluginPane, ImageBox ] )
2010-09-13 12:10:43 +01:00
2013-03-04 12:57:17 +00:00
seperatorImage = GdkPixbuf.Pixbuf.new_from_file( self.dottedfile )
2010-09-13 12:10:43 +01:00
self.plugins = {}
2013-03-04 16:50:14 +00:00
for plugin in self.pluginlist:
2010-09-13 12:10:43 +01:00
if plugin in self.plugins:
print u"Duplicate plugin in list: ", plugin
continue
if plugin != "newpane":
try:
X = __import__( plugin )
# If no parameter passed to plugin it is autonomous
if X.pluginclass.__init__.func_code.co_argcount == 1:
MyPlugin = X.pluginclass()
else:
# pass mintMenu and togglebutton instance so that the plugin can use it
MyPlugin = X.pluginclass( self, self.toggle, self.de )
2010-09-13 12:10:43 +01:00
if not MyPlugin.icon:
MyPlugin.icon = "mate-logo-icon.png"
2010-09-13 12:10:43 +01:00
#if hasattr( MyPlugin, "hideseparator" ) and not MyPlugin.hideseparator:
2013-03-04 12:57:17 +00:00
# Image1 = Gtk.Image()
2010-09-13 12:10:43 +01:00
# Image1.set_from_pixbuf( seperatorImage )
# if not ImageBox.get_child():
# ImageBox.add( Image1 )
# Image1.show()
#print u"Loading plugin '" + plugin + "' : sucessful"
except Exception, e:
2013-03-04 12:57:17 +00:00
MyPlugin = Gtk.EventBox() #Fake class for MyPlugin
2010-09-13 12:10:43 +01:00
MyPlugin.heading = _("Couldn't load plugin:") + " " + plugin
2013-03-04 12:57:17 +00:00
MyPlugin.content_holder = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
# create traceback
info = sys.exc_info()
2013-03-04 12:57:17 +00:00
errorLabel = Gtk.Label( "\n".join(traceback.format_exception( info[0], info[1], info[2] )).replace("\\n", "\n") )
2010-09-13 12:10:43 +01:00
errorLabel.set_selectable( True )
errorLabel.set_line_wrap( True )
errorLabel.set_alignment( 0.0, 0.0 )
errorLabel.set_padding( 5, 5 )
errorLabel.show()
MyPlugin.content_holder.add( errorLabel )
MyPlugin.add( MyPlugin.content_holder )
MyPlugin.width = 270
MyPlugin.icon = 'mate-logo-icon.png'
2010-09-13 12:10:43 +01:00
print u"Unable to load " + plugin + " plugin :-("
self.panesToColor.append( MyPlugin.content_holder )
2010-09-13 12:10:43 +01:00
MyPlugin.content_holder.show()
2013-03-04 12:57:17 +00:00
VBox1 = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
if MyPlugin.heading != "":
2013-03-04 12:57:17 +00:00
Label1 = Gtk.Label(label= MyPlugin.heading )
Align1 = Gtk.Alignment.new( 0, 0, 0, 0 )
2010-09-13 12:10:43 +01:00
Align1.set_padding( 10, 5, 10, 0 )
Align1.add( Label1 )
self.headingsToColor.append( Label1 )
2010-09-13 12:10:43 +01:00
Align1.show()
Label1.show()
if not hasattr( MyPlugin, 'sticky' ) or MyPlugin.sticky == True:
2013-03-04 12:57:17 +00:00
heading = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
Align1.set_padding( 0, 0, 10, 0 )
heading.set_visible_window( False )
2010-09-13 12:10:43 +01:00
heading.set_size_request( MyPlugin.width, 30 )
else:
2013-03-04 12:57:17 +00:00
heading = Gtk.HBox()
#heading.set_relief( Gtk.ReliefStyle.NONE )
2010-09-13 12:10:43 +01:00
heading.set_size_request( MyPlugin.width, -1 )
#heading.set_sensitive(False)
#heading.connect( "button_press_event", self.TogglePluginView, VBox1, MyPlugin.icon, MyPlugin.heading, MyPlugin )
heading.add( Align1 )
heading.show()
2013-03-05 02:56:18 +00:00
VBox1.pack_start( heading, False, False, 0 )
2010-09-13 12:10:43 +01:00
VBox1.show()
#Add plugin to Plugin Box under heading button
MyPlugin.content_holder.reparent( VBox1 )
#Add plugin to main window
2013-03-04 12:57:17 +00:00
PaneLadder.pack_start( VBox1 , True, True, 0)
2010-09-13 12:10:43 +01:00
PaneLadder.show()
if MyPlugin.window:
MyPlugin.window.destroy()
try:
if hasattr( MyPlugin, 'do_plugin' ):
MyPlugin.do_plugin()
if hasattr( MyPlugin, 'height' ):
MyPlugin.content_holder.set_size_request( -1, MyPlugin.height )
if hasattr( MyPlugin, 'itemstocolor' ):
self.panesToColor.extend( MyPlugin.itemstocolor )
if hasattr( MyPlugin, 'headingstocolor' ):
self.headingsToColor.extend( MyPlugin.headingstocolor )
2010-09-13 12:10:43 +01:00
except:
# create traceback
info = sys.exc_info()
error = _("Couldn't initialize plugin") + " " + plugin + " : " + "\n".join(traceback.format_exception( info[0], info[1], info[2] )).replace("\\n", "\n")
2013-03-04 12:57:17 +00:00
msgDlg = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, error )
2010-09-13 12:10:43 +01:00
msgDlg.run();
msgDlg.destroy();
self.plugins[plugin] = MyPlugin
else:
self.paneholder.pack_start( ImageBox, False, False, 0 )
self.paneholder.pack_start( PluginPane, False, False, 0 )
2013-03-04 12:57:17 +00:00
PluginPane = Gtk.EventBox()
PaneLadder = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
PluginPane.add( PaneLadder )
2013-03-04 12:57:17 +00:00
ImageBox = Gtk.EventBox()
self.panesToColor.extend( [ PluginPane, ImageBox ] )
2010-09-13 12:10:43 +01:00
ImageBox.show()
PluginPane.show_all()
if self.plugins and hasattr( MyPlugin, 'hideseparator' ) and not MyPlugin.hideseparator:
2013-03-04 12:57:17 +00:00
Image1 = Gtk.Image()
2010-09-13 12:10:43 +01:00
Image1.set_from_pixbuf( seperatorImage )
Image1.show()
#ImageBox.add( Image1 )
2013-03-05 02:56:18 +00:00
Align1 = Gtk.Alignment.new(0, 0, 0, 0)
2010-09-13 12:10:43 +01:00
Align1.set_padding( 0, 0, 6, 6 )
Align1.add(Image1)
ImageBox.add(Align1)
ImageBox.show_all()
self.paneholder.pack_start( ImageBox, False, False, 0 )
self.paneholder.pack_start( PluginPane, False, False, 0 )
self.tooltips.disable()
#print u"Loading", (time.time() - start), "s"
# A little hacky but works
def getDefaultStyle( self ):
widget = Gtk.EventBox()
widget.show()
return Gtk.rc_get_style(widget)
def loadTheme( self ):
defaultStyle = self.getDefaultStyle()
self.SetPaneColors( self.panesToColor, defaultStyle )
self.SetupMintMenuBorder( defaultStyle )
self.SetHeadingStyle( self.headingsToColor )
def SetPaneColors( self, items, defaultStyle = None ):
2013-03-09 00:31:58 +00:00
if self.usecustomcolor:
for item in items:
item.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.customcolor ) )
# TODO: Changing background color isn't working for pixmaps! The following does not work:
item.get_style().bg_pixmap[Gtk.StateType.NORMAL] = None
elif defaultStyle is not None:
for item in items:
item.modify_bg( Gtk.StateType.NORMAL, defaultStyle.lookup_color('bg_color')[1] )
item.get_style().bg_pixmap[Gtk.StateType.NORMAL] = defaultStyle.bg_pixmap[Gtk.StateType.NORMAL]
2010-09-13 12:10:43 +01:00
def SetHeadingStyle( self, items ):
if self.usecustomcolor:
2013-03-09 00:31:58 +00:00
color = self.customheadingcolor
else:
color = None
2010-09-13 12:10:43 +01:00
for item in items:
2013-03-09 00:31:58 +00:00
item.set_use_markup(True)
text = item.get_text()
if color == None:
markup = '<span size="12000" weight="bold">%s</span>' % (text)
else:
markup = '<span size="12000" weight="bold" color="%s">%s</span>' % (color, text)
item.set_markup( markup )
2010-09-13 12:10:43 +01:00
def setTooltip( self, widget, tip, tipPrivate = None ):
self.tooltips.set_tip( widget, tip, tipPrivate )
def RegenPlugins( self, *args, **kargs ):
#print
#print u"Reloading Plugins..."
for item in self.paneholder:
item.destroy()
for plugin in self.plugins.values():
if hasattr( plugin, "destroy" ):
plugin.destroy()
try:
del plugin
except:
pass
try:
del self.plugins
except:
pass
gc.collect()
2013-03-09 02:29:49 +00:00
self.getSetGSettingEntries()
2010-09-13 12:10:43 +01:00
self.PopulatePlugins()
self.loadTheme()
2010-09-13 12:10:43 +01:00
#print NAME+u" reloaded"
def onKeyPress( self, widget, event ):
if event.keyval == Gdk.KEY_Escape:
self.hide()
return True
return False
2010-09-13 12:10:43 +01:00
def show( self ):
self.window.present()
# Hack for opacity not showing on first composited draw
if self.firstTime:
self.firstTime = False
self.SetupMintMenuOpacity()
2010-09-13 12:10:43 +01:00
self.window.window.focus( Gdk.CURRENT_TIME )
2010-09-13 12:10:43 +01:00
for plugin in self.plugins.values():
if hasattr( plugin, "onShowMenu" ):
plugin.onShowMenu()
if ( "applications" in self.plugins ) and ( hasattr( self.plugins["applications"], "focusSearchEntry" ) ):
if (self.startWithFavorites):
self.plugins["applications"].changeTab(0)
self.plugins["applications"].focusSearchEntry()
2010-09-13 12:10:43 +01:00
def hide( self, forceHide = False ):
2010-09-13 12:10:43 +01:00
for plugin in self.plugins.values():
if hasattr( plugin, "onHideMenu" ):
plugin.onHideMenu()
self.window.hide()
def onFocusIn( self, *args ):
def dummy( *args ): pass
signalId = GObject.signal_lookup( "focus-out-event", self.window )
while True:
result = GObject.signal_handler_find( self.window,
GObject.SignalMatchType.ID | GObject.SignalMatchType.UNBLOCKED,
signalId, 0, None, dummy, dummy )
if result == 0:
self.window.handler_unblock( self.loseFocusId )
else:
break
return False
def onFocusOut( self, *args):
if self.window.get_visible():
2010-09-13 12:10:43 +01:00
self.hide()
return False
def stopHiding( self ):
self.window.handler_block( self.loseFocusId )
2009-07-27 11:45:34 +01:00
class MenuWin( object ):
2010-09-13 12:10:43 +01:00
def __init__( self, applet, iid ):
2013-03-04 15:01:20 +00:00
self.applet = applet
2013-03-04 16:50:14 +00:00
self.settings = Gio.Settings.new("com.linuxmint.mintmenu")
self.keybinder = keybinding.GlobalKeyBinding()
2013-03-09 02:52:47 +00:00
self.settings.connect( "changed::applet-text", self.reloadSettings )
self.settings.connect( "changed::theme-name", self.changeTheme )
self.settings.connect( "changed::hot-key", self.reloadSettings )
self.settings.connect( "changed::applet-icon", self.reloadSettings )
2013-03-04 15:01:20 +00:00
self.settings.connect( "changed::hide-applet-icon", self.reloadSettings )
2013-03-09 02:52:47 +00:00
self.settings.connect( "changed::applet-icon-size", self.reloadSettings )
self.settings.connect( "changed::hot-key", self.hotkeyChanged )
2013-03-04 15:01:20 +00:00
self.loadSettings()
self.mate_settings = Gio.Settings.new("org.mate.interface")
self.mate_settings.connect( "changed::gtk-theme", self.changeTheme )
2010-09-13 12:10:43 +01:00
self.createPanelButton()
2013-03-04 15:01:20 +00:00
self.applet.set_flags( MatePanelApplet.AppletFlags.EXPAND_MINOR )
2010-09-13 12:10:43 +01:00
self.applet.connect( "button-press-event", self.showMenu )
self.applet.connect( "change-orient", self.changeOrientation )
2010-09-13 12:10:43 +01:00
self.applet.connect("enter-notify-event", self.enter_notify)
self.applet.connect("leave-notify-event", self.leave_notify)
self.mainwin = MainWindow( self.button_box, self.settings, self.keybinder )
self.mainwin.window.connect( "map-event", self.onWindowMap )
self.mainwin.window.connect( "unmap-event", self.onWindowUnmap )
self.mainwin.window.connect( "realize", self.onRealize )
2010-09-13 12:10:43 +01:00
self.mainwin.window.connect( "size-allocate", lambda *args: self.positionMenu() )
2010-09-17 14:55:03 +01:00
self.mainwin.window.set_name("mintmenu") # Name used in Gtk RC files
self.applyTheme()
self.mainwin.loadTheme()
2010-09-17 14:55:03 +01:00
if self.mainwin.icon:
Gtk.Window.set_default_icon_name( self.mainwin.icon )
2010-09-13 12:10:43 +01:00
self.bind_hot_key()
self.applet.set_can_focus(False)
self.pointerMonitor = pointerMonitor.PointerMonitor()
self.pointerMonitor.connect("activate", self.onPointerOutside)
def onWindowMap( self, *args ):
self.applet.set_state( Gtk.StateType.SELECTED )
self.keybinder.set_focus_window( self.mainwin.window.window )
self.pointerMonitor.grabPointer()
return False
def onWindowUnmap( self, *args ):
self.applet.set_state( Gtk.StateType.NORMAL )
self.keybinder.set_focus_window()
self.pointerMonitor.ungrabPointer()
return False
def onRealize( self, *args):
self.pointerMonitor.addWindowToMonitor( self.mainwin.window.window )
self.pointerMonitor.addWindowToMonitor( self.applet.window )
self.pointerMonitor.start()
return False
def onPointerOutside(self, *args):
self.mainwin.hide()
return True
2010-09-13 12:10:43 +01:00
2013-03-10 00:43:27 +00:00
def onBindingPress(self, binder):
self.toggleMenu()
return True
2010-09-13 12:10:43 +01:00
def enter_notify(self, applet, event):
self.do_image(self.buttonIcon, True)
def leave_notify(self, applet, event):
# Hack for mate-panel-test-applets focus issue (this can be commented)
if event.state & Gdk.ModifierType.BUTTON1_MASK and applet.state & Gtk.StateType.SELECTED:
if event.x >= 0 and event.y >= 0 and event.x < applet.window.get_width() and event.y < applet.window.get_height():
self.mainwin.stopHiding()
2010-09-13 12:10:43 +01:00
self.do_image(self.buttonIcon, False)
def do_image(self, image_file, saturate):
2013-03-04 12:57:17 +00:00
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_file)
2010-09-13 12:10:43 +01:00
if saturate:
2013-03-04 12:57:17 +00:00
GdkPixbuf.Pixbuf.saturate_and_pixelate(pixbuf, pixbuf, 1.5, False)
2010-09-13 12:10:43 +01:00
self.button_icon.set_from_pixbuf(pixbuf)
def createPanelButton( self ):
2013-03-04 15:01:20 +00:00
self.button_icon = Gtk.Image.new_from_file( self.buttonIcon )
2013-03-04 12:57:17 +00:00
self.systemlabel = Gtk.Label(label= self.buttonText )
2010-09-13 12:10:43 +01:00
if os.path.exists("/etc/linuxmint/info"):
import commands
tooltip = commands.getoutput("cat /etc/linuxmint/info | grep DESCRIPTION")
tooltip = tooltip.replace("DESCRIPTION", "")
tooltip = tooltip.replace("=", "")
tooltip = tooltip.replace("\"", "")
self.systemlabel.set_tooltip_text(tooltip)
self.button_icon.set_tooltip_text(tooltip)
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.HBox()
2013-03-04 15:01:20 +00:00
self.button_box.pack_start( self.button_icon, False, False, 0 )
self.button_box.pack_start( self.systemlabel, False, False, 0 )
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 5, 0 )
# if we have a vertical panel
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 270 )
2014-01-22 18:23:23 +00:00
self.button_box.pack_start( self.button_icon , False, False, 0)
self.button_box.pack_start( self.systemlabel , False, False, 0)
self.button_icon.set_padding( 0, 5 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 90 )
2014-01-22 18:23:23 +00:00
self.button_box.pack_start( self.systemlabel , False, False, 0)
self.button_box.pack_start( self.button_icon , False, False, 0)
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 0, 5 )
self.button_box.set_homogeneous( False )
self.button_box.show_all()
self.sizeButton()
self.applet.add( self.button_box )
self.applet.set_background_widget( self.applet )
2010-09-13 12:10:43 +01:00
2013-03-04 15:01:20 +00:00
def loadSettings( self, *args, **kargs ):
self.hideIcon = self.settings.get_boolean( "hide-applet-icon" )
self.buttonText = self.settings.get_string( "applet-text" )
self.theme_name = self.settings.get_string( "theme-name" )
self.hotkeyText = self.settings.get_string( "hot-key" )
self.buttonIcon = self.settings.get_string( "applet-icon" )
self.iconSize = self.settings.get_int( "applet-icon-size" )
def changeTheme(self, *args):
2013-03-04 15:01:20 +00:00
self.reloadSettings()
self.applyTheme()
self.mainwin.loadTheme()
def applyTheme(self):
2013-03-04 12:57:17 +00:00
style_settings = Gtk.Settings.get_default()
desktop_theme = self.mate_settings.get_string('gtk-theme')
if self.theme_name == "default":
2010-09-17 14:55:03 +01:00
style_settings.set_property("gtk-theme-name", desktop_theme)
else:
try:
style_settings.set_property("gtk-theme-name", self.theme_name)
except:
style_settings.set_property("gtk-theme-name", desktop_theme)
2010-09-13 12:10:43 +01:00
def changeOrientation( self, *args, **kargs ):
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.HBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 0 )
self.button_box.reorder_child( self.button_icon, 0 )
self.button_icon.set_padding( 5, 0 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 270 )
2014-01-22 18:23:23 +00:00
self.button_box.reorder_child( self.button_icon, 0 )
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 0, 5 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 90 )
2014-01-22 18:23:23 +00:00
self.button_box.reorder_child( self.button_icon, 1 )
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 0, 5 )
tmpbox.set_homogeneous( False )
# reparent all the hboxes to the new tmpbox
for i in self.button_box:
i.reparent( tmpbox )
self.button_box.destroy()
self.button_box = tmpbox
self.button_box.show()
# this call makes sure width stays intact
self.updateButton()
self.applet.add( self.button_box )
def updateButton( self ):
self.systemlabel.set_text( self.buttonText )
self.button_icon.clear()
self.button_icon.set_from_file( self.buttonIcon )
self.sizeButton()
def bind_hot_key (self):
2013-03-09 19:26:22 +00:00
try:
if self.hotkeyText != "":
self.keybinder.grab( self.hotkeyText )
2013-03-10 00:43:27 +00:00
self.keybinder.connect("activate", self.onBindingPress)
self.keybinder.start()
2013-03-09 19:26:22 +00:00
# Binding menu to hotkey
print "Binding to Hot Key: " + self.hotkeyText
except Exception, cause:
print "** WARNING ** - Menu Hotkey Binding Error"
print "Error Report :\n", str(cause)
pass
2010-09-13 12:10:43 +01:00
def hotkeyChanged (self, schema, key):
self.hotkeyText = self.settings.get_string( "hot-key" )
self.keybinder.rebind(self.hotkeyText)
2010-09-13 12:10:43 +01:00
def sizeButton( self ):
if self.hideIcon:
self.button_icon.hide()
else:
self.button_icon.show()
2013-03-06 23:23:28 +00:00
# This code calculates width and height for the button_box
# and takes the orientation in account
sl_req = Gtk.Requisition()
bi_req = Gtk.Requisition()
self.button_icon.size_request(bi_req)
self.systemlabel.size_request(sl_req)
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
if self.hideIcon:
2014-01-22 18:23:23 +00:00
self.applet.set_size_request( sl_req.width + 2, bi_req.height )
2013-03-06 23:23:28 +00:00
else:
self.applet.set_size_request( sl_req.width + bi_req.width + 5, bi_req.height )
else:
if self.hideIcon:
self.applet.set_size_request( bi_req.width, sl_req.height + 2 )
else:
self.applet.set_size_request( bi_req.width, sl_req.height + bi_req.height + 5 )
2013-03-04 15:01:20 +00:00
def reloadSettings( self, *args ):
self.loadSettings()
self.updateButton()
2010-09-13 12:10:43 +01:00
2013-03-07 03:08:11 +00:00
def showAboutDialog( self, action, userdata = None ):
2010-09-13 12:10:43 +01:00
2013-03-04 12:57:17 +00:00
about = Gtk.AboutDialog()
2010-09-13 12:10:43 +01:00
about.set_name("mintMenu")
import commands
version = commands.getoutput("/usr/lib/linuxmint/common/version.py mintmenu")
about.set_version(version)
try:
h = open('/usr/share/common-licenses/GPL','r')
s = h.readlines()
gpl = ""
for line in s:
gpl += line
h.close()
about.set_license(gpl)
except Exception, detail:
print detail
about.set_comments( _("Advanced Gnome Menu") )
2013-03-07 03:08:11 +00:00
# about.set_authors( ["Clement Lefebvre <clem@linuxmint.com>", "Lars-Peter Clausen <lars@laprican.de>"] )
2010-09-13 12:10:43 +01:00
about.set_translator_credits(("translator-credits") )
#about.set_copyright( _("Based on USP from S.Chanderbally") )
2013-03-04 12:57:17 +00:00
about.set_logo( GdkPixbuf.Pixbuf.new_from_file("/usr/lib/linuxmint/mintMenu/icon.svg") )
2010-09-13 12:10:43 +01:00
about.connect( "response", lambda dialog, r: dialog.destroy() )
about.show()
2013-03-07 01:16:45 +00:00
def showPreferences( self, action, userdata = None ):
# Execute( "mateconf-editor /apps/mintMenu" )
2010-09-13 12:10:43 +01:00
Execute( os.path.join( PATH, "mintMenuConfig.py" ) )
2013-03-07 01:16:45 +00:00
def showMenuEditor( self, action, userdata = None ):
Execute( "mozo" )
2010-09-13 12:10:43 +01:00
def showMenu( self, widget=None, event=None ):
if event == None or event.button == 1:
self.toggleMenu()
# show right click menu
elif event.button == 3:
self.create_menu()
# allow middle click and drag
elif event.button == 2:
self.mainwin.hide( True )
def toggleMenu( self ):
2013-03-04 12:57:17 +00:00
if self.applet.state & Gtk.StateType.SELECTED:
2010-09-13 12:10:43 +01:00
self.mainwin.hide( True )
else:
self.positionMenu()
self.mainwin.show()
self.wakePlugins()
def wakePlugins( self ):
self.mainwin.wakePlugins()
def positionMenu( self ):
# Get our own dimensions & position
ourWidth = self.mainwin.window.get_size()[0]
ourHeight = self.mainwin.window.get_size()[1] + self.mainwin.offset
2013-03-06 23:39:13 +00:00
x = c_int()
y = c_int()
2010-09-13 12:10:43 +01:00
# Get the dimensions/position of the widgetToAlignWith
2013-03-06 23:39:13 +00:00
gdk.gdk_window_get_origin(hash(self.applet.window), byref(x), byref(y))
entryX = x.value
entryY = y.value
2010-09-13 12:10:43 +01:00
entryWidth, entryHeight = self.applet.get_allocation().width, self.applet.get_allocation().height
entryHeight = entryHeight + self.mainwin.offset
# Get the screen dimensions
2013-03-04 12:57:17 +00:00
screenHeight = Gdk.Screen.height()
screenWidth = Gdk.Screen.width()
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2010-09-13 12:10:43 +01:00
if entryX + ourWidth < screenWidth or entryX + entryWidth / 2 < screenWidth / 2:
# Align to the left of the entry
newX = entryX
else:
# Align to the right of the entry
newX = entryX + entryWidth - ourWidth
if entryY + entryHeight / 2 < screenHeight / 2:
# Align to the bottom of the entry
newY = entryY + entryHeight
else:
newY = entryY - ourHeight
else:
if entryX + entryWidth / 2 < screenWidth / 2:
# Align to the left of the entry
newX = entryX + entryWidth
else:
# Align to the right of the entry
newX = entryX - ourWidth
if entryY + ourHeight < screenHeight or entryY + entryHeight / 2 < screenHeight / 2:
# Align to the bottom of the entry
newY = entryY
else:
newY = entryY - ourHeight + entryHeight
# -"Move window"
self.mainwin.window.move( newX, newY )
# this callback is to create a context menu
def create_menu(self):
2013-03-07 01:16:45 +00:00
action_group = Gtk.ActionGroup("context-menu")
action = Gtk.Action("MintMenuPrefs", _("Preferences"), None, "gtk-preferences")
action.connect("activate", self.showPreferences)
action_group.add_action(action)
action = Gtk.Action("MintMenuEdit", _("Edit menu"), None, "gtk-edit")
action.connect("activate", self.showMenuEditor)
action_group.add_action(action)
action = Gtk.Action("MintMenuReload", _("Reload plugins"), None, "gtk-refresh")
action.connect("activate", self.mainwin.RegenPlugins)
action_group.add_action(action)
action = Gtk.Action("MintMenuAbout", _("About"), None, "gtk-about")
action.connect("activate", self.showAboutDialog)
action_group.add_action(action)
action_group.set_translation_domain ("mintmenu")
2013-03-09 01:06:06 +00:00
xml = os.path.join( os.path.join( os.path.dirname( __file__ )), "popup.xml" )
2013-03-07 01:16:45 +00:00
self.applet.setup_menu_from_file(xml, action_group)
2009-07-27 11:45:34 +01:00
2013-03-01 16:56:54 +00:00
def applet_factory( applet, iid, data ):
2010-09-13 12:10:43 +01:00
MenuWin( applet, iid )
applet.show()
return True
2009-07-27 11:45:34 +01:00
def quit_all(widget):
2013-03-04 12:57:17 +00:00
Gtk.main_quit()
2010-09-13 12:10:43 +01:00
sys.exit(0)
2009-07-27 11:45:34 +01:00
2013-03-01 16:56:54 +00:00
MatePanelApplet.Applet.factory_main("MintMenuAppletFactory", True,
MatePanelApplet.Applet.__gtype__,
applet_factory, None)