This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 407749 - Keyboard shortcuts for certain practically macro - command creation using ICommandService
Summary: Keyboard shortcuts for certain practically macro - command creation using ICo...
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: IDE (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 4.4 M1   Edit
Assignee: Paul Webster CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 379162 (view as bug list)
Depends on:
Blocks: 414794
  Show dependency tree
 
Reported: 2013-05-10 10:50 EDT by Harinath Atmaram CLA
Modified: 2013-09-25 15:47 EDT (History)
6 users (show)

See Also:


Attachments
practically macro plugin (latest version) that I use (192.14 KB, application/octet-stream)
2013-05-10 10:54 EDT, Harinath Atmaram CLA
no flags Details
log file (19.60 KB, application/octet-stream)
2013-05-13 11:30 EDT, Harinath Atmaram CLA
no flags Details
old log file (138.15 KB, text/plain)
2013-05-13 11:33 EDT, Harinath Atmaram CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Harinath Atmaram CLA 2013-05-10 10:50:20 EDT
I used Eclipse Indigo (C/C++) and practically macro plugin (with keyboard shortcuts for custom macros). However, when I tried Eclipse Juno and Kepler, the keyboard shortcuts do not work (the macros work when played manually without using the keyboard shortcuts).
Comment 1 Harinath Atmaram CLA 2013-05-10 10:54:52 EDT
Created attachment 230779 [details]
practically macro plugin (latest version) that I use
Comment 2 Paul Webster CLA 2013-05-13 09:11:11 EDT
Please attach any errors in your error log.  <workspace>/.metadata/.log

PW
Comment 3 Harinath Atmaram CLA 2013-05-13 11:30:27 EDT
Created attachment 230874 [details]
log file

Here is the log file. I deleted the old one, opened Eclipse Juno (updated to latest available), and tried my macro key binding (Ctrl+Shift+A) and closed Eclipse. Interestingly, no key binding errors show up. I have also tried various key bindings (and ensured they have no conflicts), but none of them work.

Thanks for your help!
Comment 4 Harinath Atmaram CLA 2013-05-13 11:33:22 EDT
Created attachment 230875 [details]
old log file

I have attached the old log file, that shows several key binding errors from last week. If you need anything else please let me know. Thanks again!
Comment 5 Paul Webster CLA 2013-05-13 11:37:35 EDT
(In reply to comment #3)
> Here is the log file. I deleted the old one, opened Eclipse Juno (updated to
> latest available), and tried my macro key binding (Ctrl+Shift+A) and closed
> Eclipse. Interestingly, no key binding errors show up. I have also tried
> various key bindings (and ensured they have no conflicts), but none of them


I don't see CTRL+SHIFT+A defined in the macro plugin that you attached here, only CTRL+SHIFT+P/R/Q (in the plugin.xml).  To find out what's going on you would have to do some tracing: http://wiki.eclipse.org/Platform_Command_Framework#Tracing_Option

You replace the command id in org.eclipse.ui/trace/handlers.verbose.commandId=org.eclipse.jdt.ui.navigate.open.type with the command id of the command you expect to execute with your keybinding.

PW
Comment 6 Harinath Atmaram CLA 2013-06-20 17:30:05 EDT
Sorry for the delay.  With Practically Macro, users can create and save custom macros.  Keybindings can be assigned to these custom macros in the Preferences->General->Keys dialog.  We tried the tracing option you suggested, but the debug.log file is completely empty.   The non-custom, preset CTRL+SHIFT+P/R/Q macro keybindings do work correctly, but our custom defined macro keybindings do not work in Juno or Kepler.  The custom macros work when activated from the menu bar, it is only the keybindings that do not play the macro.  Thanks for all your help.
Comment 7 Paul Webster CLA 2013-06-21 08:38:44 EDT
How are you attaching the macro to a keybinding?

PW
Comment 8 Harinath Atmaram CLA 2013-06-21 10:54:55 EDT
In Eclipse, I go to Window->Preferences->Keys, and the custom macro I created shows up under "Command" with the name with which I saved the macro. Under "Binding" I choose a keyboard shortcut (and make sure there are no conflicts). This works fine in Gallileo, Helios and Indigo. Thanks.
Comment 9 Paul Webster CLA 2013-06-21 11:23:19 EDT
(In reply to comment #8)
> In Eclipse, I go to Window->Preferences->Keys, and the custom macro I
> created shows up under "Command" with the name with which I saved the macro.
> Under "Binding" I choose a keyboard shortcut (and make sure there are no
> conflicts). This works fine in Gallileo, Helios and Indigo. Thanks.

What matters is how the plugin creates the command in eclipse if the user is left to create the keybinding themselves.

You need to open a bug against the providers of the plugin and direct them here as well.

PW
Comment 10 Ernest Pasour CLA 2013-06-28 22:22:07 EDT
Hi, I'm the author of the plugin that's at issue here.  After digging into this a little bit, I think I have a workaround, but probably not a good one.  Here are the details:
1. The plugin was written against Eclipse 3.4.  It does not use any e4 apis.
2. To create a command, I am creating a Command and using the HandlerService to associate the command with code that will execute it (with activateHandler).  
3. I recreate the commands in my plugin each time Eclipse starts
4. The commands I create do show up in the General->Keys dialog, along with any keystrokes that have been assigned to those commands

The problems:
1. Any key binding I assign is ignored.  After debugging, the problem appears to be that the ApplicationImpl class doesn't contain my dynamic commands in its list of commands.  As a result, the binding table fails to update.  I have worked around that by explicitly adding to that list of commands when my plugin starts.  
  For each command I create, I am doing this:
        ...newCommand is defined above...
	IEclipseContext context=(IEclipseContext)PlatformUI.getWorkbench().getAdapter(IEclipseContext.class);
	MCommand anMCommand=CommandsFactoryImpl.INSTANCE.createCommand();
	anMCommand.setElementId(newCommand.getId());
	try
	{
		anMCommand.setCommandName(newCommand.getName());
	}
	catch (Exception e)
	{
		e.printStackTrace();
	}
	MApplication app=context.get(MApplication.class);
	List<MCommand> allCommands=app.getCommands();
	allCommands.add(anMCommand);

2. If a keybinding exists from a previous eclipse session, that keybinding isn't associated in the binding table.  I assume this is because my plugin starts too late.  My hack to work around that is to reapply all the keys as happens from the General->Keys dialog.  Here's the code for that:
        IEclipseContext context=(IEclipseContext)PlatformUI.getWorkbench().getAdapter(IEclipseContext.class);
        final IBindingService bindingService=context.get(IBindingService.class);
	BindingManager bindingManager=context.get(BindingManager.class);
	Display.getDefault().asyncExec(new Runnable() {
	public void run() {
	try {
	            		   bindingService.savePreferences(bindingService.getActiveScheme(), bindingService.getBindings());
	} catch (IOException e) {
	     e.printStackTrace();
	}
	}
	});


I'm not sure why either of these hacks should be necessary since the system (in the form the key assignment dialog) obviously knows about the commands and the key bindings.  So maybe there is an Eclipse bug here.  At minimum, I hope there's a better way to register dynamic commands properly.
Comment 11 Paul Webster CLA 2013-07-03 11:47:04 EDT
Hi Ernest, thanks for dropping by.

I think we might be causing you a problem in our Command Model to Command/CommandManager code.  In theory on startup our org.eclipse.ui.internal.CommandToModelProcessor makes sure that anything in an extension point has a model representation.  Our org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon takes the model and makes sure that there are valid Command objects for it.

How are you adding your dynamic command in the first place?  org.eclipse.ui.commands.ICommandService.getCommand(String) and then using command.define(*) ?  It might be that we don't have a callback to update the model in that case.

You don't define the keybinding yourself, right?  Just depend on users doing it (and our losing commands is preventing them from being read back in correctly)?

Thanks for any insight,
Paul
Comment 12 Ernest Pasour CLA 2013-07-03 12:43:11 EDT
Paul, thanks for your response.

Here is how I create a command (note that I also have my own category if that matters):

 ...macro is one of my objects...
 ICommandService cs = MacroManager.getOldCommandService();
 Category category=cs.getCategory(MacroManager.UserMacroCategoryID);
 Command newCommand=cs.getCommand(macro.getID());
 newCommand.define(macro.getName(), macro.getDescription(), category);
 newCommand.setHandler(new MacroHandler(macro.getID()));
 IHandlerService hs=MacroManager.getOldHandlerService();
 if (hs!=null)
    hs.activateHandler(newCommand.getId(), newCommand.getHandler());


You are correct; I do not create any keystroke bindings via code.
Comment 13 Paul Webster CLA 2013-07-03 13:09:23 EDT
(In reply to comment #12)
> 
>  ...macro is one of my objects...
>  ICommandService cs = MacroManager.getOldCommandService();
>  Category category=cs.getCategory(MacroManager.UserMacroCategoryID);
>  Command newCommand=cs.getCommand(macro.getID());
>  newCommand.define(macro.getName(), macro.getDescription(), category);
>  newCommand.setHandler(new MacroHandler(macro.getID()));
>  IHandlerService hs=MacroManager.getOldHandlerService();
>  if (hs!=null)
>     hs.activateHandler(newCommand.getId(), newCommand.getHandler());

This looks like a reasonable use of the old API except for:

newCommand.setHandler(new MacroHandler(macro.getID()));

If you are activating a handler, you don't need to set it on the command.  It's also not a recommended practice in 3.6.x and on as it can interfere with correct operation of the commands.  Will your code work (on 3.x) even if you remove that line?

So I suspect if we start persisting the commands defined by the CommandManager, that will fix your problems in 4.x.

PW
Comment 14 Ernest Pasour CLA 2013-07-03 14:22:36 EDT
(In reply to comment #13)
> (In reply to comment #12)
> > 
> >  ...macro is one of my objects...
> >  ICommandService cs = MacroManager.getOldCommandService();
> >  Category category=cs.getCategory(MacroManager.UserMacroCategoryID);
> >  Command newCommand=cs.getCommand(macro.getID());
> >  newCommand.define(macro.getName(), macro.getDescription(), category);
> >  newCommand.setHandler(new MacroHandler(macro.getID()));
> >  IHandlerService hs=MacroManager.getOldHandlerService();
> >  if (hs!=null)
> >     hs.activateHandler(newCommand.getId(), newCommand.getHandler());
> 
> This looks like a reasonable use of the old API except for:
> 
> newCommand.setHandler(new MacroHandler(macro.getID()));
> 
> If you are activating a handler, you don't need to set it on the command. 
> It's also not a recommended practice in 3.6.x and on as it can interfere
> with correct operation of the commands.  Will your code work (on 3.x) even
> if you remove that line?
> 
> So I suspect if we start persisting the commands defined by the
> CommandManager, that will fix your problems in 4.x.
> 
> PW

re: setHandler.  Who knows :)  I first wrote this code against 3.4 back in 2008.  I can certainly remove it and see.

I currently have my hacks (from comment #10) wrapped in try..catch blocks.  Will leaving them in (so that 4.2 and 4.3 work) likely cause any harm, either in 4.3 or subsequent releases?  I assume the call to savePreferences is likely pretty safe.  The hack to augment the list of MCommands is much sketchier.

It would be great if you can make the command fix in future versions of Eclipse.
Comment 15 Ernest Pasour CLA 2013-07-04 14:24:46 EDT
Hmm...a problem.

I tried commenting out the call to setHandler that you flagged: "newCommand.setHandler(new MacroHandler(macro.getID()));"

Results in 4.3: the key bindings no longer work.  So it seems like calling activateHandler is *not* sufficient.  Note that I am using IHandlerService, not EHandlerService.

I did not try again Eclpse 3.x.
Comment 16 Paul Webster CLA 2013-07-04 14:30:34 EDT
(In reply to comment #15)
> Hmm...a problem.
> 
> I tried commenting out the call to setHandler that you flagged:
> "newCommand.setHandler(new MacroHandler(macro.getID()));"


Thanks for checking ... I'll try and reproduce this as well, maybe we can get that fixed in Kepler SR1

PW
Comment 17 Paul Webster CLA 2013-07-31 15:45:25 EDT
Here's a possible fix: 

https://git.eclipse.org/r/15028

I'll need to add some test scenarios to make sure it works.

PW
Comment 18 Paul Webster CLA 2013-08-01 14:08:20 EDT
OK, in testing the keybinding persists with the fix and disappears without it.

Paul, could you please review this in the context of master/4.4 ?

My test involves dynamically creating a command (handler below), defining a keybinding for it, restarting the eclipse, and then checking the keybinding.

public Object execute(ExecutionEvent event) throws ExecutionException {
	IWorkbenchWindow window = HandlerUtil
			.getActiveWorkbenchWindowChecked(event);
	ICommandService cmdService = (ICommandService) window.getService(ICommandService.class);
	Category cat = cmdService.getCategory("org.eclipse.ui.category.file");
	Command cmd = cmdService.getCommand("new.tmp.command");
	cmd.define("Temp Command Name", "Tmp command to get thrings going", cat);
	return null;
}


PW
Comment 20 Paul Webster CLA 2013-08-09 15:04:02 EDT
.
Comment 21 Paul Webster CLA 2013-09-25 15:47:41 EDT
*** Bug 379162 has been marked as a duplicate of this bug. ***