StrokesPlus.net
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
zzm  
#1 Posted : Monday, August 30, 2021 7:28:13 PM(UTC)
zzm

Rank: Member

Reputation:

Groups: Approved
Joined: 5/5/2019(UTC)
Posts: 12
China

Thanks: 6 times
Global Actions > Mouse Events > release

Code:
if (click.Button == MouseButtons.Right){
    var browser = ["chrome.exe","MicrosoftEdge.exe","msedge.exe","Firefox.exe"]
    var mouseWindow = sp.WindowFromPoint(sp.GetCurrentMousePoint(), true);
    if(browser.includes(click.Window.Process.MainModule.ModuleName) && click.Point.Y >= mouseWindow.Rectangle.Top && click.Point.Y <= mouseWindow.Rectangle.Top + 60) {
        if (sp.GetKeyState(vk.CONTROL) & 0x8000) {
            sp.MouseClick(click.Point, MouseButtons.Right, true, true);
        } else {
            sp.SendVKey(vk.ESCAPE);
            sp.MouseClick(click.Point, MouseButtons.Middle, true, true);
        }
    }
}


Line 8 is currently using sp.SendVKey(vk.ESCAPE); is a temporary program, how to prevent default right-click menu?


Rob  
#2 Posted : Wednesday, September 1, 2021 12:25:52 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 1,349
United States
Location: Tampa, FL

Thanks: 28 times
Was thanked: 416 time(s) in 354 post(s)
Can you give me some more specifics?

The Release is just for the stroke button(s), which the right-click wouldn't be sent to Chrome after drawing a gesture.

Or is this just when you right-click without drawing a gesture?

You may want to use the OnMouseHookButtonEvent (not the Async version, as that cannot consume the event) in that case as it gives you more control, and lets you perform actions before S+ takes over.

Search for Mouse Button/Wheel script example, synchronous on this page and expand the Spoiler:

https://forum.strokesplus.net/posts/t7209-Mouse---Keyboard-Event-Subscriptions

The Release tab may need to have a consume option, but I feel like there was a reason I didn't add it - will have to think it through.

Also, since you're running this for all clicks, you might want to see if you can change from using the EXE, to maybe title partials or class names, just for performance reasons as getting the EXE is probably 10x more resource heavy than the other methods. But if you have a powerful computer and don't notice any lag, then EXE name matching is fine.

These are the properties of the event args passed in for each click (shown as mouseHookEvent in the post above):
Code:
public bool Consume // For synchronous hooks, instructs S+ to consume the event before S+ or any app sees it
public bool HorizontalWheel // Doesn't apply to a mouse click event hook
public MouseButtons Button // The button which raised the event
public MouseEventButtonState ButtonState //ButtonState.None, ButtonState.Down, ButtonState.Up
public Point Location // Location of the event (mouse cursor)
public MSLLHOOKSTRUCT LowLevelMouseHookStruct  // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msllhookstruct
public bool Injected //Synthetic input, not from hardware
public bool InjectedByHost // Synthetic input, injected by S+ (e.g. sp.MouseClick)
public bool InExclusionZone // If the event occurred in an exclusion zone (options or per app)
public long wParam // From hook message
public long lParam // From hook message
public short WheelDelta // Doesn't apply to a mouse click event hook
zzm  
#3 Posted : Thursday, September 2, 2021 10:23:08 AM(UTC)
zzm

Rank: Member

Reputation:

Groups: Approved
Joined: 5/5/2019(UTC)
Posts: 12
China

Thanks: 6 times
Hi, Rob
My intention is to click the right button to close the tab under the mouse position.
I tried to use OnMousehookButtonEvent, but I found that it is not smooth.

I really want a consume option, instead of pressing the ESC key to block the right-click menu.
Slightly modified the code, in fact, I didn't find any questions according to sp.SendVKey(vk.ESCAPE);, just see if there is a more perfect way

Code:
if (click.Button == MouseButtons.Right){
    var browser_classname = ["Chrome_WidgetWin_1", "MozillaWindowClass"];
    var mousePoint = sp.GetCurrentMousePoint();
    var mouseWindow = sp.WindowFromPoint(mousePoint, true);
    if(browser_classname.includes(mouseWindow.ClassName) && mousePoint.Y >= mouseWindow.Rectangle.Top && mousePoint.Y < mouseWindow.Rectangle.Top + 45) {
        if (sp.GetKeyState(vk.CONTROL) & 0x8000) {
            sp.MouseClick(mousePoint, MouseButtons.Right, true, true);
        } else {
            sp.SendVKey(vk.ESCAPE);
            sp.MouseClick(mousePoint, MouseButtons.Middle, true, true);
        }
    }
}

Edited by user Thursday, September 2, 2021 10:24:15 AM(UTC)  | Reason: Not specified

Rob  
#4 Posted : Thursday, September 2, 2021 2:42:47 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 1,349
United States
Location: Tampa, FL

Thanks: 28 times
Was thanked: 416 time(s) in 354 post(s)
Okay, there are internal reasons that consuming on the release action cannot be easily implemented.

The only issue with the mouse hook not being smooth that I found is sending the middle click while in the callback, as the hook is still waiting for the method to return while the new mouse event (middle click) is getting queued.

This seems to work fine for me in Global Actions > Load/Unload > Load script:
Code:
// Define globally instead of each click
var browser_classname = ["Chrome_WidgetWin_1", "MozillaWindowClass"];

var mouseButtonEventObj = sp.GetStoredObject("mouseButtonEvent");
//Disconnect any existing binding for this object name
if(mouseButtonEventObj.GetType().FullName.includes('EventConnection'))
{
    mouseButtonEventObj.disconnect();
    sp.DeleteStoredObject("mouseButtonEvent");
} 

//Create the event binding and bind to synchronous event
var mouseButtonEvent = MouseHook.OnMouseHookButtonEvent.connect(
    function (sender, mouseHookEvent) {
        //Wrap all code in try/catch, exceptions will crash S+
        try
        {
            if(mouseHookEvent.Button == MouseButtons.Right)
            {
                var mouseWindow = sp.WindowFromPoint(mouseHookEvent.Location, true);
                if(browser_classname.includes(mouseWindow.ClassName) 
                    && mouseHookEvent.Location.Y >= mouseWindow.Rectangle.Top 
                    && mouseHookEvent.Location.Y < mouseWindow.Rectangle.Top + 45) 
                {
                    if (!(sp.GetKeyState(vk.CONTROL) & 0x8000)) 
                    {
                        if(mouseHookEvent.ButtonState == ButtonState.Up)
                        {
                            // Invoke middle click on new thread so the hook
                            // doesn't get stuck while waiting for this method 
                            // to return
                            sp.CreateTimer("middleClick", 
                                           0, 
                                           -1, 
                                           `sp.MouseClick(sp.GetCurrentMousePoint(), MouseButtons.Middle, true, true); 
                                            sp.DeleteTimer("middleClick");`
                                          );
                        }
                        mouseHookEvent.Consume = true;
                    } 
                }
            }
        }
        catch {}
    });

//Note that on S+ reload, events in Stored Object list have disconnect called on them
sp.StoreObject("mouseButtonEvent", mouseButtonEvent);

Edited by user Thursday, September 2, 2021 3:34:40 PM(UTC)  | Reason: Changed code

thanks 1 user thanked Rob for this useful post.
zzm on 9/3/2021(UTC)
Rob  
#5 Posted : Thursday, September 2, 2021 3:35:38 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 1,349
United States
Location: Tampa, FL

Thanks: 28 times
Was thanked: 416 time(s) in 354 post(s)
Since I've been testing this, I like the use!

I'm leaving it in my scripts, I hate trying to click right on the X to close tabs.
Rob  
#6 Posted : Friday, September 3, 2021 12:05:06 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 1,349
United States
Location: Tampa, FL

Thanks: 28 times
Was thanked: 416 time(s) in 354 post(s)
Updated script - I had Control as my ignore key, so I didn't notice that was why Control+Right click was working fine.
Code:
// Define globally instead of each click
var browser_classname = ["Chrome_WidgetWin_1", "MozillaWindowClass"];

var mouseButtonEventObj = sp.GetStoredObject("mouseButtonEvent");
//Disconnect any existing binding for this object name
if(mouseButtonEventObj.GetType().FullName.includes('EventConnection'))
{
    mouseButtonEventObj.disconnect();
    sp.DeleteStoredObject("mouseButtonEvent");
} 

//Create the event binding and bind to synchronous event
var mouseButtonEvent = MouseHook.OnMouseHookButtonEvent.connect(
    function (sender, mouseHookEvent) {
        //Wrap all code in try/catch, exceptions will crash S+
        try
        {
            if(mouseHookEvent.Button == MouseButtons.Right)
            {
                var mouseWindow = sp.WindowFromPoint(mouseHookEvent.Location, true);
                if(browser_classname.includes(mouseWindow.ClassName) 
                    && mouseHookEvent.Location.Y >= mouseWindow.Rectangle.Top 
                    && mouseHookEvent.Location.Y < mouseWindow.Rectangle.Top + 45
                    && !mouseHookEvent.InjectedByHost) 
                {
                    if(mouseHookEvent.ButtonState == ButtonState.Up)
                    {
                        if (sp.GetKeyState(vk.CONTROL) & 0x8000)
                        {
                            // Invoke right click on new thread so the hook
                            // doesn't get stuck while waiting for this method 
                            // to return
                            sp.CreateTimer("rightClick", 
                                           0, 
                                           -1, 
                                           `sp.MouseClick(sp.GetCurrentMousePoint(), MouseButtons.Right, true, true); 
                                            sp.DeleteTimer("rightClick");`
                                          );
                            
                        }
                        else
                        {
                            // Invoke middle click on new thread so the hook
                            // doesn't get stuck while waiting for this method 
                            // to return
                            sp.CreateTimer("middleClick", 
                                           0, 
                                           -1, 
                                           `sp.MouseClick(sp.GetCurrentMousePoint(), MouseButtons.Middle, true, true); 
                                            sp.DeleteTimer("middleClick");`
                                          );
                        }
                    }
                    mouseHookEvent.Consume = true;
                }
            }
        }
        catch(err) 
        {
            StrokesPlus.Console.Log(err.message);
        }
    });

//Note that on S+ reload, events in Stored Object list have disconnect called on them
sp.StoreObject("mouseButtonEvent", mouseButtonEvent);
thanks 1 user thanked Rob for this useful post.
zzm on 9/3/2021(UTC)
zzm  
#7 Posted : Friday, September 3, 2021 4:13:25 PM(UTC)
zzm

Rank: Member

Reputation:

Groups: Approved
Joined: 5/5/2019(UTC)
Posts: 12
China

Thanks: 6 times
There is still a little bug, in places other than the conditions, Control+Right click does not work.

Although, I didn't find a use for Control+Right click, but maybe it's useful in some software.
So it is better to fix the bug:-)
Rob  
#8 Posted : Saturday, September 4, 2021 11:31:33 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 1,349
United States
Location: Tampa, FL

Thanks: 28 times
Was thanked: 416 time(s) in 354 post(s)
That's normal operation, since S+ supports Control as a modifier. If you don't consume the event, then S+ picks up and begins working like normal, which would see Control+Right click as a possible action.

The workaround for this (other than having Control as an ignore key) is to create an action which handles Control+Right click to allow it to happen like normal. You would select Control as the modifier, then have the script send the right-click, this is like the one in the default S+ config for Shift+Right click
Code:
//This will allow you to retain the expected functionality of holding the shift key and right clicking.
//Since this is an event that would be captured by S+, this action simply sends Shift+Right click directly
//This script operates under the assumption that the Shift key is still being held down when it executes

sp.ConsumePhysicalInput(true); //Suppress all mouse/keyboard input to ensure this action executes properly
sp.MouseClick(action.Start, MouseButtons.Right, true, true); //Click the right mouse button
sp.ConsumePhysicalInput(false); //Resume normal input
thanks 1 user thanked Rob for this useful post.
zzm on 9/5/2021(UTC)
zzm  
#9 Posted : Tuesday, September 7, 2021 1:57:16 PM(UTC)
zzm

Rank: Member

Reputation:

Groups: Approved
Joined: 5/5/2019(UTC)
Posts: 12
China

Thanks: 6 times
The script will have problems when the right button click down(not in browser tab area) is not released and up in the area(browser tab area).
So I have modified it, it seems that there is no problem.

Code:
// Define globally instead of each click
var browser_name = ["chrome.exe","MicrosoftEdge.exe","msedge.exe","Firefox.exe"];

var mouseButtonEventObj = sp.GetStoredObject("mouseButtonEvent");
//Disconnect any existing binding for this object name
if(mouseButtonEventObj.GetType().FullName.includes('EventConnection'))
{
    mouseButtonEventObj.disconnect();
    sp.DeleteStoredObject("mouseButtonEvent");
} 

var start_Y = 0;
//Create the event binding and bind to synchronous event
var mouseButtonEvent = MouseHook.OnMouseHookButtonEvent.connect(
    function (sender, mouseHookEvent) {
        //Wrap all code in try/catch, exceptions will crash S+
        try
        {
            if(mouseHookEvent.Button == MouseButtons.Right)
            {
                if(mouseHookEvent.ButtonState == ButtonState.Down)
                {
                    start_Y = mouseHookEvent.Location.Y;
                }
                var mouseWindow = sp.WindowFromPoint(mouseHookEvent.Location, true);
                if(browser_name.includes(mouseWindow.Process.MainModule.ModuleName)
                    && mouseHookEvent.Location.Y >= mouseWindow.Rectangle.Top
                    && mouseHookEvent.Location.Y < mouseWindow.Rectangle.Top + 45
                    && start_Y >= mouseWindow.Rectangle.Top
                    && start_Y < mouseWindow.Rectangle.Top + 45
                    && !mouseHookEvent.InjectedByHost) 
                {
                    if(mouseHookEvent.ButtonState == ButtonState.Up)
                    {
                        if (sp.GetKeyState(vk.CONTROL) & 0x8000)
                        {
                            // Invoke right click on new thread so the hook
                            // doesn't get stuck while waiting for this method 
                            // to return
                            sp.CreateTimer("rightClick", 
                                           0, 
                                           -1, 
                                           `sp.MouseClick(sp.GetCurrentMousePoint(), MouseButtons.Right, true, true); 
                                            sp.DeleteTimer("rightClick");`
                                          );
                            
                        }
                        else
                        {
                            // Invoke middle click on new thread so the hook
                            // doesn't get stuck while waiting for this method 
                            // to return
                            sp.CreateTimer("middleClick", 
                                           0, 
                                           -1, 
                                           `sp.MouseClick(sp.GetCurrentMousePoint(), MouseButtons.Middle, true, true); 
                                            sp.DeleteTimer("middleClick");`
                                          );
                        }
                    }
                    mouseHookEvent.Consume = true;
                }
            }
        }
        catch(err) 
        {
            StrokesPlus.Console.Log(err.message);
        }
    });

//Note that on S+ reload, events in Stored Object list have disconnect called on them
sp.StoreObject("mouseButtonEvent", mouseButtonEvent);

Edited by user Wednesday, September 8, 2021 2:55:23 AM(UTC)  | Reason: Not specified

Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.