| Summary: | [api][context] provide method to determine whether a context is active | ||
|---|---|---|---|
| Product: | z_Archived | Reporter: | Miles Parker <milesparker> |
| Component: | Mylyn | Assignee: | Mylyn Inbox <mylyn-inbox> |
| Status: | CLOSED MOVED | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | shawn.minto |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
One way to check that is through the InteractionContextManager.PROPERTY_CONTEXT_ACTIVE system property. Shawn, do you have any thoughts on this? Miles, can you describe what kind of UI you are implementing? Miles, you could listen for context activation and deactivation yourself to avoid this problem. We should consider following the TODO and either changing the behavior of isContextActive (which may be bad for other clients, or may help if they haven't realized this problem) or make a separate method that will not include the paused check. (In reply to comment #3) > Miles, you could listen for context activation and deactivation yourself to > avoid this problem. We should consider following the TODO and either changing > the behavior of isContextActive (which may be bad for other clients, or may > help if they haven't realized this problem) or make a separate method that will > not include the paused check. Yes, in general it makes sense to listen to the activation events. In this case, though I am not in control over the UI context consumer's plugin life-cycle. So I might not be able to predict whether the context listener is activated before or after my other extension usage is. At that point I just need to be able to determine the present state in order to have a consistent state for future context related events. I have the ordering working ok now, but I'm concerned that that might just be the luck o' the draw. Alternatively, if I could be assured that say context startup extensions always got loaded before workbench window activation, then that would also work. I don't think that you can be guaranteed that the context startup extensions will always be loaded before workbench window activation. We should consider adding a new method to determine whether the task is active based on just whether there is a context and not include the paused check. If you need to be activated on context activation an IContextUiStartup extensions would be the best choice which is guaranteed to be loaded before first context activation. I am still not quite understanding what kind of UI integration you are working on. Can you give an example? Shawn, I think we should change the semantics of the method or deprecate it. The name is misleading since it implements something like hasActiveContextElementsAndIsCapturing() which seems like a weird combination of checks. Yes, I agree and should investigate why it is performing the check for the paused state as well. (In reply to comment #6) > If you need to be activated on context activation an IContextUiStartup > extensions would be the best choice which is guaranteed to be loaded before > first context activation. I am still not quite understanding what kind of UI > integration you are working on. Can you give an example? Sure, I can give you the code. (It's *really* rough right now, caveat, caveat) https://github.com/MilesParker/mylyn.incubator/blob/master/org.eclipse.mylyn.modeling.gmf/src/org/eclipse/mylyn/modeling/gmf/MylynDecoratorProvider.java This is for the Modeling Bridge. Here GMF has its own extension, which allows you to load a provider that then gets called by a GMF service through an IOperation to provide a set of adapters that then provide an IDecorator which is given an IDecoratorTarget, which has an EditPart that is an abstraction of the diagram element, which you can then use to actually create the IFigure that you want to add to the diagram. (These guys never met an abstraction layer they didn't like.) The upshot is that at some point (depending on e.g. whether the user has the diagram open in the saved workbench state and Mylyn is inactive, or whether the diagram was closed and then Mylyn actually triggers the resource being loaded, or the phases of the moon) the GMF service asks for the decorations. And at some (many) point, the context manager reports changes to the context. The class above's job is to manage that ensuring that nothing falls through the cracks. It sounds like there are two scenarios that need to be handled: 1. If a task is active when the manager instance is created it needs to decorate accordingly. 2. If a task is activated after the manager instance is created it needs to be notified. AbstractFocusViewAction and AbstractAutoFocusViewAction which are the action that enables focusing for structured views register a context listener in the constructor and check in the init method if a context is already active. Task/Context activation is guaranteed to execute on the UI thread so you can avoid race conditions as long as the relevant stuff happens on the UI thread. (In reply to comment #9) > It sounds like there are two scenarios that need to be handled: > > 1. If a task is active when the manager instance is created it needs to > decorate accordingly. > 2. If a task is activated after the manager instance is created it needs to be > notified. Yep, exactly. Plus I need actual changes, which works perfectly. > AbstractFocusViewAction and AbstractAutoFocusViewAction which are the action > that enables focusing for structured views register a context listener in the > constructor and check in the init method if a context is already active. Thanks for the pointer, that's very close to my usage. (Looks like just AbstractAutoFocusViewAction is doing that.) A somewhat different aspect is that I can't base things on part activation because I have to rely on the whole GMF life-cycle. That just adds some mystery to things but seems to be working fine. I think you're referring to: // can not run this until the view has been initialized PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @SuppressWarnings("deprecation") public void run() { try { if (ContextCore.getContextManager().isContextActive() && ContextUiPlugin.getDefault() .getPreferenceStore() .getBoolean(IContextUiPreferenceContstants.AUTO_FOCUS_NAVIGATORS)) { internalSuppressExpandAll = true; update(true); } } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not toggle focus action on view: " + getPartForAction(), e)); //$NON-NLS-1$ } } }); I'm not sure what's different in this usage but this didn't work for me -- I needed to take out the pause check in order to get it working. > Task/Context activation is guaranteed to execute on the UI thread so you can > avoid race conditions as long as the relevant stuff happens on the UI thread. Good to know. I'll avoid throwing context processing into a non-UI thread. Everything seems quite well-behaved so far and as I say it actually works so I'm thinking I should just be happy with that rather than try to imagine cases where something _might_ break. :) Mylyn has been restructured, and our issue tracking has moved to GitHub [1]. We are closing ~14K Bugzilla issues to give the new team a fresh start. If you feel that this issue is still relevant, please create a new one on GitHub. [1] https://github.com/orgs/eclipse-mylyn |
There are some confusing/unclear aspects to the ContextManager API -- that or I'm just not clear on some context concepts. In implementing modeling bridge, I've got a usage where I need to determine whether there is any active context at all. If there isn't then of course the bridge should not modify the UI presentation in any way. The obvious thing seemed to be just to call IInteractionContextManager#getActiveContext but that returns a context even when the user hasn't activated one. I then tried isContextActive but that also gives a false positive because the context capture is paused. // TODO consider removing check for pause and making clients explicitly determine this, // or provide a separate method public boolean isContextActive() { return !contextCapturePaused && activeContext.getContextMap().values().size() > 0; } So it isn't really obvious how to determine whether or not there is an active context.