设置非所有的窗口总是在顶部 - 像应用程序“Afloat” [英] Set non-owned window always on top - Like the app "Afloat"
问题描述
我已经用 RegisterEventHotkey
设置了一个全局热键。当用户按下它,它获得当前关注的窗口与 CGWindowListCopyWindowInfo
,然后我需要设置它总是在顶部。
如果当前窗口在我的进程(我从中执行代码),我可以简单地转换 windowNumber
从 CGWindowListCopyWindowInfo
到
NSWindow
并执行 setLevel
:
nswin = [NSApp windowWithWindowNumber:windowNumber]
[nswin setLevel:Int(CGWindowLevelForKey(kCGFloatingWindowLevelKey))]
我的问题 如果当前关注的窗口不在我的进程中,我无法执行此操作。
$ b
:
$ b- 这个名为Afloat的应用程序使用SIMBL来完成此操作。从任何窗口,你可以打Cmd + A,它将始终设置在顶部。然而,我想从我的正常的桌面应用程序的C / ObjC,而不使用帮助器如SIMBL。
-
我在
CGPrivate.h
中遇到CGSSetWindowLevel
stuff - https://gist.github.com/Noitidart/3664c5c2059c9aa6779f#file-cgsprivate-h- L63 - 但我记得我在过去尝试过这样的,但会得到一个错误,因为我试图连接到一个不在调用过程中的窗口。
-
只有窗口的所有者才能操作它。所以,苹果拥有一个普遍所有者的概念拥有所有的窗口,可以操纵他们所有。
-
也许,无论如何,假装我的调用过程暂时成为dock?
-
>
我的使用:我试图复制功能我的开源,免费的浏览器插件 - https://addons.mozilla.org/en-US/firefox/addon/topick/ - 所以我的调用过程如果Firefox。
解决方案
p>正如此答案中所述,如果您使用 orderFront
或 orderFrontRegardless
而不是 setLevel
。
在 setLevel
和 orderFront
/ 3124552>这回答。
对于另一个,orderFront :, makeKeyAndOrderFront :,和setLevel:do
工作。特别是,setLevel:将窗口放在整个其他
平面上,所以它总是在前面(或后面,取决于您选择的
级别)窗口与默认级别,无论什么你
do。
正如你已经可以集中窗口,这应该是你缺少的步骤。
希望这有帮助。
要控制其他进程的窗口,你可以使用苹果脚本,并使用工具,如 ASTranslate 。
示例:
告诉应用程序系统事件
将进程设置为最前面为真的第一个进程
将窗口设置为属性 AXFocusedWindow的过程
end tell
为了保持顶部使用 AXRaise
,或者如果您要更改公开范围,请这里解释
I have set up a global hotkey with RegisterEventHotkey
. When the user presses it, it gets the currently focused window with CGWindowListCopyWindowInfo
, and then I need to set it always on top.
If the current window is in my process (from which I am executing the code) I can simply convert the windowNumber
from CGWindowListCopyWindowInfo
to a NSWindow
and do setLevel
:
nswin = [NSApp windowWithWindowNumber:windowNumber]
[nswin setLevel: Int(CGWindowLevelForKey(kCGFloatingWindowLevelKey))]
My Problem I am not able to do this if the currently focused window is not in my process. Can you please show me how?
Stuff I tried:
- This app here named "Afloat" used "SIMBL" to accomplish this. From any window you can hit Cmd + A and it will set always on top. However I am trying to do with C/ObjC from my normal desktop app without the use of helpers like SIMBL.
I come across
CGSSetWindowLevel
inCGPrivate.h
- undocumented stuff - https://gist.github.com/Noitidart/3664c5c2059c9aa6779f#file-cgsprivate-h-L63 - However I recall I tried something like this in the past but would get an error as I tried to connect to a window that wasn't in the calling process.Only the owner of a window can manipulate it. So, Apple has the concept of a universal owner that owns all windows and can manipulate them all. There can only be one universal owner at a time (the Dock).
Maybe, is there anyway to pretend for my calling process to temporarily be the dock? Maybe
CGSGetConnectionIDForPSN
for the dock then use that connection?
My use: I'm trying to replicate the functionality my open source, free, browser addon - https://addons.mozilla.org/en-US/firefox/addon/topick/ - so my calling process if Firefox. It works on Windows and Linux right now, and just need to figure out how to do it in mac for non-Firefox windows.
As explained in this answer it will work if you used orderFront
or orderFrontRegardless
instead of setLevel
.
And the difference in setLevel
and orderFront
is explained in this answer.
For another, orderFront:, makeKeyAndOrderFront:, and setLevel: do work. In particular, setLevel: puts the window on an entire other plane, so it will always be in front of (or behind, depending on the level you choose) windows with the default level, no matter what you do.
As you can already focus the window, this should be the step you are missing. Hope this helps.
To take control of other process's windows you could use apple script and translate it to objective c code using a tool like ASTranslate.
Example:
tell application "System Events"
set theprocess to the first process whose frontmost is true
set thewindow to the value of attribute "AXFocusedWindow" of theprocess
end tell
For keeping it on top use AXRaise
or if you want to change visibility it's explained here
这篇关于设置非所有的窗口总是在顶部 - 像应用程序“Afloat”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!