Search code examples
eclipsekeyboard-shortcutsrcp

How to ensure that my key bindings have priority over other definitions


I am developing an RCP app. The app has an execution mode where I want to enable various key bindings to control Start, Stop, Continue, Repeat etc. The bindings will be enabled using an 'ExecutionContext' which is set when any of the relevant views are activated.

The context switching is done in each of the 'Execution' views.

@Override
public final void createPartControl(Composite parent)
{
    addPartListener();

    ...
}

private void addPartListener()
{
    this.getViewSite().getPage().addPartListener(new IPartListener2()
    {
        IContextActivation token = null;

        @Override
        public void partDeactivated(IWorkbenchPartReference partRef)
        {
            if (token != null)
            {
                System.out.println("End exec context");
                IContextService contextService = (IContextService) PlatformUI.getWorkbench().getService(
                        IContextService.class);
                contextService.deactivateContext(token);
                token = null;
            }
        }

        @Override
        public void partActivated(IWorkbenchPartReference partRef)
        {
            System.out.println("Set exec context");
            IContextService contextService = (IContextService) PlatformUI.getWorkbench().getService(
                    IContextService.class);
            token = contextService.activateContext("AtfExecutionContext");
        }
    });

}

I can see via Console messages that my context is being set and some of the key bindings are working as expected.

However, if a key binding has already been assigned from another plugin, that binding has priority. E.g. I want to use Ctrl+F8 to stop but when that is pressed I get the 'Next perspective' action which is the workbench default.

The binding definition is

   <extension
         point="org.eclipse.ui.bindings">
      <scheme
            id="atfscheme"
            name="atfscheme"
            parentId="org.eclipse.ui.defaultAcceleratorConfiguration">
      </scheme>
      <key
            commandId="com.xxx.atf.model.ui.commands.ExecKey.Start"
            contextId="AtfExecutionContext"
            schemeId="atfscheme"
            sequence="M1+M2+F5">
<!-- F5 does not work but Ctrl-Shift-F5 does -->
      </key>
   </extension>
   <extension
         point="org.eclipse.ui.contexts">
      <context
            id="AtfExecutionContext"
            name="AtfExecutionContext"
            parentId="org.eclipse.debug.ui.debugging">
<!-- have tried various parentid values... -->
      </context>
   </extension>

It seems that only previously undefined accelerators work. What do I have to do to override existing definitions and activate mine when my context has been set?


Solution

  • There is a separate context service for each part, you must use the correct context service.

    It isn't necessary to activate / deactivate the context on part activation / deactivation. The separate context services will deal with that automatically.

    So activate in createPartControl with:

    IContextService contextService = getSite().getService(IContextService.class);
    
    token = contextService.activateContext("AtfExecutionContext");
    

    and deactivate when the part closes.

    You are also defining a new key binding scheme - that has to be activated separately and isn't what you want here. Just remove that and just use org.eclipse.ui.defaultAcceleratorConfiguration as the schemeId