This App is No Longer Maintained. Visit the Replacement at StrokesPlus.net

StrokesPlus Forum
                       
StrokesPlus Forum
Home | Profile | Active Topics
Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 General Discussion
 General Discussion
 Run script until a mouse button is released
 Forum Locked
 Printer Friendly
Author Previous Topic Topic Next Topic  

boombyte

Croatia
18 Posts

Posted - 02/17/2014 :  00:59:18  Show Profile
Hi Rob,

I've been using S+ for quite some time now, but there is still one thing I've been meaning to ask you from the beginning: Is it possible to implement a functionality which lets the user run an action script in a loop while some mouse button is pressed down?

I've been using S+ in combination with some of my AutoIt scripts to enable me to move window without touching the Title bar. This is the way I do it:

1. I click both my gesture button (right) and left button, and then release the gesture button while still holding the left one.

2. This activates a S+ action which fires a hotkey combination which, in turn, activates the AutoIt script

3. The script is basically an infinite loop which repositions the window following the mouse pointer until I release the left mouse button.

I am looking for a way to do this in StrokesPlus entirely.

One way would be to have an option to fire recognition with a button other than gesture button and then keep an action running until the gesture button is released – or – to fire recognition with a standard release of a gesture button, but keep the action running until some other button is released. Either way, one button starts the action script and an infinite loop inside it, and the other button breaks that loop, thus ending the action script.

If I could detect with a function in S+ a pressed state of a mouse button, I could break the infinite loop with its release. I've tried using a global variable as a condition for a do-while loop. I've set function sp_after_release() to change its value, but this doesn't work (global variable get's changed, but the loop doesn't see it).

Do you have any suggestions?

Rob

USA
2615 Posts

Posted - 02/17/2014 :  10:07:09  Show Profile  Visit Rob's Homepage
The reason after release isn't working is because there are 2 Lua engine contexts, which are completely separate from each other. Since context 1 is running, S+ will fire the after release event into context 2.

A quick thought that comes to mind is to have the after release script create a file that the loop checks for, and if exists, deletes and stops the move sequence. A little hackish, I know, but it's one idea.

Or you could pass data between the 2 Lua contexts via acGetClipboardText/acSetClipboardText, at the expensive of losing whatever was in the clipboard.

Or capture the window size in the main script when it starts, and in release script change it by a pixel, which tells context 1 you're done...and you could reset the window's size back, of course.

I'll let you know if anything else comes to mind; things like this will usually stir around in my head for days...and I either have a breakthrough, or realize there's simply no better alternative within the existing S+ framework.
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 02/17/2014 :  16:42:07  Show Profile
It seems that global scripts are not working while the move loop is running. Neither sp_after_release(), nor sp_middle_mouse_down() are executing while the execution context is still in that loop, so I cannot change anything in this manner.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/17/2014 :  19:55:45  Show Profile  Visit Rob's Homepage
Can you post your scripts so I can mess around and see if I can figure something out?
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 02/17/2014 :  21:22:56  Show Profile
Global Lua:

mWinHandle = 0

function sp_after_release()
	acSetWindowTransparency(mWinHandle, nil, nil, 255)
end

function sp_middle_mouse_down()
	acSetWindowTransparency(mWinHandle, nil, nil, 255)
end

function setHandle(val)
	mWinHandle = val
end


Action:

moveWindow(acGetParentWindowByPoint(gsx, gsy))


Window Move function (put in global or inside Action script):

function moveWindow(wHandle)
	setHandle(wHandle)
	acSetWindowTransparency(wHandle, nil, nil, 254)
	local xDelta = acGetMouseLocationX() - acGetWindowLeft(wHandle, nil, nil)
	local yDelta = acGetMouseLocationY() - acGetWindowTop(wHandle, nil, nil)
	while (acGetWindowTransparency(wHandle, nil, nil) == 254) do
		acMoveWindow(wHandle, nil, nil, acGetMouseLocationX()-xDelta, acGetMouseLocationY()-yDelta)
		
		if (acGetWindowTransparency(wHandle, nil, nil) == 255) then
			break
		end
	
		-- Safety breaker: If the above break mechanism fails, we can stop 
		-- the loop by moving pointer to the left edge of the Desktop
		if (acGetMouseLocationX() == 0) then	
			break
		end

		acDelay(10)
	end
end


I tried to use window transparency as a state switch indicator both in After Release and Middle Click function. Doesn't work either way.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/17/2014 :  21:31:35  Show Profile  Visit Rob's Homepage
I'm not at my computer at the moment, but at first glance, it wouldn't because mWinHandle isn't assigned in the second context (after script).

It's set when the action runs, but is only set in context 1, not context 2 where the after script is running. I know, it's kind of confusing.

Probably would be better in the after script to get the window below the mouse cursor.

When I get some time, I'm going to create an action pair specifically for sharing/passing data between the Lua contexts; or something more robust, haven't thought it through yet.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/17/2014 :  21:34:31  Show Profile  Visit Rob's Homepage
99% of the time your actions will always be executing in the first context. Only when the first context is busy does S+ execute in the second context. These two contexts are completely independent, despite the term "global" being used :-)
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/17/2014 :  21:37:44  Show Profile  Visit Rob's Homepage
S+ used to crash when two actions tried to run at the same time, or almost the same time. I found out it was because the Lua engine was processing a script when another was being force started in the same Lua state. So I had to add the additional context, but did note the sandbox nature of the two contexts, though it's not really obvious just by using S+
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/18/2014 :  01:34:39  Show Profile  Visit Rob's Homepage
Ok, found a problem in the code for the after release, middle click, and a other button click events.

The code was entering a loop if either state 1 or state 2 were executing when it was supposed to loop if BOTH 1 and 2 were executing. So even using my suggestion above, it doesn't work.

I'll put together a build in the next few days with the fix as well as some functionality for sharing data between Lua states.
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 02/18/2014 :  16:05:05  Show Profile
That's great!

One more thing, however. Regarding the idea I've mentioned in the first post, would it be possible to have additional buttons for firing recognition, other than a gesture button? That is, the gesture button to be the one starting the gesture, but not necessarily the one which ends it (the ending point in this scenario would be a mouse pressed state of another button, not a mouse released state of the gesture button).

For example, in Easystroke (Linux) you can use additional buttons in the gesture, but those can end the stroke and start the action when pressed, and end the action when released afterwards.

I used to have an action which was triggered by pressing right (gesture btn) and then immediately pressing left button. The action would be set to send (via internal function) an ALT button down event + left mouse btn down. Alt + Left button = move window in Linux. This action would remain active as long as I would keep both mouse buttons pressed, so I could move the window that way, without touching the keyboard.

Since I'm trying to emulate that behavior using while loops and is_pressed functions via external AutoIt scripts, I'm wondering would it be possible to add an option for a mouse modifier to execute gesture recognition, but still have S+ keeping the action active until the gesture button is released?

Maybe I didn't fully understand those contexts you mentioned and this would be too complicated to implement. But if it's not, the S+ would, in my opinion, greatly surpass the Easystroke's power with this functionality added.

Since I have a gesture with left button modifier, and S+ consumes the input, I have to make the action mouse-click again on a neutral area on the desktop for AutoIt to be able to tell that I'm actually holding a button down. This seems too ugly, so maybe we could solve it all with StrokesPlus.
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/19/2014 :  00:03:23  Show Profile  Visit Rob's Homepage
The problem is that S+ was intended to support multiple modifiers, so it's a little challenging without changing the core of the program. For example, I have actions which use right down, then a left and X1 click, so firing on left click would cause a big problem, obviously.

It seems nowadays that more and more people want to fire all kinds of stuff on various mouse events, straying from the original foundation of the base engine.

The only compromise I can think of is to create an action which triggers the completion of a gesture, which could be called from a new global for left click, for example, which would fire the recognition or something. It's complicated to implement without breaking other parts of S+; the unfortunate reality of trying to make everyone happy being impossible :-)

It's almost getting to the point of needing to have two completely different modes of operation, which I'd really like to try to avoid if at all possible. But I'll let this steep and see what I can come up with.
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 02/20/2014 :  16:19:20  Show Profile
If it's like that then please disregard my last post. I was curious to see if the idea could be painlessly implemented that way, but changing the core of the program for just one feature is a road to ruin. What's most powerful about S+ is it's simplicity. It's ultra light on memory, smooth and quite reliable; it should be kept that way.
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 02/20/2014 :  16:30:35  Show Profile
Sharing data between two states and a trigger which would change that data to exit a loop when the user releases some modifier button - that should be enough to make it work.

That way the action would, say, keep Ctrl key down until the user releases the left mouse button. :)
Go to Top of Page

Rob

USA
2615 Posts

Posted - 02/21/2014 :  10:08:21  Show Profile  Visit Rob's Homepage
I still haven't had the time to sit down and actually analyze/code any of this yet, been a very busy week...but I haven't forgot!
Go to Top of Page

Rob

USA
2615 Posts

Posted - 03/02/2014 :  12:19:36  Show Profile  Visit Rob's Homepage
Added acGetNumber / acSetNumber in 2.8.2 as well as fixed that bug I mentioned. Also added option to fire scripts on left and right mouse click (as long as it's not the stroke button, of course).

I didn't add anything to trigger the end of a sequence, that was a lot more complicated and troublesome than I expected.
Go to Top of Page

boombyte

Croatia
18 Posts

Posted - 03/04/2014 :  19:25:23  Show Profile
It works!!

Dragging windows seems to be working perfectly. I'm testing resizing right now. I will post these scripts in the General Scripts section soon.

This gives S+ a lot more power! Well done, Rob
Go to Top of Page
  Previous Topic Topic Next Topic  
 Forum Locked
 Printer Friendly
Jump To:
StrokesPlus Forum © 2011-2018 Rob Yapchanyk Go To Top Of Page
Snitz Forums 2000