2020-03-30 16:11:23 +01:00
|
|
|
#!/usr/bin/python3
|
2009-07-27 11:45:34 +01:00
|
|
|
|
2019-05-20 14:31:05 +01:00
|
|
|
import locale
|
2019-02-11 13:54:20 +00:00
|
|
|
import gc
|
|
|
|
import gettext
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import traceback
|
|
|
|
|
2013-03-01 16:56:54 +00:00
|
|
|
import gi
|
2016-09-06 15:58:34 +01:00
|
|
|
gi.require_version("Gtk", "3.0")
|
2016-05-21 18:08:09 +01:00
|
|
|
gi.require_version('MatePanelApplet', '4.0')
|
2013-03-09 20:37:17 +00:00
|
|
|
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
|
|
|
|
2016-12-06 22:30:46 +00:00
|
|
|
import xdg.Config
|
2019-02-11 13:54:20 +00:00
|
|
|
|
2016-12-06 22:30:46 +00:00
|
|
|
import keybinding
|
|
|
|
import pointerMonitor
|
2016-12-06 22:37:02 +00:00
|
|
|
import setproctitle
|
2019-02-11 13:54:20 +00:00
|
|
|
from plugins.execute import Execute
|
2009-07-27 11:45:34 +01:00
|
|
|
|
2013-03-09 20:37:17 +00:00
|
|
|
GObject.threads_init()
|
|
|
|
|
2009-07-27 11:45:34 +01:00
|
|
|
# Rename the process
|
2016-12-06 22:37:02 +00:00
|
|
|
setproctitle.setproctitle('mintmenu')
|
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")
|
2019-05-20 14:31:05 +01:00
|
|
|
locale.bindtextdomain("mintmenu", "/usr/share/linuxmint/locale")
|
|
|
|
locale.textdomain("mintmenu")
|
2009-07-27 11:45:34 +01:00
|
|
|
|
2009-07-29 21:50:43 +01:00
|
|
|
NAME = _("Menu")
|
2019-02-11 13:54:20 +00:00
|
|
|
PATH = os.path.abspath(os.path.dirname(sys.argv[0]))
|
2010-01-13 16:32:15 +00:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
sys.path.append(os.path.join(PATH , "plugins"))
|
2009-07-27 11:45:34 +01:00
|
|
|
|
2011-11-18 10:42:20 +00:00
|
|
|
windowManager = os.getenv("DESKTOP_SESSION")
|
2011-08-29 14:41:36 +01:00
|
|
|
if not windowManager:
|
2011-11-18 10:42:20 +00:00
|
|
|
windowManager = "MATE"
|
2019-02-11 13:54:20 +00:00
|
|
|
xdg.Config.setWindowManager(windowManager.upper())
|
2009-07-27 11:45:34 +01:00
|
|
|
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
class MainWindow(object):
|
2010-09-13 12:10:43 +01:00
|
|
|
"""This is the main class for the application"""
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def __init__(self, toggleButton, settings, de):
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2013-03-04 15:01:20 +00:00
|
|
|
self.settings = settings
|
2010-09-13 12:10:43 +01:00
|
|
|
self.path = PATH
|
2019-02-11 13:54:20 +00:00
|
|
|
sys.path.append(os.path.join(self.path, "plugins"))
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2016-12-07 01:43:01 +00:00
|
|
|
self.de = de
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
self.toggle = toggleButton
|
2013-03-04 16:50:14 +00:00
|
|
|
builder = Gtk.Builder()
|
2019-05-20 14:31:05 +01:00
|
|
|
builder.set_translation_domain("mintmenu")
|
|
|
|
builder.add_from_file("/usr/share/linuxmint/mintmenu/main.ui")
|
2019-02-11 13:54:20 +00:00
|
|
|
self.window = builder.get_object("mainWindow")
|
|
|
|
self.paneholder = builder.get_object("paneholder")
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2013-03-04 16:50:14 +00:00
|
|
|
builder.connect_signals(self)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
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)
|
2014-04-01 12:26:00 +01:00
|
|
|
self.loseFocusBlocked = False
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
self.window.stick()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
plugindir = os.path.join(os.path.expanduser("~"), ".linuxmint/mintMenu/plugins")
|
|
|
|
sys.path.append(plugindir)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +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)
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2014-01-22 17:51:49 +00:00
|
|
|
self.getSetGSettingEntries()
|
|
|
|
|
2016-09-06 15:58:34 +01:00
|
|
|
self.tooltipsWidgets = []
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
self.PopulatePlugins()
|
2019-05-14 16:49:40 +01:00
|
|
|
self.toggleTooltipsEnabled(self.settings, "tooltips-enabled")
|
2019-02-11 13:54:20 +00:00
|
|
|
self.firstTime = True
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
@classmethod
|
|
|
|
def on_window1_destroy (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)
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def wakePlugins(self):
|
2010-09-13 12:10:43 +01:00
|
|
|
# Call each plugin and let them know we're showing up
|
|
|
|
for plugin in self.plugins.values():
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(plugin, "wake"):
|
2010-09-13 12:10:43 +01:00
|
|
|
plugin.wake()
|
|
|
|
|
2019-05-14 16:49:40 +01:00
|
|
|
def toggleTooltipsEnabled(self, settings, key, args=None):
|
|
|
|
enableTooltips = settings.get_boolean(key)
|
|
|
|
for widget in self.tooltipsWidgets:
|
|
|
|
widget.set_has_tooltip(enableTooltips)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def toggleStartWithFavorites(self, settings, key):
|
2013-03-09 00:31:58 +00:00
|
|
|
self.startWithFavorites = settings.get_boolean(key)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def getSetGSettingEntries(self):
|
|
|
|
self.dottedfile = os.path.join(self.path, "dotted.png")
|
|
|
|
self.pluginlist = self.settings.get_strv("plugins-list")
|
|
|
|
self.offset = self.settings.get_int("offset")
|
|
|
|
self.enableTooltips = self.settings.get_boolean("tooltips-enabled")
|
|
|
|
self.startWithFavorites = self.settings.get_boolean("start-with-favorites")
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def PopulatePlugins(self):
|
2013-03-04 12:57:17 +00:00
|
|
|
PluginPane = Gtk.EventBox()
|
2010-09-13 12:10:43 +01:00
|
|
|
PluginPane.show()
|
2019-02-11 13:54:20 +00:00
|
|
|
PaneLadder = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
PluginPane.add(PaneLadder)
|
2013-03-04 12:57:17 +00:00
|
|
|
ImageBox = Gtk.EventBox()
|
2010-09-13 12:10:43 +01:00
|
|
|
ImageBox.show()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
seperatorImage = GdkPixbuf.Pixbuf.new_from_file(self.dottedfile)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
self.plugins = {}
|
|
|
|
|
2016-05-21 17:11:36 +01:00
|
|
|
for plugin in self.pluginlist:
|
2010-09-13 12:10:43 +01:00
|
|
|
if plugin in self.plugins:
|
2019-02-11 13:54:20 +00:00
|
|
|
print("Duplicate plugin in list: %s" % plugin)
|
2010-09-13 12:10:43 +01:00
|
|
|
continue
|
|
|
|
|
|
|
|
if plugin != "newpane":
|
|
|
|
try:
|
2019-02-11 13:54:20 +00:00
|
|
|
X = __import__(plugin)
|
2010-09-13 12:10:43 +01:00
|
|
|
# If no parameter passed to plugin it is autonomous
|
2020-03-30 16:11:23 +01:00
|
|
|
if X.pluginclass.__init__.__code__.co_argcount == 1:
|
2010-09-13 12:10:43 +01:00
|
|
|
MyPlugin = X.pluginclass()
|
|
|
|
else:
|
|
|
|
# pass mintMenu and togglebutton instance so that the plugin can use it
|
2019-02-11 13:54:20 +00:00
|
|
|
MyPlugin = X.pluginclass(self, self.toggle, self.de)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
if not MyPlugin.icon:
|
2011-11-18 10:42:20 +00:00
|
|
|
MyPlugin.icon = "mate-logo-icon.png"
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
#if hasattr(MyPlugin, "hideseparator") and not MyPlugin.hideseparator:
|
2013-03-04 12:57:17 +00:00
|
|
|
# Image1 = Gtk.Image()
|
2019-02-11 13:54:20 +00:00
|
|
|
# Image1.set_from_pixbuf(seperatorImage)
|
2010-09-13 12:10:43 +01:00
|
|
|
# if not ImageBox.get_child():
|
2019-02-11 13:54:20 +00:00
|
|
|
# ImageBox.add(Image1)
|
2010-09-13 12:10:43 +01:00
|
|
|
# Image1.show()
|
|
|
|
|
|
|
|
#print u"Loading plugin '" + plugin + "' : sucessful"
|
2019-02-11 13:54:20 +00:00
|
|
|
except Exception:
|
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()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
errorLabel = Gtk.Label("\n".join(traceback.format_exception(info[0], info[1], info[2])).replace("\\n", "\n"))
|
|
|
|
errorLabel.set_selectable(True)
|
|
|
|
errorLabel.set_line_wrap(True)
|
|
|
|
errorLabel.set_alignment(0.0, 0.0)
|
|
|
|
errorLabel.set_padding(5, 5)
|
2010-09-13 12:10:43 +01:00
|
|
|
errorLabel.show()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
MyPlugin.content_holder.add(errorLabel)
|
|
|
|
MyPlugin.add(MyPlugin.content_holder)
|
2010-09-13 12:10:43 +01:00
|
|
|
MyPlugin.width = 270
|
2011-11-18 10:42:20 +00:00
|
|
|
MyPlugin.icon = 'mate-logo-icon.png'
|
2019-02-11 13:54:20 +00:00
|
|
|
print("Unable to load %s plugin" % plugin)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
MyPlugin.content_holder.show()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
VBox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
2016-05-21 17:11:36 +01:00
|
|
|
if MyPlugin.heading != "":
|
2019-05-20 14:27:41 +01:00
|
|
|
label1 = Gtk.Label()
|
|
|
|
label1.set_markup("<span size=\"12000\" weight=\"bold\">%s</span>" % MyPlugin.heading)
|
2019-02-11 13:54:20 +00:00
|
|
|
Align1 = Gtk.Alignment.new(0, 0, 0, 0)
|
|
|
|
Align1.set_padding(10, 5, 10, 0)
|
2019-05-20 14:27:41 +01:00
|
|
|
Align1.add(label1)
|
2010-09-13 12:10:43 +01:00
|
|
|
Align1.show()
|
2019-05-20 14:27:41 +01:00
|
|
|
label1.show()
|
2019-05-20 15:19:55 +01:00
|
|
|
heading = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
|
|
heading.set_size_request(MyPlugin.width, -1)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
heading.add(Align1)
|
2010-09-13 12:10:43 +01:00
|
|
|
heading.show()
|
2019-02-11 13:54:20 +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
|
2016-09-06 15:58:34 +01:00
|
|
|
MyPlugin.content_holder.get_parent().remove(MyPlugin.content_holder)
|
2019-02-11 13:54:20 +00:00
|
|
|
VBox1.add(MyPlugin.content_holder)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
#Add plugin to main window
|
2019-02-11 13:54:20 +00:00
|
|
|
PaneLadder.pack_start(VBox1 , True, True, 0)
|
2010-09-13 12:10:43 +01:00
|
|
|
PaneLadder.show()
|
|
|
|
|
2016-09-06 15:58:34 +01:00
|
|
|
try:
|
|
|
|
MyPlugin.get_window().destroy()
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
try:
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(MyPlugin, 'do_plugin'):
|
2010-09-13 12:10:43 +01:00
|
|
|
MyPlugin.do_plugin()
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(MyPlugin, 'height'):
|
|
|
|
MyPlugin.content_holder.set_size_request(-1, MyPlugin.height)
|
2010-09-13 12:10:43 +01:00
|
|
|
except:
|
|
|
|
# create traceback
|
|
|
|
info = sys.exc_info()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
error = _("Couldn't initialize plugin") + " " + plugin + " : " + "\n".join(traceback.format_exception(info[0], info[1], info[2])).replace("\\n", "\n")
|
|
|
|
msgDlg = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, error)
|
|
|
|
msgDlg.run()
|
|
|
|
msgDlg.destroy()
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
self.plugins[plugin] = MyPlugin
|
|
|
|
|
|
|
|
else:
|
2019-02-11 13:54:20 +00:00
|
|
|
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()
|
2019-02-11 13:54:20 +00:00
|
|
|
PaneLadder = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
PluginPane.add(PaneLadder)
|
2013-03-04 12:57:17 +00:00
|
|
|
ImageBox = Gtk.EventBox()
|
2010-09-13 12:10:43 +01:00
|
|
|
ImageBox.show()
|
|
|
|
PluginPane.show_all()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
if self.plugins and hasattr(MyPlugin, 'hideseparator') and not MyPlugin.hideseparator:
|
2013-03-04 12:57:17 +00:00
|
|
|
Image1 = Gtk.Image()
|
2019-02-11 13:54:20 +00:00
|
|
|
Image1.set_from_pixbuf(seperatorImage)
|
2010-09-13 12:10:43 +01:00
|
|
|
Image1.show()
|
2019-02-11 13:54:20 +00:00
|
|
|
#ImageBox.add(Image1)
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2013-03-05 02:56:18 +00:00
|
|
|
Align1 = Gtk.Alignment.new(0, 0, 0, 0)
|
2019-02-11 13:54:20 +00:00
|
|
|
Align1.set_padding(0, 0, 6, 6)
|
2010-09-13 12:10:43 +01:00
|
|
|
Align1.add(Image1)
|
|
|
|
ImageBox.add(Align1)
|
|
|
|
ImageBox.show_all()
|
|
|
|
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
self.paneholder.pack_start(ImageBox, False, False, 0)
|
|
|
|
self.paneholder.pack_start(PluginPane, False, False, 0)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def setTooltip(self, widget, tip):
|
|
|
|
self.tooltipsWidgets.append(widget)
|
|
|
|
widget.set_tooltip_text(tip)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def RegenPlugins(self, *args, **kargs):
|
2010-09-13 12:10:43 +01:00
|
|
|
#print u"Reloading Plugins..."
|
|
|
|
for item in self.paneholder:
|
|
|
|
item.destroy()
|
|
|
|
|
|
|
|
for plugin in self.plugins.values():
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(plugin, "destroy"):
|
2010-09-13 12:10:43 +01:00
|
|
|
plugin.destroy()
|
|
|
|
|
|
|
|
try:
|
|
|
|
del plugin
|
|
|
|
except:
|
|
|
|
pass
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2010-09-13 12:10:43 +01:00
|
|
|
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()
|
2019-05-14 16:49:40 +01:00
|
|
|
self.toggleTooltipsEnabled(self.settings, "tooltips-enabled")
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
#print NAME+u" reloaded"
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def onKeyPress(self, widget, event):
|
2014-01-22 20:16:27 +00:00
|
|
|
if event.keyval == Gdk.KEY_Escape:
|
|
|
|
self.hide()
|
|
|
|
return True
|
|
|
|
return False
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def show(self):
|
2010-09-13 12:10:43 +01:00
|
|
|
self.window.present()
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2014-01-22 16:15:58 +00:00
|
|
|
# Hack for opacity not showing on first composited draw
|
|
|
|
if self.firstTime:
|
|
|
|
self.firstTime = False
|
2016-06-21 16:55:19 +01:00
|
|
|
self.window.set_opacity(1.0)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
self.window.get_window().focus(Gdk.CURRENT_TIME)
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2010-09-13 12:10:43 +01:00
|
|
|
for plugin in self.plugins.values():
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(plugin, "onShowMenu"):
|
2010-09-13 12:10:43 +01:00
|
|
|
plugin.onShowMenu()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
if "applications" in self.plugins and hasattr(self.plugins["applications"], "focusSearchEntry"):
|
|
|
|
if self.startWithFavorites:
|
2014-01-22 20:16:27 +00:00
|
|
|
self.plugins["applications"].changeTab(0)
|
|
|
|
self.plugins["applications"].focusSearchEntry()
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def hide(self):
|
2010-09-13 12:10:43 +01:00
|
|
|
for plugin in self.plugins.values():
|
2019-02-11 13:54:20 +00:00
|
|
|
if hasattr(plugin, "onHideMenu"):
|
2010-09-13 12:10:43 +01:00
|
|
|
plugin.onHideMenu()
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2014-01-22 20:16:27 +00:00
|
|
|
self.window.hide()
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def onFocusIn(self, *args):
|
2014-04-01 12:26:00 +01:00
|
|
|
if self.loseFocusBlocked:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.window.handler_unblock(self.loseFocusId)
|
2014-04-01 12:26:00 +01:00
|
|
|
self.loseFocusBlocked = False
|
|
|
|
|
2016-05-21 17:11:36 +01:00
|
|
|
return False
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def onFocusOut(self, *args):
|
2014-01-22 20:16:27 +00:00
|
|
|
if self.window.get_visible():
|
2010-09-13 12:10:43 +01:00
|
|
|
self.hide()
|
|
|
|
return False
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def stopHiding(self):
|
2014-04-01 12:26:00 +01:00
|
|
|
if not self.loseFocusBlocked:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.window.handler_block(self.loseFocusId)
|
2014-04-01 12:26:00 +01:00
|
|
|
self.loseFocusBlocked = True
|
2009-07-27 11:45:34 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
class MenuWin(object):
|
|
|
|
|
|
|
|
def __init__(self, applet, iid):
|
2016-05-21 17:11:36 +01:00
|
|
|
self.applet = applet
|
2016-12-07 01:43:01 +00:00
|
|
|
self.detect_desktop_environment()
|
2013-03-04 16:50:14 +00:00
|
|
|
self.settings = Gio.Settings.new("com.linuxmint.mintmenu")
|
2019-06-13 14:41:18 +01:00
|
|
|
self.icon_theme = Gtk.IconTheme.get_default()
|
2019-09-26 11:32:07 +01:00
|
|
|
self.button_icon = Gtk.Image()
|
2017-04-28 16:26:39 +01:00
|
|
|
self.loadSettings()
|
|
|
|
|
|
|
|
self.createPanelButton()
|
|
|
|
|
|
|
|
self.mate_settings = Gio.Settings.new("org.mate.interface")
|
2019-02-11 13:54:20 +00:00
|
|
|
self.mate_settings.connect("changed::gtk-theme", self.changeTheme)
|
|
|
|
|
|
|
|
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)
|
2019-05-20 14:27:41 +01:00
|
|
|
self.settings.connect("changed::show-applet-icon", self.reloadSettings)
|
2019-02-11 13:54:20 +00:00
|
|
|
self.settings.connect("changed::applet-icon-size", self.reloadSettings)
|
|
|
|
|
|
|
|
self.applet.set_flags(MatePanelApplet.AppletFlags.EXPAND_MINOR)
|
|
|
|
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)
|
2016-12-07 01:43:01 +00:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
self.mainwin = MainWindow(self.button_box, self.settings, self.de)
|
|
|
|
self.mainwin.window.connect("map-event", self.onWindowMap)
|
|
|
|
self.mainwin.window.connect("unmap-event", self.onWindowUnmap)
|
|
|
|
self.mainwin.window.connect("size-allocate", lambda *args: self.positionMenu())
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2010-09-17 14:55:03 +01:00
|
|
|
self.mainwin.window.set_name("mintmenu") # Name used in Gtk RC files
|
2014-01-22 17:51:49 +00:00
|
|
|
self.applyTheme()
|
2010-09-17 14:55:03 +01:00
|
|
|
|
2017-06-12 15:44:24 +01:00
|
|
|
try:
|
|
|
|
self.keybinder = keybinding.GlobalKeyBinding()
|
|
|
|
if self.hotkeyText != "":
|
2019-02-11 13:54:20 +00:00
|
|
|
self.keybinder.grab(self.hotkeyText)
|
2017-06-12 15:44:24 +01:00
|
|
|
self.keybinder.connect("activate", self.onBindingPress)
|
|
|
|
self.keybinder.start()
|
2019-02-11 13:54:20 +00:00
|
|
|
self.settings.connect("changed::hot-key", self.hotkeyChanged)
|
|
|
|
print("Binding to Hot Key: %s" % self.hotkeyText)
|
|
|
|
except Exception as e:
|
2017-06-12 15:44:24 +01:00
|
|
|
self.keybinder = None
|
2019-02-11 13:54:20 +00:00
|
|
|
print("** WARNING ** - Keybinder Error")
|
|
|
|
print("Error Report :\n", e)
|
2017-06-12 15:44:24 +01:00
|
|
|
|
2014-01-22 20:16:27 +00:00
|
|
|
self.applet.set_can_focus(False)
|
|
|
|
|
2017-06-12 15:36:46 +01:00
|
|
|
try:
|
|
|
|
self.pointerMonitor = pointerMonitor.PointerMonitor()
|
|
|
|
self.pointerMonitor.connect("activate", self.onPointerOutside)
|
2019-02-11 13:54:20 +00:00
|
|
|
self.mainwin.window.connect("realize", self.onRealize)
|
|
|
|
except Exception as e:
|
|
|
|
print("** WARNING ** - Pointer Monitor Error")
|
|
|
|
print("Error Report :\n", e)
|
|
|
|
|
|
|
|
def onWindowMap(self, *args):
|
|
|
|
self.applet.get_style_context().set_state(Gtk.StateFlags.SELECTED)
|
|
|
|
self.button_box.get_style_context().set_state(Gtk.StateFlags.SELECTED)
|
2017-06-12 15:44:24 +01:00
|
|
|
if self.keybinder is not None:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.keybinder.set_focus_window(self.mainwin.window.get_window())
|
2014-01-22 20:16:27 +00:00
|
|
|
return False
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def onWindowUnmap(self, *args):
|
|
|
|
self.applet.get_style_context().set_state(Gtk.StateFlags.NORMAL)
|
|
|
|
self.button_box.get_style_context().set_state(Gtk.StateFlags.NORMAL)
|
2017-06-12 15:44:24 +01:00
|
|
|
if self.keybinder is not None:
|
|
|
|
self.keybinder.set_focus_window()
|
2014-01-22 20:16:27 +00:00
|
|
|
return False
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def onRealize(self, *args):
|
|
|
|
self.pointerMonitor.addWindowToMonitor(self.mainwin.window.get_window())
|
|
|
|
self.pointerMonitor.addWindowToMonitor(self.applet.get_window())
|
2014-01-22 20:16:27 +00:00
|
|
|
self.pointerMonitor.start()
|
|
|
|
return False
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2014-01-22 20:16:27 +00:00
|
|
|
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):
|
2014-01-22 20:16:27 +00:00
|
|
|
self.toggleMenu()
|
|
|
|
return True
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
def enter_notify(self, applet, event):
|
2019-06-13 14:41:18 +01:00
|
|
|
self.set_applet_icon(True)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
def leave_notify(self, applet, event):
|
2016-05-21 17:11:36 +01:00
|
|
|
# Hack for mate-panel-test-applets focus issue (this can be commented)
|
2019-02-11 13:54:20 +00:00
|
|
|
# if event.state & Gdk.ModifierType.BUTTON1_MASK and applet.get_style_context().get_state() & Gtk.StateFlags.SELECTED:
|
|
|
|
# if event.x >= 0 and event.y >= 0 and event.x < applet.get_window().get_width() and event.y < applet.get_window().get_height():
|
|
|
|
# self.mainwin.stopHiding()
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2019-06-13 14:41:18 +01:00
|
|
|
self.set_applet_icon()
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-06-13 14:41:18 +01:00
|
|
|
def set_applet_icon(self, saturate=False):
|
2019-09-26 14:16:05 +01:00
|
|
|
if not self.symbolic:
|
|
|
|
if saturate:
|
|
|
|
self.button_icon.set_from_surface(self.saturated_surface)
|
|
|
|
else:
|
|
|
|
self.button_icon.set_from_surface(self.surface)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def createPanelButton(self):
|
2019-06-13 14:41:18 +01:00
|
|
|
self.set_applet_icon()
|
2019-02-11 13:54:20 +00:00
|
|
|
self.systemlabel = Gtk.Label(label= "%s " % self.buttonText)
|
|
|
|
if os.path.isfile("/etc/linuxmint/info"):
|
|
|
|
with open("/etc/linuxmint/info") as info:
|
|
|
|
for line in info:
|
|
|
|
if line.startswith("DESCRIPTION="):
|
|
|
|
tooltip = line.split("=",1)[1].strip('"\n')
|
|
|
|
self.systemlabel.set_tooltip_text(tooltip)
|
|
|
|
self.button_icon.set_tooltip_text(tooltip)
|
|
|
|
break
|
2013-03-04 15:01:20 +00:00
|
|
|
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
|
|
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(5, 0)
|
2010-09-13 12:10:43 +01:00
|
|
|
# if we have a vertical panel
|
2013-03-04 15:01:20 +00:00
|
|
|
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.button_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
self.systemlabel.set_angle(270)
|
|
|
|
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)
|
2017-05-04 09:15:06 +01:00
|
|
|
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.button_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
self.systemlabel.set_angle(90)
|
|
|
|
self.button_box.pack_start(self.systemlabel , False, False, 0)
|
|
|
|
self.button_box.pack_start(self.button_icon , False, False, 0)
|
|
|
|
self.button_icon.set_padding(0, 5)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
self.button_box.set_homogeneous(False)
|
2010-09-13 12:10:43 +01:00
|
|
|
self.button_box.show_all()
|
|
|
|
self.sizeButton()
|
2017-05-01 17:00:00 +01:00
|
|
|
self.button_box.get_style_context().add_class('mintmenu')
|
2019-02-11 13:54:20 +00:00
|
|
|
self.applet.add(self.button_box)
|
|
|
|
self.applet.set_background_widget(self.applet)
|
2017-05-01 17:00:00 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def loadSettings(self, *args, **kargs):
|
2019-05-20 14:27:41 +01:00
|
|
|
self.showIcon = self.settings.get_boolean("show-applet-icon")
|
2016-12-07 01:43:01 +00:00
|
|
|
self.buttonText = self.settings.get_string("applet-text")
|
2019-02-11 13:54:20 +00:00
|
|
|
self.theme_name = self.settings.get_string("theme-name")
|
|
|
|
self.hotkeyText = self.settings.get_string("hot-key")
|
2019-06-13 14:41:18 +01:00
|
|
|
|
|
|
|
applet_icon = self.settings.get_string("applet-icon")
|
|
|
|
if not (os.path.exists(applet_icon) or self.icon_theme.has_icon(applet_icon)):
|
2017-04-28 16:34:26 +01:00
|
|
|
self.settings.reset("applet-icon")
|
2019-09-26 11:32:07 +01:00
|
|
|
self.scale = self.button_icon.get_scale_factor()
|
2019-09-26 14:16:05 +01:00
|
|
|
self.symbolic = False
|
|
|
|
self.pixbuf = None
|
2019-06-13 14:41:18 +01:00
|
|
|
if "/" in applet_icon:
|
|
|
|
if applet_icon.endswith(".svg"):
|
2019-09-26 11:32:07 +01:00
|
|
|
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(applet_icon, -1, 22 * self.scale)
|
2019-06-13 14:41:18 +01:00
|
|
|
else:
|
|
|
|
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(applet_icon)
|
|
|
|
else:
|
2019-09-27 22:25:58 +01:00
|
|
|
if applet_icon.endswith("symbolic"):
|
|
|
|
self.button_icon.set_from_icon_name(applet_icon, Gtk.IconSize.DIALOG)
|
|
|
|
self.button_icon.set_pixel_size(22)
|
2019-09-26 14:16:05 +01:00
|
|
|
self.symbolic = True
|
|
|
|
else:
|
|
|
|
self.pixbuf = self.icon_theme.load_icon(applet_icon, 22 * self.scale, 0)
|
|
|
|
if self.pixbuf is not None:
|
|
|
|
self.surface = Gdk.cairo_surface_create_from_pixbuf(self.pixbuf, self.scale)
|
|
|
|
self.saturated_pixbuf = self.pixbuf.copy()
|
|
|
|
GdkPixbuf.Pixbuf.saturate_and_pixelate(self.saturated_pixbuf, self.saturated_pixbuf, 1.5, False)
|
|
|
|
self.saturated_surface = Gdk.cairo_surface_create_from_pixbuf(self.saturated_pixbuf, self.scale)
|
2019-02-11 13:54:20 +00:00
|
|
|
self.buttonIcon = self.settings.get_string("applet-icon")
|
|
|
|
self.iconSize = self.settings.get_int("applet-icon-size")
|
2016-05-21 17:11:36 +01:00
|
|
|
|
|
|
|
def changeTheme(self, *args):
|
2013-03-04 15:01:20 +00:00
|
|
|
self.reloadSettings()
|
2010-09-15 17:11:24 +01:00
|
|
|
self.applyTheme()
|
2016-05-21 17:11:36 +01:00
|
|
|
|
2010-09-15 17:11:24 +01:00
|
|
|
def applyTheme(self):
|
2013-03-04 12:57:17 +00:00
|
|
|
style_settings = Gtk.Settings.get_default()
|
2014-01-22 17:51:49 +00:00
|
|
|
desktop_theme = self.mate_settings.get_string('gtk-theme')
|
2010-09-15 17:11:24 +01:00
|
|
|
if self.theme_name == "default":
|
2016-05-21 17:11:36 +01:00
|
|
|
style_settings.set_property("gtk-theme-name", desktop_theme)
|
2010-09-15 17:11:24 +01:00
|
|
|
else:
|
|
|
|
try:
|
|
|
|
style_settings.set_property("gtk-theme-name", self.theme_name)
|
|
|
|
except:
|
2016-05-21 17:11:36 +01:00
|
|
|
style_settings.set_property("gtk-theme-name", desktop_theme)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00: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:
|
2019-02-11 13:54:20 +00:00
|
|
|
tmpbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
|
|
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:
|
2019-02-11 13:54:20 +00:00
|
|
|
tmpbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
self.systemlabel.set_angle(270)
|
|
|
|
self.button_box.reorder_child(self.button_icon, 0)
|
|
|
|
self.button_icon.set_padding(0, 5)
|
2013-03-04 15:01:20 +00:00
|
|
|
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
|
2019-02-11 13:54:20 +00:00
|
|
|
tmpbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
self.systemlabel.set_angle(90)
|
|
|
|
self.button_box.reorder_child(self.button_icon, 1)
|
|
|
|
self.button_icon.set_padding(0, 5)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
tmpbox.set_homogeneous(False)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
# reparent all the hboxes to the new tmpbox
|
|
|
|
for i in self.button_box:
|
2019-02-11 13:54:20 +00:00
|
|
|
i.reparent(tmpbox)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
self.button_box.destroy()
|
|
|
|
|
|
|
|
self.button_box = tmpbox
|
|
|
|
self.button_box.show()
|
|
|
|
|
|
|
|
# this call makes sure width stays intact
|
|
|
|
self.updateButton()
|
2019-02-11 13:54:20 +00:00
|
|
|
self.applet.add(self.button_box)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def updateButton(self):
|
|
|
|
self.systemlabel.set_text(self.buttonText)
|
2019-06-13 14:41:18 +01:00
|
|
|
self.set_applet_icon()
|
2010-09-13 12:10:43 +01:00
|
|
|
self.sizeButton()
|
|
|
|
|
2013-03-31 04:46:01 +01:00
|
|
|
def hotkeyChanged (self, schema, key):
|
2019-02-11 13:54:20 +00:00
|
|
|
self.hotkeyText = self.settings.get_string("hot-key")
|
2014-01-22 20:16:27 +00:00
|
|
|
self.keybinder.rebind(self.hotkeyText)
|
2013-03-31 04:46:01 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def sizeButton(self):
|
2019-05-20 14:27:41 +01:00
|
|
|
if self.showIcon:
|
2010-09-13 12:10:43 +01:00
|
|
|
self.button_icon.show()
|
2019-05-20 14:27:41 +01:00
|
|
|
else:
|
|
|
|
self.button_icon.hide()
|
2018-02-07 05:25:58 +00:00
|
|
|
|
|
|
|
# This code calculates width and height for the button_box
|
|
|
|
# and takes the orientation and scale factor in account
|
|
|
|
bi_req = self.button_icon.get_preferred_size()[1]
|
|
|
|
bi_scale = self.button_icon.get_scale_factor()
|
|
|
|
sl_req = self.systemlabel.get_preferred_size()[1]
|
|
|
|
sl_scale = self.systemlabel.get_scale_factor()
|
2013-03-06 23:23:28 +00:00
|
|
|
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
|
2019-05-20 14:27:41 +01:00
|
|
|
if self.showIcon:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.applet.set_size_request(sl_req.width / sl_scale + bi_req.width / bi_scale + 5, bi_req.height)
|
2014-11-03 17:52:52 +00:00
|
|
|
else:
|
2019-05-20 14:27:41 +01:00
|
|
|
self.applet.set_size_request(sl_req.width / sl_scale + 2, bi_req.height)
|
|
|
|
else:
|
|
|
|
if self.showIcon:
|
2019-02-11 13:54:20 +00:00
|
|
|
self.applet.set_size_request(bi_req.width, sl_req.height / sl_scale + bi_req.height / bi_scale + 5)
|
2019-05-20 14:27:41 +01:00
|
|
|
else:
|
|
|
|
self.applet.set_size_request(bi_req.width, sl_req.height / sl_scale + 2)
|
2013-03-04 15:01:20 +00:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def reloadSettings(self, *args):
|
2013-03-04 15:01:20 +00:00
|
|
|
self.loadSettings()
|
2016-05-21 17:11:36 +01:00
|
|
|
self.updateButton()
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def showAboutDialog(self, action, userdata = None):
|
2013-03-04 12:57:17 +00:00
|
|
|
about = Gtk.AboutDialog()
|
2010-09-13 12:10:43 +01:00
|
|
|
about.set_name("mintMenu")
|
2019-02-27 17:12:14 +00:00
|
|
|
about.set_version("__DEB_VERSION__")
|
2010-09-13 12:10:43 +01:00
|
|
|
try:
|
2019-02-11 13:54:20 +00:00
|
|
|
gpl = open('/usr/share/common-licenses/GPL','r').read()
|
2010-09-13 12:10:43 +01:00
|
|
|
about.set_license(gpl)
|
2019-02-11 13:54:20 +00:00
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
|
|
|
about.set_comments(_("Advanced MATE Menu"))
|
|
|
|
# about.set_authors(["Clement Lefebvre <clem@linuxmint.com>", "Lars-Peter Clausen <lars@laprican.de>"])
|
|
|
|
about.set_translator_credits(("translator-credits"))
|
|
|
|
# about.set_copyright(_("Based on USP from S.Chanderbally"))
|
|
|
|
about.set_logo(GdkPixbuf.Pixbuf.new_from_file("/usr/lib/linuxmint/mintMenu/icon.svg"))
|
|
|
|
about.connect("response", lambda dialog, r: dialog.destroy())
|
2010-09-13 12:10:43 +01:00
|
|
|
about.show()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def showPreferences(self, action, userdata = None):
|
2019-05-20 14:27:41 +01:00
|
|
|
Execute("/usr/lib/linuxmint/mintMenu/preferences.py")
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def showMenuEditor(self, action, userdata = None):
|
2019-12-10 16:06:40 +00:00
|
|
|
if os.path.exists("/usr/bin/mozo"):
|
2019-07-23 11:33:52 +01:00
|
|
|
Execute("mozo")
|
2019-12-10 16:06:40 +00:00
|
|
|
elif os.path.exists("/usr/bin/menulibre"):
|
|
|
|
Execute("menulibre")
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def showMenu(self, widget=None, event=None):
|
2010-09-13 12:10:43 +01:00
|
|
|
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:
|
2014-12-01 12:16:01 +00:00
|
|
|
self.mainwin.hide()
|
2010-09-13 12:10:43 +01:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def toggleMenu(self):
|
2016-09-06 15:58:34 +01:00
|
|
|
if self.applet.get_style_context().get_state() & Gtk.StateFlags.SELECTED:
|
2014-12-01 12:16:01 +00:00
|
|
|
self.mainwin.hide()
|
2010-09-13 12:10:43 +01:00
|
|
|
else:
|
|
|
|
self.positionMenu()
|
|
|
|
self.mainwin.show()
|
|
|
|
self.wakePlugins()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def wakePlugins(self):
|
2010-09-13 12:10:43 +01:00
|
|
|
self.mainwin.wakePlugins()
|
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def positionMenu(self):
|
2010-09-13 12:10:43 +01:00
|
|
|
# Get our own dimensions & position
|
|
|
|
ourWidth = self.mainwin.window.get_size()[0]
|
|
|
|
ourHeight = self.mainwin.window.get_size()[1] + self.mainwin.offset
|
|
|
|
|
|
|
|
# Get the dimensions/position of the widgetToAlignWith
|
2017-04-28 13:02:28 +01:00
|
|
|
try:
|
|
|
|
entryX = self.applet.get_window().get_origin().x
|
|
|
|
entryY = self.applet.get_window().get_origin().y
|
|
|
|
except:
|
|
|
|
# In Betsy get_origin returns an unamed tuple so the code above fails
|
|
|
|
entryX = self.applet.get_window().get_origin()[1]
|
|
|
|
entryY = self.applet.get_window().get_origin()[2]
|
2013-03-06 23:39:13 +00:00
|
|
|
|
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
|
|
|
|
|
2017-07-16 11:05:34 +01:00
|
|
|
# Get the monitor dimensions
|
|
|
|
display = self.applet.get_display()
|
|
|
|
if (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION) >= (3, 22):
|
|
|
|
monitor = display.get_monitor_at_window(self.applet.get_window())
|
|
|
|
monitorGeometry = monitor.get_geometry()
|
2010-09-13 12:10:43 +01:00
|
|
|
else:
|
2017-07-16 11:05:34 +01:00
|
|
|
screen = display.get_default_screen()
|
|
|
|
monitor = screen.get_monitor_at_window(self.applet.get_window())
|
|
|
|
monitorGeometry = screen.get_monitor_geometry(monitor)
|
|
|
|
|
|
|
|
applet_orient = self.applet.get_orient()
|
|
|
|
if applet_orient == MatePanelApplet.AppletOrient.UP:
|
|
|
|
newX = entryX
|
|
|
|
newY = entryY - ourHeight
|
|
|
|
elif applet_orient == MatePanelApplet.AppletOrient.DOWN:
|
|
|
|
newX = entryX
|
|
|
|
newY = entryY + entryHeight
|
|
|
|
elif applet_orient == MatePanelApplet.AppletOrient.RIGHT:
|
|
|
|
newX = entryX + entryWidth
|
|
|
|
newY = entryY
|
|
|
|
elif applet_orient == MatePanelApplet.AppletOrient.LEFT:
|
|
|
|
newX = entryX - ourWidth
|
|
|
|
newY = entryY
|
|
|
|
|
|
|
|
# Adjust for offset if we reach the end of the screen
|
|
|
|
# Bind to the right side
|
|
|
|
if newX + ourWidth > (monitorGeometry.x + monitorGeometry.width):
|
|
|
|
newX = (monitorGeometry.x + monitorGeometry.width) - ourWidth
|
|
|
|
if applet_orient == MatePanelApplet.AppletOrient.LEFT:
|
|
|
|
newX -= entryWidth
|
|
|
|
|
|
|
|
# Bind to the left side
|
|
|
|
if newX < monitorGeometry.x:
|
|
|
|
newX = monitorGeometry.x
|
|
|
|
if applet_orient == MatePanelApplet.AppletOrient.RIGHT:
|
2019-02-11 13:54:20 +00:00
|
|
|
newX -= entryWidth
|
2017-07-16 11:05:34 +01:00
|
|
|
|
|
|
|
# Bind to the bottom
|
|
|
|
if newY + ourHeight > (monitorGeometry.y + monitorGeometry.height):
|
|
|
|
newY = (monitorGeometry.y + monitorGeometry.height) - ourHeight
|
|
|
|
if applet_orient == MatePanelApplet.AppletOrient.UP:
|
|
|
|
newY -= entryHeight
|
|
|
|
|
|
|
|
# Bind to the top
|
|
|
|
if newY < monitorGeometry.y:
|
|
|
|
newY = monitorGeometry.y
|
|
|
|
if applet_orient == MatePanelApplet.AppletOrient.DOWN:
|
|
|
|
newY -= entryHeight
|
|
|
|
|
|
|
|
# Move window
|
2019-02-11 13:54:20 +00:00
|
|
|
self.mainwin.window.move(newX, newY)
|
2010-09-13 12:10:43 +01:00
|
|
|
|
|
|
|
# this callback is to create a context menu
|
|
|
|
def create_menu(self):
|
2019-07-29 11:12:58 +01:00
|
|
|
menu_file = "popup-without-edit.xml"
|
2016-09-06 15:58:34 +01:00
|
|
|
action_group = Gtk.ActionGroup(name="context-menu")
|
2019-07-21 15:01:50 +01:00
|
|
|
action = Gtk.Action(name="MintMenuPrefs", label=_("Preferences"), tooltip=None)
|
2013-03-07 01:16:45 +00:00
|
|
|
action.connect("activate", self.showPreferences)
|
|
|
|
action_group.add_action(action)
|
2019-07-29 11:12:58 +01:00
|
|
|
if os.path.exists("/usr/bin/menulibre") or os.path.exists("/usr/bin/mozo"):
|
|
|
|
action = Gtk.Action(name="MintMenuEdit", label=_("Edit menu"), tooltip=None)
|
|
|
|
action.connect("activate", self.showMenuEditor)
|
|
|
|
action_group.add_action(action)
|
|
|
|
menu_file = "popup.xml"
|
2019-07-21 15:01:50 +01:00
|
|
|
action = Gtk.Action(name="MintMenuReload", label=_("Reload plugins"), tooltip=None)
|
2013-03-07 01:16:45 +00:00
|
|
|
action.connect("activate", self.mainwin.RegenPlugins)
|
|
|
|
action_group.add_action(action)
|
2019-07-21 15:01:50 +01:00
|
|
|
action = Gtk.Action(name="MintMenuAbout", label=_("About"), tooltip=None)
|
2013-03-07 01:16:45 +00:00
|
|
|
action.connect("activate", self.showAboutDialog)
|
|
|
|
action_group.add_action(action)
|
|
|
|
action_group.set_translation_domain ("mintmenu")
|
|
|
|
|
2019-07-29 11:12:58 +01:00
|
|
|
xml = os.path.join(os.path.join(os.path.dirname(__file__)), menu_file)
|
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
|
|
|
|
2016-12-07 01:43:01 +00:00
|
|
|
def detect_desktop_environment (self):
|
|
|
|
self.de = "mate"
|
|
|
|
try:
|
|
|
|
de = os.environ["XDG_CURRENT_DESKTOP"].lower()
|
|
|
|
if de in ["gnome", "gnome-shell", "mate", "kde", "xfce"]:
|
|
|
|
self.de = de
|
|
|
|
elif de in ['cinnamon', 'x-cinnamon']:
|
2017-08-26 16:35:45 +01:00
|
|
|
self.de = 'cinnamon'
|
2016-12-07 01:43:01 +00:00
|
|
|
else:
|
|
|
|
if os.path.exists("/usr/bin/caja"):
|
|
|
|
self.de = "mate"
|
|
|
|
elif os.path.exists("/usr/bin/thunar"):
|
|
|
|
self.de = "xfce"
|
2019-02-11 13:54:20 +00:00
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
2016-12-07 01:43:01 +00:00
|
|
|
|
2019-02-11 13:54:20 +00:00
|
|
|
def applet_factory(applet, iid, data):
|
|
|
|
MenuWin(applet, iid)
|
2010-09-13 12:10:43 +01:00
|
|
|
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)
|