Author Topic: Key Macros plugin  (Read 25441 times)

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Key Macros plugin
« on: December 11, 2006, 03:37:46 pm »
I've written a plugin to create and playback key macros.

A key macrosText looks like "{END}{ENTER}{TAB 2}//{SPACE}" for example.

The keyMacro is played back by creating a menu item with a command key chosen by the user, eg., "MyMac \tCtrl-Enter" such that when the user types Ctrl-Enter the interpreted macroText is stuffed into the keyboard queue.

Now, lets say a user creates a keyMacro with the text "{}" with a menu command key of "MyMacro \t{". This acturally works. The user types { on the keyboard and {} appears in the editor. Over and over and over and over.....

The macro processor (plugin) is in a loop because the OS sees the '{' in the keyboard queue, sees that its a menu command and invokes the macro plugin again.

I can prevent this by disallowing any keyMacro whos macroText contains the menu command key. eg. if a menu item with command key '{' invokes a  keyMacro whos macroText contains '{', refuse to play it back.

I'd rather not do that. I'd like to find a way to play the macro but stop the loop.

Some ideas that didnt work...
  • A timer. Very iffy. On different systems, keyMacro could get through multiple times.
  • Play back only once. Ok, how do you play it next time? What would clear the "I just played that" status?

I'd appreciate some ideas.
Thanks
pecan

 
« Last Edit: December 11, 2006, 03:56:28 pm by Pecan »

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Key Macros plugin
« Reply #1 on: December 11, 2006, 03:55:29 pm »
this sounds like a handy macro.

some thoughts/questions:

* would you have the same problem if someone pasted text containing "{"?

* it seems that you need some way to distinguish typed input from inserted input. failing that you could require all key assignments use a CTRL or ALT modifier.

* are you trapping the "changed" status of the cbEditor rather than the "keystroke" status?

* does the plugin operate only when focus is in the editor window or on all C::B windows?

* it would be nice if this plugin was integrated with "Keyboard shortcuts"

hope to see it working soon :)

Offline byo

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 837
Re: Key Macros plugin
« Reply #2 on: December 11, 2006, 07:12:05 pm »
Some ideas that didnt work...
  • A timer. Very iffy. On different systems, keyMacro could get through multiple times.
  • Play back only once. Ok, how do you play it next time? What would clear the "I just played that" status?

Ok few ideas:
  • Mixing Playback-once with a timer (blocking flag set before executing macro and timer clears blocking flag) - this may still be risky becuase of different speed on different computers
  • Accessing cb editor directly (I'm not sure but they shouldn't throw keys into system's message queue avoiding recall of menu entry)
  • Setting some blocking flag just before senting key events and resetting it after all keys are sent. But thils will work only if keys will be sent using immediate functions - so no AddPEndingEvent could be used just ProcessEvent or it will require calling Manager::Yield() before clearing flag

Regards
   BYO

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #3 on: December 11, 2006, 07:47:36 pm »
Thanks for your response.

this sounds like a handy macro.
some thoughts/questions:
* would you have the same problem if someone pasted text containing "{"?
No, the loop does not occur on paste. Only when invoked via the keyboard.
However, pasting does not provide anywhere near the flexibility of the keyboard.
Quote
* it seems that you need some way to distinguish typed input from inserted input. failing that you could require all key assignments use a CTRL or ALT modifier.
Indeed. But the macroText is not inserted. It's actually pushed onto the keyboard queue. Thus there is no distinction between chars originating from the macro and those typed at the keyboard by the user.

An Alt-N macro that contained "{Alt}n" puts me in the same hard place.

With wxWidgets, chars cannot be "inserted" into native controls, they can only come from the keyboard. If the plugin attempted to use the widgets facilities, SetValue(), ScrollWindow() etc, it'd have to determine the control type, the function to use, etc etc. It'd have to recreate the wxWidgets wheel.
Quote
* are you trapping the "changed" status of the cbEditor rather than the "keystroke" status?
KeyMacs is not trapping any status at all right now. It's invoked by the menu system, looks up the menu name, matches that to a keyMacro of the same name, translates its menuText to keystrokes and pushes 'em into the keyboard queue.

Edit: 2006/12/11 2:27 PM
Ah, I see what you mean. But the cbEditor changed flag may not be raised if the macro changed say the find dialog. {Ctrl}f"{"{ENTER} would not raise the "changed" flag, but it would cause the loop.

It does know the last macro name, the time, and the macroText.
Quote
* does the plugin operate only when focus is in the editor window or on all C::B windows?
I have restricted the macro to execute only when invoke from a CBeditor window. However, the macroText can open/close/switch/start pgms/invoke other menus etc. eg. "{Ctrl}fFIXME{ENTER}" opens the find dialog, types FIXME into the find control and executes the find.
Quote
* it would be nice if this plugin was integrated with "Keyboard shortcuts"
hope to see it working soon :)
I suspect that in future, the KeyBinder plugin will be deprecated. So integration might not be forthcoming.

Got any ideas about that loop problem?
« Last Edit: December 11, 2006, 08:30:56 pm by Pecan »

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Key Macros plugin
« Reply #4 on: December 11, 2006, 08:42:27 pm »
you could try something like the following, a slight twist on byos proposal (far from perfect, but not sure how you could do anything else if you are using the key buffer)

1. receive keystroke to invoke macro
2. switch off key macro lookups
3. insert macro text into key buffer + append a final key command to switch on key macro lookups when done
« Last Edit: December 11, 2006, 08:49:10 pm by dmoore »

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Key Macros plugin
« Reply #5 on: December 11, 2006, 08:46:32 pm »
a more general alternative would be to write code to convert UI keystrokes to a squirrel script (assuming there are enough hooks in CB to handle most of the UI in a squirrel script)

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #6 on: December 11, 2006, 08:58:33 pm »
I think I'm misunderstanding this loop.

Say: Menu hotkey '{' invokes KeyMacro which pushes '{' and '}' onto the keyboard buffer.

'{' could not possibly ever reach the editor even if the plugin turned off further processing. The OS would eat all '{'s attempting to execute the menu entry.

So allowing a user to use a hotkey that is also in the macroText is futile and should not be allowed.

Am I on the right track now?

However, the loop problem still exists. macroA contains command keys that invoke macroB which contains command key  that invokes macroA again.
The loop still lives.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #7 on: December 11, 2006, 09:09:20 pm »
I think I'm misunderstanding this loop.
...
However, the loop problem still exists. macroA contains command keys that invoke macroB which contains command key  that invokes macroA again.
The loop still lives.

But the macro editor could handle this.
It knows all the hotkeys and has access to every macro's text.
It could then put up a msg like:
 *"Hey bozo, this macro causes a loop and the big kahuna banishes plugins that allow that."
Then trash the macro. Not with standing tears, crys of innocents, and threats of death to the programmer.
« Last Edit: December 12, 2006, 12:44:34 am by Pecan »

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #8 on: January 10, 2007, 10:14:06 pm »
Under windows, pressing keyboard Alt+0+1+9+1 will produce a '' (reversed question mark).

Does this facility work under Xwindows or Linux?

Edit: 4:52 PM
It appears that Alt-0-anything is ok from the windows FireFox side.
But then when I try to enter the same thing from the andLinux Firefox size, nothing happens.

Makes sense. But I thought maybe Xwindows would get a scan code from the keyboard. Alt-0xxx must work from the opsys, not the keyboard.

Am I getting warm?

I hate to delete this code from Linux cbKeyMacs if I'm wrong.
« Last Edit: January 10, 2007, 10:53:29 pm by Pecan »

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #9 on: January 16, 2007, 01:40:51 am »
KeyMacs is a Code::Blocks plugin providing the user an ability to group sequences of keystokes as a macro (KeyMac). The KeyMac can be executed by either the main Plugin menu, a menu command key, or the context menu.



KeyMacs editor:


Wiki article:
KeyMacs_plugin

Download cbKeyMacs03.zip
http://savefile.com/files/416395

Installation:

Unzip cbKeyMacs03.zip to a clean folder.

Compile KeyMacs for MSWindows with KeyMacs.cbp. Then copy KeyMacs.dll to ...\trunk\src\devel\share\CodeBlocks\plugins\KeyMacs.dll. Copy KeyMacs.zip to ...\trunk\src\devel\share\CodeBlocks\KeyMacs.zip

Compile KeyMacs for Linux with KeyMacs(unix).cbp. Then copy KeyMacs.dll to .../trunk/src/devel/share/codeclocks/plugins/KeyMacs.dll. Copy KeyMacs.zip to .../trunk/src/devel/share/codeblocks/KeyMacs.zip

Linux users will need the X11 and Xtst development libraries. Ubuntu Synaptic provided the following libraries when I searched for xtst:


« Last Edit: January 16, 2007, 01:45:55 am by Pecan »

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #10 on: January 17, 2007, 08:17:10 pm »
KeyMacs is a Code::Blocks plugin providing the user an ability to group sequences of keystokes as a macro (KeyMac). The KeyMac can be executed by either the main Plugin menu, a menu command key, or the context menu.

Update: KeyMacs v 0.3.3

http://savefile.com/files/420813


changes:
Code: [Select]
// ----------------------------------------------------------------------------
//  Commit  0.3.3 2007/01/17 Published
//    1) Escaped recorded user {}!^+ chars in KeyEvtLogr::RecordEvent()
//    2) reverse refactored change header to version.h
//    3) Set recorded macro to Scratch at "stop recording" as well as "play macro"
// ----------------------------------------------------------------------------

Help entry:

http://wiki.codeblocks.org/index.php?title=KeyMacs_plugin


Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #11 on: January 23, 2007, 11:37:08 pm »
KeyMacs is a Code::Blocks plugin providing the user an ability to group sequences of keystokes as a macro (KeyMac). The KeyMac can be executed by either the main Plugin menu, a menu command key, or the context menu.

Update: KeyMacs v 0.3.5

http://savefile.com/files/436447


changes:
Code: [Select]
// ----------------------------------------------------------------------------
//  Commit  0.3.5 2007/01/23    Publish
//           4) version.h/cpp rework and editor spelling corrections
//           5) Fixes for crashes when enabled/disabled by Plugin Manager
// ----------------------------------------------------------------------------

Help entry (Wiki):

http://wiki.codeblocks.org/index.php?title=KeyMacs_plugin

Offline arst

  • Multiple posting newcomer
  • *
  • Posts: 19
Re: Key Macros plugin
« Reply #12 on: January 24, 2007, 09:44:15 am »
Hello,

I've been downloading the KeyMacs 0.3.5 plugin. I've been lacking
macro support in CB. But... when compiling in CB (3521), I receive
a bunch of preprocessor errors, see below.

They all relate to Windows preprocessor symbols, so they are
nowhere defined, neither in CB source folder nor in wxWidgets one.

How should this be compiled?

Thanks,
Arst


:: === KeyMacs-MSW-plugin, default ===
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:35: error: `VK_SHIFT' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:35: error: `MapVirtualKey' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:36: error: `VK_CONTROL' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:37: error: `VK_MENU' was not declared in this scope
....
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:298: error: `byte' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:298: error: expected `)' before "scCode"
:: More errors follow but not being shown.
:: Edit the max errors limit in compiler options...
:: === Build finished: 50 errors, 0 warnings ===

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2178
Re: Key Macros plugin
« Reply #13 on: January 24, 2007, 03:15:04 pm »
Hello,

I've been downloading the KeyMacs 0.3.5 plugin. I've been lacking
macro support in CB. But... when compiling in CB (3521), I receive
a bunch of preprocessor errors, see below.

They all relate to Windows preprocessor symbols, so they are
nowhere defined, neither in CB source folder nor in wxWidgets one.

How should this be compiled?

Thanks,
Arst


:: === KeyMacs-MSW-plugin, default ===
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:35: error: `VK_SHIFT' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:35: error: `MapVirtualKey' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:36: error: `VK_CONTROL' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:37: error: `VK_MENU' was not declared in this scope
....
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:298: error: `byte' was not declared in this scope
D:\Proj\Ext\CB\src\plugins\contrib\KeyMacs\MSWrunmacro.cpp:298: error: expected `)' before "scCode"
:: More errors follow but not being shown.
:: Edit the max errors limit in compiler options...
:: === Build finished: 50 errors, 0 warnings ===

I'm using gcc 3.4.4 with wxWidgets 2.6.3, so for me the windows headers are being brought in by wxWidgets pre-compiled headers (eg., winuser.h).

Are you using the .cbp provided?

What version of wxWidgets are you using?

What compiler/system are you using?

Could you post your project. I cannot seem to re-create these errors even when turning off precompiled headers.
« Last Edit: January 24, 2007, 04:44:29 pm by Pecan »

Offline arst

  • Multiple posting newcomer
  • *
  • Posts: 19
Re: Key Macros plugin
« Reply #14 on: January 24, 2007, 05:26:25 pm »
Hello,

Yes, I'm using the supplied KeyMacs project. On reading your reply,
I worked a bit with it again and got past the Windows preproc
problems. I had to do this (including windows.h and a couple of defines:

// ----------------------------------------------------------------------------
//  MSWrunmacro.cpp
// ----------------------------------------------------------------------------
// RCS-ID: $Id: MSWrunmacro.cpp 15 2007-01-14 05:32:30Z Pecan $

#if defined(__WXMSW__)
 // headers for MSW here

#ifdef wxUSE_UNICODE
#define _UNICODE
#define UNICODE
#endif
#include <windows.h>
Also I had to add the search path to MinGw/Include to the project.

However... I think we get a very direct dependence on MinGw (going
past the wxW layer).

When the compiler continues, I get some other errors (below). They
all concern the PageUp and PageDown keys, where different defines
have the same value, in the switch case.

:: === KeyMacs-MSW-plugin, default ===
C:\wxWidgets-2.8.0\include\wx\wxprec.h:28: warning: "WX_PRECOMP" redefined
:9:1: warning: this is the location of the previous definition
cmdkeytextctrl.cpp:236: error: duplicate case value
cmdkeytextctrl.cpp:221: error: previously used here
cmdkeytextctrl.cpp:237: error: duplicate case value
cmdkeytextctrl.cpp:222: error: previously used here
cmdkeytextctrl.cpp:321: error: duplicate case value
cmdkeytextctrl.cpp:320: error: previously used here
cmdkeytextctrl.cpp:323: error: duplicate case value
cmdkeytextctrl.cpp:322: error: previously used here
:: === Build finished: 8 errors, 2 warnings ===
OK
// Arst