Switch Virtual Desktop when Mouse is at edge of screen

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 04:21

So I'm relatively new to AutoHotKey and I've made a few little "programs" myself but I can't figure this out:

What I want:

When I move my mouse fully to the left side of the screen, I want it to switch to my Virtual Desktop to the left. (CTRL+WIN+LEFT)
When I move my mouse fully to the right side of the screen, I want it to switch to my Virtual Desktop to the right. (CTRL+WIN+RIGHT)

I got this code already, but only leftside works, and it only works once.

(Parts of it are from code I found from other programs that kind of work the same. So I don't know a lot of the code)
(Inspired by "AltEdge" by "Skrommel's One Hour Software")

=========================================================================================================================================

Code: Select all


#NoEnv
#Persistent,On
#SingleInstance,Force
#WinActivateForce
SetBatchLines,-1
SetWinDelay,0
SetKeyDelay,0
CoordMode,Mouse,Screen

applicationname=WinTab


Loop
{
  MouseGetPos,mx,my


  If (mx=0)
  {
    ; #LCtrl:: ; switch to previous desktop with Windows key + Left CTRL key
      SendInput #^{Left}
      Return
  }
  Sleep,50
}      

Loop
{
  MouseGetPos,mx,my

  If (mx=1920)
  {
    ; #LCtrl:: ; switch to previous desktop with Windows key + Left CTRL key
      SendInput #^{Right}
  }
  Sleep,50
}  

; TAB:
; Send,{LWin Down}{Tab}
; Return




WM_MOUSEMOVE(wParam,lParam)
{
  Global hCurs
  MouseGetPos,,,,ctrl
  If ctrl in Static8,Static12,Static16
    DllCall("SetCursor","UInt",hCurs)
  Return
}
Return


EXIT:
ExitApp


User avatar
mikeyww
Posts: 26599
Joined: 09 Sep 2014, 18:38

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by mikeyww » 25 Oct 2021, 05:16

Since you have two infinite loops without a Break, the second loop will never execute. In addition, the first Return will stop the loop. Instead, use a single SetTimer that checks the mouse position and acts accordingly. I think you will want to identify the condition when the mouse enters or exits a "trigger zone" on each edge of the screen. You will probably want a zone width greater than one (I call it a margin).

viewtopic.php?f=76&t=84220

viewtopic.php?p=387247#p387247

viewtopic.php?p=418992#p418992

Running the following script will illustrate the problem with your script.

Code: Select all

Loop {
 Send 1
 Return
}
Loop
 Send 2
The script below provides another potential approach, but a timer is more straightforward.

Code: Select all

SetKeyDelay, 50
Loop {
 Loop {
  Send 1
  Break
 }
 Loop {
  Send 2
  Break
 }
}
The script shown still has the problem that the two loops must run in sequence. One of the loops cannot execute twice consecutively. Another alternative is below. This uses a single loop to check two conditions.

Code: Select all

Loop {
 If (1 = 1)
  Send a
 If (2 = 2)
  Send b
 Sleep, 50
}

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 08:59

Hello, Thanks for answering so quick!

I'm still struggling. I read your reply and your other post but I still can't get the program to work.
I don't really understand how SetTimer works and where/how to use it. I don't understand the info from the AHK Help Index.

This is my code now:

Code: Select all

#NoEnv
#Persistent,On
#SingleInstance,Force
#WinActivateForce
SetBatchLines,-1
SetWinDelay,0
SetKeyDelay,0
CoordMode,Mouse,Screen

applicationname=WinTab


; ==========================================


SetKeyDelay, 50
Loop
{
  ; Static margin := 50     ; Width and height of the tap zone
  ; CoordMode, Mouse  
  SetTimer, Check, 200
  Check:
  MouseGetPos,mx,my
  left := mx < margin,  right := mx > A_ScreenWidth  - margin
  
  Loop
  {
    If (mx=left)
    {
      ; #LCtrl:: ; switch to previous desktop with Windows key + Left CTRL key
        SendInput #^{Left}
        SetTimer
    }
  }
  Sleep,50

  Loop
  {
    If (mx=right)
    {
      ; #LCtrl:: ; switch to previous desktop with Windows key + Left CTRL key
        SendInput #^{Left}
        SetTimer
    }
  }
  Sleep,50
}  

; TAB:
; Send,{LWin Down}{Tab}
; Return




WM_MOUSEMOVE(wParam,lParam)
{
  Global hCurs
  MouseGetPos,,,,ctrl
  If ctrl in Static8,Static12,Static16
    DllCall("SetCursor","UInt",hCurs)
  Return
}
Return


EXIT:
ExitApp


User avatar
mikeyww
Posts: 26599
Joined: 09 Sep 2014, 18:38

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by mikeyww » 25 Oct 2021, 09:28

A timer executes a subroutine repeatedly, so there is generally no need to add a loop to it.

Try the following in Notepad, with no other code. You can change the Send to whatever you need. Zone 1 is the left edge. Zone 2 is the right edge.

Code: Select all

#Persistent
left := 10, right := A_ScreenWidth - left
SetTimer, Check, 200
Check:
CoordMode, Mouse
MouseGetPos, mx
last := zone, zone := mx <= left ? 1 : mx >= right ? 2 : 0
If !zone || last = "" || zone = last
 Return
Switch zone {
 Case 1: Send x
 Case 2: Send y
}
Return

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 10:57

Oh wow! It actually works with that code! Thanks a lot!

I'm trying to kind of learn it myself how the code actually works since I know Switch+ cases from C# but don't know declaring variables/ methods and such yet.

Now how would I go about this? (Example made in paint to visualize what I mean: https://imgur.com/a/oXOisOv)

Right now the desktop will switch also when wanting to press the Windows Start menu or anything in corners like the close button of a program.

How can I make it so it would skip like 100 pixels from the top of the screen and 100 pixels from the bottom of the screen and only work between those 2 points?
Side-Question: Can I also make it so that when I have the start menu open or a fullscreen application, it's temporarily disabled?

Thank you again for all the help already! If I'm asking/questioning to much stuff then you've already helped enough! :)

User avatar
mikeyww
Posts: 26599
Joined: 09 Sep 2014, 18:38

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by mikeyww » 25 Oct 2021, 12:12

You can define any zones you need. Another example is below. I'm not sure about the other menu & windowing questions, but a forum search will likely reveal the answers there. A full-screen program might be defined by a window size that matches or exceeds the screen's dimensions. A forum search for "zone" or "edge" may yield additional examples.

Code: Select all

#Persistent
margin := 10
SetTimer, Check, 200
Check:
CoordMode, Mouse
MouseGetPos, xpos, ypos
last := zone
top  := ypos < margin, bottom := ypos > A_ScreenHeight - margin
left := xpos < margin, right  := xpos > A_ScreenWidth  - margin
Switch top bottom left right {
 Case "1010": zone := 1 ; Top left
 Case "1001": zone := 2 ; Top right
 Case "0110": zone := 3 ; Bottom left
 Case "0101": zone := 4 ; Bottom right
 Default:     zone := 0 ; None of the above
}
If !zone || last = "" || zone = last
 Return
Switch zone {
 Case 1: Send 1
 Case 2: Send 2
 Case 3: Send 3
 Case 4: Send 4
}
Return

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 14:04

Ah ok thanks but with that code it only works in the corners but I meant the opossite. Is it possible to have the active part of the edge (where it should work) start from 200 pixels up from the bottom and end 200 pixels down from the top?
So both corners would not activate the program?

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 14:08

I mean it like this:

=== For the left side:
x= 0
Mininimum y= 200
Maximum y= A_ScreenHeight - 200

=== For the right side:
x= A_ScreenWidth
Mininimum y= 200
Maximum y= A_ScreenHeight - 200


So the program's only active in those regions

User avatar
mikeyww
Posts: 26599
Joined: 09 Sep 2014, 18:38

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by mikeyww » 25 Oct 2021, 14:14

It's just an example. You can change how the zones are defined, to be whatever you want. You can use If (xpos... AND ypos...) kinds of statements to define zones (no need for Switch specifically). You can then act according to the zone. The second Switch can be replaced, too, to If (zone = 1)...., etc. Or you can just have a single kind of assessment + action.

Code: Select all

If (xpos < 10 AND ypos > 100 AND ypos < 200)
 Send abc
Or:

Code: Select all

If xpos between 0 and 10
 If ypos between 100 and 200
  Send abc
Etc.

Give it a go.

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 14:21

Nvm, I found out how it works with the && operator.

I just needed to add a my into the program and add it to the things that must be true in this line

last := zone, zone := mx <= left && my >= bottom && my <= top ? 1 : mx >= right && my >= bottom && my <= top ? 2 : 0

Sorry for wasting that last bit of time. All I had to do was think more. haha

Thanks again for all the help! You made my day!

here's the code:

Code: Select all

#Persistent
left := 10, right := A_ScreenWidth - left
bottom := 200, top := A_ScreenHeight - 200
SetTimer, Check, 200
Check:
CoordMode, Mouse
MouseGetPos, mx, my
last := zone, zone := mx <= left && my >= bottom && my <= top ? 1 : mx >= right && my >= bottom && my <= top ? 2 : 0
If !zone || last = "" || zone = last
 Return
Switch zone {
 Case 1: SendInput #^{Left}
 Case 2: SendInput #^{Right}
}
Return

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 14:33

Actually,

I tried your way since it reads WAY easier with the if's. But I have one problem if I do it that way. How do I keep it from constantly (instantly) outputting the same thing and only let it to the output once?

When I hold my mouse to the border it immediately goes abcabcabcabc instead of abc just once and then waiting.

Anyhow the program works so I'm happy. I'm just curious if that's also possible with an if command like yours.

Code: Select all

#Persistent
left := 10, right := A_ScreenWidth - left
bottom := 200, top := A_ScreenHeight - 200
SetTimer, Check, 200
Check:
CoordMode, Mouse
MouseGetPos, mx, my

If mx between 0 and 10
 If my between 200 and 800
  Send abc

If mx between 1910 and 1920
 If my between 200 and 800
  Send 123

User avatar
mikeyww
Posts: 26599
Joined: 09 Sep 2014, 18:38

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by mikeyww » 25 Oct 2021, 14:43

That's why the initial script saves the previous zone and then compares the current zone to the previous one.

Code: Select all

#Persistent
margin = 10
SetTimer, Check, 200
Check:
CoordMode, Mouse
MouseGetPos, mx, my
last := zone, zone := 0
If my between 200 and 800
{ If (mx <= margin)
   zone = 1
  If (mx >= A_ScreenWidth - margin)
   zone = 2
}
If (last > "" && zone != last)
 Switch zone {
  Case 1: SendInput #^{Left}
  Case 2: SendInput #^{Right}
 }
Return

brecht2202
Posts: 31
Joined: 17 Mar 2019, 15:12

Re: Switch Virtual Desktop when Mouse is at edge of screen

Post by brecht2202 » 25 Oct 2021, 14:58

Ah ok! Thanks a lot!

This really helps!

Post Reply

Return to “Ask for Help (v1)”