How to get AHK to pause the script when chrome is not in focus and resumes when it is? - google-chrome

This script is supposed to press Z every 50 um..units of time when I press Q until I press W.
What I have trouble doing is making it pause(stops pressing z) whenever chrome is not in focus and resumes when it comes back into focus again.
Thank you. Below is the script that does what I said in the first sentence.
q::
stop = 0
Loop
{
SendInput, z
Sleep 50 ;adjust for speed of repetition
if stop
break
}
return
w::
stop = 1
return

Try adding a WinWaitActive command after the sleep command.

Related

How can I wake a Mac display using Python?

My computer isn't asleep, but the dispaly turns off after 15 minutes. I don't want my display to never sleep, but I need the display to automatically turn back on to process some other tasks.
I'm not sure if PyAutoGui is the right tool to use for this task. The following code does execute, but is not waking my display from sleep when it is set to sleep after 60 seconds:
import time
import pyautogui
# pyautogui.FAILSAFE = False
time.sleep(90)
pyautogui.press('shift')
for i in range(1, 200):
pyautogui.moveTo(i, i)
Thoughts?

Trigger Brave "Search Tabs" feature from Autohotkey

I would like to be able to trigger "Search Tabs" from Autohotkey, since I have lots of opened tabs this would help me quickly find the tab I am looking for, I know I might be able to loop through all tabs by scripting this, but that's not what I want.
This is what I've done
!+a::
WinActivate, Brave
Sleep, 100
Send, {Ctrl}{Shift}a
Return
If I change Send, {Ctrl}{Shift}a with Send, {Ctrl}t is correctly opens a tab, so the problem must be either some error in my {Ctrl}{Shift}a configuration or that Brave is somehow not reacting.
The most appropriate way to activate a specific window and send keystrokes to it is as follows:
!+a::
SetTitleMatchMode, 2 ; if you want to use it only in this hotkey
IfWinNotExist, Brave
{
MsgBox, Cannot find Brave
Return ; end of the hotkey's code
}
; otherwise:
WinActivate, Brave
WinWaitActive, Brave, ,2 ; wait 2 seconds maximally until the specified window is active
If (ErrorLevel) ; if the command timed out
{
MsgBox, Cannot activate Brave
Return
}
; otherwise:
; Sleep 300 ; needed in some programs that may not react immediately after activated
Send, ^+a
Return
Otherwise the script can send the keystrokes to another window.
For not repeating the whole code in every hotkey you can create a function:
!+b::
SetTitleMatchMode, 2
Activate("Brave", 2)
; Sleep 300
Send, ^+a
Return
Activate(title, seconds_to_wait){
IfWinNotExist, % title
{
MsgBox % "Cannot find """ . title . """."
Return
}
; otherwise:
WinActivate, % title
WinWaitActive, % title, ,% seconds_to_wait
If (ErrorLevel)
{
MsgBox % "Cannot activate """ . title . """."
Return
}
}

Tcl/Tk : How to create progressbar along with running code?

proc foo {} {
# do something
# sleep for 5sec
# do something
# sleep for 5sec
# do something
}
I want as soon as we enter foo, progressbar should appear and running horizontally,
along with that foo code should also be running,
and as everything in foo finishes, progressbar should show 100% horizontally and disappear .
How to do that?
The widget you're looking for is a ttk::progressbar (Tcl) or tkinter.ttk.Progressbar (Python). You'll need to decide whether to use it in determinate or indeterminate mode and stuff like that.
There's one key tricky thing about using a progress bar: you need to keep the event loop running while you're displaying it. This means you need to either put the work in a separate thread or call update periodically. Both options have their tricky aspects:
When using a separate worker thread, that thread must not touch the GUI at all. Instead, it has to send messages to the GUI thread asking it to do the update.
When using periodic update calls (once every quarter second or so is usually enough) you need to be very careful to not recursively enter full event loop processing (see the TkDocs page on the event loop for a discussion). This often involves doing things like disabling buttons while the processing is going on.
Were you instead after a progress bar in a terminal, those are comparatively simple because you don't have to manage an event loop; the terminal itself will do that for you.
If you have a good idea of the time it takes to do what you have to do you can use the after command to update the progress bar at regular intervals.
# pop up progress bar for a calibration that takes 20 seconds
toplevel .progress
label .progress.calib -text "Calibrating ..."
ttk::progressbar .progress.bar \
-variable ::progress \
-length 300
grid .progress.calib
grid .progress.bar
wm geometry .progress +180+180
#
# wait 20 seconds and update the progress every 0.5 s
#
set wait_time 20000
# use a variable to wait until the progressbar is complete
after 20100 "destroy .progress"
# create updates every 0.5 second
for {set i 500} {$i <= $wait_time} {incr i 500} {
after $i "set ::progress [expr $i*100/$wait_time]"
}
# do your stuff in less than 20 seconds
...

TK spinbox goes into infinite cycle of updating GUI

I cannot fix a strange behavior of spinbox. Specifically, I need to update GUI at changing the spinbox's value, by means of -command and update in it.
The code a bit simplified is like:
package require Tk
set sv 1
ttk::spinbox .sp -from 1 -to 9 -textvariable ::sv \
-command {
after 50 ;# some processing imitated
puts [incr ::tmp]:$::sv ;# changes shown in CLI - ok
update ;# changes shown in GUI - ???
}
pack .sp
The problem is when the spinbox's arrow (more "Up" than "Down", but I've not found any regularity in this) is clicked and then pressed 10-20 seconds, the spinbox goes in the infinite cycle of updating, as puts shows.
Of course, the reason is update in the -command code, but I cannot do without it.
Tried in Windows (Tk 8.6.8) and Linux (Tk 8.6.10), ttk::spinbox and spinbox, all revealing the freak.
Is any way to overcome this? Thanks a lot for any help.
In general, don't update the spinbox variable from within the -command callback, and in particular don't run update from within the -command callback. You probably shouldn't do that at all. That command allows processing of events (it runs a subsidiary event loop until the event queue is drained) and is exactly the source of your problems. (I also would suggest not doing update idletasks; that will trigger the reconfigure and redraw that is at the heart of the issue.)
Instead, just stop running the command callback. That returns control to the Tk widget, which will in turn return to the main event loop. You are also advised to not do substantial processing in the callback, and instead to schedule such processing to occur later. Exactly how you do this can be complex, and will definitely be application-specific. One way to move processing later is to just punt it to a procedure that runs in an after event, like this:
package require Tk
set sv 1
proc updateVar {varName} {
upvar "#0" $varName var
after 50; # Processing...
incr var; # Actually update the variable
}
ttk::spinbox .sp -from 1 -to 9 -textvariable ::sv \
-command {after 0 updateVar ::sv}
pack .sp
Note that this does not call update. More substantial postponements of code might involve threads or subprocesses. As I said, getting this right can be complex. It's particularly so when changes to the GUI layout while a mouse button is down cause the selected value to change which in turn causes changes to the GUI layout which …
I made this archive with video to demonstrate the strange behavior of spinbox when update is included in its -command option.
There are two tests in the archive:
test1.tcl presents a way how it should not be done. There are two issues:
the -command code isn't moved to a separate procedure
update is fired immediately from the -command code
The result is seen in test1-spx.mp4: when pressed a spinbox arrow 10-20 seconds, the spinbox goes into an infinite cycle of updating. This behavior is not regular, though well revealed when the focus is switched to another application.
test2.tcl presents a way how this freak can be overcome. The after idle is used to postpone the updating. You can use also after 0 for this.
In a "real test" test2_pave.tcl I use the following procedure for the -command:
proc fontszCheck {} {
lappend ::afters [after 0 {
foreach a $::afters {after cancel $a}
set ::afters [list]
::t::toolBut 4 -3
}]
}
Hopefully, this information would be useful at dealing with Tk spinbox.

A way to intervene "after" in tcl

I have written a tcl script where there is wait for 20 seconds in between.
Sometimes I have to come out of the waiting (or rather stop ) in between.
I have used:
after 20000
Is there a way to stop the waiting?
If you just use:
after 20000
Then no, there's no way (other than killing the process with Ctrl+C or kill, of course).
If you want an interruptable wait in Tcl, use this:
after 20000 set done 1
vwait done
That will continue to service events and so can be interrupted. Save the token returned by after 20000 set done 1 and you can cancel the timer (e.g., if you want to reschedule it). Set the (global done) variable yourself otherwise and you'll finish waiting sooner.
In one of my previous projects at work, I had to deal with a similar situation where my scripts wait for N seconds, then continue on, unless the user hit Ctrl+C, then the wait is canceled. Below is my script, reduced to bare essential to show how it works.
package require Tclx
proc abortTest {} {
after cancel $::afterId
set ::status "Ctrl+C detected"
}
#
# Main
#
puts "start"
set status "Ctrl+C not detected"
# when Ctrl+c detected, call abortTest
signal trap SIGINT abortTest
# Wait for N seconds
set WAIT_TIME 10000
set afterId [after $WAIT_TIME {set status "Exit normally"}]
puts "Wait for [expr {$WAIT_TIME / 1000}] seconds"
vwait status; # wait until status changed
puts $status
puts "end"
Discussion
The signal command said, "if the user hit Ctrl+C, then call abortTest"
Notice that in this form, the after command will exit right away, but the TCL interpreter will execute the set status ... command 10 seconds later.
The vwait command waits until the variable status to change its value.
After 10 seconds, if the user had not hit Ctrl+C, then the variable status will be set to "Exit normally", at that time, the vwait command exits
If the user hit Ctrl+C during that time, then status will be changed and the vwait command exits
Update
While reducing the original script, I took out the part to cancel the after command. Now I am putting it back in. Notice that the after command returns an ID, which I used in abortTest to cancel the action.