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

Notification

Icon
Error

Options
Go to last post Go to first unread
liuchina  
#1 Posted : Wednesday, October 16, 2019 1:52:05 AM(UTC)
liuchina

Rank: Member

Reputation:

Groups: Approved
Joined: 9/25/2018(UTC)
Posts: 20
China
Location: 北京

Thanks: 10 times
Hi Rob

When I set more and more shortcut keys in S + net, it will be inconvenient to use if I can't group them. Does it take a lot of work to implement this function?

Thank you!
Rob  
#2 Posted : Wednesday, October 16, 2019 7:26:09 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 506
United States

Thanks: 5 times
Was thanked: 99 time(s) in 86 post(s)
So you mean the hot keys section having categories like actions?
liuchina  
#3 Posted : Wednesday, October 16, 2019 6:27:41 PM(UTC)
liuchina

Rank: Member

Reputation:

Groups: Approved
Joined: 9/25/2018(UTC)
Posts: 20
China
Location: 北京

Thanks: 10 times
I mean that in the process of using S + net, when users are managing shortcut keys, they can be grouped like management gestures to manage them.
Mateus  
#4 Posted : Wednesday, November 27, 2019 1:51:26 AM(UTC)
Mateus

Rank: Newbie

Reputation:

Groups: Approved
Joined: 8/21/2019(UTC)
Posts: 7

Thanks: 1 times
Not sure I understood the requirement here, but I would also like to be able to control shortcuts better. In my case, it would be grouping it per application, which I believe can be already done with some "ifs", but is a lot easier to do with the "applications" panel.

Use cases for the app level shortcuts:
- Having shared shortcuts for different browsers or similar applications.
- Using macros and hotkeys in games.
- Performing application-specific operation for when it does not support a shortcut for it (ex: actions that would require multiple shortcuts to be pressed).

Another good thing would be an abstraction of the macro in hotkeys or just of its behavior in general. ex:
- Play while hotkey is pressed (for operations that need to be performed an unknown number of times, ex: moving, deleting, scrolling)
- Play once hotkey is pressed. (for operations that need to be executed once, ex: perform a combo in a game)
- Toggle when the hotkey is pressed (for operations that might take a good amount of time, ex: bots, like clicking on a cookie in a cookie-clicker game).

I hope this helps understand the requirement :). I'm not a .net developer, but most scripts are rather simple to do thanks to the abstraction and the sp helpers so this would be a great help for me.

Edited by user Wednesday, November 27, 2019 1:54:03 AM(UTC)  | Reason: Not specified

Rob  
#5 Posted : Wednesday, November 27, 2019 8:27:46 AM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 506
United States

Thanks: 5 times
Was thanked: 99 time(s) in 86 post(s)
The reason hot keys are separate is because originally they were officially registered hot keys with Windows, meaning only one instance of that hot key can be claimed. So application-level doesn't make sense for a global hot key.

Starting with version 0.3.3.0, hot keys can be configured as Unregistered, where they are simply monitored by S+ and fired, though I don't really like the feature from a performance/UX perspective because it involves processing against every keystroke. This also happens if any Text Expansions are defined, and of course ignore keys are also checked.

That is about as much keyboard interference as I would like to have, since it all adds up and has the potential to begin impacting the user when they're simply typing an email, as every keystroke has to pass through S+ and be evaluated. Adding applications to this mix add a significant increase of processing per keystroke.

It's always a balancing act between features and performance/UX, since certain things have a cost for simply using the computer while S+ is running and there's only so many CPU cycles I can add to each keyboard and mouse event until it starts to become noticeable that these events are slower when S+ is running; which then defeats the purpose of this being a productivity enhancing application :)

So yes, in these instances the recommendation is to use conditional execution within a single script. There are numerous ways to decentralize this or control via other methods. For example using the Global Actions > Window Events > Foreground Window Change script, you could set variables, activate/deactivate hot keys, etc. based on the current foreground window.

Your hot key behavior recommendations can all be accomplished now via script logic, sp.GetKeyState, and variable storage.

- Play while hotkey is pressed is the default behavior currently, the script will be continually repeated. However, depending on what you're doing in the script itself, you might have to add some extra lines to handle key states. This is also subject to standard Windows repeat key delay settings, etc. You could certainly create a faster repetition script by leveraging some of the logic shown below.

- Play once hotkey is pressed - This script demonstrates how this can be accomplished:
Code:
//This test hot key is defined as Shift+5

//Only execute if the hot key was not already pressed
if(!sp.GetStoredBool("hotkey_s5_pressed")) {

    //Set a variable to say the hot key is down
    //This ensures the next repeating keyboard event doesn't execute this script 
    //over and over
    sp.StoreBool("hotkey_s5_pressed", true);

    //---------------------------------------------------------------------------
    //TODO: Put whatever you want this script to do here, replace my example code
    //Below I'm sending the Shift key up so "6" is typed instead of Shift+6 ("^")
    //because this hot key uses Shift and it would be physically held down while
    //executing this hot key, but then I set the Shift key back to being down to
    //return it to the original state
    sp.SendShiftUp();
    sp.SendKeys("6");
    sp.SendShiftDown();
    //---------------------------------------------------------------------------


    //Create a timer that watches the key state of the key "5", as defined for this hot key
    //Once the 5 key is no longer being held down, it clears the timer and stored variable
    //so the next Shift+5 will execute the script once
    sp.CreateTimer("hotkey_5_pressed_watcher", 0, 100, `if(!(sp.GetKeyState(vk.VK_5) & 0x8000)) {
                                                          sp.DeleteStoredBool("hotkey_s5_pressed");
                                                          sp.DeleteTimer("hotkey_5_pressed_watcher");
                                                        }`); 
}


- Toggle when the hotkey is pressed - this script will handle toggling on/off:
Code:
//This test hot key is defined as Shift+6

//Toggle the variable, setting it to the opposite state of whatever
//it currently holds (true/false) - the first time this runs, it will be 
//false (toggled off) and will start the timer
sp.StoreBool("hotkey_s6_pressed", !sp.GetStoredBool("hotkey_s6_pressed")); 

var repeatDelay = 5000; //Executes the timer script every 5000 ms (5 seconds)

//If the hotkey is in the toggled on state, create a timer to run 
if(sp.GetStoredBool("hotkey_s6_pressed")) {
    sp.CreateTimer("hotkey_s6_timer", 0, repeatDelay, `if(!sp.GetStoredBool("hotkey_s6_loop_executing")) {
                                                           //"hotkey_s6_loop_executing" is just used to make sure the
                                                           //timer executions don't step on each other and run in parallel
                                                           sp.StoreBool("hotkey_s6_loop_executing", true);

                                                           //TODO: Add your code here, replace the line below
                                                           sp.MessageBox("Hi, still running hotkey script", "Shift+6 Hot Key");

                                                           sp.DeleteStoredBool("hotkey_s6_loop_executing");
                                                        }`); 
} else {
    //Toggled off, delete the timer
    sp.DeleteTimer("hotkey_s6_timer");
}


Again, these are just examples, some of this could be moved into functions (in Load Scripts tab) to simplify the hot key code and make more generic/reuseable code for other hot keys instead of duplicating the logic in each one.
Mateus  
#6 Posted : Wednesday, November 27, 2019 1:14:43 PM(UTC)
Mateus

Rank: Newbie

Reputation:

Groups: Approved
Joined: 8/21/2019(UTC)
Posts: 7

Thanks: 1 times
Thank you for examples, will see what I can do. Out of curiosity, wouldn't it be possible to add and remove event handlers based on the focused application instead of verifying the application on every key pressed? I think it wouldn't impact performance too much that way. In that sense having it as a stroke+ feature would make more sense if we can't create a watcher for toggling shortcuts (maybe we can. Haven't explored it too much yet).
Rob  
#7 Posted : Wednesday, November 27, 2019 5:16:40 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 506
United States

Thanks: 5 times
Was thanked: 99 time(s) in 86 post(s)
Yeah, it was kind of a quick simplification without putting too much thought into it; I will at least add it to the list of things to research/consider.

The main thing is that there are just always so many requests to do things specific which don't often affect the broad user base, and I have limited personal time. There are still so many things on my TODO list! So I often try to find a way to work within the available functionality, especially when it's something in one of the main mouse/keyboard hooks since those are the lifeblood of the app.

Also, if the intent is for the actual keystrokes of the hot key itself to be consumed (so only the script runs, and those key events are not passed on to the application), then events don't really work since the low level hook needs to respond as quickly as possible and synchronously. Though even that has complications in terms of modifier key states, etc.

Over the years since the original StrokesPlus, I've gradually added new logic into those pathways as legitimate needs or features have warranted it. So I try to keep additions to a minimum unless I can tell it's something which cannot be handled via other means (or is just one of those 'yeah, that makes absolute sense across the board without question' things), since time has shown that there will be more added in the future and I want to keep a reserve of processing headroom in both of those areas.



Mateus  
#8 Posted : Wednesday, November 27, 2019 7:20:18 PM(UTC)
Mateus

Rank: Newbie

Reputation:

Groups: Approved
Joined: 8/21/2019(UTC)
Posts: 7

Thanks: 1 times
Thank you for considering it :), it's interesting to know about the limitations, I thought it would be just a simple verification that, if match, would prevent the default behavior and execute the script.

btw, is there any place where we can see a roadmap for stroke+?


Rob  
#9 Posted : Wednesday, November 27, 2019 8:10:16 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 506
United States

Thanks: 5 times
Was thanked: 99 time(s) in 86 post(s)
Yeah low level hooks (the kind which can prevent the keyboard/mouse event from being passed on) are in memory and Windows passes every single event through the hook.

You have to either return 1 (prevent the event) or call CallNextHook quickly to pass it onto any other hooks or ultimately the applications.

If the hook doesn't respond in a timely fashion, Windows can evict it without the hooking application even knowing.

And in terms of hot keys, it's complicated in that it's not like you just receive the ultimate combo, you get the Control key down message (followed by the continual repeat messages), any other modifiers (and their down/up messages), the final "normal" key down event (and repeated down messages, up message). Then you have to check the key states to see if the correct modifiers are down to indicate triggering the script.

Keep in mind, for each message above, the hook has to completely process and return 1 or CallNextHook. These messages queue up and if the hook isn't handling the keyboard events fast enough, the hook will be evicted. Also note that subsequent keyboard events are not processed until the hook returns from the previous one.

So this is why I don't like to add logic to those hooks unless absolutely necessary.

I don't have a roadmap, just a list of things I work on in whatever random order I feel like :)

Edited by user Wednesday, November 27, 2019 9:56:46 PM(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.