Fix Launcher focus for most cases (#4362)

* Add SendInput hack

* Cleaned up code

* Fixed formatting

* Moved Activate fn call

* Add more comments with link to issue
This commit is contained in:
Arjun Balgovind 2020-06-22 14:47:33 -07:00 committed by GitHub
parent 196055e50e
commit 720fad80c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 3 deletions

View File

@ -64,6 +64,17 @@ namespace PowerLauncher
_viewModel.Save();
}
private void BringProcessToForeground()
{
// Use SendInput hack to allow Activate to work - required to resolve focus issue https://github.com/microsoft/PowerToys/issues/4270
WindowsInteropHelper.INPUT input = new WindowsInteropHelper.INPUT { type = WindowsInteropHelper.INPUTTYPE.INPUT_MOUSE, data = { } };
WindowsInteropHelper.INPUT[] inputs = new WindowsInteropHelper.INPUT[] { input };
// Send empty mouse event. This makes this thread the last to send input, and hence allows it to pass foreground permission checks
WindowsInteropHelper.SendInput(1, inputs, WindowsInteropHelper.INPUT.Size);
Activate();
}
private void OnLoaded(object sender, RoutedEventArgs _)
{
WindowsInteropHelper.DisableControlBox(this);
@ -79,7 +90,7 @@ namespace PowerLauncher
ListBox.SuggestionsList.PreviewMouseLeftButtonUp += SuggestionsList_PreviewMouseLeftButtonUp;
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
Activate();
BringProcessToForeground();
}
private void SuggestionsList_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
@ -105,7 +116,7 @@ namespace PowerLauncher
// Not called on first launch
// Additionally called when deactivated by clicking on screen
UpdatePosition();
Activate();
BringProcessToForeground();
if (!_viewModel.LastQuerySelected)
{

View File

@ -34,6 +34,68 @@ namespace Wox.Helper
}
}
[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public INPUTTYPE type;
public InputUnion data;
public static int Size
{
get { return Marshal.SizeOf(typeof(INPUT)); }
}
}
[StructLayout(LayoutKind.Explicit)]
public struct InputUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal uint dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal uint dwFlags;
internal int time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
internal int uMsg;
internal short wParamL;
internal short wParamH;
}
public enum INPUTTYPE : uint
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2,
}
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);