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

Notification

Icon
Error

Options
Go to last post Go to first unread
Omonym  
#1 Posted : Friday, May 6, 2022 6:49:55 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

Hi,

Switch To Last Application command restores the last NON-minimized window. How do I restore the last minimized window? This is an essential function, but looks like it takes some scripting which is beyond my ability. Can someone help?
randomConstant  
#2 Posted : Saturday, May 7, 2022 7:09:11 PM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
It seems sp.LastApplication() does not have the same functionality as ALT+TAB, maybe it monitors only non-minimized windows stack.

After minimizing a window, the focus shifts to second last window and from there sp.LastApplication() takes us to third last active window (ignores the second last active window since we minimized it ourselves) but ALT+TAB takes us back to minimized original window.

Try replacing the change application gesture code
from:
Code:
sp.LastApplication();

to:
Code:
sp.SendModifiedVKeys([vk.LMENU], [vk.TAB]); //LMENU stands for ALT here


This will send ALT+TAB key combination instead of invoking sp.LastApplication() function and should solve the problem.
randomConstant  
#3 Posted : Saturday, May 7, 2022 7:43:18 PM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
oh I just realized that you were talking about step and not script when you mentioned Switch To Last Application command.

In your gesture you should see two sections right below the Use secondary stroke button and Active options..
Right now you are using Steps, you should see the Switch To Last Application command(step) listed there, right click on it and delete it.
Then move to Script section and you will see an empty coding area, paste
Code:
sp.SendModifiedVKeys([vk.LMENU], [vk.TAB]); //LMENU stands for ALT here

in that area and then Apply the changes.

Now that gesture is using script instead of steps, this gives you more control over the gesture, just like in this case we input a custom combination of keys.

Also above the coding area you will see options such as record, insert hotkey, and so on. If you press on insert hotkey option it will open a small window where you can press any keys and it will insert the code for that in the cursor location of the coding area. That is how the above code for ALT+TAB was generated.

Hope this helped.
Rob  
#4 Posted : Sunday, May 8, 2022 5:19:03 AM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Quote:
maybe it monitors only non-minimized windows stack

Yes, it just calls EnumWindows which enumerates windows in Z-order from front to back - minimized windows go to the bottom of the window stack.
Omonym  
#5 Posted : Sunday, May 8, 2022 3:04:53 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

randomConstant, thank you for the detailed reply. Did as you said. Unfortunately in Windows 8.1 (possibly in Windows 10 too) simulating ALT+TAB won't work. So is there a way to do it without using ALT+TAB?
Like committing to memory the last active window (the one just minimized) and then restoring it.

Edited by user Sunday, May 8, 2022 3:09:11 PM(UTC)  | Reason: Not specified

randomConstant  
#6 Posted : Monday, May 9, 2022 7:09:52 AM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
I don't know the exact method but you should be able to bring an application to the foreground by filtering applications using title or process ID etc.

But, ALT+TAB should work. I tested mine on Windows 10 and it works. But maybe that LMENU key in the code does not correspond to ALT key on your machine.
Code:
sp.SendModifiedVKeys([vk.LMENU], [vk.TAB]);

I'm talking about vk.LMENU in this code.

Try to insert a hotkey in the code:
  1. Make a gesture
  2. Go to its script area
  3. Press insert hotkey option from the options shown at the top of script area
  4. Press ALT+TAB and then click on OK
  5. It should insert a line very similar to the code above, maybe replacing vk.LMENU with the code for your ALT key.
  6. Apply settings and try the gesture.


The reason I suggest this method over keeping track of applications manually is because this is how it is intended to be used and it puts far less pressure on memory(resources) and is very simple. Plus you need to use ALT+TAB, ALT+ESC, SHIFT+TAB etc when making gestures to navigate applications, windows, tabs etc anyways.

If possible, please post a screen shot of the script and any errors. S+ should work fine on Windows 8.1.
Omonym  
#7 Posted : Monday, May 9, 2022 10:19:56 AM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

LMENU is fine, the script I used is exactly as you showed.

There are a number of ways to get around the ALT+TAB issue that can be achieved with the Autohotkey program, but none of them is 100% reliable (in most instances they work, but sometimes they fail to work properly for unknown reasons). So I thought that S+ might have either some built-in way of calling up a minimized window or it could be done by some clever scripting using Windows' commands (Windows messages). But it looks like this seemingly simple task is really hard to do without simulating ALT+TAB.

One way of getting around is by calling up Window Switcher directly. It works fine but the problem is Window Switcher gets in your face each time and I found no way to make it invisible (transparent, minimized, off the screen, etc).
Rob  
#8 Posted : Monday, May 9, 2022 3:47:50 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
This should restore the most recent minimized window.
Code:
// finds the first minimized window, restores it, and exits the loop
var allWindows = sp.AllApplications();
for(const w of allWindows) {
    //StrokesPlus.Console.Log(w.Title);
    if(w.Minimized) {
        w.Restore();
        break;
    }
}
Omonym  
#9 Posted : Monday, May 9, 2022 8:52:48 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

Rob, your script works in some cases, doesn't work in other cases. By "doesn't work" I mean it restores some other window, not the immediately minimized one. It seems to always work correctly when a window is minimized by clicking on the taskbar, but not when minimized by S+ gesture or by clicking in the top right corner icon. It never works with a Telegram window, even if it's minimized by clicking on the taskbar. Weird, huh?
Rob  
#10 Posted : Monday, May 9, 2022 10:37:40 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
If you're always minimizing via S+ gesture or hotkey, then it would be pretty simple since S+ is able to know which one you did last.

Minimize Action:
Code:
action.Window.Minimize();

// Store the window that was just minimized
sp.StoreObject("LastMinimized", action.Window);

In whatever script you want to restore the last window minimized by S+ action:
Code:
// In a try/catch in case there is none stored, it fails silently 
try {
    // Restore the last minimized window
    sp.GetStoredObject("LastMinimized").Restore();
} catch {}

Edited by user Monday, May 9, 2022 10:47:20 PM(UTC)  | Reason: Not specified

Omonym  
#11 Posted : Tuesday, May 10, 2022 8:30:48 AM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

That works great!
Would it be possible to make it so that instead of failing silently it would do what Switch To Last Application does? I assume I need to add the respective code to "catch {}", but I don't know the code for Switch To Last Application.
randomConstant  
#12 Posted : Tuesday, May 10, 2022 8:59:08 AM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
Yes you can.

Try this code in the catch block:
Code:
sp.LastApplication();
Omonym  
#13 Posted : Tuesday, May 10, 2022 9:27:52 AM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

That's what I did, but it doesn't work:
Code:
try {
    // Restore the last minimized window
    sp.GetStoredObject("LastMinimized").Restore();
} catch {sp.LastApplication();}
Rob  
#14 Posted : Tuesday, May 10, 2022 10:41:04 AM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Replace the second script with this:
Code:
var lastMin = sp.GetStoredObject("LastMinimized");
// See if the object has the IsValid method defined. If there's no stored object 
// in S+, it will return an empty object which won't have this method
var lastMinValid = lastMin.IsValid !== undefined
// If the object did have IsValid, let's call IsValid() to see if the window still exists
if(lastMinValid) {
    lastMinValid = lastMin.IsValid();
}

// If the IsValid method existed and the window is valid
if(lastMinValid) {
    // Restore the last minimized window
    lastMin.Restore();
    // Delete the stored window from S+ memory
    sp.DeleteStoredObject("LastMinimized");
} else {
    // Otherwise, use the last app method
    sp.LastApplication();
}

Edited by user Tuesday, May 10, 2022 10:45:36 AM(UTC)  | Reason: Not specified

randomConstant  
#15 Posted : Tuesday, May 10, 2022 10:42:20 AM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
The catch block will only execute when there is an error in the try block.

The try block is restoring a minimized window, there are a few cases where this might fail, such as when the Windows first starts and no window has been minimized yet (meaning minimize gesture was not executed from S+). Or maybe when a window is minimized, then closed completely.

In those cases catch block will execute and the application should be switched to the last non minimized active window.

I'm not sure what you are trying to achieve here, are you using the same gesture for switching between minimized and non minimized windows?

Ideally, I imagine you'd want a single gesture that forgets about the minimized status of an app and just restores the windows almost like ALT+TAB would.
Omonym  
#16 Posted : Tuesday, May 10, 2022 3:12:03 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

Rob, I'm afraid it doesn't work quite like I need it to.

As randomConstant says, I am trying to use the same gesture for minimized and non-minimzed windows. In other words, I need to activate (bring forward, restore) the last active window. By the last active window I mean:

1) a window I just minimized (mostly with S+). It may not necessarily be an active window when it's minimized (I often minimize inactive windows and I am not sure whether a window is made active by the minimization process.)

2) a window that was made active by me (because I opened it, clicked within it, clicked on the taskbar to restore it, was typing in it, etc) or that became active by itself because some other window was closed or minimized

So it probably is, as randomConstant says, what ALT+TAB does.

Let me know if it's too much trouble and I'll do with what you already provided me with.
Rob  
#17 Posted : Tuesday, May 10, 2022 3:50:59 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Ah okay, then ALT+Tab is your best bet.
Code:
sp.SendModifiedVKeys([vk.LMENU], [vk.TAB]);

It works fine for me. Are you running S+ in portable mode or from the installer?

Omonym  
#18 Posted : Tuesday, May 10, 2022 4:23:57 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

Running from installed.
Windows 8.1 doesn't allow simulating ALT+TAB, that's the problem.
Rob  
#19 Posted : Tuesday, May 10, 2022 5:57:26 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
This might work, though it won't recognize when S+ is the foreground window for internal reasons.

Once you've switched windows at least once, it should keep track of the last window. But I'm sure it may have some other odd issues, hopefully it works okay.

Global Actions > Window Events > Foreground Window Change
Code:
try {
sp.StoreObject("LastWindow", sp.GetStoredObject("CurrentWindow"));
sp.StoreObject("CurrentWindow", sp.ForegroundWindow());
} catch {}


Action to switch to last window:
Code:
var lastWindow = sp.GetStoredObject("LastWindow");
// See if the object has the IsValid method defined. If there's no stored object 
// in S+, it will return an empty object which won't have this method
var lastWindowValid = lastWindow.IsValid !== undefined
// If the object did have IsValid, let's call IsValid() to see if the window still exists
if(lastWindowValid) {
    lastWindowValid = lastWindow.IsValid();
}

// If the IsValid method existed and the window is valid
if(lastWindowValid) {
    // Restore the last minimized window
    lastWindow.Activate();
} else {
    // Otherwise, use the last app method
    sp.LastApplication();
}
Omonym  
#20 Posted : Tuesday, May 10, 2022 7:33:45 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

First it didn't work properly, then, after a few minutes it started to work. But it does have some odd issues: when I open a new window (say of Firefox) and then I call this action, instead of activating the last active window there appears a short title bar and a Firefox icon on the taskbar. The title bar is movable and can be closed by right-clicking on the taskbar icon. In another instance the right-click taskbar menu appeared that I cannot close.
But apart from the new window issue it seems to work. Will test some more.
Rob  
#21 Posted : Tuesday, May 10, 2022 7:50:07 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Yeah, at the end of the day, handling windows can be tricky as some apps have weird hidden windows that the default logic doesn't see as any different that another window, so you'd have to add further logic.

Most of the pieces are here throughout this thread, but you might need to have some special handling for certain windows.
randomConstant  
#22 Posted : Thursday, May 12, 2022 8:44:00 AM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
Originally Posted by: Omonym Go to Quoted Post
Running from installed.
Windows 8.1 doesn't allow simulating ALT+TAB, that's the problem.


Rob can you please confirm if S+ is compatible with Windows 8.1? I always thought it was.

Also Omonym please try some of the other ways to simulate ALT+TAB as well such as:
Code:
sp.SendVKeyDown(vk.LMENU);
sp.Sleep(10);
sp.SendVKeyDown(vk.TAB);
sp.SendVKeyUp(vk.TAB);
sp.SendVKeyUp(vk.LMENU);

OR
Code:
sp.SendAltDown();
sp.Sleep(10);
sp.SendKeys("{TAB}");
sp.SendAltUp();


Hopefully some of the methods work.
Omonym  
#23 Posted : Thursday, May 12, 2022 3:03:04 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

randomConstant, no way.
I wonder why it's so difficult to replicate the internal algorithm of ALT+TAB. Looks like even experts don't know its internal workings?
randomConstant  
#24 Posted : Thursday, May 12, 2022 3:44:43 PM(UTC)
randomConstant

Rank: Advanced Member

Reputation:

Groups: Translators, Approved
Joined: 7/17/2021(UTC)
Posts: 115
Pakistan

Thanks: 32 times
Was thanked: 10 time(s) in 9 post(s)
That's why I asked the expert (Rob) Laugh

It should be possible though, maybe I'll spin up a Windows 8.1 virtual machine on the weekend and check for myself.
I just can't believe something as basic as a key combination wouldn't work. Especially if AHK worked.
Omonym  
#25 Posted : Thursday, May 12, 2022 4:30:01 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

AHK can't simulate ALT+TAB either. Various AHK scripts work more or less, probably 75% of time. So far the best performance is by the latest script Rob provided, it works probably 95% of time, which is great!

So far I have been unable to explain why it doesn't work in the remaining 5%. Definitely doesn't work (or produces weird artefacts) when used immediately after a new window is opened (probably when opening, Windows produces some invisible window which then gets called up by the script). But that's a minor issue.

Rob  
#26 Posted : Thursday, May 12, 2022 5:56:17 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Try using this for the Foreground Window Change script.
Code:
try {
    var currentWindow = sp.ForegroundWindow();
    if(currentWindow.Enabled
       && currentWindow.Visible
       && !currentWindow.IsCloaked
       && (
            (!currentWindow.IsDescendantOf(currentWindow.Parent) 
                && (
                        (!currentWindow.Style.HasFlag(WindowStyleFlags.POPUP) || currentWindow.ExtendedStyle.HasFlag(WindowExStyleFlags.NOREDIRECTIONBITMAP))
                     &&
                        !currentWindow.ExtendedStyle.HasFlag(WindowExStyleFlags.TOPMOST)
                   )
                && !currentWindow.Rectangle.IsEmpty
                && !currentWindow.Style.HasFlag(WindowStyleFlags.CHILDWINDOW)
                && currentWindow.Title.length > 0
                && !currentWindow.ExtendedStyle.HasFlag(WindowExStyleFlags.TOOLWINDOW)
            )
          ||
            (
                currentWindow.Style.HasFlag(WindowStyleFlags.VISIBLE)
                &&
                currentWindow.ExtendedStyle.HasFlag(WindowExStyleFlags.APPWINDOW)
            )
        )
    ){
        sp.StoreObject("LastWindow", sp.GetStoredObject("CurrentWindow"));
        sp.StoreObject("CurrentWindow", currentWindow);
    }
} catch {}
Omonym  
#27 Posted : Thursday, May 12, 2022 7:04:25 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

First it called up the last but one active window (not the last one) and then didn't react to the next strokes. Other time it called up the last active window and again stopped doing anything.
Rob  
#28 Posted : Thursday, May 12, 2022 7:11:44 PM(UTC)
Rob

Rank: Administration

Reputation:

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

Thanks: 25 times
Was thanked: 364 time(s) in 317 post(s)
Oh well. Time to install Windows 10 or 11! :P
Omonym  
#29 Posted : Thursday, May 12, 2022 7:31:12 PM(UTC)
Omonym

Rank: Member

Reputation:

Groups: Approved
Joined: 10/31/2021(UTC)
Posts: 15
Hungary

I will be fine with what you provided me with! Thank you!
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.