90

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?

andz
  • 221

12 Answers12

64

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.

MattDMo
  • 5,409
39

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.

golvok
  • 497
20

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.

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 )
Matthijs
  • 316
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.
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.

andz
  • 221
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.

mt025
  • 3,506
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.

karel
  • 13,706
0

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

Volker
  • 119
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.

nkl
  • 9
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.

kenorb
  • 26,615
sudo
  • 9
-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

Bemipefe
  • 179