Community
Participate
Working Groups
I have a plugin that uses contexts (org.eclipse.ui.contexts extension point) to restrict some key bindings to a specific View part. The context is activated/deactivated programmatically using the IContextService#activateContext and IContextService#deactivate context methods. This works fine in E3.7, and the key bindings are applied correctly when the View Part is activated. However, on E4 using the compatibility layer, it seems that activating/deactivating the context has no effect, and the key bindings are always applied i.e. not restricted to the view part anymore.
If you can describe a small example, I'll test it. ex: do you use activate your context once when you view is created (that scopes it to when the view is active)? Or do you need to narrow the scope of your keybindings even more, say only when your view is active and in a certain mode? What context do your contexts derive from? PW
(In reply to comment #1) > If you can describe a small example, I'll test it. > > ex: do you use activate your context once when you view is created (that scopes > it to when the view is active)? > > Or do you need to narrow the scope of your keybindings even more, say only when > your view is active and in a certain mode? I actually tried both ways i.e. activating the context in the ViewPart createPartControl method and also by activating the context in a PartListener I implemented in the View part e.g. getSite().getPage().addPartListener(fPartListener = new IPartListener() { ... public void partDeactivated(IWorkbenchPart part) { if (part instanceof MyView && null != myContext) { IContextService contextService = (IContextService) getSite().getService(IContextService.class); contextService.deactivateContext(myContext); myContext = null; } } ... public void partActivated(IWorkbenchPart part) { if (part instanceof ReviewNavigatorView && null == fR4EContext) { IContextService contextService = (IContextService) getSite().getService(IContextService.class); fR4EContext = contextService.activateContext(R4EUIConstants.R4E_CONTEXT_ID); } > > What context do your contexts derive from? > > PW
Sorry I mistyped the code should read getSite().getPage().addPartListener(fPartListener = new IPartListener() { ... public void partDeactivated(IWorkbenchPart part) { if (part instanceof MyView && null != myContext) { IContextService contextService = (IContextService) getSite().getService(IContextService.class); contextService.deactivateContext(myContext); myContext = null; } } ... public void partActivated(IWorkbenchPart part) { if (part instanceof MyView && null == myContext) { IContextService contextService = (IContextService)getSite().getService(IContextService.class); myContext = contextService.activateContext(R4EUIConstants.MY_CONTEXT_ID); } } }); > > What context do your contexts derive from? My custom context has org.eclipse.ui.contexts.window has the parent /Sebastien
I would recommend doing activating your context once in createPartControl(*), as a general best practice for your usecase. Could you try that again as a workaround? IContextService contextService = (IContextService)getSite().getService(IContextService.class); contextService.activateContext(R4EUIConstants.R4E_CONTEXT_ID); But the partActived/partDeactivated should work as well, we'll look into it. PW
(In reply to comment #4) > I would recommend doing activating your context once in createPartControl(*), > as a general best practice for your usecase. Could you try that again as a > workaround? > > IContextService contextService > = (IContextService)getSite().getService(IContextService.class); > contextService.activateContext(R4EUIConstants.R4E_CONTEXT_ID); > > > But the partActived/partDeactivated should work as well, we'll look into it. > > PW Actually activating the context in the createPartControl is what I've done initially, but it didn't work either, so I then tried to do it in partActived/partDeactivated. So bottom line, the workaround you are suggesting doesn't seem to work either /Sebastien
Created attachment 220160 [details] Example demonstrating the problem Here's a small demo bundle (ca.mt.dummy) that: * creates a custom keybinding context ca.mt.dummy.context; * adds a "dummy" editor that activates the ca.mt.dummy.context using the context service; * binds M1+D in the ca.mt.dummy.context to an open-dummy-editor command. Create a new Eclipse product launch with org.eclipse.sdk.ide that includes this bundle. After opening the first dummy editor (using the Dummy toolitem or Help > Open Dummy Editor), you should be able to use M1+D from within a dummy editor to open new dummy editors. It sometimes works, but often fails. The cause is that each part's context-activation causes a RunAndTrack (a ContextService$UpdateExpression) against activePart to enable or disable the applicable context as the part is activated or deactivated. But we can't control the ordering that these RATs are notified, and so we sometimes (often?) process the part-activation (which adds the keybinding-context) and then the part-deactivation (which removes the keybinding-context), such that the result is entirely dependent on the RAT order. Working on a fix.
The problem is a bit more straightforward than I realized. Whenever the active part changes, the ContextService$UpdateExpression RATs are invoked. The in pseudocode, the RAT does: if activePart = me then activate my context else deactivate my context But the deactive-my-context doesn't check that this part *was* the last active part. So if I have three Dummy Editors open and switch to the Package Explorer, there are three deactivations of ca.mt.dummy.context; if I switch back to a Dummy Editor, I get one activation and 2 deactivations. Somehow the UpdateExpression RATs need to know whether they were active previously.
(In reply to comment #5) > Actually activating the context in the createPartControl is what I've done > initially, but it didn't work either, so I then tried to do it in > partActived/partDeactivated. Sebastien: delay the re-activation using a Display.timerExec(), like say 30ms.
Hi there I have a similar problem, can you please tell me if it belongs to this bug or I should open a new one? we have a pure e4 application. We have a part with 3 grids in it. We want the users to be able to delete a row using the DEL key. For this, each table has its own command / handler (we have already a context menu using these handlers and they work fine). So I defined 3 binding contexts on the part. Then I defined a Focus Listener on the grids and so I dynamically activated / deactivated them on focus gained / lost: contextService.activateContext("myContext1"); But...it's not working. Always the same handler is called. I added a key listener to the table and calling contextService.getActiveContextIds(); I saw that there are always all my 3 contexts in there (also one from eclipse: org.eclipse.ui.contexts.window). That means, they never get deactivated (I debugged and saw the deactivate method gets called...no idea why it has no effect?!) Am I doing something wrong? Or is it a bug? Or is there a quicker way to do this? Thanks Laura
(In reply to comment #9) > Hi there Hi Laura, Could you please open a new bug for this? Eclipse Platform/UI Thanx PW
> Could you please open a new bug for this? Eclipse Platform/UI Will do it. THx Laura
Brian, what if we cached the last eval from each UpdateExpression, and only executed an activate/deactivate if the new eval changed. That might not 100% solve the problem, but at least that should reduce the # of contenders down to 2 (one deactivate and one activate)? PW
Brian, I've released a caching step to http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=R4_2_maintenance&id=f3024549d09ec72b0326e8d06563ae53bb77cd99 It should only activate or deactivate when its expression actually changes. I've also added an improvement via bug 390379 that includes ref-counting and only firing when the activeContexts IDs would change. But I'm still able to replicate the problem via your example ... it needs some more investigation. PW
With Bogdan's fix from http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=gheorghe/contextDeferUpdates&id=e7d7c1533308013507bc092d9bda787ea974f99d it now reliably fails with one more deactivate than activate when using M1+D to open the next editor. While in the PartServiceImpl.activate it issues a ModelServiceImpl.bringToTop That creates the DummyEditor which activates its context in createPartControl(*). That creates an UpdateExpression RAT, which evaluates to false as the active part is not yet the new one. That's one deactivateContext. Then WorkbenchPage sets the new active editor, and UpdateExpression is run again, adding a activateContext. Then the UpdateExpression from the original editor runs, adding a deactivateContext. That leaves us with +1 and -2, which wipes out the existing context already activated. PW
When the UpdateExpression is first created, it goes from null to FALSE, and then from FALSE to true. The transition from null to FALSE shouldn't deactivate a context, as it has never been activated. http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=R4_2_maintenance&id=2fc58f83f01d492b66cfbdb08ab67ba4da64505d Brian, could you also test to make sure it works in your scenarios. Sebastien, it should show up in this week's M build, M20121114-1200 from http://download.eclipse.org/eclipse/downloads/ if you could test it in your scenario when it becomes available. PW
This greatly improves the situation. But if I open several dummy editors, and then close an editor (thus switching to a different dummy editor), the context isn't restored.
On closing a part, the dispose blindly deactivated its contexts: http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=R4_2_maintenance&id=dae54ce66efbd830eac95db3dea446306f3ef47b On close, disposing the part causes an extra deactivate after the UpdateExpression for that part has done the deactivate. The UpdateExpression needs to do the final deactivate, as it knows via its cached value if it has an activate to clear. PW
.
(In reply to comment #15) > When the UpdateExpression is first created, it goes from null to FALSE, and > then from FALSE to true. The transition from null to FALSE shouldn't > deactivate a context, as it has never been activated. > > http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/ > ?h=R4_2_maintenance&id=2fc58f83f01d492b66cfbdb08ab67ba4da64505d > > Brian, could you also test to make sure it works in your scenarios. > > Sebastien, it should show up in this week's M build, M20121114-1200 from > http://download.eclipse.org/eclipse/downloads/ if you could test it in your > scenario when it becomes available. > > PW Sure I will try it out as ASAP. /Sebas
I tested the new code in M20121121-1200 and it seems the solution is partly working. Basically all Key Bindings that are using default contextIds seem to work fine. However, I also have bindings that use a context I defined myself (which has org.eclipse.ui.contexts.window as parent) and these ones do not seem to be activated and do not appear anywhere. See included plugin.xml file for our plugin setup
Created attachment 223984 [details] plugin.xml file
(In reply to comment #20) > I tested the new code in M20121121-1200 and it seems the solution is > partly working. > > Basically all Key Bindings that are using default contextIds seem to work > fine. However, I also have bindings that use a context I defined myself > (which has org.eclipse.ui.contexts.window as parent) and these ones do not > seem to be activated and do not appear anywhere. > > See included plugin.xml file for our plugin setup Actually I just re-read the whole thread (it's been a long time), and it seems that we get the opposite effect as the original problem i.e. my custom keys bindings, the ones that are defined with my custom context, now do not appear anywhere, even when they should. Funny thing is that I did some tests on the released E4.2.1 and the problem does not seem to appear there. So this could be another issue.
*** Bug 396128 has been marked as a duplicate of this bug. ***
in M20130116-1800 PW
I just tried 4.3RC2, most of the problems I have seen in 4.2 are solved now, however it looks like there is still something wrong. We use the keybinding "ALT+PageUp" which is also assign to "Next Sub-Tab". This works in 3.8 but not in 4.3.
Please open a new bug with the key that's not working and your usecase. Thanks. PW