Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict Pin View and Open View to active CPP debug context. #1049

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

raghucssit
Copy link
Contributor

That is if any CPP application is under debug. Because Pin View is never enabled other than CPP application debug session.

This also includes Action to Command migration.

see #1048

@raghucssit
Copy link
Contributor Author

This is how fix looks like.
@
pin-view-open-view-fix

@raghucssit
Copy link
Contributor Author

FYI, @iloveeclipse , @jonahgraham

Copy link

github-actions bot commented Jan 21, 2025

Test Results

   635 files  +   34     635 suites  +34   55m 18s ⏱️ + 42m 25s
11 417 tests +1 217  11 206 ✅ +1 029  143 💤 +120  60 ❌ +60  8 🔥 +8 
11 455 runs  +1 217  11 244 ✅ +1 029  143 💤 +120  60 ❌ +60  8 🔥 +8 

For more details on these failures and errors, see this check.

Results for commit cc045d1. ± Comparison against base commit 9e04dc5.

♻️ This comment has been updated with latest results.

@raghucssit
Copy link
Contributor Author

Git diff is strange. I removed old Action delegates and added new Handlers. But it shows as old files are modified.

@iloveeclipse
Copy link
Contributor

Git diff is strange. I removed old Action delegates and added new Handlers. But it shows as old files are modified.

Not strange, but clever. It detects a move/rename, because the remaining code similarity is high enough to the old one.

@raghucssit
Copy link
Contributor Author

Oh bad.. There is a compilation problem. I will fix it. I did not have the project which is dependent on OpenNewViewAction so did not find in ws.

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2014 Texas Instruments and others
* Copyright (c) 2025 Advantest Europe GmbH and others.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Git diff is strange. I removed old Action delegates and added new Handlers. But it shows as old files are modified.

Not strange, but clever. It detects a move/rename, because the remaining code similarity is high enough to the old one.

The copyright should probably not be changed here as a result since you have copied at least the function body to the new code, the copyright start date and original author should remain here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I have fixed the copyright.

@raghucssit raghucssit force-pushed the migrate_pin_view_action branch from 877abc1 to 8e73224 Compare January 21, 2025 16:22
That is if any CPP application is under debug. Because Pin View is never
enabled other than CPP application debug session.

This also includes Action to Command migration.

see eclipse-cdt#1048
@raghucssit raghucssit force-pushed the migrate_pin_view_action branch from 8e73224 to 9a457cb Compare January 21, 2025 16:24
Copy link
Member

@jonahgraham jonahgraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good, but there is new, unexpected, behaviour when I am debugging both Java and C in the same workspace. The pin context + new view buttons are visible and enabled on the Java context. Prior to this change, they were visible, but only the new view was enabled. See:

image

The interesting irony, is that with pin command enabled, it is working to pin Java contexts:

image

I think you should keep enablement condition otherwise pin is enabled on illegal contexts, even within CDT:

image

I think the enablement should be based on org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils.isPinnable(IWorkbenchPart, ISelection)

}
}
}
// Check if any CDT launch is active.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am concerned that this is too narrow a check. I know of at least one CDT extender that doesn't extend GdbLaunch (not open source). The PDALaunch is supposed to demonstrate this, but that code has bitrotten and no longer works.

The actions used org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils.isPinnable(IWorkbenchPart, ISelection) to determine if the pin should be enabled. You could see if any of the launches have an adapter of type IPinProvider, and if they do, show the button.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

org.eclipse.cdt.dsf.gdb.launching.GdbLaunch does not provide an adapter for IPinProvider. I need to find a way to reuse the org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils.isPinnable(IWorkbenchPart, ISelection) . It was bit difficult to achieve that. So I use the approach currently in place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure by your wording in the last comment. Are you still looking into this? I would like to not break known existing extenders, I don't have access to their source now, but I think they still extend DsfLaunch, so at a minimum that should be required, along with checking if the launch is of that type, rather than exactly GdbLaunch.

The GdbExtendedLaunch example in the CDT source shows what many many extenders do. With the change as currently written, the pin and open new button disappear for those users.

Here is a screenshot that shows the buttons missing, along with how to change the launch type:

image

Comment on lines +259 to +272
}

class ViewDisposeListener implements DisposeListener {
IViewPart viewPart;

public ViewDisposeListener(IViewPart vPart) {
viewPart = vPart;
}

@Override
public void widgetDisposed(DisposeEvent e) {
pinned.remove(viewPart);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreferenced class?

private IPartListener2 fPartListener;
private DebugContextPinProvider fProvider;
private static Set<IViewPart> pinned = new HashSet<>();
Image image;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add access modifier

Suggested change
Image image;
private Image image;

@Override
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
if (PIN_VIEW_COMMAND_PROP_TEST_NAME.equals(property)) {
// Check if the View was pinned, then button must be there to Unpin.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code doesn't quite match the comment because the test of if (args[0].equals(vPart.getPartName())) only works for the original view and only works in English because the strings in the plugin.xml are not translated.

To test, open a second view on Variables and pin it. Stop the debug session and the pin disappears. But if you apply the pin to the original view it remains on closing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reply to the above note and #1049 (comment)

Note that you can update the comment rather than the code, but they should match. However the language part is a problem regardess.

Even if I plan to contribute a dedicated Command/Handler per view still problem cannot be solved because we can duplicate the View and the duplicated view still use the shared handler.

I would go simpler rather then more complicated. The pins could be left visible on all views if any view is still pinned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go simpler rather then more complicated. The pins could be left visible on all views if any view is still pinned?

This is also not possible. Because PropertyTester has no idea which ToolBarItem from a specific View is being asked to show/hide.
The receiver is simply a workbench selection has no information about from which part that the ToolBarItem being asked to show/hide. So PropertyTester can never know whether that view was pinned.
I have only this information public boolean test(Object receiver, String property, Object[] args, Object expectedValue) and none of then give me the ViewPart or ToolBarItem. I need any of these to decide if I can leave that button visible or hide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@raghucssit
Copy link
Contributor Author

Migrating Action Contribution to Command/Handler is tedious.
The reason is platform maintains an Instance of IViewActionDelegate for each action contribution. i.e. an instance per view in this case.
As Action is always there(Not show/hide), IViewActionDelegate takes care of enable/disable. And IViewActionDelegate has the complete state of the Action like isChecked, IViewPart where it is added. Based on this controlling enable/disable has every information needed.

On the other hand, Command/Handler, Uses a single instance of Handler and single instance of Property Tester for all the contributions on the workbench. This make it hard to track from which Part/Command enablement request is coming. Command asks Property Tester each time when there is selection change on the workbench. It only supplies the changed selection. From this little information Property Tester cannon decide if it can display/hide the command.
This is the reason I maintained a list of pinned views and passed the view name as an argument from the command where is is requested.

Even if I plan to contribute a dedicated Command/Handler per view still problem cannot be solved because we can duplicate the View and the duplicated view still use the shared handler.

Command/Handler is good for reusing the common state of the Command on all the contributions. And Property Tester never knows what was the state of the Command in case of Toggle if we plan to decide show/hide based on the toggle state.(Currently that is how it is done for Pin Action. i.e If it is pinned(checked) never touch it for enable/disable).

I will evaluate how can I work around this limitation.

Comment on lines 42 to 51
// Check if the View was pinned, then button must be there to Unpin.
Set<IViewPart> pinnedViews = PinViewHandler.getPinnedViews();
if (pinnedViews.size() > 0 && args.length == 1) {
for (IViewPart viewPart : pinnedViews) {
WorkbenchPart vPart = (WorkbenchPart) viewPart;
if (args[0].equals(vPart.getPartName())) {
return true;
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@raghucssit what I was thinking is this, leave command visible everywhere if any pin is in use anywhere. That removes need for argument and removes current bug where it depends on whether it is primary or secondary view that the pin is applied to.

Suggested change
// Check if the View was pinned, then button must be there to Unpin.
Set<IViewPart> pinnedViews = PinViewHandler.getPinnedViews();
if (pinnedViews.size() > 0 && args.length == 1) {
for (IViewPart viewPart : pinnedViews) {
WorkbenchPart vPart = (WorkbenchPart) viewPart;
if (args[0].equals(vPart.getPartName())) {
return true;
}
}
}
// Check if any View was pinned, then leave pin visible on all views
if (!PinViewHandler.getPinnedViews().isEmpty()) {
return true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will enable Pin Command on all the Views if only one View is pinned. As this is the only instance used by all the Views to check if they can show Command.
Example pin Variable View, then change the selection to Java Debug Launch Config in the Debug View then we can see Pin Command shown for Expressions View. This is because Expressions View asks PropertyTester if it can show Pin Command and tester says Yes.!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am working on Non declarative approach. I have registered a IDebugContextListener with Debug Service. Now I get debug changes. Based on the change I will poll the views on the workbench contribute Action dynamically.
Hope this is not an overkill..:-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #1049 (review) AFAICT the pin command shows when Java process is selected with your version because there is some gdblaunch present pin commands are visible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will enable Pin Command on all the Views if only one View is pinned.

Yes - this is intent of my recommendation, make pin commands either visible or not visible globally rather than trying to do it per view. This is a simplification that I assume would resolve the issue. i.e. pin command is only visible if user is actually doing CDT work.

@raghucssit
Copy link
Contributor Author

@jonahgraham I think i fixed the suggestion you gave me. I actually installed IDebugContextListener and reusing the PinCloneUtils.isPinnable(null, debugContext).
Please check my latest commit.
Here is how it works.

fix.mp4

<visibleWhen
checkEnabled="false">
<test
args="Variables"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you aren't using the arg, please remove them from the plugin.xml

Suggested change
args="Variables"

Comment on lines 40 to 41
private ISelection debugContext;
private boolean isDclInstalled;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonahgraham I think i fixed the suggestion you gave me. I actually installed IDebugContextListener and reusing the PinCloneUtils.isPinnable(null, debugContext).

Sadly this violates the API contract of PropertyTester. See javadoc key part quoted:

So property testers should always be implemented in a stateless fashion.

If you are listening to the active debug context, then I think lots of commands do that already. Have you had a look at how other debug commands are implemented? I am quite short of time now, but I can find you a specific example later if you want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find you a specific example later if you want.

For example, look at how debugContext variable is used in org.eclipse.debug.examples.ui (source link)

CDT also has reverse commands (E.g. org.eclipse.cdt.debug.ui.command.reverseStepInto) and the property tester ReverseDebuggingPropertyTester and expression definition org.eclipse.cdt.debug.ui.testIsReverseDebuggingEnabled which uses debugContext variable.

The CDT case is interesting, but more complicated because it is a retargettable command, whilst the o.e.debug.examples.ui is simpler.

the visibility of commands.

Basically we need to have Debug View for an application under debug. So
asking the selection from Debug View and checking it against an active
DSF session should give the most accurate visibility condition.

Along with this we plan to show the commands in all views if any of the
view is pinned.
@raghucssit
Copy link
Contributor Author

raghucssit commented Jan 24, 2025

@jonahgraham I have fixed all the review comments.
The latest fix for property tester now asks the debug view for selection and then decides if it can show command based on if the selection is an active DSF session. Basically i am reusing existing property tester for that.
In other case, If any View is pinned we leave commands visible in all the views.
If developer not working on both Java and CPP both at the same time then there will not be any issues at all.
Please check if it is good.

If things are good then i will squash and push all the commits. I have made different commits to differentiate the changes to help review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants