UI script fails with trigger but not when selected from menu
  • The following script hides/shows the Bookmarks Bar and Toolbar in Safari -

    activate application \"Safari\"
    tell application \"System Events\"
    tell process \"Safari\"
    keystroke \"b\" using {command down, shift down}
    keystroke \"|\" using command down
    end tell
    end tell

    It works fine when run from Script Editor, or when selected from FastScripts’ drop down menu. But it doesn’t seem to work when accessed with a FastScripts keyboard shortcut. (Nor, for that matter, from a Quicksilver trigger, although, again, it works when navigated to using the arrow keys in Quicksilver.)

    I was just curious if anyone could provide some insight into this situation!

    For the record, the following script does work when run from a shortcut, so the above problem isn't a show stopper. But the below does run more slowly:

    tell application \"System Events\"
    tell application \"Safari\" to activate
    tell process \"Safari\"
    try
    click menu item \"Hide Bookmarks Bar\" of menu \"View\" of menu bar 1
    click menu item \"Hide Toolbar\" of menu \"View\" of menu bar 1
    on error
    click menu item \"Show Bookmarks Bar\" of menu \"View\" of menu bar 1
    click menu item \"Show Toolbar\" of menu \"View\" of menu bar 1
    end try
    end tell
    end tell

    Thanks!
  • Hi Peter - there is unfortunately a class of limitations that boil down to: "the script is trying to synthesize keystrokes while your keys are still down from invoking the script". What happens is the UI Scripting keystrokes get mixed up with your real keys still being held down.

    The solution is to either add a delay at the beginning of your script, so FastScripts doesn't get to the keystroke events until you've safely let up on the keys, or to choose a keystroke that doesn't have competing modifier keys, etc.

    I'm hoping in some future release of OS X Apple will provide a means of "clearing" the keystrokes or somehow indicating that UI Scripting should only consider the new keystrokes being indicated.

    Daniel
  • Thanks so much Daniel - your response was really clear. That is an unfortunate limitation, but definitely good to know - it really had me stumped.

    I hope it’s okay, but I posted your reply to a thread that I started a few days ago on MacScripter.

    Take care.
  • Certainly fine that you reposted my reply. The more people who know about this limitation, the better ;)
  • Interesting... I have a similar script, but mine does work from the QS trigger. What's the difference?

    Note that this is UI scripting, and the Universal Access thingy has to be turned on.

    tell application \"Safari\"
    activate
    if bounds of window 1 is not equal to {0, 22, 1280, 800} then
    tell application \"System Events\"
    keystroke \"b\" using {command down, shift down}
    keystroke \"|\" using command down
    keystroke \"/\" using command down
    keystroke \"t\" using {command down, shift down}
    end tell
    set bounds of window 1 to {0, 22, 1280, 800}
    else
    tell application \"System Events\"
    keystroke \"b\" using {command down, shift down}
    keystroke \"|\" using command down
    keystroke \"/\" using command down
    keystroke \"t\" using {command down, shift down}
    keystroke \"m\" using {control down, option down, command down}
    click button 2 of window 1 of process \"Safari\"
    end tell
    end if
    end tell
  • I haven't examined QS lately but historically one of the "problems" with FastScripts is it's "too fast" and thus the script is running before you get the chance to lift up on the key.

    If you run the script with QS but make a point to be especially lazy about lifting up the trigger keys, does the same error occur with QS?

    If not, then maybe QS has come up with a way to work around the problem, and I will try to investigate.

    Daniel
  • I take it all back. Perhaps I'm going nuts, but now it does not do what I thought in QS. The behaviour is the same.

    So... Never mind :-/

    On second thought: If you insert 'delay 1' before any of the keystroke calls, as you suggested, it does work. It's not nice and quick like we'd want, but it ain't bad.
  • Yeah, the delay workaround is annoying. Hopefully one of these years Apple will give us a way to avoid the problem without the delay.
  • Just for something to do, here's a version without the delay. It's not bad, but I think I need to put some stuff in functions.

    -- This script makes a Safari window the size of the desktop, or toggles it to a more reasonable size by pressing the \"Zoom\" button.
    -- The size of the screen is hard coded to the size of the desktop minus the menu bar. If we try to detect the size of the screen, the returned value is the entire screen. The menu bar is not taken into account, and we never get to the 'else' side of the conditional. We could detect the other coordinates, but what's the point. ...cb
    tell application \"Safari\"
    activate
    -- check to see if Safari is already as big as it can be on a 1280x800 screen
    if bounds of window 1 is not equal to {0, 22, 1280, 800} then -- go as big as you can
    -- from: http://www.macosxhints.com/article.php?story=20060921045743404
    tell application \"System Events\"
    tell process \"Safari\"
    tell menu bar 1
    tell menu bar item \"View\"
    tell menu \"View\"
    click menu item \"Hide Bookmarks Bar\"
    click menu item \"Hide Status Bar\"
    click menu item \"Hide Tab Bar\"
    click menu item \"Hide Toolbar\"
    end tell
    end tell
    end tell
    end tell
    end tell
    set bounds of window 1 to {0, 22, 1280, 800}
    else
    tell application \"System Events\" to click button 2 of window 1 of process \"Safari\" -- push the green button. It's a quick way to get a moderate size window.
    -- opposite of above
    tell application \"System Events\"
    tell process \"Safari\"
    tell menu bar 1
    tell menu bar item \"View\"
    tell menu \"View\"
    click menu item \"Show Bookmarks Bar\"
    click menu item \"Show Status Bar\"
    click menu item \"Show Tab Bar\"
    click menu item \"Show Toolbar\"
    end tell
    end tell
    end tell
    end tell
    end tell
    end if
    end tell
  • I find this more readable - go figure :-/

    -- This script makes a Safari window the size of the desktop, or toggles it to a more reasonable size by pressing the \"Zoom\" button.
    -- The size of the screen is hard coded to the size of the desktop minus the menu bar. If we try to detect the size of the screen, the returned value is the entire screen. The menu bar is not taken into account, and we never get to the 'else' side of the conditional. We could detect the other coordinates, but what's the point. ...cb
    tell application \"Safari\"
    activate
    -- check to see if Safari is already as big as it can be on a 1280x800 screen
    if bounds of window 1 is not equal to {0, 22, 1280, 800} then -- go as big as you can
    -- from: http://www.macosxhints.com/article.php?story=20060921045743404
    tell application \"System Events\" to tell process \"Safari\" to tell menu bar 1 to tell menu bar item \"View\" to tell menu \"View\"
    click menu item \"Hide Bookmarks Bar\"
    click menu item \"Hide Status Bar\"
    click menu item \"Hide Tab Bar\"
    click menu item \"Hide Toolbar\"
    end tell
    set bounds of window 1 to {0, 22, 1280, 800}
    else
    tell application \"System Events\" to click button 2 of window 1 of process \"Safari\" -- push the green button. It's a quick way to get a moderate size window.
    -- opposite of above
    tell application \"System Events\" to tell process \"Safari\" to tell menu bar 1 to tell menu bar item \"View\" to tell menu \"View\"
    click menu item \"Show Bookmarks Bar\"
    click menu item \"Show Status Bar\"
    click menu item \"Show Tab Bar\"
    click menu item \"Show Toolbar\"

    end tell
    end if
    end tell
  • Here's a tweak:

    In the 'else' clause the "Show Tab Bar" needs to be last in the sequence.

    Explanation:

    If Safari is full screen, and there is more than one tab open, "Show Tab Bar" breaks the 'try' statement, and the "Show Toolbar" is never executed. I wondered why it didn't always work... Now it's perfect :O
  • Cool - thanks for updating us!
Start a New Discussion

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!