Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Mac Question: Anybody know how to get services or keyboard shortcuts to work in a plugin?

LEGEND ,
Sep 07, 2010 Sep 07, 2010

I have a plugin that really benefits from being able to press a single key to issue a multi-key sequence.

I'm doing this on WIndows using AutoHotKey, and it works great on Mac using QuickKeys, but I'd like to find a way to do it without requiring the user to purchase QuickKeys. I've been able to use Automator to define a script that issues the desired keystrokes, and tie it to the keyboard as a shortcut initiated service, and this works in Lightroom proper, but is disabled when using my plugin.

Any ideas?

Thanks,

Rob

TOPICS
SDK
1.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 17, 2010 Nov 17, 2010

So now I have:

on the fly applescript (osascript -e  ... -e ... -e ...) to send various keystrokes to Lightroom on Mac -  that's working great although not fully validated.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 18, 2010 Nov 18, 2010

Do you have to enable "Universal Access" in System Preferences or can you circumvent this?

How does a real call look like?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 18, 2010 Nov 18, 2010

Sorry I may have confused.

Original post was about getting keyboard shortcuts set up for the user, and the follow-up/reply post was about issuing keystrokes programmatically.

Regarding the former, maybe univesal access is required - dont really know.

Regarding the latter, the following code is part of the framework available at https://www.assembla.com/spaces/lrdevplugin/

It allows a plugin to send keystrokes like "p" to pick a photo, or "Cmd-S" to save metadata. There is a windows counterpart as well...

--[[
        Send key string verbatim to Lightroom.
       
        Uses applescript string passed to osascript.
--]]
function Mac:sendUnmodifiedKeys( keyStr, keyDowns, keyUps )
    local scriptTbl = {}

    scriptTbl[#scriptTbl + 1] = "-e 'tell application \"Lightroom\" to activate'"
    scriptTbl[#scriptTbl + 1] = "-e 'tell application \"System Events\"'"

     if keyDowns then
        tab:appendArray( scriptTbl, keyDowns )
    end

    scriptTbl[#scriptTbl + 1] = "-e 'keystroke \"" .. keyStr .. "\"'"

    if keyUps then
        tab:appendArray( scriptTbl, keyUps )
    end

    scriptTbl[#scriptTbl + 1] = "-e 'end tell'"

    local scriptStr = table.concat( scriptTbl, ' ' )
    local command = 'osascript'
    local params = scriptStr

    return self:executeCommand( command, params ) -- no targets, no output.
end

--[[
        Send mac-modified keystroke sequence to mac os / lightroom.
       
        Format examples:
       
            Ctrl-S
            Cmd-FS
            ShiftCtrl-S

        i.e. mash the modifiers together (in any order), follow with a dash, then mash the keystrokes together (order matters).
--]]
function Mac:sendModifiedKeys( modKeys )
    local k1, k2 = modKeys:find( '-' )
    local keyMods
    local keyStr
    if k1 then
        keyStr = modKeys:sub( k2 + 1 )
        keyMods = modKeys:sub( 1, k1 - 1 )
    else
        error( "No keystroke" )
    end
    local keyDownTbl = {}
    local keyUpTbl = {}
    if keyMods:find( 'Shift' ) then
        keyDownTbl[#keyDownTbl + 1] = "-e 'key down shift'"
        keyUpTbl[#keyUpTbl + 1] = "-e 'key up shift'"
    end
    if keyMods:find( 'Option' ) then
        keyDownTbl[#keyDownTbl + 1] = "-e 'key down option'"
        keyUpTbl[#keyUpTbl + 1] = "-e 'key up option'"
    end
    if keyMods:find( 'Cmd' ) then
        keyDownTbl[#keyDownTbl + 1] = "-e 'key down command'"
        keyUpTbl[#keyUpTbl + 1] = "-e 'key up command'"
    end
    if keyMods:find( 'Ctrl' ) then
        keyDownTbl[#keyDownTbl + 1] = "-e 'key down control'"
        keyUpTbl[#keyUpTbl + 1] = "-e 'key up control'"
    end
    return self:sendUnmodifiedKeys( keyStr, keyDownTbl, keyUpTbl )
end

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 18, 2010 Nov 18, 2010

Very neat.  I'll be interested to learn your experience in how this works out in your plugins.

In the past, in different contexts, my experience with keystroke stuffing (on Windows) was that it was "fragile".  I've thought a bit, and here are some of the issues I've encountered in the past:

It's hard to handle dynamic application behavior.  A simple example is LR's Library menu -- when a non-folder source is selected, there is one menu command (Plug-in Extras) with S shortcut key, but when a folder source is selected, there are two (Plug-in Extras, Synchronize Folders), and thus the keystrokes needed to invoke Plug-in Extras vary depending on the LR source.  Since I rarely use folders as sources in LR (my workflow is not folder-based), I didn't even see this behavior until an Any File user point it out to me.  In general, the developer of a plugin using keystroke stuffing would have to carefully test it out in all the different LR contexts in which the plugin might be invoked).

More complicated behavior, such as confirmation dialog boxes that only appear based on selection or application state, can be more problematic.

Manipulating dialog boxes has been troublesome for the utilities I've used.  They typically have some facility for waiting until a dialog box appears, and then resuming the keystroke stuffing.   But if the application doesn't use the standard Windows toolkits (and at least some Adobe applications don't), the utilities may not be able to find the dialog box by name.  So then you have to program in a delay in your macro.  If you make the delay too short, the macro will fail.  If you make it too long, the user has to wait.  And if the user starts typing during the middle of the macro execution, you'll get unpredictable results.

A lot of apps don't follow the Windows conventions and don't fully implement the standard tab, cursor key, and enter semantics (again, I've experienced that with Adobe apps).  While the utilities allow you to use relative mouse coordinates to "move" the mouse and make mouse clicks, that's incredibly fragile, since the app window could have different layout each time it's invoked.

Despite all this, I've used keystroke macros to automate routine tasks in Photoshop Elements Editor (which disabled the action recording of full Photoshop) and Photosohop Elements Organizer.   But they were not entirely reliable.  But it may very well be that the uses you're envisioning for LR plugins will be straightforward and robust enough.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 18, 2010 Nov 18, 2010
LATEST

John,

Thank you for pointing out some of the "gotchas".

I agree that keyboard stuffing is not a panacea, to say the least.

That said, it can be a potential solution when there are no other alternatives.

Some things:

  • Keystrokes are best directed at Lightroom proper - they can not be directed at edit fields and as you've pointed out, they will fail if Lr dialog boxes get in the way (as presently programmed by me anyway).

However, there are cases where they may also work just fine:

  • Plugin has been invoked in Library mode, and no dialog boxes have popped up - so far things like "p" for pick and Ctrl/Cmd-S for saving metadata have worked for me.

Summary: Consider alternative work-arounds first, and if none seem better, then use with caution, test well, and document any gotchas for the user.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines