-
Notifications
You must be signed in to change notification settings - Fork 5
File explorer support #27
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
Conversation
And upgrade to .net 5
Okay, the failing pipeline is absolutely my fault, as I attempted to upgrade to .NET 5 without changing the pipeline scripts. So either I downgrade back, or a lovely maintainer takes a look at how to upgrade the pipeline. |
I am currently afk on my mobile, will take a look later :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make reviewing slightly easier, I'll point out some important changes
@@ -148,11 +151,18 @@ private ProcessArguments GetProcessArguments(Command c, IEnumerable<string> term | |||
} | |||
|
|||
var workingDir = c.WorkingDirectory; | |||
if (workingDir == "{explorer}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working directory can be set to {explorer}
, which will trigger the new behavior where it tries to get the path of the topmost file explorer window.
public static List<string> GetOpenExplorerPaths() | ||
{ | ||
var results = new List<string>(); | ||
if (OperatingSystem.IsWindows()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just saw this, is this referring to OS type? Flow is windows only so not sure if this check is necessary.
{ | ||
class ExplorerPathsService | ||
{ | ||
public static List<string> GetOpenExplorerPaths() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses the "Shell" to iterate over all file explorer windows and read the file paths and HWNDs from them.
Then it uses "Win32" stuff to iterate over all open windows (sorted by how close to the user they are), and read the HWNDs from there.
Finally, it combines that info to return a sorted list of open file explorer windows. This means that GetOpenExplorerPaths().First()
will always return the topmost open file explorer.
<OutputType>Library</OutputType> | ||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> | ||
<RestorePackages>true</RestorePackages> | ||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
<Nullable>enable</Nullable> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also enabled the nullable references stuff, which makes it a lot easier to spot potential null pointer exceptions at compile time.
Lgtm. Shall we also implement similar thing in flow? I remember @Garulf has shared a similar idea about pasting the first explorer path to flow. |
Was about to ask you same thing if we want to expose this via the flow API instead? |
Oh, that'd be a lovely API to have in Flow. I personally use this for
and have thought about things like
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also could you resolve the null safety check since we have enabled it? To mark all property that allows null as nullable and create a constructor for all other properties.
var result = fullResults.Find(v => v.HWND == hwnd); | ||
if(result != null) | ||
{ | ||
result.ZIndex = zIndex; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we set the result.ZIndex to zIndex? To put the window up to front?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's used for sorting the windows correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why do we want to sort out the windows?
Shouldn't we pick the window with the largest zindex?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thought process was that it might make sense to be able to get other open file explorer paths. But honestly, I'm not sure if that would ever be useful.
(See https://github.com/Flow-Launcher/Flow.Launcher/pull/1018/files#r922377206 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I messed up with the logic. So the EnumWindow Call will enumerate with the ZIndex order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you plan to make usage of the ZIndex? But I think it would be a bit hard to do so lol. Maybe adding multiple results instead of only the first one, but order them based on the zindex? BTW, you can order the results with the Score
property for Result
class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I slightly tweaked the code, let me know if it's easier to understand now
Flow-Launcher/Flow.Launcher#907 |
Flow-Launcher/Flow.Launcher#1018 And for this one, do you have any clues about a better implementation? |
@taooceros I did my best to fix the null warnings, however there were quite a few places where I ended up placing a |
Alrighty, I took a look at it and left some comments there. |
@@ -21,9 +21,9 @@ public void LoadCommands() | |||
RunnerConfiguration.Commands.Select( c => new CommandViewModel( c ) ) ); | |||
} | |||
|
|||
public ObservableCollection<CommandViewModel> Commands { get; set; } | |||
public ObservableCollection<CommandViewModel>? Commands { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe refactor a bit to make this not nullable. The viewmodel is not intended to have null Commands.
Thanks it looks great. I think when you ends up placing a |
btw maybe it would be even useful if we can put this as part of the parameter? I think it would be fairly easy to just use a replace (though you may need to consider a bit about the escaping). I wonder whether it is possible to use the ArgumentList api instead of the current one so that we don't need to worry about the escaping. |
@taooceros Okay, I modified the null checks. I didn't fix the XAML stuff, since that's way out of my depth. (I don't understand how it works.) |
Yeah, probably would be useful. I think that could be done in a future pull request? |
No problem, I will fix that part. |
Done, do you want to include the multiple explorer path or leave it in the future? |
@taooceros Let's leave it for the future |
This is ready to roll? |
From my side: Yes, I've been using it for a week now without issues and it's pretty sweet. There is Flow-Launcher/Flow.Launcher#1275 for getting a part of the functionality into Flow itself, but that's a separate story. |
Ah sorry I was supposed to approve it earlier but I forget |
Oh there's one more thing that needs to be done (I always forget). Update the version in plugin.json. |
Fix #26
I already implemented this, so I figured I'd carefully open a pull request with the feature. I'd love some feedback :)