AHK: Different hotkeys via sequences with repeating keys - keyboard-shortcuts

Ok my code has the following which works:
^m::Send M text{enter}
Return
^s::Send S text{enter}
Return
^t::Send T text{enter}
Return
Now I want to be able to add something like the following (this way it doesn't work):
^m & ^t:: Send M and T text{enter}
Return
^m & ^s:: Send M and S text{enter}
Return
^t & ^s:: Send T and S text{enter}
Return
I want AHK to take all three sequences like Ctrl+S does one thing and Ctrl+M does another but Ctrl+S+M does a different third action.
There is a similar post to this here: AutoHotKey key SEQUENCE, not just single-key hotkey

If you don't find a fitting solution, you might want to try the workaround which I've been using.
Note: the following does not include any hotkey triggers like ^m::, the problem is being solved with the hotkey-command and fitting label names, which actually look like a hotkey trigger (^m:)
hotkey, ^m, ^m, On
hotkey, ^t, ^m, On
return
^m_and_^t: ; will also be called from ^t & ^m
Send M and T text{enter}
triggered = true
return
^m_and_^s:
Send M and S text{enter}
triggered = true
return
^t_and_^s:
Send T and S text {enter}
triggered = true
return
^m:
triggered = false
hotkey, ^t, ^m_and_^t, On
hotkey, ^s, ^m_and_^s, On
loop
{
getkeystate, isDown, m, P
if isDown = U
break
}
hotkey, ^t, ^t, On
hotkey, ^s, ^m_and_^s, Off ; -> ^s will keep its natural function
if triggered = false
{
Send M text{enter}
}
return
^t:
triggered = false
hotkey, ^s, ^t_and_^s, On
hotkey, ^m, ^m_and_^t, On
loop
{
getkeystate, isDown, t, P
if isDown = U
break
}
hotkey, ^m, ^m, On
hotkey, ^s, ^m_and_^s, Off ; -> ^s will keep its natural function
if triggered = false
{
Send T text{enter}
}
return

Related

Pysimplegui and Pygame merge

hi I am trying to merge a pygame program with pysimplegui.
i'm looking for a way of grabbing the downstroke of a keyboard key. at the moment i can only see an upstroke of the key no matter what im doing.
I have sucessfully created pysimplegui programs but this is the first time i'm trying to merge with pygame.
window is setup by
window = sg.Window('UNICHALL V2.0',
Win_layout,
border_depth =20,
resizable = True,
keep_on_top = False,
finalize=True,
return_keyboard_events=True,
use_default_focus=False)
and in my pygame program i use
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
stop = pygame.time.get_ticks()
delta = stop - start
key = event.key
if key == 27:
sys.exit(1) ...
i can't get these two work in harmony, they either internally loop forever or simply stop the program dead.
Any help appreciated.
If you just need to detect when key pressed and released, try to bind the event '<KeyPress>' and '<KeyRelease>', not set option return_keyboard_events=True of sg.Window.
Example Code
import PySimpleGUI as sg
layout = [
[sg.InputText('', key='-INPUT-')],
[sg.Button('Add Binding'), sg.Button('Remove Binding')],
]
window = sg.Window('Test Program', layout, finalize=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
elif event in ('Press', 'Release'):
e = window.user_bind_event
action = 'pressed' if event == 'Press' else 'released'
print(f'char:{repr(e.char)} | keycode:{e.keycode} | keysym:{e.keysym} | keysym_num:{e.keysym_num} {action}')
elif event == 'Add Binding':
window.bind("<KeyPress>", "Press")
window.bind("<KeyRelease>", "Release")
elif event == 'Remove Binding':
window.TKroot.unbind("<KeyPress>")
window.user_bind_dict.pop("<KeyPress>", None)
window.TKroot.unbind("<KeyRelease>")
window.user_bind_dict.pop("<KeyRelease>", None)
window.close()

Any function in DMS3.0 or later that runs in the background and allow user interaction (like FloatingModelessDialog)

In DMS3.42 or later, I am wondering if we have a function that the user is allowed to select an image to operate. Basically, the function needs to run in the background and allows user interaction, something like "FloatingModelessDialog" in the previous version (it seems "FloatingModelessDialog" is not supported in DMS3.0).
Thank you!
FloatingModelessDialog is still supported in GMS 3:
// $BACKGROUND$
number sem = NewSemaphore()
FloatingModelessDialog("Message", "YES", sem )
Result("\n Do continue stuff...")
// hold and wait for the dialog
number OK
Try { GrabSemaphore(sem); OK = 1; }
catch { OK = 0; break; }
Result("\n Button pressed:" + OK )
However, this is only a workaround solution and requires the script to be executed on a background thread (or GMS appears to be frozen.)
A more complete approach would be to create a dialog and have its buttons drive the actions, like in the example below:
class MyActionDialog : UIFrame{
void Launch( object self ){
// Build dialog
TagGroup DLGtgs, DLGItems
DLGtgs = DLGCreateDialog( "My Dialog", DLGItems )
TagGroup Button1 = DLGCreatePushButton( "Act on front image", "OnButtonAct" )
TagGroup Button2 = DLGCreatePushButton( "Close", "OnButtonClose" )
DLGItems.DLGAddElement( Button1 )
DLGItems.DLGAddElement( Button2 )
DLGtgs.DLGTableLayout( 2, 1, 0 )
// Create and display the modeless Dialog
self.init( DLGtgs )
self.Display( "My Dialog" )
}
void OnButtonAct( object self ){
image front
if ( !GetFrontImage(front) )
Result( "\n Please select an image first." )
else
Result("\n Acting on image [" + front.ImageGetLabel() + "]....")
}
void OnButtonClose( object self ){
Result( "\n Closing dialog actions." )
self.close()
}
}
Alloc(MyActionDialog).Launch()

Error - Unexpected } at the end of While Loop

I'm using while true loop to constantly check run this script. After adding the if expression with whitelist ahk gives an error about unexpected } at the end of code. As far as I know there should be }.
Using Loop command gives the same error.
Removing the problematic } at the end causes the code running in background but not doing anything.
;Setup
Sleep, 1000
whiteList = "none"
;Main Loop
While True
{
siteName = YouTube
WinGetActiveTitle, tabName
Sleep, 10000
if tabName = %whiteList%{
Continue
}
;If current website is Youtube, ask if am I supposted to be here
if InStr(tabName, siteName){
Sleep, 10000
MsgBox, 292, Reality Check, Should you do this?
IfMsgBox, Yes
{
whiteList = tabName
}
;Close tab in mozilla
else
{
WinActivate, %tabName%
Sleep, 10
Send ^w
}
}
}
Code is unfinished, It should run in background and when the user is using YouTube fore some time it should ask him whether is he supposted to watch Youtube.
If he clicks yes, the program should ignore that specific page.
Else it should close it.
The % around the whiteList-var shouldn't be there. When I wrote it like below it seems to work:
if tabName = whiteList
Continue
Also the whiteList = tabName will just assign the string "tabName" to whiteList. Use whiteList := tabName for assigning, and if var1 = var2 for comparison.

How to send a key only on double-tap?

I know I can use
F1::Return
to disable the F1 key. But I would like to be able to still use it by simply double-tapping. However, when I try
$F1::
if (A_PriorHotkey <> F1 or A_TimeSincePriorHotkey > 400) {
KeyWait, F1
Return
}
Send, {F1}
(based on this post), the first press of F1 passes through while all following ones (including double-taps) are completely ignored.
Check your quotation marks...
$F1::
if (A_PriorHotkey <> "$F1" or A_TimeSincePriorHotkey > 400) {
KeyWait, F1
Return
}
Send, {F1}

AutoHotkey: Similar function like ClipWait for "Select All"

Does AutoHotkey have anything similar to "ClipWait" for "Ctrl+A" / "Select All".
Or is there a possibility to get such a function somehow ?
Would this be sufficient?
^b::
send ^a
selectionWait()
msgbox, All has been selected
return
selectionWait() {
clipboardSave := clipboardAll
loop {
send ^c
if(clipboard != clipboardSave)
if(clipboard != "")
break
}
clipboard := clipboardSave
}
ctrl+c IS fired before everything is selected, but this is on purpose. the action will be repeated until the clipboard contents have changed, and the clipboard will be reset to the previous value afterwards
I had the same problem when selecting many rows from a network database.
The “Select All” command didn't have time to complete, hence making
Copy & ClipWait useless,
Here's the beautiful fix:
Loop
{
Send, ^a
Send, ^c
ClipWait, 1
if (!ErrorLevel)
break
}
Or like this if you want to limit the wait to 5 seconds:
Loop, 5
{
Send, ^a
Send, ^c
ClipWait, 1
if (!ErrorLevel)
break
}