84

I'd like raise-on-click and sloppy focus-follows-mouse on Windows 10 because this is the setup I've been using on Windows and Linux for years.

Under Windows 10, I tried the regedit Xmouse changes mentioned in this link that were originally meant for Windows 8: http://winaero.com/blog/turn-on-xmouse-active-window-tracking-focus-follows-mouse-pointer-feature-in-windows-8-1-windows-8-and-windows-7/

However, I experienced the following issues:

  1. When you open the Start Menu by pressing the Windows key, it doesn't receive keyboard input.

  2. When you open Start, Search or Notifications by clicking on them, they close before you can interact with them.

Is there anyway to get usable focus follows mouse?

Is anyone successfully using Win10 like this?

2
  • 1
    A workaround for issue #1 is to click the magnifying glass (search) instead. The shortcut key for this is Window + S.
    – andz
    Commented Aug 11, 2015 at 18:33
  • 1
    You might be able to avoid Issue #2 by setting ActiveWndTrkTimeout to a higher value. WinAero Xmouse Tuner used to have a minimum of 500ms, but it is now lowered to a minimum of 100ms in WinAero Tweaker due to overwhelming requests. It is still not possible to lower it to below 100ms but there might be a good reason for that.
    – andz
    Commented Aug 11, 2015 at 18:33

12 Answers 12

61

Use X-Mouse Controls (Wayback Machine link), it's the closest I've found to true Focus Follows Mouse, and it has some options to tweak. It's a small open-source utility that doesn't require installing or rebooting, and saves you from changing the registry yourself.

As far as I've experimented, I can use the keyboard to search for files/programs after pressing the Win key. Also, Start and Notifications menu don't go away before I can use them, even with the raise-on-hover option, as you can set a small delay for the behavior (one or two hundred ms will suffice), which gives you more than enough room to move the pointer to the new window.

I've used it for a while and I'm quite happy with it, plus the bug.n tiling window manager. This setup is as close as I've been to using dwm on unix.

2
  • 1
    this worked well for me. Download the zip file, unzip it, execute X-Mouse Controls.exe, choose options in the dialog window, press 'Apply', that's it! You can change the various options to try them out. This helped me because long ago I had configured Windows to automatically raise windows when the cursor hovers over them. This gradually became annoying and confusing but I couldn't remember how I'd done it.
    – Kai Carver
    Commented Apr 9, 2023 at 8:29
  • 2
    Still working in 2023. Also reverting to default settings works without any issues. Commented Aug 8, 2023 at 10:16
37

The following powershell script should have the same effect as the XMouse program... without having to execute a 3rd party binary.

$signature = @"
[DllImport("user32.dll")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, UIntPtr pvParam, uint fWinIni);
"@
$systemParamInfo = Add-Type -memberDefinition $signature -Name SloppyFocusMouse -passThru
$newVal = [UintPtr]::new(1) # use 0 to turn it off
$systemParamInfo::SystemParametersInfo(0x1001, 0, $newVal, 2)

Constants & types retrieved from the SystemParametersInfoA docs. It seems the pvParam arg (a void pointer) is re-interpreted as a boolean for this particular action, so turing it on/off requires passing a non-null/null pointer.

7
  • That works beautifully, better than anything else I've tried. Just save this in a .ps1 file, right-click it and choose Run with Powershell. You can even add it in Task Scheduler to start at boot.
    – Zurd
    Commented Jan 22, 2018 at 17:36
  • 1
    To eliminate the default 500ms delay, I used regedit to change HKEY_CURRENT_USER\Control Panel\Desktop 's ActiveWndTrkTimeout to 0. Requires you to log out and back in. Commented Feb 6, 2020 at 0:17
  • For a permanent SloppyFocusMouse, I changed Computer\HKEY_CURRENT_USER\Control Panel\Desktop 's UserPreferenceMask's first hex data from "9e" to "9f" Commented Feb 6, 2020 at 0:19
  • 1
    I used this but found it a one-way street and so installed XMouse to disable it :) Changing $newVal = 0 did not put it back to normal, which is odd. Perhaps if I'd done a restart it would have reverted, although enabling it was instant.
    – noelicus
    Commented Mar 25, 2020 at 9:45
  • $newVal must not be passed by reference, it should be passed by value. That's why this only works to enable the behavior (since the address is non-zero). To disable, you need to pass zero, not the address of a zero variable.
    – JohnLock
    Commented Apr 29 at 4:20
19

The registry modifications mentioned in the question's link do work on Windows 10. However, it seems they have to be made when the option “Activate a window by hovering over it with the mouse” is selected in the accessibility settings. This option can be found under Control Panel > Ease of Access > Change How Your Mouse Works.

This option also makes windows auto-raise, but the registry modifications stop this behaviour.

If you are experiencing the same issues and the checkbox is selected, unselect it, click apply, select it again and redo the modifications. The mouse should behave properly the next time you log in.

1
  • 4
    However, that does what the name suggests - raises the windows automatically. OP wants it to NOT raise, but still allow focus on a background window. Following the Q's Winaero instructions (setting first hex code to 9F) and logging in and out seems to be working okay. Win key + typing = works for search. Win button with mouse + typing = does NOT work for search if focus is ever away from said button, but does if I keep the mouse hovering over the button. Killing explorer.exe and running userinit.exe did not work to load the reg settings, so logoff seems needed.
    – mpag
    Commented Sep 8, 2017 at 18:00
18

Windows actually has a flag to enable focus-follows-mouse ("active window tracking"), which can be enabled easily via the monstrous "SystemParametersInfo" Win32 API call. There are third-party programs to enable the flag, such as X-Mouse Controls, or you can perform the call directly using PowerShell.

The documentation isn't always super clear on how the pvParam argument is used, and some powershell snippets incorrectly pass a pointer to the value, rather than the value itself, when setting this particular flag. This ends up always being interpreted as true, i.e. they accidently work for enabling the flag, but not for disabling it again.

Below is a powershell snippet that performs the call correctly. It also includes proper error-checking, and I've tried to go for cleanliness rather than brevity, to also make it easier to add wrappers for other functionality of SystemParametersInfo, should you find some that interests you.

Shout-out to pinvoke.net for being a helpful resource for stuff like this.

Add-Type -TypeDefinition @'
    using System;
    using System.Runtime.InteropServices;
    using System.ComponentModel;

    public static class Spi {
        [System.FlagsAttribute]
        private enum Flags : uint {
            None            = 0x0,
            UpdateIniFile   = 0x1,
            SendChange      = 0x2,
        }

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SystemParametersInfo(
            uint uiAction, uint uiParam, UIntPtr pvParam, Flags flags );

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SystemParametersInfo(
            uint uiAction, uint uiParam, out bool pvParam, Flags flags );

        private static void check( bool ok ) {
            if( ! ok )
                throw new Win32Exception( Marshal.GetLastWin32Error() );
        }

        private static UIntPtr ToUIntPtr( this bool value ) {
            return new UIntPtr( value ? 1u : 0u );
        }

        public static bool GetActiveWindowTracking() {
            bool enabled;
            check( SystemParametersInfo( 0x1000, 0, out enabled, Flags.None ) );
            return enabled;
        }

        public static void SetActiveWindowTracking( bool enabled ) {
            // note: pvParam contains the boolean (cast to void*), not a pointer to it!
            check( SystemParametersInfo( 0x1001, 0, enabled.ToUIntPtr(), Flags.SendChange ) );
        }
    }
'@

# check if mouse-focus is enabled
[Spi]::GetActiveWindowTracking()

# disable mouse-focus (default)
[Spi]::SetActiveWindowTracking( $false )

# enable mouse-focus
[Spi]::SetActiveWindowTracking( $true )
9
  • 2
    Hello, wellcome to superuser. Please, when you make new contributions, try to give some explanations attached to your code. Although your answer seems correct, it would be better if you explained WHY it works, so if someone wants to make something slightly different they can get an starting point on your answer. Anyway, thank you for sharing your knoweldge with us!
    – DGoiko
    Commented May 13, 2019 at 19:26
  • 1
    There, I've fleshed out the explanation.
    – Matthijs
    Commented May 14, 2019 at 21:26
  • 1
    Great! I'm glad to be your first upvote, hope a lot more will come :D
    – DGoiko
    Commented May 14, 2019 at 21:41
  • 1
    @rotton raise and focus are different things, and the whole point for focus-follows-mouse is to be able to focus windows without being forced to raise them. what you're describing (raising a window when hovering over it with some delay) sounds extremely annoying to me, but is presumably meant as an accessibility feature for people with limited hand functionality
    – Matthijs
    Commented Feb 5, 2021 at 11:06
  • 1
    No need anyway, I'm aware there are indeed problems with it and some Windows applications (including some Microsoft apps) are quite ill-behaved when the feature is enabled since it's deeply hidden and therefore not something developers will take into account. There's nothing you can really do about that other than giving up on focus-follows-mouse or just not using Windows.
    – Matthijs
    Commented Feb 11, 2021 at 10:08
2

For those who couldn't get it to work by just subtracting 40 from the first byte of UserPreferencesMask, just get the WinAero Tweaker utility itself at http://winaero.com/download.php?view.1796

Note that issue #1 above is still present, but easily worked around by just using the magnifying glass (search) icon to the right of the start menu (shortcut key Window + S). A small price to pay for getting X-Mouse functionality.

I don't experience issue #2 when I use WinAero Tweaker.

2

Depending on which build of Windows 10 you are running, the menu path to access "Focus Follows Mouse" may be slightly different from some of the instructions in this thread. I was able to get to the proper menu with this sequence:

  1. Click "Start", then select "Control Panel".
  2. Select "Ease of Access Center"
  3. Optional: If the two check boxes for "Always Read This Section Aloud" and "Always Scan This Section" are enabled, you might want to turn them off - they can get pretty annoying.
  4. Select "Make the Mouse Easier to Use" under "Explore all settings"
  5. Click the checkbox next to "Activate a Window by hovering over it with the mouse", under "Make it Easier to Manage Windows".
  6. Click "Apply", then "Okay". You can close the window now.

NOTE: there is about a 1/2-second delay built into this setting by default. You can change the delay time by way of a Registry edit.

  1. Open Regedit.exe
  2. Navigate to this key: [HKEY_CURRENT_USER\Control Panel\Desktop]
  3. In the right pane of the Desktop key, double click/tap on the [ActiveWndTrkTimeout] DWORD to modify it. If you don't see this entry, go back to Step 1 above, and make sure that you did in fact turn on the check box in Steps 5 and 6. In the "Edit DWORD" dialog box that should pop-up, select DECIMAL under BASE.
  4. The default value, 500, equals 500 milliseconds. Change this to a larger value to increase the delay time, or a smaller value to decrease the delay time (speeding up the response).
  5. Click "OK", then close Regedit.
  6. Sign out and sign back in, or restart the computer to apply the change.
1
1

To solve issue #2 on Windows 10

2) When you open Start, Search or Notifications by clicking on them, they close before you can interact with them.

All you need to do is:

  • Press Windows + X
  • Control panel
  • Ease of Access
  • Change how your mouse works
  • Enable the checkbox: Prevent windows from being automatically arranged when moved to the edge of the screen

No need for third-party software.

2
  • This setting is not found in Win 10 (any more?) Commented Aug 19, 2020 at 16:46
  • 1
    Works for me (Windows 10)! I can live that 'activate' also means 'raise the window'. ;-)
    – andiba
    Commented Jan 14, 2021 at 7:28
0

Using the method to achieve the sloppy mouse behavior, that I'm so accustomed to, from previous versions of windows and linux from the post. I do not experience issue #2 that you are having. Issue #1 that you and all will have when using this registry modification is not an issue. It does exactly as expected because you have changed the way focus is handled in windows with this modification. Using the windows key brings the mouse into the start menu not the search menu so it gets focus, not the search menu. So, if you wish to use search either click in the search bar or magnification icon (depending on your settings for its appearance) or use the Win+S key combo and it will do the right thing.

0

I haven't tested Winaero yet because:

  1. I'm not keen on running unknown software from the internet.
  2. As I have upgraded all PC's I use from Windows 7 to Windows 10, the Windows 7 "Activate a window by hovering over it with the mouse" setting has continued to be in effect in Windows 10, even though there seems to be no method of setting this in the Windows 10 GUI.

I haven't found these workarounds anywhere on the internet yet, so I'll document here for others.

Using the following workarounds, makes using Windows 10 in Xmouse mode practical:

  1. Switching to another window when there are multiple windows available via the app icon in the taskbar:

    Do NOT click the app icon in the taskbar before trying to select a window. If you do, as soon as you move the mouse pointer above the taskbar, the windows will disappear. Just hover above the app icon until the windows appear, then you can move the pointer into the one you need.

  2. Switching to another virtual desktop or app using the task view button:

    • Click on task view button.
    • Click again and hold button down.
    • Move pointer into required task or virtual desktop.
    • Release mouse button, then click again.

Note: the Windows 10 "Scroll inactive windows when I hover over them" setting is a useful addition (see Start -> Settings -> Devices -> Mouse & Touchpad). This seems independent from Xmouse functionality and ON seems to be the default.

0

Set Regkey HKCU\Control Panel\Desktop\ActiveWndTrackTimeout to something higher than 0 to Setup delay unless other window gets active

2
  • 4
    Fix your key; it's Trk not Track; e.g. ActiveWndTrkTimeout. I have no idea what the Track one does but changing the Trk one is what works for me.
    – lumpynose
    Commented Oct 5, 2018 at 20:45
  • @lumpynose Do you have both ActiveWndTrackTimeout and ActiveWndTrkTimeout, and only the latter works for you? My copy of W10 22H2 has the former as a key. Commented Oct 13, 2023 at 15:54
0

No need to poke around in the Windows registry or use obscure PowerShell scripts. If you're a Python fan, you can enable Focus-Follow-Mouse with a Python script.

  1. Install pywin32 pip install pywin32

  2. Create focus-follow-mouse.py:

import win32gui
from win32con import SPI_SETACTIVEWINDOWTRACKING, SPI_GETACTIVEWINDOWTRACKING, SPIF_SENDCHANGE, SPIF_UPDATEINIFILE


def get_active_window_tracking():
    return win32gui.SystemParametersInfo(SPI_GETACTIVEWINDOWTRACKING)


def set_active_window_tracking(flag: bool):
    """SPI_SETACTIVEWINDOWTRACKING
        Sets active window tracking (activating the window the mouse is on) either on or off. 
        Set pvParam to TRUE for on or FALSE for off.
    SPIF_UPDATEINIFILE 
        Writes the new system-wide parameter setting to the user profile. 
    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa"""

    return 0 != win32gui.SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, flag, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)


print("Before:", get_active_window_tracking())
print("Activate OK?:", set_active_window_tracking(True))
# print("De-Activate OK?:", set_active_window_tracking(False))
print("After:", get_active_window_tracking())

  1. Run python.exe focus-follow-mouse.py.

This activates this feature permanently.

You can disable this feature with set_active_window_tracking(False).

Tested on Windows 11.

4
  • I haven't seen a python tag in the question
    – Toto
    Commented Sep 27, 2023 at 13:33
  • 1
    @Toto there doesn't need to be a Python tag in question to answer with Python solution...?
    – Destroy666
    Commented Sep 27, 2023 at 13:53
  • 1
    There wasn't a "Powershell" tag either, but the answer using PowerShell script received many upvotes.
    – nkl
    Commented Sep 28, 2023 at 14:27
  • Great approach. Did not know that somethins like this can be done with Python! Thanks
    – Volker
    Commented Oct 15, 2023 at 8:28
-1

If you want the focus to follow the mouse in a computer with multiple monitors, the proposed solutions (Activate a window by hovering over it with the mouse) are probably not enough or at least not the best option. I found quite frustrating the lost of focus while you are on the same screen. For example if the mouse cursor go slightly out of the window where you are typing, you suddenly loose the focus and another window is shown on top of the one you where working on.

To solve this problem the only solution that I found was to turn off the Activate a window by hovering over it with the mouse feature and use AutoHotKey (it's a free and open-source software) to activate the focus on the window under the mouse cursor but only when the mouse moves from one screen to another.

Here is the script that you can use to get this behavior:

#Persistent
CoordMode, Mouse, Screen

; Initialize a variable to keep track of the last active screen
lastActiveMonitor := 0

; Check the active screen every 500 ms
SetTimer, CheckScreen, 500
return

CheckScreen:

; Get mouse position and the screen where the mouse is visible
MouseGetPos, mouseX, mouseY

; Get the count of screens
SysGet, monitorCount, MonitorCount

; Loop through each screen to find the one containing the mouse
Loop, %monitorCount%
{
    SysGet, monitor, Monitor, %A_Index%
    
    if (mouseX >= monitorLeft && mouseX <= monitorRight && mouseY >= monitorTop && mouseY <= monitorBottom)
    {
        screenNumberContainingMouse := A_Index
        break 
    }
}

; Check if mouse changed screen
if (lastActiveMonitor != screenNumberContainingMouse) 
{
    lastActiveMonitor := screenNumberContainingMouse

    ; Skip activation while dragging on another screen
    if (GetKeyState("LButton", "P") ) 
    {
        ;return
    }
    
    WinGet, windowList, List
    Loop, %windowList%
    {
        classPrefix := "Shell"
        hWnd := windowList%A_Index%
        WinGetClass, class, ahk_id %hWnd%
        
        VarSetCapacity(rect, 16)
        DllCall("user32\GetWindowRect", "Ptr", hWnd, "Ptr", &rect)
        windowLeft := NumGet(rect, 0, "Int")
        windowTop := NumGet(rect, 4, "Int")
        windowRight := NumGet(rect, 8, "Int")
        windowBottom := NumGet(rect, 12, "Int")
        
        ;Check if mouse is inside the window rect
        isInside := (mouseX >= windowLeft && mouseX <= windowRight) && (mouseY >= windowTop && mouseY <= windowBottom) 

        if(isInside) 
        {

            topmostHWND := hWnd
            ;ToolTip %hWnd% %windowTitle% %class% %windowLeft% %windowTop% %windowRight% %windowBottom% %mouseX% %mouseY%
            break
        }
    }

    ; Activate the topmost window on the monitor where the mouse is located
    if (topmostHWND) 
    {   
        WinActivate, ahk_id %topmostHWND%
        WinGetTitle, windowTitle, ahk_id %topmostHWND%
        WinGetClass, class, ahk_id %topmostHWND%
        ;ToolTip Activated: hwnd %hwnd% windowTitle %windowTitle% class %class%
    }
}

return

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .