I am considering specifying windows and manipulating them on macOS. To do this, I researched how to list window IDs. When creating a program that operates using macOS features, implementing it in Objective-C or Swift is more straightforward since documentation is available on the official website.
In fact, there are others who have done similar things. GetWindowID implements the functionality to obtain window IDs. While this code is quite small, I will extract the essential parts from that code and confirm its functionality.
I will use Cocoa and CoreGraphics to retrieve the window ID.
#include <Cocoa/Cocoa.h>
#include <CoreGraphics/CGWindow.h>
int main(int argc, char **argv) {
NSArray *windows = (NSArray *)CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements,
kCGNullWindowID);
for(NSDictionary *window in windows) {
NSString *currentApp = window[(NSString *)kCGWindowOwnerName];
NSString *currentWindowTitle = window[(NSString *)kCGWindowName];
printf("%10d : %-50s : %s\n",
[window[(NSString *)kCGWindowNumber] intValue],
currentApp.UTF8String,
currentWindowTitle.UTF8String);
}
printf("Okay\n");
}
I use clang to build it. Since I am using the Cocoa and CoreGraphics frameworks, I pass them as optional arguments.
clang ListWindowId.m -o ListWindowIdObc -framework CoreGraphics -framework Cocoa
When this is executed, it outputs a list in the format Window ID : Application Name : Window Title
to standard output.
If it can be done in Objective-C
, it can certainly be done in Swift as well. Let’s also check the implementation method in Swift.
import Cocoa
import CoreGraphics
func main() {
let windows = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID) as! [[String: Any]]
for window in windows {
let windowId = window[kCGWindowNumber as String] as! Int
let appName = window[kCGWindowOwnerName as String] as! String
let title = (window[kCGWindowName as String] as? String) ?? ""
print(String(format:"%d: %@ : %@", windowId, appName, title))
}
}
main()
To run it without producing a binary file, use the swift
command.
swift ListWindowId.swift
Let’s make it possible to verify this implementation from Emacs.
(setq macos-window-list-executable
(let ((exec-path (list (expand-file-name "~/ng/symdon/articles/posts/1729078231"))))
(executable-find "ListWindowIdObc")))
(defun macos-window-list ()
(interactive)
(shell-command macos-window-list-executable))
(provide 'macos-window-list)
;; macos-window-list.el ends here