iTunes迷你播放器(仅举一个例子)支持点击,当使用播放/暂停和音量控制时,应用程序不会被带到前面.
这是怎么做到的?
我一直在查看Apple的文档,并在Cocoa事件处理指南,事件调度中指出:
某些事件(其中许多是由Application Kit定义的(类型为NSAppKitDefined))与由窗口或应用程序对象本身控制的操作有关.这些事件的示例是与激活,停用,隐藏和显示应用程序相关的事件.NSApp在其调度例程的早期过滤掉这些事件并自行处理它们.
因此,从我有限的理解(如何一个事件进入Cocoa,应用程序)子类化NSApplication和覆盖
- (void)sendEvent:(NSEvent *)theEvent应该捕获每个鼠标和键盘事件,但仍然,窗口是单击时引发的.因此,在NSApplication看到事件之前窗口会被提升,或者我错过了其他内容.
我通过重新创建它看了Matt Gallagher的Demystifying NSApplication,不幸的是Matt没有覆盖事件队列,所以除此之外,我很难过.
任何帮助将不胜感激,谢谢.
编辑补充:在劳埃德休息室找到一个帖子,他在讲述同样的问题并链接到CocoaBuilder的帖子,首先捕获右键.我正在尝试在那里提供的代码,在一些摆弄并重新激活[theEvent类型]的NSLog之后,鼠标左键活动被捕获.
现在,左键单击窗口将其向前移动会生成一系列事件类型13, 1, 13,这些类型分别是NSAppKitDefined,NSLeftMouseDown和NSAppKitDefined.我可以过滤掉它们或找到它们的去向吗?
我一直在搜索Apple文档,我唯一能找到的关于双击的功能只是返回了点击之间的可接受时间,因为它被认为是双击.
有人可以给我看一个双击事件的例子吗?
好的,我知道如何从NSEvent确定是否按下了modifierkey:
if ([theEvent modifierFlags] & NSAlternateKeyMask) {
// The Option/Alt key was pressed
}
Run Code Online (Sandbox Code Playgroud)
但是这也同时捕获了optionkey和另一个modifierkey,例如Option + Shift,或者与optionkey的任意组合.
如何仅测试选项键而不测试其他任何内容?
我在OS X检测按键时遇到问题。每当按下键盘键时,我都需要检测按键按下,释放或按键释放。当使用拦截应用程序的事件处理链时,这非常简单[ NSEvent addLocalMonitorForEventsMatchingMask: handler: ]。这样,您可以截取和修改NSEvents的各种事件类型,包括NSKeyUp和NSKeyDown常规打印键,以及NSFlagsChanged可用于检测shift,ctrl,alt和cmd键的s 。事实上,由于修正标志更改两个关键起来为Shift,Ctrl,Alt和CMD键按下按键,NSFlagsChanged可以用来作为检查的重要上升,键按下事件对于那些键[NSEvent modifierFlags]与一起[NSEvent keyCode]。
但Capslock是不同的。因为capslock修饰符实际上仅作用于向下按下键,所以当您按下capslock时,只会获得NSFlagsChanged带有capslock的按下,而不是在释放时按下。并且NSKeyUp和NSKeyDown不会与Capslock和shift和ctrl等修饰键一起发出。
任何人都可以建议一种方法,甚至可以使用较低级别的界面来获取capslock键启动事件吗?我是否将不得不使用kqueues或其他东西?
假设我有一个浮动的、无边框的、圆形的NSWindow。
它是圆形的,因为内容视图只是绘制了一个红色圆圈。
该内容视图需要是图层支持的 ( [contentView setWantsLayer:YES]),因为我正在其上应用CoreAnimations,例如动画缩放。
通常,NSWindow 的可点击区域是由内容视图像素的透明度定义的。然而,不幸的是,一旦 NSWindow 的内容视图变得受图层支持,透明区域也会收到点击。
就我而言,这是一个严重的问题,因为我只想接收半径内的点击。但现在,在窗口矩形内但超出圆半径的单击将激活窗口(从而激活整个应用程序),但事实并非如此。该窗口还可以通过其内容视图的一角进行拖动。

我最初的想法是在子类中实现[NSWindow sendEvent:]并检查单击是否在半径内执行,使用[theEvent locationInWindow]. 我想我可以简单地丢弃该事件,如果它超出了半径,那么就不再调用[super sendEvent:theEvent]。然而这不起作用:我注意到, mouseDown:; window 方法甚至在 sendEvent:; 之前被调用 方法。
我搜索了很多,但我发现的唯一想法是在窗口顶部有一个类似非层支持的 NSWindow 的代理,它有条件地委托点击,但这会导致不可预测的 UI 行为。
你们有什么想法,如何解决吗?
我正在尝试模拟 Spotlight 在 Yosemite 中的工作方式,其中 NSTextField(搜索字段)在按下向上/向下箭头键并上下移动表格视图选择时始终保持焦点。
\n\n我已经实现了以下代码:
\n\n- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector\n{\n if (commandSelector == @selector(moveUp:)) {\n // move up\n return YES;\n } else if(commandSelector == @selector(moveDown:)){\n // move down\n return YES;\n }\n\n return NO;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n虽然我可以使用它来向上/向下移动行选择,例如:
\n\n[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:currentRow \xc2\xb1 1] byExtendingSelection:NO];\nRun Code Online (Sandbox Code Playgroud)\n\n我遇到的问题是我创建了不应选择的节标题行,并且我已使用 NSTableViewDelegate 方法禁用了对这些行的选择:
\n\n- (BOOL)tableView: (NSTableView *)tableView shouldSelectRow: (NSInteger)row\nRun Code Online (Sandbox Code Playgroud)\n\n但发生的情况是selectRowIndexes:indexSetWithIndex:currentRowbyExtendingSelection:即使委托方法表明无法选择该行,该方法也会选择标题行。
无论 NSTableViewDelegate 说什么,您似乎仍然可以以编程方式选择行。我想要的是选择跳过标题行。
\n\n如果 NSTableView 是firstResponder则内置键盘控件会跳过标题行。
所以我的问题是有没有办法将向上/向下事件转发到 NSTableView 以便移动选择的内置机制起作用?
\n我一直在尝试(从事件处理程序中)确定哪个键盘触发了该事件。我一直在使用这两篇文章:
在第二篇文章中,作者使用Carbon技术成功地分离了键盘,但是使用Cocoa尝试相同的技巧失败了。
在我自己的系统上,两者都失败了,可能是因为我的无线键盘也是苹果制造的,所以可能报告的标识符与内置键盘相同。
在第一篇文章中,有人提出了一种解决方案,该方案在较低级别(可以区分键盘)上监视键盘事件,并将此数据存储在队列中,然后让事件处理程序检索信息。
这看起来有些毛茸茸,所以我只是在这里检查是否有人发现了更好的东西。
这是我的代码,展示了在事件处理程序中区分键盘的失败:
// compile and run from the commandline with:
// clang -fobjc-arc -framework Cocoa -framework Carbon ./tap_k.m -o tap_k
// sudo ./tap_k
#import <Foundation/Foundation.h>
#import <AppKit/NSEvent.h>
//#import <CarbonEventsCore.h>
#include <Carbon/Carbon.h>
typedef CFMachPortRef EventTap;
// - - - - - - - - - - - - - - - - - - - - -
@interface KeyChanger : NSObject
{
@private
EventTap _eventTap;
CFRunLoopSourceRef _runLoopSource;
CGEventRef _lastEvent;
}
@end
// - - - …Run Code Online (Sandbox Code Playgroud) 我有基于NSTextView的组件,我想禁用它上面的单击,这样它的插入点不会受到这些单击的影响,但仍然能够为复制和粘贴工作选择文本片段:
我想要的正是我们默认的终端应用程序:有插入点,无法通过鼠标点击更改它,但仍然可以选择文本进行复制和粘贴.
我试过看- (void)mouseDown:(NSEvent *)theEvent方法,但没有找到任何帮助.
我正在尝试在OS X用户拖动OS X中的任何文件时收到通知,而不仅仅是在我的应用程序中.
我目前的做法是使用addGlobalMonitorForEventsMatchingMask:handler:上NSEvent,具体如下:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask handler:^(NSEvent* event) {
NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
NSLog(@"%@", [pb propertyListForType:NSFilenamesPboardType]);
}];
Run Code Online (Sandbox Code Playgroud)
这部分工作 - 当我开始从桌面或Finder中拖动文件时调用处理程序,但是当我执行包含鼠标左键拖动的所有其他操作(例如移动窗口)时也会调用它.问题是NSDragPboard仍然似乎包含最新的拖动文件URL,例如当我放开文件并开始移动窗口时,这使得很难区分这些操作.
TL; DR - 我对系统范围内的文件拖动操作感兴趣.我不需要有关拖动文件本身的任何信息,只需要文件拖动操作已启动或停止的信息.我将不胜感激任何暗示这个问题的可能解决方案.
我目前正在开发一个适用于 iOS 和 macOS 的跨平台应用程序,使您的 iOS 设备充当触控板。
使用CGDisplayMoveCursorToPoint,我可以在屏幕上移动光标。奇迹般有效。通过“主机”应用程序(即在 macOS 上运行)中的这段代码,我可以单击鼠标:
let currentPosition = foo() // call to my helper function
// that translates NSEvent.mouseLocation()
let downEvent = CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseDown,
mouseCursorPosition: currentPosition,
mouseButton: .left
)
let upEvent = CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseUp,
mouseCursorPosition: currentPosition,
mouseButton: .left
)
downEvent?.post(tap: CGEventTapLocation.cghidEventTap)
upEvent?.post(tap: CGEventTapLocation.cghidEventTap)
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。
现在我想在iOS设备上用两根手指实现滚动。问题不在于 iOS 和 macOS 之间的通信(顺便说一句,PeerTalk 很棒),而是我似乎无法在主机上触发滚动事件。
起初,我尝试了这样的事情:
let eventSource = CGEventSource(stateID: .hidSystemState)
let event = CGEvent(
mouseEventSource: eventSource,
mouseType: .scrollWheel,
mouseCursorPosition: currentPosition,
mouseButton: …Run Code Online (Sandbox Code Playgroud) nsevent ×10
cocoa ×9
macos ×5
keyboard ×2
objective-c ×2
appkit ×1
calayer ×1
iokit ×1
macos-carbon ×1
modifier-key ×1
mouseevent ×1
nstableview ×1
nstextview ×1
nswindow ×1