"passthrough" click_script for alias #236
Replies: 4 comments 3 replies
-
scrap findings with System EventsI threw a lot of time down this well with little success It seems like what we care mostly/(exclusively?) is UI Elements with property I wrote some manual filtering for that after I found that some apps (like iStats) were in fact populating stuff into wip AliasHelper.scptscript AliasHelper
property theApp : null
property menuBar : null
property menuItem : null
on findBar(whatApp)
set theApp to whatApp
tell application "System Events"
tell process whatApp
repeat with n from 1 to count of menu bars
set mi to properties of first menu bar item of menu bar n
if (mi contains {subrole:"AXMenuExtra"}) then set menuBar to (a reference to menu bar n)
end repeat
end tell
end tell
end findBar
-- also started an on findItem, but didn't seem to go anywhere
end script
But then I come to realize that the menu bar with the items, at least seems to be reliably advertised under the "AXExtrasMenuBar" attribute so (as continues to work with Fantastical and not others), we can at least change the call from the first google answerto the slightly more general set processName to "Fantastical Helper" --e.g.
tell application "System Events" to tell (value of attribute "AXExtrasMenuBar" of process processName ) to click first menu bar item calling |
Beta Was this translation helpful? Give feedback.
-
Some time ago I did some tinkering with this as well. I ultimately stopped experimenting with it since I was not able to move the popup window to the appropriate location below sketchybar. Maybe it is possible via the AX API but I was not successful. I can contribute this snippet which I used for testing: helper.c #include <Carbon/Carbon.h>
void ax_init() {
const void *keys[] = { kAXTrustedCheckOptionPrompt };
const void *values[] = { kCFBooleanTrue };
CFDictionaryRef options;
options = CFDictionaryCreate(kCFAllocatorDefault,
keys,
values,
sizeof(keys) / sizeof(*keys),
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks );
AXIsProcessTrustedWithOptions(options);
CFRelease(options);
}
void ax_perform_click(AXUIElementRef element) {
if (!element) return;
AXUIElementPerformAction(element, kAXPressAction);
}
AXUIElementRef ax_get_extra_menu_item(AXUIElementRef app, char* name) {
AXUIElementRef extra_menus_ref = NULL;
CFTypeRef extra_menu = NULL;
CFArrayRef children_ref = NULL;
AXError error = AXUIElementCopyAttributeValue(app,
kAXExtrasMenuBarAttribute,
(CFTypeRef*)&extra_menus_ref);
if (app) CFRelease(app);
if (error == kAXErrorSuccess) {
error = AXUIElementCopyAttributeValue(extra_menus_ref,
kAXVisibleChildrenAttribute,
(CFTypeRef*)&children_ref);
uint32_t count = CFArrayGetCount(children_ref);
if (count == 1 || (count > 0 && !name)) {
extra_menu = CFRetain(CFArrayGetValueAtIndex(children_ref, 0));
} else {
// Loop through array and find correct item via name...
}
CFRelease(extra_menus_ref);
CFRelease(children_ref);
}
return (AXUIElementRef) extra_menu;
}
int main (int argc, char **argv) {
ax_init();
pid_t pid = 0;
if (argc > 1) {
char* pid_str = argv[1];
pid = strtol(pid_str, NULL, 10);
}
if (!pid) return 1;
AXUIElementRef app = AXUIElementCreateApplication(pid);
AXUIElementRef menu = ax_get_extra_menu_item(app, NULL);
ax_perform_click(menu);
return 0;
} (compile with which presses on a menu item when given the pid of the parent process. e.g. with ./helper $(pidof MeetingBar) Note that the current implementation will always click the "first" item. If there is more than one the |
Beta Was this translation helpful? Give feedback.
-
Re moving into place: Well, its not NOT madness 1 but, for the record/public-interest, the following (alongside the Not sure how much of it is strictly dependent on the private apis and scripting-additions of yabai vs what might be more easily available to sketchybar directly (it probably could mostly also be achieved similarly with a "simple"
ALIAS_NAME="iStat Menus Status,com.bjango.istatmenus.time"
sketchybar --add alias "$ALIAS_NAME" right
APP_NAME="${ALIAS_NAME%,*}"
# making floa
yabai -m rule --add app="$APP_NAME" manage=off #mouse_follows_focus=on
X_SPOT=$(sketchybar --query "$ALIAS_NAME" | jq '.bounding_rects."display-1".origin[0]')
yabai -m signal --add app="${ALIAS_NAME%,*}" event=window_created action="$(cat <<EOS
bash -c "
#for debugging:
#set -x; exec > $HOME/output.txt; exec 2> $HOME/output.txt
X_SPOT=$X_SPOT;"\
'ffm=\$(yabai -m config focus_follows_mouse)
mff=\$(yabai -m config mouse_follows_focus)
yabai -m config focus_follows_mouse off
yabai -m config mouse_follows_focus off
INFO="\$(yabai -m query --windows --window \$YABAI_WINDOW_ID)"
# echo "\$INFO"
WIDTH="\$(echo "\$INFO" | jq "(.frame.w)|floor")"
REAL_X_SPOT=\$(( \$X_SPOT - \$WIDTH/2 ))
yabai -m window \$YABAI_WINDOW_ID --move abs:\$REAL_X_SPOT:25 --focus
yabai -m config mouse_follows_focus \$mff
yabai -m config focus_follows_mouse \${ffm//disabled/off}'
EOS
)" In addition to handling the major "bug" I'm seeing as in 2 below, it could probably/definitely be otherwise tightened up to not (in other cases) ~false-positive; and probably, you know, use labels on the rules and signals to create some level of idempotence? also possiblt worth caching the width and/or desired spot after the first call. Footnotes
|
Beta Was this translation helpful? Give feedback.
-
Self-quoting most recent message (#236 (reply in thread)) :
I'm not gonna fall prey to digging into it at least at the moment, (cause its 3am and I should go to sleep and/cause like ... I don't even know Swift (or Obj C really) - but it seems like this nut might have been cracked and shared by either https://github.com/dwarvesf/hidden |
Beta Was this translation helpful? Give feedback.
-
I wanted to pull forward the unfurl of an item mirrored on click of an alias.
I assume someone else has done this (and if you have a different/better version please share 😬), but I didn't find it so I wanted to share my AppleScript versions. - which ... mostly work
[Probably the logic here could be more succinctly/reliably turned into Objective C if Felix is inclined or someone wants to PR; either into sketchybar per se or as an accessory process]
What google mostly says, which mostly doesn't work
This approach worked in my very first testing with (only) Fantastical!
sketchybar --default \ click_script='osascript -e "tell application \\"System Events\\" to tell process \\"${NAME%,*}\\" to tell first menu bar item of menu bar 2 to click"'
Alas for pretty much* everything else this returns
missing value
with no sign of life.I also had no better luck with
perform action "AXPress"
(nor other guesses like e.g. directing the click to occur at the site of item, trying to direct the click/action through the menu bar delegate, etc.; unhiding menu bar didn't seem to change; callingactivate
,select
)*the exception that proved the rule was "CleanShot X", which did respond with unfurl to the click, but only after I first manually made it visible by opening the Bartender Menu - this is part of what leads to...
Imperfect but works: Bartender 4
Pro: Seems to work across items
Cons:
yabai -m config mouse_follows_focus on
moves mouse there but for others no)If like me, you are half-committed to the the sketchybar lifestyle, you probably have Bartender running still;
and in checking OSA dictionaries I found it exposes a scripting hook for activating arbitrary menu bar items.
the
sketchybarrc
"one"-linerI arrived at this version later, and it's probably the saner place to start. It doesn't require/create extra files - its slow in theory but idk that its super noticeable.
the AppleScript maximalist approach (w/ JIT + memoized compilation)
I spent hours doing premature optimization (and remembering how ✨interesting 🤔 OSA is) and you can (benefit from it) too!
sketchybarrc
$PLUGIN_DIR/bartender_dispatcher.scpt
the first time you run this it will move itself (the source code) version to
${path}.src
- and also will attempt to create the per-alias storage location from the third arg of the first call (so$PLUGIN_DIR/bartender/
as shown above).There might be some small speedup if you reconfig
there is/are probably also middle ground(s) between these two extremes
Beta Was this translation helpful? Give feedback.
All reactions