Log in

View Full Version : [Mojo] Build 14: New code for injecting keystrokes



Freddie
01-06-2010, 11:39 AM
My apologies for the long delay since the last build.

This new build has a lot of new code in it, but most of it is invisible. Or should be invisible. You may see new bugs in things that used to work.

(How much new code? 43 new files and 66 changed files.)

There are two new features.

1. The code for injecting keystrokes was totally rewritten. It uses a new technique that I never tried in HotkeyNet. Hopefully, if this works:

-- All broadcasted characters will get shifted (capitalized) correctly.

-- The code is very fast (it's done without thread changes).

-- Quick bar icons change appearance correctly if they are bound to [modifier:] macros.

-- It's done purely with the normal operating system API (no hooking or hackery).

-- It works no matter if WoW is remote, local, foreground, or background.

2. The WoW button now displays icons and info for WoWs that are either running on the computer or are configured to be launched by Mojo. In this build, this stuff is only eye candy. It doesn't yet do anything. However you should be able to add icons for instances of WoW that you want to run, and the program should save that info and redisplay it when it restarts.

Fursphere
01-06-2010, 01:05 PM
I'll download it later today and get to the testing. :D

Thanks!

Fursphere
01-07-2010, 04:51 PM
So - fired up mojo and saw the auto-update feature kick off and work flawlessly. Nice!

Did some simple 'boxing this morning - everything worked fine. I didn't check out the CTRL - ALT - SHIFT passing, totally forgot about that.

Also notice it was picking up and "showing" each running WoW on each instance of mojo - but it didn't show clients from other PCs. I assume thats a work in progress still?

I was thinking maybe you could code in a hook to Windows Notepad.exe for testing? That way I can just test a crap ton of key combinations and see the output outside of WoW? (sometimes WoW does funny stuff with combinations)

Fursphere
01-07-2010, 04:58 PM
I take part of that back - CTRL passes just fine. Has since build 13 at least - just dawned on me that I use it all the time for some stuff. :)

Freddie
01-08-2010, 09:08 AM
So - fired up mojo and saw the auto-update feature kick off and work flawlessly. Nice!
Thanks for testing!

Microsoft gets the credit for auto-update -- it's handled entirely by CickOnce.


Also notice it was picking up and "showing" each running WoW on each instance of mojo - but it didn't show clients from other PCs. I assume thats a work in progress still?
Right. I'm having trouble figuring out how much info should be sent from one PC to the others. Here's the problem. My first inclination was to show info from each Mojo on all Mojos. That's a simple rule: everything appears everywhere.

But if all the Mojos know everything about all the WoWs that are configured to be launched, people will expect to be able to change the info on any copy of Mojo. But that won't work because the config info will break if the user makes a change while one Mojo is off and then later turns all the Mojos on and they find themselves out of sync with each other. So there has to be some limitation on info-trading, or some indication that one particular Mojo is in control, and I'm not sure how to do that without making the program seem complicated.


I was thinking maybe you could code in a hook to Windows Notepad.exe for testing? That way I can just test a crap ton of key combinations and see the output outside of WoW? (sometimes WoW does funny stuff with combinations)
I could do that but it will only test a fraction of what needs to be tested. I think the new key broadcast code can only be tested thoroughly with WoW.

Edit: I'll explain what I just said in a second. But first, I don't think it's necessary to test this thoroughly now because it will get tested very thoroughly in normal use as people use the program more and more.

As far as keystroke signals go (which is only part of what this new code does) Notepad would only show whether character keys get shifted properly and whether a handful of Ctrl combos (the ones that are assigned to Notepad's menu items) get received.

There's another aspect to this code that wouldn't get tested very well. In addition to sending keystroke signals, the code maintains something called a keyboard state for each WoW. Normally this is maintained by the operating system but in order to handle shifting on remote PCs (and also things like AltGr keys in foreign languages), build 14 has a system where Mojo counterfeits the keyboard state for each WoW. Different programs (WoW, Notepad, etc.) may use their keyboard states in different ways, and I'm afraid that the only way to see if the code works with WoW is to test it with WoW.

Pocalypse
01-08-2010, 01:34 PM
But if all the Mojos know everything about all the WoWs that are configured to be launched, people will expect to be able to change the info on any copy of Mojo. But that won't work because the config info will break if the user makes a change while one Mojo is off and then later turns all the Mojos on and they find themselves out of sync with each other. So there has to be some limitation on info-trading, or some indication that one particular Mojo is in control, and I'm not sure how to do that without making the program seem complicated.


Do you cache the settings in a file somewhere (or in memory somewhere)? Then, when the already open Mojo with changes detects a new Mojo on the network, it can send over all the settings at the same time, and update the new Mojo.

I suppose then you have to start thinking about which Mojo has more up to date information, and the order in which Mojos are opened.

Just a thought.

Freddie
01-08-2010, 01:50 PM
Do you cache the settings in a file somewhere (or in memory somewhere)?
Settings are saved in files.


Then, when the already open Mojo with changes detects a new Mojo on the network, it can send over all the settings at the same time, and update the new Mojo.
That works in that case but there are many other cases. Suppose one Mojo has run and been changed and shut down by itself. Then the same thing with the second. Then you start the first. Then you start the second. See the problem?


I suppose then you have to start thinking about which Mojo has more up to date information, and the order in which Mojos are opened.
Exactly. That's the problem. In general, it seems to be impossible to know which file is newer because the files have timestamps based on clocks in different computers.

I think probably the only way to do this is with a central repository for the info which means Mojo would no longer be 100% peer to peer. I'd like to hold on to peer to peer as a "100% design invariant" for the life of the project, if that's possible.

This problem has already arisen with mouseover and I handled it by creating entirely separate settings on each PC. I'm inclined to think the solution lies in that direction.

The basic idea would be, each computer is the master repository for settings that were created on that computer. As a result, each Mojo could have different settings.

It would be easier for me if each computer is the master repository for its own instances of WoW, but then maybe it starts to get complicated for the user.

Fursphere
01-08-2010, 02:27 PM
I would just make it click via tooltip or something that information shown for other mojo's is INFORMATIONAL ONLY, and that each mojo must be configured independently.

Which makes perfect sense btw - when I switch computers (via Input Director software KVM) - the new computer "owns" the keyboard and mouse - so do I want keystrokes to be broadcast from the "current" master?

Master is whatever has "focus" at the time. Once you start thinking this way, its quite simple. Assuming most people use HARDARE KVM switches to manage multiple PCs on one desk, this makes perfect since anyway...

ElectronDF
01-08-2010, 08:01 PM
I agree with the info (show only) for other computers. I expect 80% of boxers use 1 computer. I also expect 99% of boxers to not change their setup (start of WOW) once it works. So it shouldn't have to be changed very often and they can do it from the other Mojos.

Fursphere
01-08-2010, 08:52 PM
I expect 80% of boxers use 1 computer.

I'd wager that this number is much closer to 95%

Aragent
01-08-2010, 09:23 PM
Could we not setup an additional tab like we have for wow and toons, for other computers mojo network paths.

we can even make it and Advanced setting to maintain ease of use for the multitude, and have a button to allow us to push updated info to our other computers Mojo.

Then we take the respocability off Mojo of having to remember which Mojo was last updated, and put it on the User.
we can even give an option to push the data to pc's even if the mojo was off, but the PC was still on the network.

Just a thought.

TheFallenOne
01-09-2010, 01:14 PM
Exactly. That's the problem. In general, it seems to be impossible to know which file is newer because the files have timestamps based on clocks in different computers.

I think probably the only way to do this is with a central repository for the info which means Mojo would no longer be 100% peer to peer. I'd like to hold on to peer to peer as a "100% design invariant" for the life of the project, if that's possible.

This problem has already arisen with mouseover and I handled it by creating entirely separate settings on each PC. I'm inclined to think the solution lies in that direction.

The basic idea would be, each computer is the master repository for settings that were created on that computer. As a result, each Mojo could have different settings.

It would be easier for me if each computer is the master repository for its own instances of WoW, but then maybe it starts to get complicated for the user.


Another option (food for thought):

Settings are saved with a version #, starting at 0, incremented by 1 every time the file is updated. The version number is also appended with a unique identifier specifying which computer the settings came from (maybe a MAC ID, some kind of product ID, or something similar).

When multiple computers connect, they compare version stamps. Say we have C1 and C2 connecting to each other. C1 has a settings file with version stamp as, say... 18-C1, and C2 has a settings file with version 16-C1. This indicates that C2 has previously received settings from C1, and automatically updates to 18-C1 from C1.

Now, if you update the settings on C2, they would be saved with the new version stamp 19-C2. This would be sent along with the last NON-C2 version stamp that the settings were updated from, and C1 would look at the incoming stamps, see that C2 has been updated from 18-C1 (which is C1's current version and the last non-C2 version stamp that was used) to 19-C2, and so it determines it should update too (since it's on 18-C1), and now saves it's version stamp as 19-C2.

Now for the part where things might get a little less straightforward... Both computers are on 26-C1, and you disconnect both computers. You do an update on both C1 and C2, and then reconnect them. Version stamps are compared, and since both have been updated independently, a "fork" is created in the settings tree. A dialog pops up, notifying the user that the settings from both of them do not match, and allowing them to choose whether to use the settings from C1, settings from C2, or leave them in a forked state.


I'm running on very little sleep, so I apologize if some of this is a little unintelligible. Anyways, just some food for thought, maybe you'll get some ideas from it.


EDIT: I also actually rather like the idea of "pushing" settings from one Mojo to the others (mentioned by Aragent above), ALA how Jamba handles things. I believe that would work rather nicely.

Freddie
01-09-2010, 02:03 PM
I would just make it click via tooltip or something that information shown for other mojo's is INFORMATIONAL ONLY, and that each mojo must be configured independently.
How would you deal, for example, with setting afinity for a particular instance of WoW?

Let's say that WoW runs on PC 3.

Can you set that option for that WoW on PC 2?

Freddie
01-09-2010, 02:13 PM
Could we not setup an additional tab like we have for wow and toons, for other computers mojo network paths.
What would that tab do? I don't understand.


we can even make it and Advanced setting to maintain ease of use for the multitude, and have a button to allow us to push updated info to our other computers Mojo. Then we take the respocability off Mojo of having to remember which Mojo was last updated, and put it on the User.
That sounds like a good idea, but I'm not sure if it really takes any responsibility off Mojo. As the config screens develop, people will use them and we'll all have a better idea of the issues..

Freddie
01-09-2010, 02:36 PM
Another option (food for thought):

Settings are saved with a version #, starting at 0, incremented by 1 every time the file is updated. The version number is also appended with a unique identifier specifying which computer the settings came from (maybe a MAC ID, some kind of product ID, or something similar).

When multiple computers connect, they compare version stamps. Say we have C1 and C2 connecting to each other. C1 has a settings file with version stamp as, say... 18-C1, and C2 has a settings file with version 16-C1. This indicates that C2 has previously received settings from C1, and automatically updates to 18-C1 from C1.

Now, if you update the settings on C2, they would be saved with the new version stamp 19-C2. This would be sent along with the last NON-C2 version stamp that the settings were updated from, and C1 would look at the incoming stamps, see that C2 has been updated from 18-C1 (which is C1's current version and the last non-C2 version stamp that was used) to 19-C2, and so it determines it should update too (since it's on 18-C1), and now saves it's version stamp as 19-C2.

Now for the part where things might get a little less straightforward... Both computers are on 26-C1, and you disconnect both computers. You do an update on both C1 and C2, and then reconnect them. Version stamps are compared, and since both have been updated independently, a "fork" is created in the settings tree. A dialog pops up, notifying the user that the settings from both of them do not match, and allowing them to choose whether to use the settings from C1, settings from C2, or leave them in a forked state.
Maybe I'm missing something, but it seems to me there are basically two main cases. In one case, the Mojos are running simultaneously and talking to each other. In that situation, whenever you change one Mojo, it tells the others. All changes immediately propagate. There's no need for version numbers or anything else.

The second case is what you call "less straightforward." It occurs when you change Mojo A while it's not talking to Mojo B, and then you change Mojo B while it's not talking to Mojo A. When they find themselves in communication again, they have no way to know which one was updated more recently.

If the first case doesn't require a solution, and your solution doesn't solve the second problem, what is it useful for?

Those two cases aren't logically exclusive so there must be other circumstances, but I'm having trouble getting a sense of how common they would be. Can you give me an example where version numbers would help?


EDIT: I also actually rather like the idea of "pushing" settings from one Mojo to the others (mentioned by Aragent above), ALA how Jamba handles things. I believe that would work rather nicely.
I'll look into Jamba. Thanks for suggesting it.

Fursphere
01-09-2010, 08:51 PM
How would you deal, for example, with setting afinity for a particular instance of WoW?

Let's say that WoW runs on PC 3.

Can you set that option for that WoW on PC 2?

How can you be sure that PC 2 and 3 are identical hardware? (you can't). If you really want a central "launch" WoW - I would configure it like this.

Make it so each "mojo" can see every other mojo's running copies of WoW. (And SAVE them for future refernce).

Whenever you want to launch mulitple wow's on seperate PCs, just highlight them all (ctrl click?) and "launch" them.

that way any copy of mojo can luanch another copy of WoW on another machine, provided mojo is runnin there already.

This would keep your "no master no slave" setup.

as far as affinity goes, you'll maybe.. right click each wow config and set it there? remote mojo config from another mojo? have it save on the local mojo for each wow?

And I STRONGLY advise against all this "pushing / pulling" config nonsense. If you do that, you'll basically be moving to the master / slave setup. I like the concept that there is no master or slave.

Freddie
01-10-2010, 04:26 AM
How can you be sure that PC 2 and 3 are identical hardware? (you can't).
They wouldn't need identical hardware. The only hardware that would be taken into account is the PC that the program is going to run on. The PC you're typing on wouldn't matter. (I'm not saying I'm going to do this. I was only asking what you thought about it.)


If you really want a central "launch" WoW - I would configure it like this.

Make it so each "mojo" can see every other mojo's running copies of WoW. (And SAVE them for future refernce).

Whenever you want to launch mulitple wow's on seperate PCs, just highlight them all (ctrl click?) and "launch" them.

that way any copy of mojo can luanch another copy of WoW on another machine, provided mojo is runnin there already.

This would keep your "no master no slave" setup.
I've been thinking pretty much the same thing with one difference. I don't think there's any reason to save the info on other PCs because the other PCs can only use the info when they are connected to the installation PC, and if they are connected, they can just read the info in real time across the network from the installation PC.


And I STRONGLY advise against all this "pushing / pulling" config nonsense. If you do that, you'll basically be moving to the master / slave setup. I like the concept that there is no master or slave.
I'm glad you like that concept. I like it too. :)

But I don't think pushing configs is master/slave. Unless I misunderstood it just means "copy settings from one PC to another."

rocnroll
01-10-2010, 03:09 PM
I'd wager that this number is much closer to 95%

94.786754321% to be precise Captain Fursphere. :)

Aragent
01-12-2010, 11:22 AM
What would that tab do? I don't understand.

Sorry it took so long to get back to this question Lost my main HD the other day and had to wait for its replacement to come in.

However what I envisioned for this tab would do is a place to configure know mojo paths, similar to how the wow tab works to know where the know wows are.

then when we pushed the mojo configuration files it would use these to know where to push the settings.

This would not be a master/slave becouse these settings could be done from any Mojo and pushed to any other so long as it the other mojos were configured in the Mojo tab.

example in a 3 machine environment (provided you had all 3 configured on all 3 machines)
1 could push to 2&3
2 could push to 1&3
3 could push to 1&3

Freddie
01-12-2010, 11:50 AM
However what I envisioned for this tab would do is a place to configure know mojo paths, similar to how the wow tab works to know where the know wows are.
I misread this. I'm going to write a new reply.

Freddie
01-12-2010, 12:11 PM
what I envisioned for this tab would do is a place to configure know mojo paths, similar to how the wow tab works to know where the know wows are.

Each Mojo already knows about the others. They find each other automatically. The Computers tab shows other Mojos. It's called "Computers" instead of "Mojos" because I thought the name "Mojos" would be confusing in this context.

Mojos don't remember anything about each other. Each Mojo only knows about another while the other is running and they are connected. It's done this way because it guarantees that every Mojo's info about the others is correct. By designing it this way, a whole class of errors is prevented.


This would not be a master/slave becouse these settings could be done from any Mojo and pushed to any other...
I agree.

By the way, in order to copy info from a local PC to a remote PC, the local Mojo needs the IP address and/or hostname of the remote Mojo, not the pathname. The local Mojo needs to ask the remote Mojo to save the settings, and it does this by sending info over a socket connection, not by doing anything with the remote PC's hard disk.

There are two reasons why a Mojo doesn't mess with the hard disk on a another computer.

1. The OS on the PC where the hard disk is located may not allow another PC's Mojo to read or write the file. (Mojo runs with admin privileges but they only apply to the PC where that instance of Mojo is running.)

2. If more than one Mojo could write to the same file, the file could become corrupted or out of sync with other data.

Fursphere
01-17-2010, 10:41 PM
BUG REPORT! :D

So, I'm not sure how to reproduce this one, as it is a bit strange.

I'm currently playing with 4x feral druids. Just hit level 30 (yay me!). Anyway, so I learned feral charge and assigned it to the "1" key. Acquire target - hit "1" - only main flys in. Hmmmm....

Try doing one of the followers solo - get target, hit 1, nothing happens - WoW gives "target too close" error (even thought I know its not). I try this sort of thing 20 different ways in five minutes. I'm totally able to pass the "1" key in chat windows. I hit 1 and I see the wow action bar light up - but the actual ability doesn't get used.

So, I close mojo and try it (moused over to the alt) - and it works! Rinse repeat on all 3 "alt" PCs, and it fixes the problem. Strange right? Other keys were working fine....

So I reload mojo on every PC, and so far so good, everything appears to be working fine - including the "1" key.

I had similar problems lately with left mouse clicks on alts - I usually have to reload WoW to fix the issue. I honeslty don't know if its Input Director or Mojo - but reloading Mojo did fix it. If it happens again, I'll try closing input director first to see what happens.

So ya, don't have much to go on, but _something_ is acting goofy. :)

Freddie
01-17-2010, 11:08 PM
BUG REPORT! :D
Fun fun fun!


get target, hit 1, nothing happens - WoW gives "target too close" error (even thought I know its not).
Is WoW displaying "target too close" in response to your keystroke? If so, then it's doing something.

Key broadcast can only break in two ways:

(1) WoW doesn't receive anything, or

(2) WoW receives the wrong key info.

If you press a key and WoW doesn't react at all, it's problem (1). If WoW displays an error message (or does anything else) it's problem (2). From my point of view, that's a big difference.

If it's (2), can you figure out what key info WoW is receiving based on what it does?


I try this sort of thing 20 different ways in five minutes. I'm totally able to pass the "1" key in chat windows. I hit 1 and I see the wow action bar light up - but the actual ability doesn't get used.
What key strokes would WoW have to receive to make WoW's action bar light up?

Would that happen if Shift or Alt or Ctrl is down?


If it happens again, I'll try closing input director first to see what happens.
Thanks, sounds like a good idea.

Also, next time it happens, could you broadcast Alt Ctrl Shift to all your WoWs (press and release those three keys in no special order) and see if that fixes the problem.

Fursphere
01-17-2010, 11:20 PM
Ok, got it to do it again. Shutting down Input DIrector (on all machines) solved the problem.

Its going to be near impossible to tell if its a bug in IP - a bug in Mojo - or an incompatibility with the two running at the same time. (I'm running a beta version of Input Director to boot. lol).

So.. whats the status of getting mouseover in Mojo working at the same time key boardcasting is on? :D

Fursphere
01-17-2010, 11:29 PM
Ok - 3rd times the charm. Figured it out. Its the CTRL-ALT sticky thing again.

ALT-1 stills shows the action bar being "hit" but its not actually clicking the button. After "rolling" the ctrl and alt kets a few times, it solved the problem.

This was with Input DIrector shutdown - so its gota be mojo. And I even tried a PS/2 hardware attached keyboard to PC #2 (while it was having the issue) and same results - rolling the ctrl / alt keys "unlocked" them and the "1" key started acting normal again.

Freddie
01-17-2010, 11:42 PM
(Edit: This post crossed the one right above it)

We might be able to figure out why the programs are interacting this way. The reason I asked about alt/ctrl/shift is because the only complicated thing Mojo does is keep its own record of whether those keys are down or up.

Today I came within a hair of finishing the new hotkey stuff. Tomorrow, in order to finish it, I have to make some changes to mouseover and to the keyboard hook, and those are the two parts of the program that have to be changed for mouseoever and broadcasting to work at the same time. So I'll try to change it all tomorrow when I'm working on it.

Freddie
01-17-2010, 11:43 PM
Ok - 3rd times the charm. Figured it out. Its the CTRL-ALT sticky thing again.

ALT-1 stills shows the action bar being "hit" but its not actually clicking the button. After "rolling" the ctrl and alt kets a few times, it solved the problem.

This was with Input DIrector shutdown - so its gota be mojo. And I even tried a PS/2 hardware attached keyboard to PC #2 (while it was having the issue) and same results - rolling the ctrl / alt keys "unlocked" them and the "1" key started acting normal again.
Good work!

That was my guess ... that's why I asked you to press those keys. Can you figure out a sequence of actions that causes the problem?

If you can do that, I'll probably be able to fix it pretty easily.

Fursphere
01-17-2010, 11:49 PM
Honestly, it seems to be tied to when I ALT-TAB in and out of WoW on the main machine - going to the web browser and such. When I go back to WoW, it seems to "forget" where the ALT key is.

Hmm.... just had an Idea. BRB!

EDIT - Strach that . I was thinking maybe it had something to do with how I went back to WoW - either by clicking on the WoW window, bring it back into the foreground, or ALT-TABBING back - made no different.

I have to hit ALT on the slave machine to get it back in sync.

Freddie
01-17-2010, 11:58 PM
Honestly, it seems to be tied to when I ALT-TAB in and out of WoW on the main machine - going to the web browser and such. When I go back to WoW, it seems to "forget" where the ALT key is.

Hmm.... just had an Idea. BRB!

EDIT - Strach that . I was thinking maybe it had something to do with how I went back to WoW - either by clicking on the WoW window, bring it back into the foreground, or ALT-TABBING back - made no different.

I have to hit ALT on the slave machine to get it back in sync.

Oh, okay, that explains it. This is the same problem you told me before, right?

Excellent detective work!

I think I know what's wrong but I haven't figured out what to do about it.

I think it's just that when you Alt Tab, by the time you release the Alt key, WoW is no longer the focus window, so Mojo never broadcasts the release of the Alt key.

As a result, Mojo's key state tables (the fake ones it maintains for each WoW) show the Alt key down. Then next time you broadcast a key, Mojo translates the key with the screwed up key state tables. This could have odd effects since the operating system has a complicated way of interpreting keystrokes when Alt is down.

Fursphere
01-18-2010, 12:04 AM
Makes perfect sense to me. Hard has is it for mojo to actually verify the keystate?

Freddie
01-18-2010, 12:15 AM
Makes perfect sense to me. Hard has is it for mojo to actually verify the keystate?

There isn't anything to verify these key state tables against. They are the only record of what Mojo has broadcast.

They are doing that correctly. The problem is that Mojo doesn't broadcast the alt-was-released signal. Therefore the alt-was-released signal doesn't get put in the key state tables.

The reason for the error is that Mojo follows the simple algorithm "broadcast whenever WoW is the focus window."

But this algorithm is inadequate because when you Alt-tab, WoW stops being the focus window before you release the Alt key.

I have to change the algorithm. I have to make it more complicated so Mojo will broadcast the alt-was-released signal even though WoW no longer has the focus.

Freddie
01-18-2010, 12:22 AM
An addition to what I just wrote:

You're probably thinking that Mojo could look at the physical key state on the local machine to see what the key state "really" is.

But it can't do that because very soon Mojo will be able to broadcast keystrokes to WoWs that are different from the keystrokes you pressed physically. Once that happens, each target WoW will have its own unique idea of the keyboard state which will be different from the physical state on any machine.

Mojo has to be able to track those keyboard states accurately. The code is essential so I put it in the program now and it's got to be made to work perfectly.

Fursphere
01-18-2010, 12:30 AM
Ok, I follow ya. Just don't know how to deal with that.

So you're basically creating "X" number of virtual keyboards (where "X" = # of active WoWs).

I can't think of a reason where I'd want to hold the alt key down for very long - although I multibox very differently than a lot of folks out there.

Freddie
01-18-2010, 12:45 AM
So you're basically creating "X" number of virtual keyboards (where "X" = # of active WoWs).
Exactly. I've tried about ten different ways of handling this problem in HotkeyNet. This is a new idea that just occurred to me a few weeks ago. Despite this problem (which is totally solvable) I think this will turn out to be the best way.


I can't think of a reason where I'd want to hold the alt key down for very long - although I multibox very differently than a lot of folks out there.
This kind of code is necessary whenever the injected keystrokes are different from physical ones. With FTL for example. It doesn't matter how long the keys are pressed.

TheFallenOne
01-18-2010, 02:19 PM
I think I know what's wrong but I haven't figured out what to do about it.

I think it's just that when you Alt Tab, by the time you release the Alt key, WoW is no longer the focus window, so Mojo never broadcasts the release of the Alt key.

As a result, Mojo's key state tables (the fake ones it maintains for each WoW) show the Alt key down. Then next time you broadcast a key, Mojo translates the key with the screwed up key state tables. This could have odd effects since the operating system has a complicated way of interpreting keystrokes when Alt is down.

What about marking all keys as released (and sending the relevant key up events) when the focused window changes?

Freddie
01-18-2010, 03:37 PM
What about marking all keys as released (and sending the relevant key up events) when the focused window changes?
My first thought was along similar lines. But there are some complications and I'm not sure how to deal with them.

The first question is, What triggers Mojo to act? You suggest the trigger should be a change in the focus window. But how can Mojo know that the focus window changes? The only way I can think of is for Mojo to install an OS hook of some kind, probably a WH_SHELL hook. This might slow the computer down appreciably. I don't know, it would require testing. If somebody can think of a different way please tell me.

Second, what action does Mojo take? The suggestion is, tell every broadcast target that modifiers are up. I think there would need to be some conditional restrictions on this because the user might not want that to happen. To take an extreme example, the program is going to allow people to write a hotkey like this:



Hotkey ( F1 )
{
SendTo ( WoW1 )
PressKey ( Alt );
}


That basically means, "Make the target program think Alt is pressed and let it keep thinking that until I say so."

I can't foresee why somebody would write that, but it's legal given the program's syntax so part of my job is to ensure that it works and avoid automatic actions that interfere with the user's intent.

Fursphere
01-18-2010, 05:17 PM
Does HotKeyNet have this same problem?

Freddie
01-18-2010, 06:20 PM
Does HotKeyNet have this same problem?
Nope. HotkeyNet is very good at making sure it sends key releases.

I'm glad you asked this question because it hadn't occurred to me to think about how I handled this in HotkeyNet. The two programs are so different, I didn't think HotkeyNet could help. But actually, it uses a trick that could work in Mojo too.

Here's how HotkeyNet does it. Every time you press a key that triggers an action, HotkeyNet thinks ahead and figures out what it will do in the future when your finger releases the key. It writes a little note that tells itself what to do at that future time and puts it in a table. Then it performs the action for the key press.

Later, when you lift your finger, HotkeyNet looks in the table to see what it should do. By that time the local computer's state may have changed -- you may have alt tabbed, you may have closed a window, you may have done all kinds of things -- but that doesn't matter because HotkeyNet already decided, back when the computer was in an earlier state, what to do in this later state.

Edit: By the way, hotkeys seem to be working now in Mojo. I just wrote the web documentation and I'll probably post a build in a few hours after I test it some more. Also I need to temporarily disable a bunch of new stuff that's half finished so people don't wonder if they should tell me it's half finished. :)

TheFallenOne
01-19-2010, 02:33 AM
Nope. HotkeyNet is very good at making sure it sends key releases.

I'm glad you asked this question because it hadn't occurred to me to think about how I handled this in HotkeyNet. The two programs are so different, I didn't think HotkeyNet could help. But actually, it uses a trick that could work in Mojo too.

Here's how HotkeyNet does it. Every time you press a key that triggers an action, HotkeyNet thinks ahead and figures out what it will do in the future when your finger releases the key. It writes a little note that tells itself what to do at that future time and puts it in a table. Then it performs the action for the key press.

Later, when you lift your finger, HotkeyNet looks in the table to see what it should do. By that time the local computer's state may have changed -- you may have alt tabbed, you may have closed a window, you may have done all kinds of things -- but that doesn't matter because HotkeyNet already decided, back when the computer was in an earlier state, what to do in this later state.

Good solution. :)

The other advantage to this is you could likely (if it was ever found to be needed) pretty easily set Mojo up to allow the action taken on key up change dynamically on key down, based on some script, just have to override the data in the table. :) Of course, there's always that thin line we want to be careful not to cross, and I'm not entirely sure where I'd draw it in that case, haha.

Freddie
01-19-2010, 12:44 PM
Good solution. :)
Thanks. :) I think I'm going to reuse it in Mojo.


The other advantage to this is you could likely (if it was ever found to be needed) pretty easily set Mojo up to allow the action taken on key up change dynamically on key down, based on some script, just have to override the data in the table. :) Of course, there's always that thin line we want to be careful not to cross, and I'm not entirely sure where I'd draw it in that case, haha.
That's how HotkeyNet works and that's also how Mojo will work. The data in the table is actually a pointer to a hotkey definition that the user wrote (assuming one was written).

It's just a hotkey definition like any other hotkey definition that the user writes. I'm not sure why you think a line needs to be drawn.

Right now we're talking about broadcasting instead of hotkeys, but broadcast is actually a subset of hotkeys where every key is a hotkey that sends itself both when it's pressed and released.

Freddie
01-19-2010, 12:45 PM
Good solution. :)
Thanks. :) I think I'm going to reuse it in Mojo.


The other advantage to this is you could likely (if it was ever found to be needed) pretty easily set Mojo up to allow the action taken on key up change dynamically on key down, based on some script, just have to override the data in the table. :) Of course, there's always that thin line we want to be careful not to cross, and I'm not entirely sure where I'd draw it in that case, haha.
That's how HotkeyNet works and that's also how Mojo will work. The data in the table is actually a pointer to a hotkey definition that the user wrote (assuming one was written). The code in the definition can't change dynamically but the code can evaluate conditions dynamically and take different actions at different times, so it amounts to the same thing.

(Edit: HotkeyNet does not and Mojo will not have the ability to know what's going on inside a game, so what I just wrote doesn't mean that they can be used for automation. When I say "conditions" I mean things like which program is in the foreground, which window the mouse is over, etc.)

It's just a hotkey definition like any other hotkey definition that the user writes. With any hotkey definition, the user has to be careful not to do things that break rules. I don't think this becomes a bigger problem because the hotkey gets triggered on a release instead of a press.

Right now we're talking about broadcasting instead of hotkeys, but broadcast is actually a subset of hotkeys where every key is a hotkey that sends itself both when it's pressed and released.