Applescript access to last.fm app via application icon in menu bar - applescript

I want to create an Applescript to drive the last.fm player app. I'm trying to do this via last.fm application icon in the menu bar rather than using the main application menus, as this approach (I think) won't cause last.fm to switch to the foreground. The overall plan is to bind my script to a quicksilver trigger so I can stop|start|skip|love|ban|tag tracks from the keyboard.
My problem is I can't find what UI element to bind the applescript to. I've used UI Browser to scan through the UI object model but it draws a blank with the last.fm icon in the menu bar. Any thoughts appreciated.

Items in the menu bar are NSStatusItem and the part of the menu bar in which they live is an NSStatusBar. I suspect from past experience, though I am not sure, that if your applescript would have caused the main application to switch to the foreground, it will cause the menu bar item to switch to the foreground to the extent that it can, meaning that the application in the foreground will probably lose focus.

Related

Is there anyway to hide menubar items in MacOS?

I know I can "auto hide menu bar" in system preferences, however, what I like to do is hide items like this repository.
https://github.com/dwarvesf/hidden
This repository can hide items on right, but I wonder if I can hide left items (which are application menus).
Any idea is appreciated.
As for application menus on the left, those can't be hidden, I'm pretty sure.
Applications often have the option to enable or disable their menu bar helper app in the main preferences. If that doesn't help, e.g. if it's a full-fledged menu bar app, not just a helper, then to my knowledge the only solutions are Hidden Bar, which you mentioned, and Bartender.
I'm using the latter, and it does a very fine job. You have four options in Bartender's preferences:
Show (default macOS behavior)
Hide (menulet will be hidden in a special Bartender secondary menu bar, accessible via the triple-bullet icon ยทยทยท on the far right)
Always show (menulet will be visible in the main macOS menu bar as well as the secondary Bartender menu bar at the same screen position)
Always hide (menulet will be completely hidden)
Some older menulets seem to switch their position occasionally, e.g. after wake-from-sleep, and Bartender isn't yet able to fix the position of BitBar instances. But for the vast majority of menu bar apps and helpers it will work just fine.

Programmatically obtaining a Windows application's tray menu items

I have an application with a tray menu and I'm trying to automate some tests that involve the tray menu. Basically I need obtain the tray menu's items and do stuff with them.
However, I've only been able to find ways to programmatically obtain menu items for within the application. But my automation tests are going to be an external application, so that doesn't help me.
How can I obtain an external application's tray menu items programmatically?
There are ways to enumerate/access the tray icons themselves (usually involving hooking into the notification tray itself, or using UI Automation), but there is no way to access a popup menu that appears when a tray icon is clicked on. The reason is because the icon's owning application receives a message when the click occurs and then acts accordingly, which usually involves displaying its own popup menu. There is no menu associated with the icon itself.
For what you are attempting, you would have to enumerate the icons and figure out which icon belongs to the app you are interested in (not a trivial task on its own), then simulate a click on the icon so the app displays its popup menu. See the following question for some details:
Finding and simulating a click on a system tray icon?
Interacting with the popup menu once it is displayed will be more difficult. You won't have access to the menu itself. You will likely have to resort to just issuing mouse events via mouse_event() or SendInput() to move the mouse cursor over the menu and click its items (assuming they appear in predictable locations relative to the icon).
If you can obtain the icon's HWND+ID or GUID (by hooking the notification tray itself), you can use Shell_NotifyIconGetRect() to get the icon's coordinates, at least.
How can I obtain an external application's tray menu items programmatically?
You cannot. There is no public API that provides access to notification icons.
Depending on what sort of assumptions you find acceptable, you can programmatically interact with the taskbar button's menu once it's visible. The image below shows the Inspect SDK tool reporting properties on the OneNote clipping tool button's menu. (And the menu items say they support the UIA Invoke Patten, so they should be programmatically invokable by UIA client code.)
If you want to invoke your tray button's menu items, you might consider the following steps using UIA. You may feel the assumptions that I make here are unacceptable for your situation.
Find the element with a class name "NotifyIconOverflowWindow", that's a direct child of the root menu. I'm assuming the button is in the overflow area.
Enumerate the children of the overflow element, looking for a button with the name of your button. This assumes the UI language is known and accounted for.
Get the bounding rect of the button and simulate a mouse right-click on the button. The click simulation is necessary because I'll bet the UI doesn't support IUIAutomationElement3::ShowContextMenu(), (but you could always try it).
Once the context menu's up, find the element with a ControlType a Menu, a Name of "Context", that's a direct child of the root element.
Once you have the menu, enumerate the child elements in the menu to find the items, and do what you want with them. Eg get the menu item's Invoke pattern and invoke it.

OSX Fullscreen API and Menu Bar

When using the OSX FullScreen API, is there a way to detect whether the Menu Bar (or the Dock, for that matter) are currently being displayed over top of your application?
For example, a delegate which notifies the application when the Menu Bar animates in, and then sends another notification when the Menu Bar animates out?
NSMenu.menuBarVisible()
there's also NSMenuBarDelegate protocol which has menuWillOpen() and menuWillClose(). but so far I haven't gotten any luck with this one

Background application with menu bar

I have an application which I would like to hide from the dock. Therefore Application is agent (UIElement) to YES.
Still, I would like to show a window to the user and therefore I would like to show a menu bar and have the window shown in the task switcher (CMD+Tab). Is there any way to do this?
Not as such, no. That's part of the meaning of UIElement. It can show windows, but not have a menu bar nor an icon in the Dock or application switcher (which is run by the Dock).
You can transform a UIElement to a normal application using -[NSApplication setActivationPolicy:] but not back again.
Your UIElement could launch a helper application to present the GUI, which would then quit when it's done. That might achieve the effect you're looking for, but will of course be more complicated.
I wouldn't do this. It's not the apple way and just gets confusing.
I guess NSMenuItem would be a good way to solve this.

Is there a way to make changes to the titlebar with GTK2?

I have a desktop application written in Ruby that is using GTK2. It's just a small test application to play with GTK2, but I'm having problems achieving what I want to do. Is there any way using GTK2 to get at the titlebar (apart from setting the title), specifically to either add a button to it (beside the min/max/etc, B in the below diagram) or to add an option to the menu that pops up when you click the icon on the titlebar (A in the below diagram)?
I'm thinking there might not be because GTK is meant to work with many many different window managers, but I just wondered if there was. As a side question, what event does clicking the 'cross' button fire? At the moment if the user clicks that the window disappears but the program doesn't end - I need to capture that event and quit the program.
Thanks for any help, including hitting me over the head and telling me how silly I am.
Note that this is possible in GTK 3.10 and up, by using gtk_window_set_titlebar(). It replaces the window manager's title bar with a custom one. GtkHeaderBar is a good custom title bar class to use.
You can't, however, make it look just like the window manager would, because you won't know which window manager the user is running.
No, the title bar is owned by the window manager and you will typically not have direct access to it.
When the user tries to close the window by clicking the window manager's button, the window will receive the delete event.

Resources