5#include <AppKit/AppKit.h>
7#include <qpa/qplatformtheme.h>
12#include <qpa/qplatformscreen.h>
13#include <private/qguiapplication_p.h>
14#include <private/qwindow_p.h>
15#include <QtGui/private/qcoregraphics_p.h>
27Q_LOGGING_CATEGORY(lcQpaScreen,
"qt.qpa.screen", QtCriticalMsg);
30Q_LOGGING_CATEGORY(lcQpaDialogs,
"qt.qpa.dialogs")
31Q_LOGGING_CATEGORY(lcQpaMenus,
"qt.qpa.menus")
32Q_LOGGING_CATEGORY(lcQpaAccessibility,
"qt.qpa.accessibility")
38QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *array)
41 for (NSString *string in array)
42 result << QString::fromNSString(string);
48 NSMutableArray<NSString *> *result = [NSMutableArray<NSString *> arrayWithCapacity:list.size()];
49 for (
const QString &string : list)
50 [result addObject:string.toNSString()];
62 { NSDragOperationLink, Qt::LinkAction,
true },
63 { NSDragOperationMove, Qt::MoveAction,
true },
64 { NSDragOperationDelete, Qt::MoveAction,
true },
65 { NSDragOperationCopy, Qt::CopyAction,
true },
66 { NSDragOperationGeneric, Qt::CopyAction,
false },
67 { NSDragOperationEvery, Qt::ActionMask,
false },
68 { NSDragOperationNone, Qt::IgnoreAction,
false }
73 for (
int i=0;
dnd_enums[i].qt_code; i++) {
78 return NSDragOperationNone;
83 NSDragOperation nsActions = NSDragOperationNone;
84 for (
int i=0;
dnd_enums[i].qt_code; i++) {
93 Qt::DropAction action = Qt::IgnoreAction;
94 for (
int i=0;
dnd_enums[i].mac_code; i++) {
103 Qt::DropActions actions = Qt::IgnoreAction;
105 for (
int i=0;
dnd_enums[i].mac_code; i++) {
106 if (dnd_enums[i].mac_code == NSDragOperationEvery)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
133 return qt_objc_cast<QNSView *>(view);
144 bool forceTransform =
true;
145 CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
146 CFSTR(
"LSUIElement"));
148 CFTypeID valueType = CFGetTypeID(value);
151 if (valueType == CFStringGetTypeID())
152 forceTransform = !(QString::fromCFString(
static_cast<CFStringRef>(value)).toInt());
153 else if (valueType == CFBooleanGetTypeID())
154 forceTransform = !CFBooleanGetValue(
static_cast<CFBooleanRef>(value));
155 else if (valueType == CFNumberGetTypeID()) {
157 CFNumberGetValue(
static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
158 forceTransform = !valueAsInt;
162 if (forceTransform) {
163 value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
164 CFSTR(
"LSBackgroundOnly"));
166 CFTypeID valueType = CFGetTypeID(value);
167 if (valueType == CFBooleanGetTypeID())
168 forceTransform = !CFBooleanGetValue(
static_cast<CFBooleanRef>(value));
169 else if (valueType == CFStringGetTypeID())
170 forceTransform = !(QString::fromCFString(
static_cast<CFStringRef>(value)).toInt());
171 else if (valueType == CFNumberGetTypeID()) {
173 CFNumberGetValue(
static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
174 forceTransform = !valueAsInt;
179 if (forceTransform) {
180 [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
187 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR(
"CFBundleName"));
189 appName = QString::fromCFString(
static_cast<CFStringRef>(string));
191 if (appName.isEmpty()) {
192 QString arg0 = QGuiApplicationPrivate::instance()->appName();
193 if (arg0.contains(
"/")) {
194 QStringList parts = arg0.split(u'/');
195 appName = parts.at(parts.count() - 1);
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
224 return QPointF(pos.x(), reference.height() - pos.y());
229 return QRectF(qt_mac_flip(rect.bottomLeft(), reference), rect.size());
235
236
237
238
239
240
241
242
243
246 if (buttonNum >= 0 && buttonNum <= 31)
247 return Qt::MouseButton(1 << buttonNum);
252
253
254
255
256
257
258
259
260
261
262
263
266 if (cocoaEvent2QtMouseEvent(event) == QEvent::MouseMove)
269 switch (event.type) {
270 case NSEventTypeRightMouseUp:
271 case NSEventTypeRightMouseDown:
272 return Qt::RightButton;
278 return cocoaButton2QtButton(event.buttonNumber);
282
283
284
285
288 switch (event.type) {
289 case NSEventTypeLeftMouseDown:
290 case NSEventTypeRightMouseDown:
291 case NSEventTypeOtherMouseDown:
292 return QEvent::MouseButtonPress;
294 case NSEventTypeLeftMouseUp:
295 case NSEventTypeRightMouseUp:
296 case NSEventTypeOtherMouseUp:
297 return QEvent::MouseButtonRelease;
299 case NSEventTypeLeftMouseDragged:
300 case NSEventTypeRightMouseDragged:
301 case NSEventTypeOtherMouseDragged:
302 return QEvent::MouseMove;
304 case NSEventTypeMouseMoved:
305 return QEvent::MouseMove;
316 return cocoaEvent2QtMouseEvent(event) != QEvent::None;
320
321
322
323
326 return static_cast<Qt::MouseButton>(pressedMouseButtons & Qt::MouseButtonMask);
330
331
332
333
336 return cocoaMouseButtons2QtMouseButtons(NSEvent.pressedMouseButtons);
341 return QPlatformTheme::removeMnemonics(s).trimmed();
346 static const NSBundle *appKit = [NSBundle bundleForClass:NSApplication.
class];
350 return [appKit localizedStringForKey:key value:nil table:table];
356
357
358
359
360
361
362
363
364@implementation QNSPanelContentsWrapper {
366 NSButton *_cancelButton;
367 NSView *_panelContents;
368 NSEdgeInsets _panelContentsMargins;
371@synthesize okButton = _okButton;
372@synthesize cancelButton = _cancelButton;
373@synthesize panelContents = _panelContents;
374@synthesize panelContentsMargins = _panelContentsMargins;
376- (instancetype)initWithPanelDelegate:(id<QNSPanelDelegate>)panelDelegate
378 if ((self = [super initWithFrame:NSZeroRect])) {
380 _okButton = [self createButtonWithTitle:QPlatformDialogHelper::Ok];
381 _okButton.action = @selector(onOkClicked);
382 _okButton.target = panelDelegate;
383 _cancelButton = [self createButtonWithTitle:QPlatformDialogHelper::Cancel];
384 _cancelButton.action = @selector(onCancelClicked);
385 _cancelButton.target = panelDelegate;
387 _panelContents = nil;
389 _panelContentsMargins = NSEdgeInsetsMake(0, 0, 0, 0);
399 [_cancelButton release];
402 _panelContents = nil;
407- (NSButton *)createButtonWithTitle:(QPlatformDialogHelper::StandardButton)type
409 NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect];
410 button.buttonType = NSButtonTypeMomentaryLight;
411 button.bezelStyle = NSBezelStyleRounded;
412 const QString &cleanTitle =
413 QPlatformTheme::removeMnemonics(QGuiApplicationPrivate::platformTheme()->standardButtonText(type));
415 button.title = (NSString *)cleanTitle.toCFString();
416 ((NSButtonCell *)button.cell).font =
417 [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]];
418 [self addSubview:button];
424 static const CGFloat ButtonMinWidth = 78.0;
425 static const CGFloat ButtonMinHeight = 32.0;
426 static const CGFloat ButtonSpacing = 0.0;
427 static const CGFloat ButtonTopMargin = 0.0;
428 static const CGFloat ButtonBottomMargin = 7.0;
429 static const CGFloat ButtonSideMargin = 9.0;
431 NSSize frameSize = self.frame.size;
433 [self.okButton sizeToFit];
434 NSSize okSizeHint = self.okButton.frame.size;
436 [self.cancelButton sizeToFit];
437 NSSize cancelSizeHint = self.cancelButton.frame.size;
439 const CGFloat buttonWidth = qMin(qMax(ButtonMinWidth,
440 qMax(okSizeHint.width, cancelSizeHint.width)),
441 CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
442 const CGFloat buttonHeight = qMax(ButtonMinHeight,
443 qMax(okSizeHint.height, cancelSizeHint.height));
445 NSRect okRect = { { frameSize.width - ButtonSideMargin - buttonWidth,
446 ButtonBottomMargin },
447 { buttonWidth, buttonHeight } };
448 self.okButton.frame = okRect;
449 self.okButton.needsDisplay = YES;
451 NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - buttonWidth,
452 ButtonBottomMargin },
453 { buttonWidth, buttonHeight } };
454 self.cancelButton.frame = cancelRect;
455 self.cancelButton.needsDisplay = YES;
458 if (!self.panelContents)
459 for (NSView *view in self.subviews)
460 if (view != self.okButton && view != self.cancelButton) {
461 _panelContents = view;
465 const CGFloat buttonBoxHeight = ButtonBottomMargin + buttonHeight + ButtonTopMargin;
466 const NSRect panelContentsFrame = NSMakeRect(
467 self.panelContentsMargins.left,
468 buttonBoxHeight + self.panelContentsMargins.bottom,
469 frameSize.width - (self.panelContentsMargins.left + self.panelContentsMargins.right),
470 frameSize.height - buttonBoxHeight - (self.panelContentsMargins.top + self.panelContentsMargins.bottom));
471 self.panelContents.frame = panelContentsFrame;
472 self.panelContents.needsDisplay = YES;
474 self.needsDisplay = YES;
484InputMethodQueryResult queryInputMethod(QObject *object, Qt::InputMethodQueries queries)
487 QInputMethodQueryEvent queryEvent(queries | Qt::ImEnabled);
488 if (QCoreApplication::sendEvent(object, &queryEvent)) {
489 if (queryEvent.value(Qt::ImEnabled).toBool()) {
490 InputMethodQueryResult result;
491 static QMetaEnum queryEnum = QMetaEnum::fromType<Qt::InputMethodQuery>();
492 for (
int i = 0; i < queryEnum.keyCount(); ++i) {
493 auto query = Qt::InputMethodQuery(queryEnum.value(i));
495 result.insert(query, queryEvent.value(query));
508 if (range.location == NSNotFound) {
509 QDebugStateSaver saver(debug);
510 debug.nospace() <<
"{NSNotFound, " << range.length <<
"}";
512 debug << NSStringFromRange(range);
519 debug << NSStringFromSelector(selector);
\inmodule QtCore\reentrant
Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)
Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
NSString * qt_mac_AppKitString(NSString *table, NSString *key)
Qt::MouseButton cocoaButton2QtButton(NSEvent *event)
Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
QNSView * qnsview_cast(NSView *view)
Returns the view cast to a QNSview if possible.
QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
Returns the QEvent::Type that corresponds to an NSEvent.type.
Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
QString qt_mac_applicationName()
QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference)
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
void qt_mac_transformProccessToForegroundApplication()
static dndenum_mapper dnd_enums[]
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions)
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions)
QString qt_mac_removeAmpersandEscapes(QString s)
QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference)
Flips the Y coordinate of the point/rect between quadrant I and IV.
bool qt_mac_isMouseEvent(NSEvent *event)
NSDragOperation qt_mac_mapDropAction(Qt::DropAction action)
NSMutableArray< NSString * > * qt_mac_QStringListToNSMutableArray(const QStringList &list)
Qt::MouseButtons currentlyPressedMouseButtons()
Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
QDebug operator<<(QDebug debug, QDir::Filters filters)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
QDebug operator<<(QDebug dbg, const QFileInfo &fi)