Author |
Topic |
|
betty
3 Posts |
Posted - 04/20/2012 : 18:10:34
|
Actions from gestures appear to happen to the currently focused window, not the one which the gesture was drawn on. |
|
Rob
USA
2615 Posts |
Posted - 04/20/2012 : 18:23:57
|
Can you give me a specific example? Including the actual Lua script and how you're experiencing the issue?
There are many ways to specify which window receives the action, but some things can require an extra action call to set focus to a background window. acSendKeys, for example, cannot send keystrokes to a window in the background as it simply tells Windows to type the keys specified. In that case, you would need to call acActivateWindow first to bring it to the foreground, then call acSendKeys.
Of course, this is just me rattling off some specific situations for others who may read this. Tell me about what exactly is happening for you? Please let me know where you're starting and ending the gesture as well. By default, most actions will send the commands to the window exactly under the mouse where the Stroke button was pressed. So if you started drawing just outside the window, but drew the entire gesture on the window you'd like to have the action performed against, it would still be directed at whichever window was under the mouse when the drawing started. |
|
|
betty
3 Posts |
Posted - 04/20/2012 : 18:58:38
|
Specifically it's the action to close a tab in chrome (acSendKeys("^w")), but I notice a lot of the actions seem to have a similar issue.
I could go through and add acActivateWindow to every script, but I wonder if it should be the default. I imagine it doesn't effect that many users as they either maximize their windows or don't have multiple monitors.
For me, I have dual monitors so often find myself trying to close or perform another action on something on the other screen which isn't focused. It's a habbit I gained from many years of using strokeit, which I guess had a slightly different behaviour for its send key command. |
|
|
Rob
USA
2615 Posts |
Posted - 04/20/2012 : 19:10:10
|
I can understand that. However, I designed to make S+ very granular and let the user decide what happens; I guess this is one of the instances where the downside of that presents itself. For instance, there are several actions I have which I do not want the target window brought to the foreground (I have a triple monitor setup).
Win some, lose some I suppose. But thank you for the feedback...whether it's something that is changed or not, I appreciate everyone's input. Sometimes one thing leads to a whole other tangent which gives me a really good idea on how to improve S+. |
|
|
Rob
USA
2615 Posts |
Posted - 04/20/2012 : 19:25:46
|
I'll definitely poke around in the SendKeys stuff. To be honest, I just took the source from an existing CodeProject and stuck it in S+.
So yeah, to duplicate, you'd have to do something like:
local iHandle = acGetForegroundWindow() acActivateWindow(nil, gsx, gsy) acSendKeys("Rob sucks donkey balls for this lame send keys implementation!") acActivateWindow(iHandle, nil, nil)
|
|
|
betty
3 Posts |
Posted - 04/20/2012 : 19:48:03
|
Cheers, I'll use that script for now and wait to see if you come up with anything. |
|
|
Mersine
22 Posts |
Posted - 01/24/2013 : 10:18:27
|
I have triple monitors and I too would love the idea of having the action affect the application drawn on. There used to be a program that would focus and bring to front whatever window was scrolled on, but it conflicted with my ability to scroll in text boxes for some reason. It flowed better for me with one smooth gesture rather than having to click on the app. But anyway, as was said, it's a user preference.
For the most part Strokeplus already does this for me. But similar to what Betty stated, when I try a gesture to close tabs or switch between them in a browser, I have to be in the browser first. |
Edited by - Mersine on 01/24/2013 10:21:26 |
|
|
Rob
USA
2615 Posts |
Posted - 01/24/2013 : 10:22:00
|
Don't forget you can utilize the sp_before_action function in Global Lua to always activate the window below where the gesture began:function sp_before_action(gnm, gsx, gsy, gex, gey, gwd)
acActivateWindow(nil, gsx, gsy)
end It will fire before all actions (not those defined in the Hotkey tab, though) |
|
|
Mersine
22 Posts |
Posted - 01/24/2013 : 10:23:57
|
My god what can't this app do. Thanks! |
|
|
Rob
USA
2615 Posts |
Posted - 01/24/2013 : 10:26:14
|
Work with complex (Unicode, non-Latin) characters for strings, matching, acDisplayText unfortunately...it is the only real Achilles' heel due to my not understanding the internationalization issues when I started writing S+. To be honest, I never imagined this little project would become so popular and used around the world, lol. |
|
|
Mersine
22 Posts |
Posted - 01/24/2013 : 10:28:07
|
It makes me feel like a wizard :D |
|
|
Rob
USA
2615 Posts |
Posted - 01/24/2013 : 10:32:01
|
Heck, wait until you figure out that using the monitor action functions you could essentially write your own actions to duplicate what KHE Mover-Sizer is doing =)
Of course, not precisely in the sense of dragging windows, but you could make actions which do what you wanted to do with mover-sizer...Example script I use to send a window to another monitor. The possibilities are endless, really; but it's also quite a bit of script writing when mover-sizer is already meeting your needs. |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/25/2013 : 12:18:21
|
Sometimes it won't make it active, with following code:
function sp_before_action(gnm, gsx, gsy, gex, gey, gwd, gapp, gact)
acActivateWindow(nil, gsx, gsy,0)
end
It fires the actions on the active window and not the one that's drawn on. Happens intermittently, not sure what's wrong. Tried changing 0 to 1 and 2 as well. |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Rob
USA
2615 Posts |
Posted - 01/25/2013 : 12:29:19
|
It can be tricky in some cases. If you happen to gesture over a control which isn't relaying the activate message up to the parent/owner or isn't a window (control) which is eligible to receive an activate message, this could happen. You may want to try something like:acActivateWindow(acGetOwnerWindowByPoint(gsx, gsy),0,0) This would activate the owner window, which will probably always work.
|
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/25/2013 : 20:40:04
|
Still experiencing it to misfire. =/
Dragged it over Google Chrome while having mIRC active: Next tab = acSendKeys("^{TAB}") The action caused mIRC to switch channel.
This should only fire in Google Chrome and other browsers as it's filtered with: File Name Pattern = Maxthon.exe|chrome.exe|iexplore.exe|firefox.exe Also mirc.exe is in Ignored List.
I know it fires as it's executed over Google Chrome, like it should, but it should not take the action on mIRC. :) |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
Edited by - Andreasvb on 01/25/2013 20:41:12 |
|
|
Rob
USA
2615 Posts |
Posted - 01/25/2013 : 20:43:10
|
What's the action script? So I can test.
Also, is the Chrome taskbar button flashing? As if S+ sent the focus change but Windows prevented it, only alerting you. |
|
|
Rob
USA
2615 Posts |
Posted - 01/25/2013 : 20:43:52
|
Bah, I was too slow on my reply. |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/25/2013 : 20:47:03
|
Tried some more, yes the Google Chrome button is flashing. |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Rob
USA
2615 Posts |
Posted - 01/25/2013 : 20:50:19
|
Ah, yea that means Windows is denying S+ in the activate command. It's a huge pain in the ass and many others experience the issue in other programs. It's complicated and annoying. Sometimes exiting and restarting S+ can help, sometimes opening the settings window and interacting with it can help. Sometimes I've had to log off and back on. I'll have some other suggestions when I get home later. |
|
|
Andreasvb
Sweden
46 Posts |
|
Rob
USA
2615 Posts |
Posted - 01/25/2013 : 22:33:40
|
No, that's similar to StrokesPlus' Enable Mouse Wheel Relay feature, which is only forwarding mouse wheel messages to a window, not attempting to bring it to the foreground.
The issue lies with changes to Windows many years back which aimed to prevent applications from forcing another window to the foreground (think: malware continually spawning browser popup windows and bringing them to the top). Normally, this can be alleviated by calling AllowSetForegroundWindow (which S+ calls when it loads). However, there are certain restrictions which for some reason come into play sometimes, preventing S+ from being granted this privilege (see the restrictions in the link).
Because S+ is a background program which runs with a non-interactive main window (gesture draw window), sometimes Windows thinks that it's trying to gain this privilege without your knowledge/consent. For example, if I have S+ popup a message box when it starts, but before the call to AllowSetForegroundWindow, you will never experience the flashing. This is because Windows sees that you're aware this program is running and has been interacted with by you. So the subsequent call to AllowSetForegroundWindow is deemed valid and S+ is allowed to call SetForegroundWindow without any restrictions.
Believe me, you have no idea the amount of countless hours I spent trying to mitigate this annoying issue. Most of the time it's fine, but every now and then something just doesn't sit right with Windows and it determines that S+ isn't allowed to bring other windows to the foreground.
It's a very frustrating web of rules and conditions which are not always applied consistently; meaning S+ isn't doing anything differently, but Windows has simply decided it doesn't want S+ to have the ability to set the foreground window. When it happens to me, from time to time, I usually open up the S+ settings window, click OK, click another window, draw a gesture on it and everything's ok again. It doesn't happen often for me (maybe once per month), but I'm not really sure what else to try at this point...other than having a splash screen which pops up when S+ loads, so the call to AllowSetForegroundWindow occurs after you've interacted with S+. Maybe it's something I could make optional, either way it's just annoying. |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/26/2013 : 00:34:24
|
Would it be possible to use acPostMessage instead? A bit like:
MouseGetPos x, y, WinID, Ctrl
PostMessage, 0x20A, WheelPace * WheelSteps * WheelDir, y << 16 | (x & 0xFFFF), %Ctrl%, ahk_id %WinID%
http://www.autohotkey.com/docs/commands/MouseGetPos.htm http://www.autohotkey.com/docs/commands/PostMessage.htm
I've also noticed that if you right click normal on a window, not having S+ running (or on a window that's in Ignore List when it's running), it activates the window directly.
Stupid Windows. :D |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 11:35:50
|
quote: Originally posted by Andreasvb
Would it be possible to use acPostMessage instead? A bit like:
MouseGetPos x, y, WinID, Ctrl
PostMessage, 0x20A, WheelPace * WheelSteps * WheelDir, y << 16 | (x & 0xFFFF), %Ctrl%, ahk_id %WinID%
To do exactly what; send mouse wheel messages? An adaptation of this for something else? |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/26/2013 : 11:40:10
|
Yes, tried some but couldn't get it to work.
WM_ACTIVATE = 0x06 WM_MOUSEACTIVATE = 0x21 WM_LBUTTONDOWN = 0x201
Can't be that impossible. :)
What about make it active on mouse down instead of mouse up, as it is now? Is it your invisible layer that prevents that? |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
Edited by - Andreasvb on 01/26/2013 11:42:04 |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 11:45:00
|
Oh yeah, those are not fun to try and accomplish. Technically possible, but it's a big pain and often different for every app in regards to exactly which window handle is responsible for handling the message. If you use Spy++, you can certainly craft your own message by emulating the messages in the message hook...but like I said, it's pretty tedious.
Besides, even if you sent the WM_ACTIVATE message properly to the correct window handle, since S+ is the sender, it still would cause the taskbar flash if Windows has decided S+ doesn't have the privilege to bring a window to the foreground. |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 11:46:26
|
I'm thinking of adding the AllowSetForegroundWindow call to occur when you click Reload Config and Lua engine from the tray icon. It might correct it since S+ will have active focus and be the last app to receive input from the user (you). |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/26/2013 : 11:48:59
|
I never use that, but maybe have it call in sp_before_action each time, would that take too much of the processing? :P |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 11:50:48
|
No, that's a Windows API call, not something available to call in a Lua script. You could technically use Alien and bind to it, but I wouldn't recommend it. Windows will probably think S+ is trying to spam the call and may treat it the same. |
|
|
Mersine
22 Posts |
|
Andreasvb
Sweden
46 Posts |
Posted - 01/26/2013 : 11:51:39
|
I meant the reload thing. |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Andreasvb
Sweden
46 Posts |
|
Mersine
22 Posts |
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 11:58:30
|
I have to rebuild S+ with that code and release it. I'm out for the day, will do later. |
|
|
Andreasvb
Sweden
46 Posts |
Posted - 01/26/2013 : 11:59:37
|
Thanks for trying, Rob. ^^ |
Windows 8.1u3 Pro x64 Media Center / Portable StrokesPlus 2.8.2.0 |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 13:28:44
|
Mersine, that code is built into the mouse hook, so there's no script that can be fired for the mouse wheel relay functionality. I'll look at the code and maybe add something which can be set to activate the owner window (if not active) on mouse wheel forwarding events. |
|
|
Rob
USA
2615 Posts |
Posted - 01/26/2013 : 22:43:11
|
Ok, 2.5.8 has an undocumented action function which allows you to tell S+ to always activate the window below the mouse cursor when Enable Mouse Wheel Relay is active. It's undocumented for now because I'm not sure if it will work well or not, so do let me know.
Basically, add this to your Global Lua to turn the setting on when you start S+ or click Apply/OK in the Settings window:function sp_init()
acActivateWindowUnderMouseWheel(1)
end This will set that option as ON; call with 0 to turn that feature off:acActivateWindowUnderMouseWheel(0) Of course, that action can be called from any gesture/hotkey script as well, if you wanted to define actions to turn the feature on or off.
Also, when you click Reload Config and Lua Engine from the tray icon menu, S+ will call the AllowSetForegroundWindow Windows API function. This will hopefully correct a situation when Windows isn't allowing S+ to bring other windows to the foreground (the taskbar flashes instead of activating the window). This may or may not have any effect, but won't harm anything. |
|
|
Mersine
22 Posts |
Posted - 01/29/2013 : 10:10:15
|
Hi Rob, is there a way to disable the taskbar flash? |
|
|
Rob
USA
2615 Posts |
Posted - 01/29/2013 : 10:13:18
|
That's not StrokesPlus' doing, it's Windows deciding that S+ doesn't have the privilege to activate other windows (see above for my detailed explanation).
Try clicking Reload Config and Lua Engine from the tray menu and let me know if it fixes anything. As I said before, it's really quite an annoying issue since it's Windows who is deciding it doesn't want to let S+ activate other windows, even though S+ makes the appropriate API call.. |
|
|
Mersine
22 Posts |
Posted - 01/29/2013 : 10:14:12
|
Gotcha, thanks. I got a little confused up there hehe. |
|
|
Rob
USA
2615 Posts |
Posted - 01/29/2013 : 10:31:16
|
Also, open your StrokesPlus.XML file and change:<CheckForegroundTimeout>0</CheckForegroundTimeout> To:<CheckForegroundTimeout>1</CheckForegroundTimeout> I had some code to update Windows' setting for foreground timeout (which applies to this issue) but haven't had that value turned on in the default configuration since I didn't want to override users' settings. But you can give it a try and see if it works (you'll have to exit S+ completely, change the setting, and re-open).
Let me know.
Note that it changes the setting system-wide, so other apps would be able to bring windows to the foreground (which is why I didn't want to leave it on by default); I completely forgot that setting even existed =) |
|
|
Mersine
22 Posts |
Posted - 01/29/2013 : 10:42:19
|
Thanks I'll give it a try. |
|
|
anjan_oleti
22 Posts |
Posted - 04/06/2016 : 03:07:10
|
quote: Originally posted by Rob
Don't forget you can utilize the sp_before_action function in Global Lua to always activate the window below where the gesture began:function sp_before_action(gnm, gsx, gsy, gex, gey, gwd)
acActivateWindow(nil, gsx, gsy)
end It will fire before all actions (not those defined in the Hotkey tab, though)
This worked, but unfortunately broke something else. This code added, does not let S+ work in dialog boxes of apps. For instance, the gesture to 'Paste' does not work in the text field in the 'Save As' dialog of Notepad. With this option removed it works fine.
Is there any workaround? Fwiw, there was no such problem in StrokeIt. |
Edited by - anjan_oleti on 04/06/2016 06:04:59 |
|
|
Rob
USA
2615 Posts |
Posted - 04/06/2016 : 07:57:31
|
I'm pretty sure it's because, if you don't pass in a window handle (using gsx, gsy coordinates instead), acAcivateWindow internally calls GetAncestor using the GA_ROOTOWNER flag. Which tells Windows to get the top-most ultimate owner of the window and calls SetForegroundWindow().
Now that's fine when a program uses something like ShowDialog() which makes a new popup window modal and forces focus to it. However, Windows dialogs like Open/Save/Print/Color Picker are a little different in that they don't actually belong to the application, but to Explorer.exe.
So acActivateWindow finds the main Notepad window and activates it instead of the Save As dialog, because it kind of bypasses the Windows dialog that is technically modal for the app.
You can try something like this and see how it works for you, though it may not be perfect. I tried it on my machine and if the Save As dialog for Notepad was open and active, it worked fine. It also worked to activate the Save As dialog if another app had focus and I drew the gesture over the Save As window. The class "#32770" commonly represents desktop/explorer style dialogs/windows.
local className = acGetClassName(acGetParentWindowByPoint(gsx, gsy), nil, nil)
if className == "#32770" then
acActivateWindow(acGetParentWindowByPoint(gsx, gsy), nil, nil)
else
acActivateWindow(nil, gsx, gsy)
end |
|
|
anjan_oleti
22 Posts |
Posted - 04/06/2016 : 10:54:13
|
Great. It works now. Thanks Rob :) I am experiencing the same issue discussed above.. the intermittent flashing and misfiring thing. What is the workaround for that? ..couldn't figure it out properly from the discussion.
I don't mind a splash screen. I checked the preferences and found no option to enable it. |
Edited by - anjan_oleti on 04/06/2016 11:07:02 |
|
|
Rob
USA
2615 Posts |
Posted - 04/06/2016 : 23:41:50
|
I'll be putting some extra effort into addressing that in the new version. For reference of how ridiculously difficult and cryptic it is, do a Google search for something like "SetForegroundWindow isn't working", add in "flashing". There are countless threads about it, ever since the days of Windows 95 and the annoying apps/popups of the 1990's that would continually make themselves the top window, trapping you, Microsoft understandably made it far more challenging. |
|
|
anjan_oleti
22 Posts |
Posted - 04/07/2016 : 00:15:28
|
But, is there some other way of implementing it, because Strokeit works that way out of the box. There was never any issue. May be, there is some other trick to get it to work. Just guessing :) |
Edited by - anjan_oleti on 04/07/2016 00:27:40 |
|
|
Rob
USA
2615 Posts |
Posted - 04/07/2016 : 00:18:42
|
I had times where StrokeIt would cause flashing Taskbar buttons instead of existing the window, but not often and was a long time ago! |
|
|
anjan_oleti
22 Posts |
Posted - 04/07/2016 : 00:28:21
|
Oh.. okay |
|
|
anjan_oleti
22 Posts |
Posted - 04/19/2016 : 02:05:48
|
Following is a solution for this issue, posted in AHK forum..
quote: So for those having a similar "driving me crazy" problem, this may help you as it did me:
My amended code:
IfWinExist, ahk_class <Obtained_via_WindowSpy> { WinGet, hWnd, ID, ahk_class <Obtained_via_WindowSpy> DllCall("SetForegroundWindow", UInt, hWnd)
;WinActivate Send {Tab} Sleep 5000 }
Link: https://autohotkey.com/board/topic/63227-winactivate-why-so-flakey/
I've been trying to trigger a AHK script in the global lua, with the window handle as parameter. This is the best I could come up with
function sp_before_action(gnm, gsx, gsy, gex, gey, gwd, gapp, gact, gbl, gbt, gbr, gbb)
local winact = acGetWindowByPoint(gsx, gsy)
acShellExecute("open", "E:\\Zata\\Axem\\StrokesPlus\\Activate.ahk", "winact", "", 1)
End It is incorrect. Pls help me amend it :) |
Edited by - anjan_oleti on 04/19/2016 02:14:40 |
|
|
|
Topic |
|