Can’t change some menu shortcuts



  • I wanted to remove all menu shortcuts but apparently some are not added to the preferences yet. It's not possible to change them using a script either:

    ('Edit', 'Select All')
    ('Edit', 'Copy As Component')
    ('Edit', 'Paste in Layer')
    ('Python', 'Show Log File')
    ('Python', 'Jump Back')
    ('Window', 'Minimize')
    ('Window', 'New Space Center')
    ('Window', 'Zoom in A Bit')
    ('Window', 'Zoom out A Bit')
    ('Help', 'Application Help')

    Sorry for nitpicking, but I need to remove them for a tool that its shortcuts can conflict with them.


  • admin

    I would advise to take a different route... :)

    Prepolator and MetricsMachine extensions have their own shortcuts with an option to overwrite the existing shortcuts. There are just not enough modifiers and keys...

    an example:

    subscribe when your tool/window becomes active and unsubscribe when it deactivates!

    import AppKit
    
    _specialCases = [
        ("w", AppKit.NSCommandKeyMask),  # close window, dont subscribe afterwards
        ("`", AppKit.NSCommandKeyMask),  # jump to next window, dont subscribe afterwards
        ("`", AppKit.NSCommandKeyMask | AppKit.NSShiftKeyMask),  # jump to prev window, don't subscribe afterwards
    ]
    
    class KeyEventMonitor(object):
        
        def __init__(self):
            self.monitor = None
            
        def subscribe(self):
            self.unsubscribe()
            self.monitor = AppKit.NSEvent.addLocalMonitorForEventsMatchingMask_handler_(AppKit.NSKeyDownMask, self.eventHandler)
    
        def unsubscribe(self):
            if self.monitor is not None:
                AppKit.NSEvent.removeMonitor_(self.monitor)
            self.monitor = None
        
        def eventHandler(self, event):
            inputKey = event.charactersIgnoringModifiers()
            eventModifiers = event.modifierFlags()
            
            # check if inputKey and eventModifiers match with your shortcuts
            found = True
            if inputKey = "s" and eventModifiers & AppKit.NSCommandKeyMask:
                # overwrite cmd s
                pass
            else:
                found = False
    
            if not found:
                self.unsubscribe()
                AppKit.NSApp().sendEvent_(event)
                if (inputKey, eventModifiers) not in _specialCases:
                    # don't resubscribe when the window is closed
                    self.subscribe()
    


  • I didn't think of that! Thank you, Frederik. This is very interesting.



  • I rewrote your code in another way that is more clear to me, maybe others would find this useful. This opens a window in which, the start button initiates the override RF keys state and also there is a stop button:

    import AppKit
    from vanilla import *
    
    _ignore = {'⌘s', '⇧⌘s', '⌘q', '⇧⌘q'}
    
    MODIFIER_INT_TO_STR = {
    				AppKit.NSCommandKeyMask: '⌘',
    				AppKit.NSControlKeyMask: '⌃',
    				AppKit.NSAlternateKeyMask: '⌥',
    				AppKit.NSShiftKeyMask: '⇧',
    				AppKit.NSCommandKeyMask | AppKit.NSShiftKeyMask: '⇧⌘',
    				AppKit.NSCommandKeyMask | AppKit.NSAlternateKeyMask: '⌘⌥',
    				AppKit.NSCommandKeyMask | AppKit.NSControlKeyMask : '⌃⌘',
    				AppKit.NSControlKeyMask | AppKit.NSShiftKeyMask: '⇧⌃',
    				AppKit.NSAlternateKeyMask | AppKit.NSShiftKeyMask: '⇧⌥',
    				}
    
    class KeyEventMonitor(object):
    
    	def __init__(self):
    		self.monitor = None
    		self.w = Window((300, 90), "KeyEventMonitor Debuggin window")
    		self.w.b1 = Button((10, 10, -10, 20), "Stop",
    							callback=self.stop)
    		self.w.b2 = Button((10, 40, -10, 20), "Start",
    							callback=self.start)
    		self.w.bind("close", self.stop)
    		self.w.open()
    
    	def stop(self, sender):
    		self._stopOverridingRFkeys()
    
    	def start(self, sender):
    		self._startOverridingRFkeys()
    
    	def _startOverridingRFkeys(self):
    		self._stopOverridingRFkeys()
    		self.monitor = AppKit.NSEvent.addLocalMonitorForEventsMatchingMask_handler_(
    			AppKit.NSKeyDownMask, self._keyDown)
    
    	def _stopOverridingRFkeys(self):
    		if self.monitor is not None:
    			AppKit.NSEvent.removeMonitor_(self.monitor)
    		self.monitor = None
    
    	def _keyDown(self, event):
    		allKeys = MODIFIER_TO_STR.get(event.modifierFlags(), '') + event.charactersIgnoringModifiers().lower()
    		if allKeys in _ignore:
    			print("overriding %s" %allKeys)
    		else:
    			self._stopOverridingRFkeys()
    			AppKit.NSApp().sendEvent_(event)
    			self._startOverridingRFkeys()
    
    
    KeyEventMonitor()