This commit is contained in:
hordepfo 2014-02-03 02:37:20 -08:00
commit f8500acc01
7 changed files with 286 additions and 189 deletions

View File

@ -58,10 +58,11 @@ class GlobalKeyBinding(GObject.GObject, threading.Thread):
self.keymap = capi.get_widget (gdk.gdk_keymap_get_default()) self.keymap = capi.get_widget (gdk.gdk_keymap_get_default())
self.display = Display() self.display = Display()
self.screen = self.display.screen() self.screen = self.display.screen()
self.root = self.screen.root self.window = self.screen.root
self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask) self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask)
self.map_modifiers() self.map_modifiers()
self.raw_keyval = None self.raw_keyval = None
self.keytext = ""
def is_hotkey(self, key, modifier): def is_hotkey(self, key, modifier):
keymatch = False keymatch = False
@ -101,21 +102,39 @@ class GlobalKeyBinding(GObject.GObject, threading.Thread):
self.modifiers = None self.modifiers = None
return False return False
self.keytext = key
self.keycode = self.get_keycode(keyval) self.keycode = self.get_keycode(keyval)
self.modifiers = int(modifiers) self.modifiers = int(modifiers)
catch = error.CatchError(error.BadAccess) catch = error.CatchError(error.BadAccess)
for ignored_mask in self.ignored_masks: for ignored_mask in self.ignored_masks:
mod = modifiers | ignored_mask mod = modifiers | ignored_mask
result = self.root.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch) result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch)
self.display.sync() self.display.flush()
# sync has been blocking. Don't know why.
#self.display.sync()
if catch.get_error(): if catch.get_error():
return False return False
return True return True
def ungrab(self): def ungrab(self):
if self.keycode: if self.keycode:
self.root.ungrab_key(self.keycode, X.AnyModifier, self.root) self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)
def rebind(self, key):
self.ungrab()
if key != "":
self.grab(key)
else:
self.keytext = ""
def set_focus_window(self, window = None):
self.ungrab()
if window is None:
self.window = self.screen.root
else:
self.window = self.display.create_resource_object("window", gdk.gdk_x11_drawable_get_xid(hash(window)))
self.grab(self.keytext)
def get_mask_combinations(self, mask): def get_mask_combinations(self, mask):
return [x for x in xrange(mask+1) if not (x & ~mask)] return [x for x in xrange(mask+1) if not (x & ~mask)]

View File

@ -4,7 +4,7 @@
<!-- interface-naming-policy toplevel-contextual --> <!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="mainWindow"> <object class="GtkWindow" id="mainWindow">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property>
<property name="type">popup</property> <property name="type">toplevel</property>
<property name="resizable">False</property> <property name="resizable">False</property>
<property name="type_hint">menu</property> <property name="type_hint">menu</property>
<property name="skip_taskbar_hint">True</property> <property name="skip_taskbar_hint">True</property>

View File

@ -21,6 +21,7 @@ try:
import capi import capi
import xdg.Config import xdg.Config
import keybinding import keybinding
import pointerMonitor
except Exception, e: except Exception, e:
print e print e
sys.exit( 1 ) sys.exit( 1 )
@ -87,21 +88,29 @@ class MainWindow( object ):
self.panesToColor = [ ] self.panesToColor = [ ]
self.headingsToColor = [ ] self.headingsToColor = [ ]
self.window.connect( "map-event", self.onMap )
self.window.connect( "show", self.onShow )
self.window.connect( "unmap-event", self.onUnmap )
self.window.connect( "button-press-event", self.onButtonPress )
self.window.connect( "key-press-event", self.onKeyPress ) self.window.connect( "key-press-event", self.onKeyPress )
self.window.connect( "grab-broken-event", self.onGrabBroken ) self.window.connect( "focus-in-event", self.onFocusIn )
self.loseFocusId = self.window.connect( "focus-out-event", self.onFocusOut )
self.window.stick() self.window.stick()
plugindir = os.path.join( os.path.expanduser( "~" ), ".linuxmint/mintMenu/plugins" ) plugindir = os.path.join( os.path.expanduser( "~" ), ".linuxmint/mintMenu/plugins" )
sys.path.append( plugindir ) sys.path.append( plugindir )
self.panelSettings = Gio.Settings.new("org.mate.panel")
self.panelSettings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
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 )
self.settings.connect( "changed::opacity", self.toggleOpacity )
self.getSetGSettingEntries() self.getSetGSettingEntries()
self.SetupMintMenuBorder()
self.SetupMintMenuOpacity()
self.tooltips = Gtk.Tooltips() self.tooltips = Gtk.Tooltips()
if self.globalEnableTooltips and self.enableTooltips: if self.globalEnableTooltips and self.enableTooltips:
@ -110,20 +119,8 @@ class MainWindow( object ):
self.tooltips.disable() self.tooltips.disable()
self.PopulatePlugins(); self.PopulatePlugins();
self.loadTheme()
self.settings.connect( "changed::plugins-list", self.RegenPlugins ) self.firstTime = True;
self.settings.connect( "changed::start-with-favorites", self.toggleStartWithFavorites )
globalsettings = Gio.Settings.new("org.mate.panel")
globalsettings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
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 )
self.settings.connect( "changed::opacity", self.toggleOpacity )
def on_window1_destroy (self, widget, data=None): def on_window1_destroy (self, widget, data=None):
Gtk.main_quit() Gtk.main_quit()
@ -159,9 +156,7 @@ class MainWindow( object ):
def toggleUseCustomColor( self, settings, key, args = None ): def toggleUseCustomColor( self, settings, key, args = None ):
self.usecustomcolor = settings.get_boolean(key) self.usecustomcolor = settings.get_boolean(key)
self.SetupMintMenuBorder() self.loadTheme()
self.SetPaneColors( self.panesToColor )
self.SetHeadingStyle( self.headingsToColor )
def toggleCustomBorderColor( self, settings, key, args = None ): def toggleCustomBorderColor( self, settings, key, args = None ):
self.custombordercolor = settings.get_string(key) self.custombordercolor = settings.get_string(key)
@ -189,14 +184,13 @@ class MainWindow( object ):
self.enableTooltips = self.settings.get_boolean( "tooltips-enabled" ) self.enableTooltips = self.settings.get_boolean( "tooltips-enabled" )
self.startWithFavorites = self.settings.get_boolean( "start-with-favorites" ) self.startWithFavorites = self.settings.get_boolean( "start-with-favorites" )
mate_settings = Gio.Settings.new("org.mate.panel") self.globalEnableTooltips = self.panelSettings.get_boolean( "tooltips-enabled" )
self.globalEnableTooltips = mate_settings.get_boolean( "tooltips-enabled" )
def SetupMintMenuBorder( self ): def SetupMintMenuBorder( self, defaultStyle = None ):
if self.usecustomcolor: if self.usecustomcolor:
self.window.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.custombordercolor ) ) self.window.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.custombordercolor ) )
# else: elif defaultStyle is not None:
# self.window.modify_bg( Gtk.StateType.NORMAL, self.window.rc_get_style().bg[ Gtk.StateType.SELECTED ] ) self.window.modify_bg( Gtk.StateType.NORMAL, defaultStyle.lookup_color('bg_color')[1] )
self.border.set_padding( self.borderwidth, self.borderwidth, self.borderwidth, self.borderwidth ) self.border.set_padding( self.borderwidth, self.borderwidth, self.borderwidth, self.borderwidth )
def SetupMintMenuOpacity( self ): def SetupMintMenuOpacity( self ):
@ -227,10 +221,9 @@ class MainWindow( object ):
PluginPane.show() PluginPane.show()
PaneLadder = Gtk.VBox( False, 0 ) PaneLadder = Gtk.VBox( False, 0 )
PluginPane.add( PaneLadder ) PluginPane.add( PaneLadder )
self.SetPaneColors( [ PluginPane ] )
ImageBox = Gtk.EventBox() ImageBox = Gtk.EventBox()
self.SetPaneColors( [ ImageBox ] )
ImageBox.show() ImageBox.show()
self.panesToColor.extend( [ PluginPane, ImageBox ] )
seperatorImage = GdkPixbuf.Pixbuf.new_from_file( self.dottedfile ) seperatorImage = GdkPixbuf.Pixbuf.new_from_file( self.dottedfile )
@ -284,9 +277,7 @@ class MainWindow( object ):
print u"Unable to load " + plugin + " plugin :-(" print u"Unable to load " + plugin + " plugin :-("
self.SetPaneColors( [MyPlugin.content_holder] ) self.panesToColor.append( MyPlugin.content_holder )
MyPlugin.content_holder.show() MyPlugin.content_holder.show()
VBox1 = Gtk.VBox( False, 0 ) VBox1 = Gtk.VBox( False, 0 )
@ -295,14 +286,14 @@ class MainWindow( object ):
Align1 = Gtk.Alignment.new( 0, 0, 0, 0 ) Align1 = Gtk.Alignment.new( 0, 0, 0, 0 )
Align1.set_padding( 10, 5, 10, 0 ) Align1.set_padding( 10, 5, 10, 0 )
Align1.add( Label1 ) Align1.add( Label1 )
self.SetHeadingStyle( [Label1] ) self.headingsToColor.append( Label1 )
Align1.show() Align1.show()
Label1.show() Label1.show()
if not hasattr( MyPlugin, 'sticky' ) or MyPlugin.sticky == True: if not hasattr( MyPlugin, 'sticky' ) or MyPlugin.sticky == True:
heading = Gtk.EventBox() heading = Gtk.EventBox()
Align1.set_padding( 0, 0, 10, 0 ) Align1.set_padding( 0, 0, 10, 0 )
self.SetPaneColors( [heading] ) heading.set_visible_window( False )
heading.set_size_request( MyPlugin.width, 30 ) heading.set_size_request( MyPlugin.width, 30 )
else: else:
heading = Gtk.HBox() heading = Gtk.HBox()
@ -331,7 +322,9 @@ class MainWindow( object ):
if hasattr( MyPlugin, 'height' ): if hasattr( MyPlugin, 'height' ):
MyPlugin.content_holder.set_size_request( -1, MyPlugin.height ) MyPlugin.content_holder.set_size_request( -1, MyPlugin.height )
if hasattr( MyPlugin, 'itemstocolor' ): if hasattr( MyPlugin, 'itemstocolor' ):
self.SetPaneColors( MyPlugin.itemstocolor ) self.panesToColor.extend( MyPlugin.itemstocolor )
if hasattr( MyPlugin, 'headingstocolor' ):
self.headingsToColor.extend( MyPlugin.headingstocolor )
except: except:
# create traceback # create traceback
info = sys.exc_info() info = sys.exc_info()
@ -349,9 +342,8 @@ class MainWindow( object ):
PluginPane = Gtk.EventBox() PluginPane = Gtk.EventBox()
PaneLadder = Gtk.VBox( False, 0 ) PaneLadder = Gtk.VBox( False, 0 )
PluginPane.add( PaneLadder ) PluginPane.add( PaneLadder )
self.SetPaneColors( [PluginPane] )
ImageBox = Gtk.EventBox() ImageBox = Gtk.EventBox()
self.SetPaneColors( [ImageBox] ) self.panesToColor.extend( [ PluginPane, ImageBox ] )
ImageBox.show() ImageBox.show()
PluginPane.show_all() PluginPane.show_all()
@ -373,22 +365,30 @@ class MainWindow( object ):
self.tooltips.disable() self.tooltips.disable()
#print u"Loading", (time.time() - start), "s" #print u"Loading", (time.time() - start), "s"
def SetPaneColors( self, items ): # A little hacky but works
for item in items: def getDefaultStyle( self ):
if item not in self.panesToColor: widget = Gtk.EventBox()
self.panesToColor.append( item ) 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 ):
if self.usecustomcolor: if self.usecustomcolor:
for item in items: for item in items:
item.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.customcolor ) ) item.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.customcolor ) )
# else: # TODO: Changing background color isn't working for pixmaps! The following does not work:
# for item in items: item.get_style().bg_pixmap[Gtk.StateType.NORMAL] = None
# item.modify_bg( Gtk.StateType.NORMAL, self.paneholder.rc_get_style().bg[ Gtk.StateType.NORMAL ] ) 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]
def SetHeadingStyle( self, items ): def SetHeadingStyle( self, items ):
for item in items:
if item not in self.headingsToColor:
self.headingsToColor.append( item )
if self.usecustomcolor: if self.usecustomcolor:
color = self.customheadingcolor color = self.customheadingcolor
else: else:
@ -430,84 +430,63 @@ class MainWindow( object ):
self.getSetGSettingEntries() self.getSetGSettingEntries()
self.PopulatePlugins() self.PopulatePlugins()
self.loadTheme()
#print NAME+u" reloaded" #print NAME+u" reloaded"
def onKeyPress( self, widget, event ):
if event.keyval == Gdk.KEY_Escape:
self.hide()
return True
return False
def show( self ): def show( self ):
self.window.present() self.window.present()
self.window.window.focus( Gdk.CURRENT_TIME )
# Hack for opacity not showing on first composited draw
if self.firstTime:
self.firstTime = False
self.SetupMintMenuOpacity()
for plugin in self.plugins.values():
if hasattr( plugin, "onShowMenu" ):
plugin.onShowMenu()
if ( "applications" in self.plugins ) and ( hasattr( self.plugins["applications"], "focusSearchEntry" ) ): if ( "applications" in self.plugins ) and ( hasattr( self.plugins["applications"], "focusSearchEntry" ) ):
if (self.startWithFavorites): if (self.startWithFavorites):
self.plugins["applications"].changeTab(0) self.plugins["applications"].changeTab(0)
self.plugins["applications"].focusSearchEntry() self.plugins["applications"].focusSearchEntry()
def grab( self ): def hide( self, forceHide = False ):
gdk.gdk_pointer_grab (hash(self.window.window), True, Gdk.EventMask.BUTTON_PRESS_MASK, None, None, Gdk.CURRENT_TIME)
Gdk.keyboard_grab( self.window.window, False, Gdk.CURRENT_TIME )
Gtk.grab_add(self.window)
def ungrab( self ):
Gtk.grab_remove(self.window)
self.window.hide()
Gdk.pointer_ungrab(Gdk.CURRENT_TIME)
Gdk.keyboard_ungrab(Gdk.CURRENT_TIME)
def onMap( self, widget, event ):
self.grab()
def onShow( self, widget ):
for plugin in self.plugins.values():
if hasattr( plugin, "onShowMenu" ):
plugin.onShowMenu()
def onUnmap( self, widget, event ):
self.ungrab()
for plugin in self.plugins.values(): for plugin in self.plugins.values():
if hasattr( plugin, "onHideMenu" ): if hasattr( plugin, "onHideMenu" ):
plugin.onHideMenu() plugin.onHideMenu()
def onKeyPress( self, widget, event ): self.window.hide()
if event.keyval == Gdk.KEY_Escape or self.keybinder.is_hotkey(event.keyval, event.get_state()):
self.hide() def onFocusIn( self, *args ):
return True 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 return False
def onButtonPress( self, widget, event ): def onFocusOut( self, *args):
# Check if the pointer is within the menu, else hide the menu if self.window.get_visible():
winatptr = Gdk.window_at_pointer() self.hide()
if winatptr: return False
win = winatptr[0]
while win:
if win == self.window.window:
break
win = capi.get_widget(gdk.gdk_window_get_parent (hash(win)))
if not win:
self.hide( True )
else:
self.hide( True )
return True def stopHiding( self ):
self.window.handler_block( self.loseFocusId )
def onGrabBroken( self, widget, event ):
if event.grab_broken.grab_window:
try:
win = event.grab_broken.grab_window
data = c_void_p()
gdk.gdk_window_get_user_data(hash(win), byref(data))
theft = capi.get_widget(ctypes.cast(data, POINTER(capi._PyGObject_Functions)))
theft.connect( "event", self.onGrabTheftEvent )
except Exception, detail:
print detail
self.window.hide()
def onGrabTheftEvent( self, widget, event ):
if event.type == Gdk.EventType.UNMAP or event.type == Gdk.EventType.SELECTION_CLEAR:
self.grab()
def hide(self, forceHide = False):
self.window.hide()
class MenuWin( object ): class MenuWin( object ):
def __init__( self, applet, iid ): def __init__( self, applet, iid ):
@ -523,8 +502,8 @@ class MenuWin( object ):
self.settings.connect( "changed::hot-key", self.hotkeyChanged ) self.settings.connect( "changed::hot-key", self.hotkeyChanged )
self.loadSettings() self.loadSettings()
mate_settings = Gio.Settings.new("org.mate.interface") self.mate_settings = Gio.Settings.new("org.mate.interface")
mate_settings.connect( "changed::gtk-theme", self.changeTheme ) self.mate_settings.connect( "changed::gtk-theme", self.changeTheme )
self.createPanelButton() self.createPanelButton()
@ -534,8 +513,9 @@ class MenuWin( object ):
self.applet.connect("enter-notify-event", self.enter_notify) self.applet.connect("enter-notify-event", self.enter_notify)
self.applet.connect("leave-notify-event", self.leave_notify) self.applet.connect("leave-notify-event", self.leave_notify)
self.mainwin = MainWindow( self.button_box, self.settings, self.keybinder ) self.mainwin = MainWindow( self.button_box, self.settings, self.keybinder )
self.mainwin.window.connect( "map-event", lambda *args: self.applet.set_state( Gtk.StateType.SELECTED ) ) self.mainwin.window.connect( "map-event", self.onWindowMap )
self.mainwin.window.connect( "unmap-event", lambda *args: self.applet.set_state( Gtk.StateType.NORMAL ) ) self.mainwin.window.connect( "unmap-event", self.onWindowUnmap )
self.mainwin.window.connect( "realize", self.onRealize )
self.mainwin.window.connect( "size-allocate", lambda *args: self.positionMenu() ) self.mainwin.window.connect( "size-allocate", lambda *args: self.positionMenu() )
self.mainwin.window.set_name("mintmenu") # Name used in Gtk RC files self.mainwin.window.set_name("mintmenu") # Name used in Gtk RC files
@ -544,29 +524,52 @@ class MenuWin( object ):
Gtk.Window.set_default_icon_name( self.mainwin.icon ) Gtk.Window.set_default_icon_name( self.mainwin.icon )
self.bind_hot_key() 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
def onBindingPress(self, binder): def onBindingPress(self, binder):
try: self.toggleMenu()
if self.mainwin.window.get_visible(): return True
self.mainwin.window.hide()
self.mainwin.toggle.set_active(False)
else:
MenuWin.showMenu(self,self.mainwin.toggle)
self.mainwin.window.show()
#self.mainwin.wTree.get_widget( 'PluginTabs' ).set_curremenu_editor = SetGconf( self.client, "string", "/apps/usp/menu_editor", "mozo" )
except Exception, cause:
print cause
def enter_notify(self, applet, event): def enter_notify(self, applet, event):
self.do_image(self.buttonIcon, True) self.do_image(self.buttonIcon, True)
def leave_notify(self, applet, event): 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()
self.do_image(self.buttonIcon, False) self.do_image(self.buttonIcon, False)
def do_image(self, image_file, saturate): def do_image(self, image_file, saturate):
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_file) pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_file)
if saturate: if saturate:
GdkPixbuf.Pixbuf.saturate_and_pixelate(pixbuf, pixbuf, 1.5, False) pixbuf.saturate_and_pixelate(pixbuf, 50.0, False)
self.button_icon.set_from_pixbuf(pixbuf) self.button_icon.set_from_pixbuf(pixbuf)
def createPanelButton( self ): def createPanelButton( self ):
@ -584,20 +587,19 @@ class MenuWin( object ):
self.button_box = Gtk.HBox() self.button_box = Gtk.HBox()
self.button_box.pack_start( self.button_icon, False, False, 0 ) self.button_box.pack_start( self.button_icon, False, False, 0 )
self.button_box.pack_start( self.systemlabel, False, False, 0 ) self.button_box.pack_start( self.systemlabel, False, False, 0 )
self.button_icon.set_padding( 5, 0 ) self.button_icon.set_padding( 5, 0 )
# if we have a vertical panel # if we have a vertical panel
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT: elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
self.button_box = Gtk.VBox() self.button_box = Gtk.VBox()
self.systemlabel.set_angle( 270 ) self.systemlabel.set_angle( 270 )
self.button_box.pack_start( self.systemlabel , True, True, 0) self.button_box.pack_start( self.button_icon , False, False, 0)
self.button_box.pack_start( self.button_icon , True, True, 0) self.button_box.pack_start( self.systemlabel , False, False, 0)
self.button_icon.set_padding( 5, 0 ) self.button_icon.set_padding( 0, 5 )
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT: elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
self.button_box = Gtk.VBox() self.button_box = Gtk.VBox()
self.systemlabel.set_angle( 90 ) self.systemlabel.set_angle( 90 )
self.button_box.pack_start( self.button_icon , True, True, 0) self.button_box.pack_start( self.systemlabel , False, False, 0)
self.button_box.pack_start( self.systemlabel , True, True, 0) self.button_box.pack_start( self.button_icon , False, False, 0)
self.button_icon.set_padding( 0, 5 ) self.button_icon.set_padding( 0, 5 )
self.button_box.set_homogeneous( False ) self.button_box.set_homogeneous( False )
@ -619,12 +621,11 @@ class MenuWin( object ):
def changeTheme(self, *args): def changeTheme(self, *args):
self.reloadSettings() self.reloadSettings()
self.applyTheme() self.applyTheme()
self.mainwin.RegenPlugins() self.mainwin.loadTheme()
def applyTheme(self): def applyTheme(self):
style_settings = Gtk.Settings.get_default() style_settings = Gtk.Settings.get_default()
mate_settings = Gio.Settings.new("org.mate.interface") desktop_theme = self.mate_settings.get_string('gtk-theme')
desktop_theme = mate_settings.get_string('gtk-theme')
if self.theme_name == "default": if self.theme_name == "default":
style_settings.set_property("gtk-theme-name", desktop_theme) style_settings.set_property("gtk-theme-name", desktop_theme)
else: else:
@ -643,12 +644,12 @@ class MenuWin( object ):
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT: elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
tmpbox = Gtk.VBox() tmpbox = Gtk.VBox()
self.systemlabel.set_angle( 270 ) self.systemlabel.set_angle( 270 )
self.button_box.reorder_child( self.button_icon, 1 ) self.button_box.reorder_child( self.button_icon, 0 )
self.button_icon.set_padding( 0, 5 ) self.button_icon.set_padding( 0, 5 )
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT: elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
tmpbox = Gtk.VBox() tmpbox = Gtk.VBox()
self.systemlabel.set_angle( 90 ) self.systemlabel.set_angle( 90 )
self.button_box.reorder_child( self.button_icon, 0 ) self.button_box.reorder_child( self.button_icon, 1 )
self.button_icon.set_padding( 0, 5 ) self.button_icon.set_padding( 0, 5 )
tmpbox.set_homogeneous( False ) tmpbox.set_homogeneous( False )
@ -688,10 +689,8 @@ class MenuWin( object ):
pass pass
def hotkeyChanged (self, schema, key): def hotkeyChanged (self, schema, key):
self.keybinder.ungrab()
self.hotkeyText = self.settings.get_string( "hot-key" ) self.hotkeyText = self.settings.get_string( "hot-key" )
if self.hotkeyText != "": self.keybinder.rebind(self.hotkeyText)
self.keybinder.grab(self.hotkeyText)
def sizeButton( self ): def sizeButton( self ):
if self.hideIcon: if self.hideIcon:
@ -706,8 +705,7 @@ class MenuWin( object ):
self.systemlabel.size_request(sl_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.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
if self.hideIcon: if self.hideIcon:
self.systemlabel.size_request(sl_req) self.applet.set_size_request( sl_req.width + 2, bi_req.height )
self.applet.set_size_request( sl_req.width + 2, -1 )
else: else:
self.applet.set_size_request( sl_req.width + bi_req.width + 5, bi_req.height ) self.applet.set_size_request( sl_req.width + bi_req.width + 5, bi_req.height )
else: else:

View File

@ -253,7 +253,7 @@ class pluginclass( object ):
self.builder.get_object("label7").set_text(_("All applications")) self.builder.get_object("label7").set_text(_("All applications"))
self.builder.get_object("label2").set_text(_("Applications")) self.builder.get_object("label2").set_text(_("Applications"))
self.mintMenuWin.SetHeadingStyle( [self.builder.get_object("label6"),self.builder.get_object("label2")] ) self.headingstocolor = [self.builder.get_object("label6"),self.builder.get_object("label2")]
self.numApps = 0 self.numApps = 0
# These properties are NECESSARY to maintain consistency # These properties are NECESSARY to maintain consistency
@ -268,7 +268,7 @@ class pluginclass( object ):
self.content_holder =self.builder.get_object( "Applications" ) self.content_holder =self.builder.get_object( "Applications" )
# Items to get custom colors # Items to get custom colors
self.itemstocolor = [self.builder.get_object( "viewport1" ),self.builder.get_object( "viewport2" ),self.builder.get_object( "viewport3" ),self.builder.get_object( "notebook2" ) ] self.itemstocolor = [self.builder.get_object( "viewport1" ),self.builder.get_object( "viewport2" ),self.builder.get_object( "viewport3" ) ]
# Unset all timers # Unset all timers
self.filterTimer = None self.filterTimer = None
@ -341,7 +341,7 @@ class pluginclass( object ):
self.panel = "top" self.panel = "top"
self.panel_position = -1 self.panel_position = -1
self.builder.get_object("searchButton").connect( "button-release-event", self.searchPopup ) self.builder.get_object("searchButton").connect( "button-press-event", self.searchPopup )
def refresh_apt_cache(self): def refresh_apt_cache(self):
if self.useAPT: if self.useAPT:
@ -571,17 +571,28 @@ class pluginclass( object ):
elif tabNum == 1: elif tabNum == 1:
notebook.set_current_page( 1 ) notebook.set_current_page( 1 )
self.lastActiveTab = tabNum
self.focusSearchEntry() self.focusSearchEntry()
self.lastActiveTab = tabNum
def Todos( self ): def Todos( self ):
self.searchEntry.connect( "popup-menu", self.blockOnPopup )
self.searchEntry.connect( "button-press-event", self.blockOnRightPress )
self.searchEntry.connect( "changed", self.Filter ) self.searchEntry.connect( "changed", self.Filter )
self.searchEntry.connect( "activate", self.Search ) self.searchEntry.connect( "activate", self.Search )
self.showAllAppsButton.connect( "clicked", lambda widget: self.changeTab( 1 ) ) self.showAllAppsButton.connect( "clicked", lambda widget: self.changeTab( 1 ) )
self.showFavoritesButton.connect( "clicked", lambda widget: self.changeTab( 0 ) ) self.showFavoritesButton.connect( "clicked", lambda widget: self.changeTab( 0 ) )
self.buildButtonList() self.buildButtonList()
def blockOnPopup( self, *args ):
self.mintMenuWin.stopHiding()
return False
def blockOnRightPress( self, widget, event ):
if event.button == 3:
self.mintMenuWin.stopHiding()
return False
def focusSearchEntry( self ): def focusSearchEntry( self ):
# grab_focus() does select all text, # grab_focus() does select all text,
# restoring the original selection is somehow broken, so just select the end # restoring the original selection is somehow broken, so just select the end
@ -640,7 +651,6 @@ class pluginclass( object ):
separator.set_visible_window(False) separator.set_visible_window(False)
separator.set_size_request(-1, 20) separator.set_size_request(-1, 20)
separator.type = "separator" separator.type = "separator"
self.mintMenuWin.SetPaneColors( [ separator ] )
separator.show_all() separator.show_all()
self.applicationsBox.add(separator) self.applicationsBox.add(separator)
self.suggestions.append(separator) self.suggestions.append(separator)
@ -719,7 +729,6 @@ class pluginclass( object ):
last_separator.set_visible_window(False) last_separator.set_visible_window(False)
last_separator.set_size_request(-1, 20) last_separator.set_size_request(-1, 20)
last_separator.type = "separator" last_separator.type = "separator"
self.mintMenuWin.SetPaneColors( [ last_separator ] )
last_separator.show_all() last_separator.show_all()
self.applicationsBox.add(last_separator) self.applicationsBox.add(last_separator)
self.suggestions.append(last_separator) self.suggestions.append(last_separator)
@ -775,7 +784,6 @@ class pluginclass( object ):
last_separator.set_visible_window(False) last_separator.set_visible_window(False)
last_separator.set_size_request(-1, 20) last_separator.set_size_request(-1, 20)
last_separator.type = "separator" last_separator.type = "separator"
self.mintMenuWin.SetPaneColors( [ last_separator ] )
last_separator.show_all() last_separator.show_all()
self.applicationsBox.add(last_separator) self.applicationsBox.add(last_separator)
self.suggestions.append(last_separator) self.suggestions.append(last_separator)
@ -878,15 +886,18 @@ class pluginclass( object ):
i.released() i.released()
i.set_relief( Gtk.ReliefStyle.NONE ) i.set_relief( Gtk.ReliefStyle.NONE )
widget.set_relief( Gtk.ReliefStyle.HALF ) widget.set_relief( Gtk.ReliefStyle.HALF )
widget.grab_focus()
self.searchEntry.set_text( "" )
self.applicationsScrolledWindow.get_vadjustment().set_value( 0 ) self.applicationsScrolledWindow.get_vadjustment().set_value( 0 )
def FilterAndClear( self, widget, category = None ):
self.searchEntry.set_text( "" )
self.Filter( widget, category )
# Forward all text to the search box # Forward all text to the search box
def keyPress( self, widget, event ): def keyPress( self, widget, event ):
if event.string.strip() != "" or event.keyval == Gdk.KEY_BackSpace: if event.string.strip() != "" or event.keyval == Gdk.KEY_BackSpace:
self.searchEntry.grab_focus()
gtk.gtk_editable_set_position(hash(self.searchEntry), -1)
self.searchEntry.event( event ) self.searchEntry.event( event )
return True return True
@ -950,10 +961,8 @@ class pluginclass( object ):
mTree.append(propsMenuItem) mTree.append(propsMenuItem)
mTree.show_all() mTree.show_all()
self.mintMenuWin.stopHiding()
gtk.gtk_menu_popup(hash(mTree), None, None, None, None, ev.button, ev.time) gtk.gtk_menu_popup(hash(mTree), None, None, None, None, ev.button, ev.time)
#self.mintMenuWin.grab()
mTree.connect( 'deactivate', self.onMenuPopupDeactivate)
else: else:
mTree = Gtk.Menu() mTree = Gtk.Menu()
mTree.set_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK | mTree.set_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK |
@ -971,9 +980,8 @@ class pluginclass( object ):
removeMenuItem.connect( "activate", self.onFavoritesRemove, widget ) removeMenuItem.connect( "activate", self.onFavoritesRemove, widget )
insertSpaceMenuItem.connect( "activate", self.onFavoritesInsertSpace, widget, insertBefore ) insertSpaceMenuItem.connect( "activate", self.onFavoritesInsertSpace, widget, insertBefore )
insertSeparatorMenuItem.connect( "activate", self.onFavoritesInsertSeparator, widget, insertBefore ) insertSeparatorMenuItem.connect( "activate", self.onFavoritesInsertSeparator, widget, insertBefore )
self.mintMenuWin.stopHiding()
gtk.gtk_menu_popup(hash(mTree), None, None, None, None, ev.button, ev.time) gtk.gtk_menu_popup(hash(mTree), None, None, None, None, ev.button, ev.time)
#self.mintMenuWin.grab()
mTree.connect( 'deactivate', self.onMenuPopupDeactivate)
def menuPopup( self, widget, event ): def menuPopup( self, widget, event ):
if event.button == 3: if event.button == 3:
@ -1034,11 +1042,8 @@ class pluginclass( object ):
startupMenuItem.set_active( False ) startupMenuItem.set_active( False )
startupMenuItem.connect( "toggled", self.onAddToStartup, widget ) startupMenuItem.connect( "toggled", self.onAddToStartup, widget )
mTree.connect( 'deactivate', self.onMenuPopupDeactivate) self.mintMenuWin.stopHiding()
gtk.gtk_menu_popup(hash(mTree), None, None, None, None, 0, 0) gtk.gtk_menu_popup(hash(mTree), None, None, None, None, event.button, event.time)
def onMenuPopupDeactivate( self, widget):
self.mintMenuWin.grab()
def searchPopup( self, widget=None, event=None ): def searchPopup( self, widget=None, event=None ):
menu = Gtk.Menu() menu = Gtk.Menu()
@ -1114,14 +1119,12 @@ class pluginclass( object ):
menu.show_all() menu.show_all()
gtk.gtk_menu_popup(hash(menu), None, None, None, None, 3, 0) self.mintMenuWin.stopHiding()
gtk.gtk_menu_popup(hash(menu), None, None, None, None, event.button, event.time)
#menu.attach_to_widget(self.searchButton, None) #menu.attach_to_widget(self.searchButton, None)
#menu.reposition() #menu.reposition()
#menu.reposition() #menu.reposition()
#self.mintMenuWin.grab()
menu.connect( 'deactivate', self.onMenuPopupDeactivate)
self.focusSearchEntry()
return True return True
def pos_func(self, menu=None): def pos_func(self, menu=None):
@ -1348,10 +1351,9 @@ class pluginclass( object ):
space = Gtk.EventBox() space = Gtk.EventBox()
space.set_size_request( -1, 20 ) space.set_size_request( -1, 20 )
space.set_visible_window(False) space.set_visible_window(False)
space.connect( "button_release_event", self.favPopup ) space.connect( "button-press-event", self.favPopup )
space.type = "space" space.type = "space"
self.mintMenuWin.SetPaneColors( [ space ] )
space.show() space.show()
return space return space
@ -1361,13 +1363,12 @@ class pluginclass( object ):
separator.set_size_request( -1, 20 ) separator.set_size_request( -1, 20 )
separator.type = "separator" separator.type = "separator"
self.mintMenuWin.SetPaneColors( [ separator ] )
separator.show_all() separator.show_all()
box = Gtk.EventBox() box = Gtk.EventBox()
box.type = "separator" box.type = "separator"
box.add(separator) box.add(separator)
box.set_visible_window(False) box.set_visible_window(False)
box.connect( "button_release_event", self.favPopup ) box.connect( "button-press-event", self.favPopup )
box.show_all() box.show_all()
return box return box
@ -1405,7 +1406,7 @@ class pluginclass( object ):
if favButton.appExec: if favButton.appExec:
favButton.show() favButton.show()
favButton.connect( "popup-menu", self.favPopup ) favButton.connect( "popup-menu", self.favPopup )
favButton.connect( "button_release_event", self.favPopup ) favButton.connect( "button-press-event", self.favPopup )
favButton.connect( "focus-in-event", self.scrollItemIntoView ) favButton.connect( "focus-in-event", self.scrollItemIntoView )
favButton.connect( "clicked", lambda w: self.mintMenuWin.hide() ) favButton.connect( "clicked", lambda w: self.mintMenuWin.hide() )
@ -1677,7 +1678,7 @@ class pluginclass( object ):
else: else:
item["button"].mouseOverHandlerIds = None item["button"].mouseOverHandlerIds = None
item["button"].connect( "clicked", self.Filter, item["filter"] ) item["button"].connect( "clicked", self.FilterAndClear, item["filter"] )
item["button"].connect( "focus-in-event", self.categoryBtnFocus, item["filter"] ) item["button"].connect( "focus-in-event", self.categoryBtnFocus, item["filter"] )
item["button"].show() item["button"].show()

View File

@ -283,7 +283,6 @@ class ApplicationLauncher( easyButton ):
self.connectSelf( "focus-in-event", self.onFocusIn ) self.connectSelf( "focus-in-event", self.onFocusIn )
self.connectSelf( "focus-out-event", self.onFocusOut ) self.connectSelf( "focus-out-event", self.onFocusOut )
self.connectSelf( "enter-notify-event", self.onEnterNotify )
self.connectSelf( "clicked", self.execute ) self.connectSelf( "clicked", self.execute )
@ -332,9 +331,6 @@ class ApplicationLauncher( easyButton ):
def onFocusOut( self, widget, event ): def onFocusOut( self, widget, event ):
self.set_relief( Gtk.ReliefStyle.NONE ) self.set_relief( Gtk.ReliefStyle.NONE )
def onEnterNotify( self, widget, event ):
self.grab_focus()
def setupLabels( self ): def setupLabels( self ):
self.addLabel( self.appName ) self.addLabel( self.appName )

View File

@ -4,7 +4,6 @@ gi.require_version("Gtk", "2.0")
from gi.repository import Gtk, Pango from gi.repository import Gtk, Pango
import sys import sys
import os import os
import gobject
import datetime import datetime
import fcntl import fcntl
from easygsettings import EasyGSettings from easygsettings import EasyGSettings

View File

@ -0,0 +1,84 @@
import gi
gi.require_version("Gtk", "2.0")
from Xlib.display import Display
from Xlib import X, error
from gi.repository import Gtk, Gdk, GObject, GLib
import threading
import ctypes
from ctypes import *
gdk = CDLL("libgdk-x11-2.0.so.0")
gtk = CDLL("libgtk-x11-2.0.so.0")
class PointerMonitor(GObject.GObject, threading.Thread):
__gsignals__ = {
'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
}
def __init__(self):
GObject.GObject.__init__ (self)
threading.Thread.__init__ (self)
self.setDaemon (True)
self.display = Display()
self.root = self.display.screen().root
self.windows = []
self.topWindows = []
# Receives GDK windows
def addWindowToMonitor(self, window):
xWindow = self.display.create_resource_object("window", gdk.gdk_x11_drawable_get_xid(hash(window)))
self.windows.append(xWindow)
self.topWindows.append(self.getToplevelParent(xWindow))
def getToplevelParent(self, window):
parent = window.query_tree().parent
if parent == self.root:
return window
else:
return self.getToplevelParent(parent)
def grabPointer(self):
self.root.grab_button(X.AnyButton, X.AnyModifier, True, X.ButtonPressMask, X.GrabModeSync, X.GrabModeAsync, 0, 0)
self.display.flush()
def ungrabPointer(self):
self.root.ungrab_button(X.AnyButton, X.AnyModifier)
self.display.flush()
def idle(self):
self.emit("activate")
return False
def activate(self):
GLib.idle_add(self.run)
def run(self):
self.running = True
while self.running:
event = self.display.next_event()
try:
if event.type == X.ButtonPress:
# Check if pointer is inside monitored windows
for w, topW in zip(self.windows, self.topWindows):
if event.child == topW:
if topW == w:
break
else:
p = w.query_pointer()
g = w.get_geometry()
if p.win_x >= 0 and p.win_y >= 0 and p.win_x <= g.width and p.win_y <= g.height:
break
else:
# Is outside, so activate
GLib.idle_add(self.idle)
self.display.allow_events(X.ReplayPointer, event.time)
except Exception as e:
print "Unexpected error: " + str(e)
def stop(self):
self.running = False
self.root.ungrab_button(X.AnyButton, X.AnyModifier)
self.display.close()