Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

hotkey pass-through


  • Please log in to reply
11 replies to this topic
joe
  • Members
  • 44 posts
  • Last active: Sep 25 2005 09:13 PM
  • Joined: 20 Jan 2005
Is there any way to implement conditional pass-through?

For instance:

~z & v:: because of the ~, translates loosely as "do whatever the Z key is supposed to do at all times, and if the v key is pressed with it, also run this hotkey."

What I'm looking for is "do whatever the Z key is supposed to do at all times, UNLESS the v key is pressed with it, and then run this hotkey, nothing else."

The effect I need is for the z and v keys to funtion as normal, but when pressed together they provide yet another keypress or effect.

-joe

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
All you have to do is set "z" as a separate hotkey. It will be activated if "z & v" isn't. This makes it extremely simple, because all you have to do is make it a tilde hotkey:

z & v::
msgbox, You pressed %A_ThisHotkey%.
return

~z::
return

One big downside to this is that z is only sent on an up event, not down like normal. It doesn't sound like much, but trust me, I've experienced this before and it does get annoying after a while. If you don't care, though, there it is.

P.S. This only works when you press "z" first, obviously. Repeat the above with v as the prefix and tilde if you want it to work both ways.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Actually, that behavior will change in the next update. The presence of ~z will imply a tilde in "z & v" too.

I hope this won't break too many scripts, but it just didn't seem right the way it was before, plus there were some bad side effects.

If you want a "z up" hotkey, you would do it this way (which is documented):

z & v::MsgBox You pressed v while holding down z.
z::Send z

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
Oh yeah...sorry, I forgot about that, even though it was a result of my request! :D

RG
  • Guests
  • Last active:
  • Joined: --
Hello. This is in relation to the pass-through issue discussed in this thread. First I want to say that this is a GREAT PROGRAM!!! I used to use a Gateway programmable keyboard, but since having trouble with RSI I switched to a "natural" keyboard with split keys. I really miss the ability to program and remap keys, but this program solves the problem grandly!

Now for the problem I'm experiencing: I want to write a script to remap the Function Keys for a specific application (window), but I don't want the user to be forced to disable the AutoHotkeys program when switching to other applications. It seems logical to use the 'ifWinActive' condition to determine if the specified window is active, and if active, send a string instead of the function key. So far, so good. But when I switch to another application and press the function key, that application does not receive a keystroke. The key is, in effect, disabled for all applications except the one specified in the ifWinActive statement.

Here's an example of what I tried for the F1 key:

F1::
ifWinActive, [MyWindowName]
{
     Send, abc
     return
}
else
{
     Send, {F1}
     return
}


If the [MyWindowName] window is active, "abc" is sent to it, which is correct. But if any other window is active, the F1 key has no functionality at all. I understand that the ~ character can be placed before the key name, like

~F1::
...

but this causes the F1 key to be sent to [MyWindowName] before the string is sent, which is not correct.

I have discovered that using the Suspend function solves the problem, but this seems like a strange way to prevent recursive processing of a keypress:
F1::
ifWinActive, [MyWindowName]
{
	Send, abc
	return
}
else
{
	Suspend, On
	Send,{F1}
	Suspend, Off
	return
}


Maybe I'm missing something obvious...

Any help here would be greatly appreciated!!!

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
As described in the documentation, a hotkey cannot send itself unless you use the $ directive. The script cannot tell the difference between keys sent by the user and keys sent by itself unless the hook is being used; thus, sending keys which resolve to a hotkey would activate the hotkey, creating an infinite loop. So, simply change it to this, and it should work fine:

$F1::
ifWinActive, [MyWindowName]
{
     Send, abc
     return
}
else
{
     Send, {F1}
     return
}


RG
  • Guests
  • Last active:
  • Joined: --
Using the $ directive worked perfectly!

THANK YOU for your assistance, and thanks to all the people who are making this a great project!

RG

joe
  • Members
  • 44 posts
  • Last active: Sep 25 2005 09:13 PM
  • Joined: 20 Jan 2005
[note than when offering examples of hotkey execution I'm actually executing the hotkey as it's loaded in the script running in the background right now]

I'm not sure if I either didn't explain myself well, or I'm not understanding the replies. Probably a little of each. So here's some more explanation.

I have z and v. In-game these are mapped to strafe left and strafe right. As such my fingers are always on them.

"tractor all loot" was mapped to b. Because I'm a horrible touch-typist, moving the index finger from v to b to v again is more complicated than it sounds. Especially while doing umpteen other things with my right hand and my mouse (fast paced game). Also, while it is possible in general to know -about- when to tractor all loot, it's hard to know -exactly- when, because things tend to blow up at different speeds, or when I'm looking in a different direction, whatever. I re-mapped that command to shift-v, but I found that moving my pinkie wasn't any more intuitive than my pointer.

Here's my original solution:

~z & v::
	loop, 7
	{
		send, +v
		sleep, 500
	}
return

This way, hitting z and v together is a natural-flow way of triggering the "tractor all loot" command, because I never hit both at the same time in the natural control of the game, and my fingers are always right there.
Also, I can trigger the hotkey and as long as I'm within 3.5 seconds accuracy, I'll be triggering the command at the right time.

With this hotkey, pressing and holding z returns:

zzzzzzzzzzzzzzzzzzzzzzzzzz

Great! I need it to do just that. Pressing z and v however:

zVzVzzzzzzzzzzzzzzzVZzzzzzzzzzzzzzzzVzzzzzzzzzzzzzzzVZzzzzzVV

That's just a drastic example to demonstrate what the problem is. Normally I would only just tap the key combo:

zVVVVVVV

It just so happens that "strafing" in this game also provides a partial engine and momentum kill - it's great when I'm executing tight banking turns, but it's horrible when done on accident. So that initial "z" in the last string really needs to go.

I might bypass the whole mess by assigning it to some mouse combo, like maybe LBUTTON & RBUTTON - since on the other hand (pardon the almost pun) my fingers are always on those "keys" too, and pass-through has less or no effect on the mouse buttons for that game. But if there's a solution I do have an academic interest in hearing it.

-joe

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks for explaining it so clearly.

I don't see how to solve it because of the following paradox:
1) You want z to be non-suppressed (to flow directly to the game the moment you press it).
2) You want z to be supressed if you're going to press v afterward.

But how can the script know what you're going to do in the future?

I may have misunderstood something, so feel free to clarify.

joe
  • Members
  • 44 posts
  • Last active: Sep 25 2005 09:13 PM
  • Joined: 20 Jan 2005

Thanks for explaining it so clearly.

I don't see how to solve it because of the following paradox:
1) You want z to be non-suppressed (to flow directly to the game the moment you press it).
2) You want z to be supressed if you're going to press v afterward.

But how can the script know what you're going to do in the future?

I may have misunderstood something, so feel free to clarify.


I see what you mean.

Perhaps a way to state it closer to the effect I'm trying to achieve is:

"Allow z to pass through except for the time that I also press v"

Can "except for" be expressed in boolean logic? Would that be XOR?

Maybe I can write some sort of check that detects an XOR condition and reacts to it.

jonny
  • Members
  • 2951 posts
  • Last active: Feb 24 2008 04:22 AM
  • Joined: 13 Nov 2004
The only way to do that would be to send z when it's released, and that's pretty simple to do. Make a hotkey out of z and loop getkeystate for v. If z's released without fulfilling the v state, send a regular z key.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Also, the following probably isn't what you wanted but it's similar to what jonny described (so it's worth a try):
z & v:: 

   loop, 7 

   { 

      send, +v 

      sleep, 500 

   } 

return 



z::Send z