我需要收集哪个应用程序具有焦点。为此,我的方法是:列出窗口,获取具有焦点的窗口,最后,检查哪个进程和应用程序显示了它。如果有一些:getWindowWithFocus(),那就太棒了。
要求:
- 该程序是用C++实现的,但如果需要,可以与Objective-C接口。
- 程序将以root权限运行。
- 列出的窗口列表必须包括所有用户应用程序。
- 返回的窗口允许获取属性,例如它的进程以及它是否具有UI焦点。
- 理想情况下,不使用第三方工具,只使用标准库(STL,Unix API和macOS API,最终是Qt/Boost)。
- 必须支持HSierra到大苏尔。
我设法列出了所有窗口,但现在我正在努力检测窗口是否有焦点。
问题:
- 哪个API函数可以用来检查窗口是否有焦点?有示例吗?
- 有更好的方法来解决这个问题吗?
前期研究:
我创建了一个POC/sample,它列出了所有窗口,包括它的一些属性。
CGWindowListCopyWindowInfo
字符串
https://developer.apple.com/documentation/coregraphics/1455137-cgwindowlistcopywindowinfo?language=objc
免责声明:这是一个POC,只是为了演示,并错过了适当项目所需的代码质量。2例如,CFObjects没有释放,从而导致内存泄漏。
#include <CoreFoundation/CoreFoundation.h>
#include <CoreGraphics/CGWindow.h> // CoreGraphics
#include <iostream>
int main()
{
CFArrayRef ref = CGWindowListCopyWindowInfo(kCGNullWindowID, 0);
CFIndex nameCount = CFArrayGetCount( ref );
std::cout << "NumCounts: " << nameCount << " windows" << std::endl;
for( int i = 0; i < nameCount ; ++i )
{
std::cerr << " -------- " << std::endl;
CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex( ref, i );
auto printKeys = [](const void* key, const void* value, void* context)
{
CFShow(key);
std::cerr << " ";
CFShow(value);
};
CFDictionaryApplyFunction(dict, printKeys, nullptr);
// Process PID can be extracted with key:kCGWindowOwnerPID
// DOES THIS WINDOW HAS FOCUS?
}
}
型
2条答案
按热度按时间zzoitvuj1#
下面是一个例子,基于this solution,用C++(实际上主要是C) Package 。
唯一发现的问题是,它必须运行在主线程,这是不方便的,但这是另一个主题。
main.cpp:
字符串
focus_oc_wrapper.hpp
型
focus_oc_wrapper.mm
型
focus_oc.h
型
CMakeLists.txt
型
beq87vna2#
我最近需要自己做这件事,但没有接管主线程的问题。解决方案最终非常简单:
FocusedApplicationFinder.hpp
:字符串
FocusWrapper.mm
:型
如果你不熟悉objective-c集成,正如Adrian之前的回答所建议的,你所需要做的就是
ADD_EXECUTABLE
.mm
文件,这是objective-C和C++集成的文件类型。我已经包含了一些额外的代码来给予一个示例用例,这里唯一真正重要的是,您可以简单地调用
[[NSWorkspace sharedWorkspace] frontmostApplication]
来为当前最前端/重点应用程序获取NSRunningApplication*
。