diff --git a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs index b8bfee591..2d49e4840 100644 --- a/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs +++ b/Flow.Launcher.Core/Plugin/JsonRPCV2Models/JsonRPCPublicAPI.cs @@ -173,5 +173,10 @@ namespace Flow.Launcher.Core.Plugin.JsonRPCV2Models { _api.OpenAppUri(appUri); } + + public void BackToQueryResults() + { + _api.BackToQueryResults(); + } } } diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 570785be7..af09334cc 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -101,7 +101,7 @@ - + diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs index caf3f0a7f..3e57948a5 100644 --- a/Flow.Launcher/Helper/WindowsInteropHelper.cs +++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs @@ -148,4 +148,64 @@ public class WindowsInteropHelper return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY)); } + + #region Alt Tab + + private static int SetWindowLong(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, int dwNewLong) + { + PInvoke.SetLastError(WIN32_ERROR.NO_ERROR); // Clear any existing error + + var result = PInvoke.SetWindowLong(hWnd, nIndex, dwNewLong); + if (result == 0 && Marshal.GetLastPInvokeError() != 0) + { + throw new Win32Exception(Marshal.GetLastPInvokeError()); + } + + return result; + } + + /// + /// Hide windows in the Alt+Tab window list + /// + /// To hide a window + public static void HideFromAltTab(Window window) + { + var exStyle = GetCurrentWindowStyle(window); + + // Add TOOLWINDOW style, remove APPWINDOW style + var newExStyle = ((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) & ~(uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW; + + SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle); + } + + /// + /// Restore window display in the Alt+Tab window list. + /// + /// To restore the displayed window + public static void ShowInAltTab(Window window) + { + var exStyle = GetCurrentWindowStyle(window); + + // Remove the TOOLWINDOW style and add the APPWINDOW style. + var newExStyle = ((uint)exStyle & ~(uint)WINDOW_EX_STYLE.WS_EX_TOOLWINDOW) | (uint)WINDOW_EX_STYLE.WS_EX_APPWINDOW; + + SetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, (int)newExStyle); + } + + /// + /// To obtain the current overridden style of a window. + /// + /// To obtain the style dialog window + /// current extension style value + private static int GetCurrentWindowStyle(Window window) + { + var style = PInvoke.GetWindowLong(new(new WindowInteropHelper(window).Handle), WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE); + if (style == 0 && Marshal.GetLastPInvokeError() != 0) + { + throw new Win32Exception(Marshal.GetLastPInvokeError()); + } + return style; + } + + #endregion } diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index f5fd729d4..da9e1a5b5 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -20,6 +20,7 @@ Closing="OnClosing" Deactivated="OnDeactivated" Icon="Images/app.png" + SourceInitialized="OnSourceInitialized" Initialized="OnInitialized" Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Loaded="OnLoaded" diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 8ca153afc..41dc68fd9 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -171,6 +171,11 @@ namespace Flow.Launcher Environment.Exit(0); } + private void OnSourceInitialized(object sender, EventArgs e) + { + WindowsInteropHelper.HideFromAltTab(this); + } + private void OnInitialized(object sender, EventArgs e) { } diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt index 2b147c05f..88eeeca6e 100644 --- a/Flow.Launcher/NativeMethods.txt +++ b/Flow.Launcher/NativeMethods.txt @@ -14,4 +14,7 @@ FindWindowEx WINDOW_STYLE WM_ENTERSIZEMOVE -WM_EXITSIZEMOVE \ No newline at end of file +WM_EXITSIZEMOVE + +SetLastError +WINDOW_EX_STYLE \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 03ac0491f..d7a626e1d 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -95,7 +95,7 @@ - + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs index e7b43c555..4bddfd9b2 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs @@ -22,7 +22,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search internal const string WindowsIndexErrorImagePath = "Images\\index_error2.png"; internal const string GeneralSearchErrorImagePath = "Images\\robot_error.png"; - internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory"; internal const string ToolTipOpenContainingFolder = "Ctrl + Enter to open the containing folder"; @@ -31,6 +30,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search internal const string DefaultContentSearchActionKeyword = "doc:"; + internal const char UnixDirectorySeparator = '/'; + internal const char DirectorySeparator = '\\'; internal const string WindowsIndexingOptions = "srchadmin.dll"; diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index 8fd167476..12df6c145 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -187,6 +187,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search var needToExpand = EnvironmentVariables.HasEnvironmentVar(querySearch); var path = needToExpand ? Environment.ExpandEnvironmentVariables(querySearch) : querySearch; + // if user uses the unix directory separator, we need to convert it to windows directory separator + path = path.Replace(Constants.UnixDirectorySeparator, Constants.DirectorySeparator); + // Check that actual location exists, otherwise directory search will throw directory not found exception if (!FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path).LocationExists()) return results.ToList();