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

Tweak repos dropdown #10906

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

RussKie
Copy link
Member

@RussKie RussKie commented Apr 22, 2023

Resolves #10810

Proposed changes

  • Extract the working directory / recent repositories dropdown as a standalone component
  • Add "Close (go to Dashboard) to repos dropdown
  • Allow to filter the recent repositories dropdown

Screenshots

Before

image

After

  • In action:

    10810.mp4
  • Translations:
    image

Test methodology

  • manual
  • automated TBD

Merge strategy

I agree that the maintainer squash merge this PR (if the commit message is clear).


✒️ I contribute this code under The Developer Certificate of Origin.

@ghost ghost assigned RussKie Apr 22, 2023
@RussKie RussKie added this to the 4.1 milestone Apr 22, 2023
Copy link
Member

@mstv mstv left a comment

Choose a reason for hiding this comment

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

UX in the video 👍

Comment on lines 97 to 124
/// <summary>
/// Gets the form that is displaying the menu item.
/// </summary>
protected static Form? OwnerForm
=> Form.ActiveForm ?? (Application.OpenForms.Count > 0 ? Application.OpenForms[0] : null);
Copy link
Member

Choose a reason for hiding this comment

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

Please use Control.FindForm() which way more exactly does what the name promises.

Copy link
Member Author

Choose a reason for hiding this comment

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

FindForm is only available for Control type and its descendants, which this is not. This is component.

Copy link
Member

Choose a reason for hiding this comment

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

The implementation is a technical debt yet.

Copy link
Member Author

@RussKie RussKie Apr 23, 2023

Choose a reason for hiding this comment

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

I don't disagree, if we had DI we wouldn't have had these hacks... Related though OT - I have a working DI in master...RussKie:gitextensions:add_shell_take2 but struggle to plug the menu commands in...

Copy link
Member

Choose a reason for hiding this comment

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

Refer to dd2b46c, too. We have a Control. :)

Copy link
Member

Choose a reason for hiding this comment

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

We have a Control

Unfortunately, the form is not found.

Copy link
Member Author

Choose a reason for hiding this comment

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

Refer to dd2b46c

This is adding an layer of indirection (more IL) but I can't see any real benefits.

Copy link
Member

@mstv mstv Apr 24, 2023

Choose a reason for hiding this comment

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

This is adding an layer of indirection (more IL) but I can't see any real benefits.

As I wrote

I have not sorted the members yet. Some functionality could be moved to / from the Implementation class, too.
I have kept the sequence in the file in order to ease diffing.

refer to 23ef217
There is almost no more null check necessary, no _use_property_instead_ and much less violation of the SRP.
The dropdown can be closed again by clicking the button.
OwnerForm renamed to ActiveOrOpenForm. This suffices since we do not need the actual owning form.

@pmiossec
Copy link
Member

👍 because I was thinking for the first time about this exact feature yesterday 😅

I will try to have a look at the code the next days but I can't really guarantee that the review will be easy from my phone....

Copy link
Member

@gerhardol gerhardol left a comment

Choose a reason for hiding this comment

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

+1
Have not run, not reviewed in detail (got similar questions as mstv when looking at it).

@RussKie RussKie linked an issue Apr 23, 2023 that may be closed by this pull request
@gerhardol
Copy link
Member

When typing in the filter, the filter closes after entering the first character, filtering the list (but not selecting in the list).
So I cannot use the filter.

@mstv
Copy link
Member

mstv commented Apr 23, 2023

When typing in the filter, the filter closes after entering the first character, filtering the list (but not selecting in the list).

works for me

@RussKie
Copy link
Member Author

RussKie commented Apr 23, 2023

When typing in the filter, the filter closes after entering the first character, filtering the list (but not selecting in the list).
So I cannot use the filter.

Can you please share an animation?

@gerhardol
Copy link
Member

gerhardol commented Apr 25, 2023

This occur if the list is close to be as long as the window. If I have 50 items in the list, I have the problem but not with 45 with this size of the app.
I would like to add 100 items in the list if it is searchable.
App is maximized, if I minimize it I got to search occasionally.

Side note - should maybe an issue for 4.1: The dashboard seem to require more time to open.
Edit: BindRepositories() requires 0:30+0:45, (some repos are evaluated twice).

image

@RussKie
Copy link
Member Author

RussKie commented Apr 27, 2023

Can you please share an animation of it's autoclosing?

@RussKie
Copy link
Member Author

RussKie commented Apr 27, 2023

Is it autoclosing because you happen to move the mouse cursor over other toolbar elements?

10906.mp4

@gerhardol
Copy link
Member

gerhardol commented Apr 27, 2023

Is it autoclosing because you happen to move the mouse cursor over other toolbar elements?

I recorded a gif but pasted an image only.

110906-repo-dropdown

The problem is that when typing, the menu change size so if the mouse pointer is not in the new area, focus is lost.
You have guess where the resized menu will end up.

@RussKie
Copy link
Member Author

RussKie commented Apr 27, 2023

I see what's happening, and it is, essentially, described in my earlier comment: #10906 (comment).

The dropdown is opened to the side with the mouse essentially hovering over the toolbar (frame: 50):
image

As you type, the dropdown is filtered and is getting moved under the split button... (frame: 51):
image

...leaving the mouse hovering the toolbar, which initiates the "close split button" sequence (frame: 59):
image

@RussKie
Copy link
Member Author

RussKie commented Apr 28, 2023

@gerhardol I spent some time investigating how the issue you highlighted can be mitigated, but I don't think it's feasible.

Windows Forms doesn't allow to cancel closing of the dropdown:
https://github.com/dotnet/winforms/blob/3e18b18c/src/System.Windows.Forms/src/System/Windows/Forms/ToolStripDropDownItem.cs#L411

Without this ability, the dropdown's close logic is inaccessible to us. When the dropdown portion and the filter textbox is above or below the toolbar area - everything is working as expected - i.e., the dropdown is getting filtered which leads to it being closed and reopened. However, if the filter textbox is within the toolbar area - when then dropdown is getting filtered, it gets closed and reopened, but the mouse remains within the toolbar area, and that initiates the "selection changed" sequence of events that closes the dropdown...

I tried to hack around this, trying to capture when the filter is being performed, and then reopen the dropdown. However, this breaks the normal flow of events when I click away from the dropdown wanting to close it, but it remains reopened until I manually clear the filter.

The only viable workaround for your usecase (and anyone else hitting this scenario) is to resize the app so that the filter portion is NOT within the toolbar area when shown.

@RussKie
Copy link
Member Author

RussKie commented Apr 28, 2023

10906-2.mp4

@gerhardol
Copy link
Member

I spent some time investigating how the issue you highlighted can be mitigated, but I don't think it's feasible.

Then I suggest we leave it at this, open a placeholder issue that we point other issues too.
You need to learn how to use this feature.

@RussKie
Copy link
Member Author

RussKie commented Apr 28, 2023 via email

@pmiossec
Copy link
Member

pmiossec commented Apr 28, 2023 via email

@RussKie
Copy link
Member Author

RussKie commented Apr 28, 2023 via email

@pmiossec
Copy link
Member

pmiossec commented Apr 28, 2023 via email

Copy link
Member

@mstv mstv left a comment

Choose a reason for hiding this comment

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

Please consider 23ef217

@ghost ghost added the 📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity label Apr 28, 2023
@RussKie
Copy link
Member Author

RussKie commented Apr 29, 2023 via email

@ghost ghost removed the 📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity label Apr 29, 2023
@RussKie
Copy link
Member Author

RussKie commented Apr 29, 2023

Side note, not related to this PR but preventing me to setting recents to a 200 to keep more than a week of recents repos: The list is displayed very slowly when all items cannot be included.

image

Can you please open a new issue so we can discuss and investigate?

@RussKie
Copy link
Member Author

RussKie commented Apr 29, 2023

23ef217 does not add an additional layer.

It does. This generates a lot of IL and requires additional memory:
image

Class with events vs Class with inheritance.

avoids lots of null-checks all the time as in

@mstv you seem to be fixated on null checks, and I'm having difficulties understand the reason behind that. Runtime-wise those checks are very performant, and quite often can be elided by the compiler. As for the development, this type is nullable annotated, null! is a feature of the language and it is used in .NET codebases too.

Also, it does not seem to need the hack for the mouse pointer in e2cea06

Could you please elaborate on this @gerhardol?

@gerhardol
Copy link
Member

Also, it does not seem to need the hack for the mouse pointer in e2cea06

Could you please elaborate on this @gerhardol?

The mouse follow the text box when resizing

@RussKie RussKie modified the milestones: 4.1, vNext Apr 30, 2023
@RussKie RussKie changed the base branch from release/4.1 to master April 30, 2023 06:33
@mstv
Copy link
Member

mstv commented Apr 30, 2023

Potential null values always alert me when reading the code. I have seen too many bugs. I get less triggers to think about error conditions from code with non-null instances and a clear object life-time.

            private readonly Func<GitUICommands> _getUICommands;

            private readonly RepositoryHistoryUIService _repositoryHistoryUIService;

            private readonly ToolStripMenuItem _tsmiCategorisedRepos;

is much more self-explaining than

        protected RepositoryHistoryUIService RepositoryHistoryUIService
            => _use_property_instead_repositoryHistoryUIService ?? throw new InvalidOperationException("The button is not initialized");

        protected GitUICommands UICommands
            => (_use_property_instead_getUICommands ?? throw new InvalidOperationException("The button is not initialized")).Invoke();

        private Func<GitUICommands>? _use_property_instead_getUICommands;

        private RepositoryHistoryUIService? _use_property_instead_repositoryHistoryUIService;

        private ToolStripMenuItem _tsmiCategorisedRepos = null!;

But that's not the only point. There is even no need to subclass the ToolStripSplitButton.
Aggregation should be preferred over inheritance / subclassing.
It is good that the .NET codebase considers code-size and performance optimizations. That it requires a special language feature to do this, may be acceptable. Its use outside the framework needs to have a very high benefit though IMO.

@gerhardol
Copy link
Member

@RussKie What are the plans for this PR?

@RussKie
Copy link
Member Author

RussKie commented Jun 23, 2023 via email

@pmiossec
Copy link
Member

I have started to test it weeks ago (because I really like the idea) but the 1st test I made on the mouse hack was not working well.
I has started to investigate but had to stop temporary to work on it and I forgot even the existence of it 😕

I don't have the time at the moment. And I don't know exactly when I will have...

@gerhardol
Copy link
Member

The hack works for me
mstv implementation works too

An enhancement would be to list matches in the file system too.

@RussKie RussKie modified the milestones: 4.2, vNext Oct 7, 2023
@gerhardol
Copy link
Member

Time to resurrect this?
Still working fine, either with the hacks or mstv rewrite (have not tried the rewrite after .net8)

@RussKie
Copy link
Member Author

RussKie commented Nov 26, 2023

Yes, I'd love to have this functionality. But there's only so much free time I have :(

@RussKie RussKie marked this pull request as draft November 26, 2023 23:09
@pmiossec
Copy link
Member

@RussKie Could you include this little improvement over mouse hack?
98beaf7

I just discovered that the 1st commit introduce a frustrating new behavior/regression if the mouse don't go straight down:
If you hover an element of the toolbar, the dropdown disappear immediately (which is not the case in last master where the dropdown stay open):

dropdown_close

@pmiossec
Copy link
Member

Other regression:
the content of "Favorite repositories" is duplicated each times the dropdown is opened:

image

@RussKie
Copy link
Member Author

RussKie commented May 24, 2024

@RussKie Could you include this little improvement over mouse hack? 98beaf7

I rebased this on top of the latest master. Feel free to push your fix directly in this branch.

@RussKie
Copy link
Member Author

RussKie commented May 24, 2024

I extracted the first two commits as #11751 as those should be contentious-free. Once that PR is merged, I'll rebase this one.

* Place the mouse a little better (just under the filter textbox after filtering is effective)
* Enable hack to be run everytimes list is unfiltered then filtered again
@pmiossec
Copy link
Member

Other regression: the content of "Favorite repositories" is duplicated each times the dropdown is opened:

Fixed.

The content of "Favorite repositories" is not filtered. So maybe it's better to move the search box after the favorites (or filter also the favorites)

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.

Enhance the recent repo dropdown with search capabilities
4 participants